-
Notifications
You must be signed in to change notification settings - Fork 65
121 lines (108 loc) · 4.47 KB
/
rotate_sonar_token.yml
File metadata and controls
121 lines (108 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
name: Rotate Sonar Token
on:
schedule:
- cron: "0 6 1 */3 *"
workflow_dispatch:
permissions:
contents: read
actions: write
jobs:
rotate:
runs-on: ubuntu-latest
env:
SQ_URL: ${{ secrets.SONAR_HOST_URL }}
SQ_TOKEN: ${{ secrets.SONAR_ROTATOR_TOKEN }}
PROJECT_KEY: singnet_snet-daemon_701aea8d-22c4-45ce-b1e5-8a95913e15b4
SECRET_NAME: SONAR_TOKEN
steps:
- name: Install jq and gh
run: |
set -euo pipefail
sudo apt-get update -y
sudo apt-get install -y jq
gh --version
- name: Sanity check
run: |
set -euo pipefail
BASE="${SQ_URL%/}"; BASE="${BASE%%/api*}"
RESP=$(curl -sS -H "Authorization: Bearer $SQ_TOKEN" -H "Accept: application/json" \
"$BASE/api/authentication/validate")
echo "$RESP" | grep -q '"valid"[[:space:]]*:[[:space:]]*true' || { echo "Auth validate failed: $RESP"; exit 1; }
- name: Generate Project Analysis Token
id: gen
run: |
set -euo pipefail
BASE="${SQ_URL%/}"; BASE="${BASE%%/api*}"
LABEL="${PROJECT_KEY}-ci-$(date +%Y%m%d%H%M%S)"
BODY=$(mktemp)
HDR=$(mktemp)
CODE=$(curl -sS -L -D "$HDR" -o "$BODY" -w "%{http_code}" \
-H "Authorization: Bearer $SQ_TOKEN" \
-H "Accept: application/json" \
-X POST "$BASE/api/user_tokens/generate" \
--data-urlencode "name=$LABEL" \
--data-urlencode "type=PROJECT_ANALYSIS_TOKEN" \
--data-urlencode "projectKey=$PROJECT_KEY")
echo "HTTP $CODE"
CT=$(grep -i '^content-type:' "$HDR" | head -n1 || true)
echo "Content-Type: ${CT:-<none>}"
echo "$CT" | grep -qi 'application/json' || { echo "Non-JSON body head:"; head -c 400 "$BODY" || true; echo; exit 1; }
NEW_TOKEN=$(jq -r '.token // empty' "$BODY")
[ -n "$NEW_TOKEN" ] || { echo "No .token field. Body head:"; head -c 400 "$BODY" || true; echo; exit 1; }
echo "token=$NEW_TOKEN" >> "$GITHUB_OUTPUT"
- name: Get GitHub App token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.SNET_SONARQUBE_APP_ID }}
private-key: ${{ secrets.SNET_SONARQUBE_APP_KEY }}
- name: Debug App token
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
set -e
echo "== Auth status =="
gh auth status
echo "== Repo info =="
gh api repos/$GITHUB_REPOSITORY --jq '.full_name, .permissions'
echo "== Try secrets public-key =="
gh api repos/$GITHUB_REPOSITORY/actions/secrets/public-key || true
- name: Update repo secret with App token
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
echo "${{ steps.gen.outputs.token }}" | gh secret set "$SECRET_NAME" --repo "$GITHUB_REPOSITORY"
echo "Updated $SECRET_NAME"
- name: Revoke old tokens older than 120 days
run: |
set -euo pipefail
BASE="${SQ_URL%/}"; BASE="${BASE%%/api*}"
NOW=$(date +%s)
# Find the latest token so we never accidentally revoke it
LATEST=$(curl -sS -H "Authorization: Bearer $SQ_TOKEN" "$BASE/api/user_tokens/search" \
| jq -r '.userTokens[] | select(.name | test("'"$PROJECT_KEY"'-ci-")) | .name' \
| head -n1)
curl -sS -H "Authorization: Bearer $SQ_TOKEN" "$BASE/api/user_tokens/search" \
| jq -r '.userTokens[] | "\(.name)|\(.creationDate)"' \
| while IFS='|' read -r NAME DATE; do
case "$NAME" in
${PROJECT_KEY}-ci-*)
if [ "$NAME" = "$LATEST" ]; then
echo "Skipping the latest token $NAME"
continue
fi
TS=$(date -d "$DATE" +%s 2>/dev/null || echo 0)
if [ "$TS" -eq 0 ]; then
echo "Could not parse date $DATE for $NAME, skipping"
continue
fi
AGE=$(( (NOW-TS)/86400 ))
if [ "$AGE" -gt 120 ]; then
curl -sS -H "Authorization: Bearer $SQ_TOKEN" \
-X POST "$BASE/api/user_tokens/revoke" \
--data-urlencode "name=$NAME" >/dev/null
echo "Revoked $NAME (age ${AGE}d)"
fi
;;
esac
done