Livrare LOT 1 - Didi
This commit is contained in:
commit
5380c3fc63
990 changed files with 133308 additions and 0 deletions
209
ai_platform/modules/dashboard/deploy/setup-keycloak.sh
Normal file
209
ai_platform/modules/dashboard/deploy/setup-keycloak.sh
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
#!/usr/bin/env bash
|
||||
# Set up Keycloak client `ai-platform-dashboard` on sso.clossers.com realm `didi-clients`.
|
||||
# Idempotent — safe to re-run; existing client gets updated to match this config.
|
||||
#
|
||||
# Usage:
|
||||
# KC_ADMIN_USER=admin KC_ADMIN_PASS=admin123 ./setup-keycloak.sh
|
||||
#
|
||||
# Optional overrides:
|
||||
# KC_BASE_URL=https://sso.clossers.com
|
||||
# KC_REALM=didi-clients
|
||||
# KC_CLIENT_ID=ai-platform-dashboard
|
||||
# DASHBOARD_HOST=10.11.10.12 # used to build redirect URI
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Keycloak admin endpoints redirect public sso.clossers.com → internal
|
||||
# sso.clossers.local. Token issuer must match the host you call, so we use the
|
||||
# internal name end-to-end (this host has DNS for it).
|
||||
KC_BASE_URL="${KC_BASE_URL:-https://sso.clossers.local}"
|
||||
KC_REALM="${KC_REALM:-didi-clients}"
|
||||
KC_CLIENT_ID="${KC_CLIENT_ID:-ai-platform-dashboard}"
|
||||
KC_ADMIN_USER="${KC_ADMIN_USER:-admin}"
|
||||
KC_ADMIN_PASS="${KC_ADMIN_PASS:?Set KC_ADMIN_PASS}"
|
||||
DASHBOARD_HOST="${DASHBOARD_HOST:-10.11.10.12}"
|
||||
DASHBOARD_PORT="${DASHBOARD_PORT:-51300}"
|
||||
|
||||
echo "→ Authenticating to Keycloak master realm…"
|
||||
ADMIN_TOKEN=$(
|
||||
curl -ksS -X POST "$KC_BASE_URL/realms/master/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=admin-cli&grant_type=password&username=$KC_ADMIN_USER&password=$KC_ADMIN_PASS" \
|
||||
| python3 -c "import json,sys; print(json.load(sys.stdin)['access_token'])"
|
||||
)
|
||||
[ -n "$ADMIN_TOKEN" ] || { echo "FAIL: could not get admin token"; exit 1; }
|
||||
echo " OK (token length ${#ADMIN_TOKEN})"
|
||||
|
||||
# ---------- Step 1: ensure realm role 'admin' exists ----------
|
||||
echo "→ Checking realm role 'admin' exists in realm '$KC_REALM'…"
|
||||
RAW=$(curl -ksSL -H "Authorization: Bearer $ADMIN_TOKEN" \
|
||||
"$KC_BASE_URL/admin/realms/$KC_REALM/roles/admin")
|
||||
if echo "$RAW" | grep -q '"name"'; then
|
||||
echo " OK — role 'admin' present"
|
||||
else
|
||||
echo " NOT found — creating…"
|
||||
curl -ksSL -X POST -H "Authorization: Bearer $ADMIN_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"admin","description":"Platform admin (DIDI + AI platform)"}' \
|
||||
"$KC_BASE_URL/admin/realms/$KC_REALM/roles"
|
||||
echo " CREATED"
|
||||
fi
|
||||
|
||||
# ---------- Step 2: ensure client `ai-platform-dashboard` exists ----------
|
||||
echo "→ Checking client '$KC_CLIENT_ID' exists…"
|
||||
EXISTING=$(curl -ksSL -H "Authorization: Bearer $ADMIN_TOKEN" \
|
||||
"$KC_BASE_URL/admin/realms/$KC_REALM/clients?clientId=$KC_CLIENT_ID")
|
||||
CLIENT_UUID=$(echo "$EXISTING" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d[0]['id'] if d else '')")
|
||||
|
||||
REDIRECTS=$(python3 -c "
|
||||
import json
|
||||
print(json.dumps([
|
||||
'http://$DASHBOARD_HOST:$DASHBOARD_PORT/admin-ai/*',
|
||||
'https://$DASHBOARD_HOST:$DASHBOARD_PORT/admin-ai/*',
|
||||
'http://localhost:$DASHBOARD_PORT/admin-ai/*',
|
||||
'http://localhost:5173/*',
|
||||
# Reverse-proxy URL (admin-dashboard nginx exposes /admin-ai/ on port 3000)
|
||||
'https://$DASHBOARD_HOST:3000/admin-ai/*',
|
||||
]))
|
||||
")
|
||||
|
||||
PAYLOAD=$(python3 -c "
|
||||
import json, os
|
||||
print(json.dumps({
|
||||
'clientId': '$KC_CLIENT_ID',
|
||||
'name': 'AI Platform Admin Dashboard',
|
||||
'description': 'Reskinned admin dashboard for the AI platform (web/llm/embeddings/rerank/audio/video/catalog/brain)',
|
||||
'rootUrl': 'http://$DASHBOARD_HOST:$DASHBOARD_PORT/admin-ai/',
|
||||
'baseUrl': '/admin-ai/',
|
||||
'enabled': True,
|
||||
'protocol': 'openid-connect',
|
||||
'publicClient': True,
|
||||
'standardFlowEnabled': True,
|
||||
'directAccessGrantsEnabled': False,
|
||||
'serviceAccountsEnabled': False,
|
||||
'frontchannelLogout': True,
|
||||
'redirectUris': $REDIRECTS,
|
||||
'webOrigins': ['+'],
|
||||
'attributes': {
|
||||
'pkce.code.challenge.method': 'S256',
|
||||
'post.logout.redirect.uris': '+',
|
||||
},
|
||||
}))
|
||||
")
|
||||
|
||||
if [ -z "$CLIENT_UUID" ]; then
|
||||
echo " NOT found — creating…"
|
||||
curl -ksSL -X POST -H "Authorization: Bearer $ADMIN_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$PAYLOAD" \
|
||||
"$KC_BASE_URL/admin/realms/$KC_REALM/clients"
|
||||
CLIENT_UUID=$(
|
||||
curl -ksSL -H "Authorization: Bearer $ADMIN_TOKEN" \
|
||||
"$KC_BASE_URL/admin/realms/$KC_REALM/clients?clientId=$KC_CLIENT_ID" \
|
||||
| python3 -c "import json,sys; print(json.load(sys.stdin)[0]['id'])"
|
||||
)
|
||||
echo " CREATED uuid=$CLIENT_UUID"
|
||||
else
|
||||
echo " Found uuid=$CLIENT_UUID — updating to current spec…"
|
||||
curl -ksSL -X PUT -H "Authorization: Bearer $ADMIN_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$PAYLOAD" \
|
||||
"$KC_BASE_URL/admin/realms/$KC_REALM/clients/$CLIENT_UUID"
|
||||
echo " UPDATED"
|
||||
fi
|
||||
|
||||
# ---------- Step 3: smoke test JWKS reachable ----------
|
||||
echo "→ Smoke test: JWKS endpoint reachable…"
|
||||
JWKS_KEYS=$(curl -ksS \
|
||||
"$KC_BASE_URL/realms/$KC_REALM/protocol/openid-connect/certs" \
|
||||
| python3 -c "import json,sys; print(len(json.load(sys.stdin).get('keys',[])))")
|
||||
echo " OK — JWKS returns $JWKS_KEYS keys"
|
||||
|
||||
# ---------- Step 3b: ensure admin-dashboard client also exists (DIDI side) ----------
|
||||
# This is a no-op when the client already exists with correct config; included
|
||||
# so a fresh Keycloak install gets both apps wired in one go.
|
||||
ADMIN_DASH_CLIENT="admin-dashboard"
|
||||
echo "→ Checking client '$ADMIN_DASH_CLIENT' (DIDI admin) exists…"
|
||||
EXISTING_AD=$(curl -ksSL -H "Authorization: Bearer $ADMIN_TOKEN" \
|
||||
"$KC_BASE_URL/admin/realms/$KC_REALM/clients?clientId=$ADMIN_DASH_CLIENT")
|
||||
ADMIN_DASH_UUID=$(echo "$EXISTING_AD" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d[0]['id'] if d else '')")
|
||||
|
||||
ADMIN_DASH_REDIRECTS=$(python3 -c "
|
||||
import json
|
||||
print(json.dumps([
|
||||
'https://$DASHBOARD_HOST:3000/admin/*',
|
||||
'https://$DASHBOARD_HOST:3000/admin-backend/*',
|
||||
'http://localhost:3000/admin/*',
|
||||
]))
|
||||
")
|
||||
|
||||
ADMIN_DASH_PAYLOAD=$(python3 -c "
|
||||
import json
|
||||
print(json.dumps({
|
||||
'clientId': '$ADMIN_DASH_CLIENT',
|
||||
'name': 'DIDI Admin Dashboard',
|
||||
'description': 'Backend admin (framework config, users, moderation queue, history)',
|
||||
'rootUrl': 'https://$DASHBOARD_HOST:3000/admin/',
|
||||
'baseUrl': '/admin/',
|
||||
'enabled': True,
|
||||
'protocol': 'openid-connect',
|
||||
'publicClient': True,
|
||||
'standardFlowEnabled': True,
|
||||
'directAccessGrantsEnabled': False,
|
||||
'redirectUris': $ADMIN_DASH_REDIRECTS,
|
||||
'webOrigins': ['+'],
|
||||
'attributes': {
|
||||
'pkce.code.challenge.method': 'S256',
|
||||
'post.logout.redirect.uris': '+',
|
||||
},
|
||||
}))
|
||||
")
|
||||
|
||||
if [ -z "$ADMIN_DASH_UUID" ]; then
|
||||
echo " NOT found — creating…"
|
||||
curl -ksSL -X POST -H "Authorization: Bearer $ADMIN_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$ADMIN_DASH_PAYLOAD" \
|
||||
"$KC_BASE_URL/admin/realms/$KC_REALM/clients"
|
||||
ADMIN_DASH_UUID=$(
|
||||
curl -ksSL -H "Authorization: Bearer $ADMIN_TOKEN" \
|
||||
"$KC_BASE_URL/admin/realms/$KC_REALM/clients?clientId=$ADMIN_DASH_CLIENT" \
|
||||
| python3 -c "import json,sys; print(json.load(sys.stdin)[0]['id'])"
|
||||
)
|
||||
echo " CREATED uuid=$ADMIN_DASH_UUID"
|
||||
else
|
||||
echo " Found uuid=$ADMIN_DASH_UUID — leaving config as-is (would overwrite custom redirect URIs)"
|
||||
fi
|
||||
|
||||
# ---------- Step 4: print summary ----------
|
||||
cat <<EOF
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
Keycloak setup complete.
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
Realm: $KC_REALM
|
||||
Client: $KC_CLIENT_ID (uuid=$CLIENT_UUID)
|
||||
Role: admin (realm)
|
||||
Issuer: $KC_BASE_URL/realms/$KC_REALM
|
||||
JWKS: $KC_BASE_URL/realms/$KC_REALM/protocol/openid-connect/certs
|
||||
|
||||
REDIRECTS:
|
||||
$(python3 -c "import json; [print(f' - {u}') for u in $REDIRECTS]")
|
||||
|
||||
NEXT STEPS:
|
||||
1. Verify YOUR user has the 'admin' realm role assigned in $KC_REALM.
|
||||
(If you can already log into the DIDI admin-dashboard, you do.)
|
||||
|
||||
2. Update dashboard/.env:
|
||||
DASHBOARD_KEYCLOAK_URL=$KC_BASE_URL
|
||||
DASHBOARD_STAGING_MODE=false
|
||||
VITE_STAGING_MODE=false
|
||||
|
||||
3. Rebuild + redeploy:
|
||||
cd /home/admin365/didi_mono/ai_platform/modules/dashboard/deploy
|
||||
docker compose --profile dashboard up -d --build dashboard-api
|
||||
|
||||
4. Open http://$DASHBOARD_HOST:$DASHBOARD_PORT/v2/
|
||||
→ Keycloak login redirect → enter creds → SPA loads with your JWT.
|
||||
|
||||
EOF
|
||||
Loading…
Add table
Add a link
Reference in a new issue