diff --git a/.gitea/workflows/cd.yaml b/.gitea/workflows/cd.yaml index 54a00db2..457f3e09 100644 --- a/.gitea/workflows/cd.yaml +++ b/.gitea/workflows/cd.yaml @@ -252,6 +252,21 @@ jobs: GITEA_WEBHOOK_SECRET: ${{ secrets.AWOOOI_GITEA_WEBHOOK_SECRET }} # MCP Phase 3: ArgoCD API Token (2026-04-11 Claude Sonnet 4.6) ARGOCD_API_TOKEN: ${{ secrets.ARGOCD_API_TOKEN }} + # 2026-04-18 ogt + Claude Opus 4.7: ADR-090-B L3-only 升級 L2(永久連線串 + 應用 secret) + DATABASE_URL: ${{ secrets.DATABASE_URL }} + MIGRATION_DATABASE_URL: ${{ secrets.MIGRATION_DATABASE_URL }} + REDIS_URL: ${{ secrets.REDIS_URL }} + JWT_SECRET: ${{ secrets.JWT_SECRET }} + JWT_ALGORITHM: ${{ secrets.JWT_ALGORITHM }} + WEBHOOK_HMAC_SECRET: ${{ secrets.WEBHOOK_HMAC_SECRET }} + SENTRY_DSN: ${{ secrets.SENTRY_DSN }} + CLAUDE_API_KEY: ${{ secrets.CLAUDE_API_KEY }} + # AWOOOI_ 前綴避開 Gitea 保留字(同 AWOOOI_GITEA_WEBHOOK_SECRET 模式) + GITEA_API_TOKEN: ${{ secrets.AWOOOI_GITEA_API_TOKEN }} + NEMOTRON_BOT_TOKEN: ${{ secrets.NEMOTRON_BOT_TOKEN }} + OPENCLAW_BOT_TOKEN: ${{ secrets.OPENCLAW_BOT_TOKEN }} + SMTP_HOST: ${{ secrets.SMTP_HOST }} + SRE_GROUP_CHAT_ID: ${{ secrets.SRE_GROUP_CHAT_ID }} run: | # S1/S2: 統一命名 deploy_key,改用 ssh-keyscan(比 StrictHostKeyChecking=no 更安全) mkdir -p ~/.ssh @@ -332,6 +347,101 @@ jobs: echo "⚠️ ARGOCD_API_TOKEN 未設定,ArgoCD MCP 將使用空 token" fi + # ============================================================================ + # ADR-090-B 2026-04-18 ogt + Claude Opus 4.7: L3-only 升級 L2(13 個 key) + # ============================================================================ + # 目的: 消滅「只存 K8s etcd 單點」的災難盲區,Gitea Secret 成為正式真相來源 + # 注意: 每個 block 與上方維持相同結構(if guard + base64 -w 0 + json patch) + + # DATABASE_URL — PG 應用連線串(2026-04-18 輪替) + if [ -n "${DATABASE_URL}" ]; then + sudo kubectl patch secret awoooi-secrets -n awoooi-prod --type='json' -p='[ + {"op":"add","path":"/data/DATABASE_URL","value":"'$(echo -n "${DATABASE_URL}" | base64 -w 0)'"} + ]' && echo "✅ DATABASE_URL 已注入" || echo "⚠️ DATABASE_URL patch 失敗" + else + echo "⚠️ DATABASE_URL 未設定,awoooi-api 將無法連 PG" + fi + + # MIGRATION_DATABASE_URL — CI migration 用 awoooi_migrator 限權帳號(ADR-090-B) + if [ -n "${MIGRATION_DATABASE_URL}" ]; then + sudo kubectl patch secret awoooi-secrets -n awoooi-prod --type='json' -p='[ + {"op":"add","path":"/data/MIGRATION_DATABASE_URL","value":"'$(echo -n "${MIGRATION_DATABASE_URL}" | base64 -w 0)'"} + ]' && echo "✅ MIGRATION_DATABASE_URL 已注入" || echo "⚠️ MIGRATION_DATABASE_URL patch 失敗" + fi + + # REDIS_URL — Redis 連線(6380 on 188) + if [ -n "${REDIS_URL}" ]; then + sudo kubectl patch secret awoooi-secrets -n awoooi-prod --type='json' -p='[ + {"op":"add","path":"/data/REDIS_URL","value":"'$(echo -n "${REDIS_URL}" | base64 -w 0)'"} + ]' && echo "✅ REDIS_URL 已注入" || echo "⚠️ REDIS_URL patch 失敗" + else + echo "⚠️ REDIS_URL 未設定" + fi + + # JWT_SECRET / JWT_ALGORITHM — API 認證 + if [ -n "${JWT_SECRET}" ]; then + sudo kubectl patch secret awoooi-secrets -n awoooi-prod --type='json' -p='[ + {"op":"add","path":"/data/JWT_SECRET","value":"'$(echo -n "${JWT_SECRET}" | base64 -w 0)'"} + ]' && echo "✅ JWT_SECRET 已注入" || echo "⚠️ JWT_SECRET patch 失敗" + fi + if [ -n "${JWT_ALGORITHM}" ]; then + sudo kubectl patch secret awoooi-secrets -n awoooi-prod --type='json' -p='[ + {"op":"add","path":"/data/JWT_ALGORITHM","value":"'$(echo -n "${JWT_ALGORITHM}" | base64 -w 0)'"} + ]' && echo "✅ JWT_ALGORITHM 已注入" || echo "⚠️ JWT_ALGORITHM patch 失敗" + fi + + # WEBHOOK_HMAC_SECRET — Alertmanager webhook HMAC 簽章 + if [ -n "${WEBHOOK_HMAC_SECRET}" ]; then + sudo kubectl patch secret awoooi-secrets -n awoooi-prod --type='json' -p='[ + {"op":"add","path":"/data/WEBHOOK_HMAC_SECRET","value":"'$(echo -n "${WEBHOOK_HMAC_SECRET}" | base64 -w 0)'"} + ]' && echo "✅ WEBHOOK_HMAC_SECRET 已注入" || echo "⚠️ WEBHOOK_HMAC_SECRET patch 失敗" + fi + + # SENTRY_DSN — Sentry 錯誤追蹤(不是 auth token) + if [ -n "${SENTRY_DSN}" ]; then + sudo kubectl patch secret awoooi-secrets -n awoooi-prod --type='json' -p='[ + {"op":"add","path":"/data/SENTRY_DSN","value":"'$(echo -n "${SENTRY_DSN}" | base64 -w 0)'"} + ]' && echo "✅ SENTRY_DSN 已注入" || echo "⚠️ SENTRY_DSN patch 失敗" + fi + + # CLAUDE_API_KEY — Claude 備援 LLM + if [ -n "${CLAUDE_API_KEY}" ]; then + sudo kubectl patch secret awoooi-secrets -n awoooi-prod --type='json' -p='[ + {"op":"add","path":"/data/CLAUDE_API_KEY","value":"'$(echo -n "${CLAUDE_API_KEY}" | base64 -w 0)'"} + ]' && echo "✅ CLAUDE_API_KEY 已注入" || echo "⚠️ CLAUDE_API_KEY patch 失敗" + fi + + # GITEA_API_TOKEN — Gitea API Token(從 AWOOOI_GITEA_API_TOKEN 映射) + if [ -n "${GITEA_API_TOKEN}" ]; then + sudo kubectl patch secret awoooi-secrets -n awoooi-prod --type='json' -p='[ + {"op":"add","path":"/data/GITEA_API_TOKEN","value":"'$(echo -n "${GITEA_API_TOKEN}" | base64 -w 0)'"} + ]' && echo "✅ GITEA_API_TOKEN 已注入" || echo "⚠️ GITEA_API_TOKEN patch 失敗" + fi + + # NEMOTRON_BOT_TOKEN / OPENCLAW_BOT_TOKEN — 多 Bot 架構 + if [ -n "${NEMOTRON_BOT_TOKEN}" ]; then + sudo kubectl patch secret awoooi-secrets -n awoooi-prod --type='json' -p='[ + {"op":"add","path":"/data/NEMOTRON_BOT_TOKEN","value":"'$(echo -n "${NEMOTRON_BOT_TOKEN}" | base64 -w 0)'"} + ]' && echo "✅ NEMOTRON_BOT_TOKEN 已注入" || echo "⚠️ NEMOTRON_BOT_TOKEN patch 失敗" + fi + if [ -n "${OPENCLAW_BOT_TOKEN}" ]; then + sudo kubectl patch secret awoooi-secrets -n awoooi-prod --type='json' -p='[ + {"op":"add","path":"/data/OPENCLAW_BOT_TOKEN","value":"'$(echo -n "${OPENCLAW_BOT_TOKEN}" | base64 -w 0)'"} + ]' && echo "✅ OPENCLAW_BOT_TOKEN 已注入" || echo "⚠️ OPENCLAW_BOT_TOKEN patch 失敗" + fi + + # SMTP_HOST / SRE_GROUP_CHAT_ID + if [ -n "${SMTP_HOST}" ]; then + sudo kubectl patch secret awoooi-secrets -n awoooi-prod --type='json' -p='[ + {"op":"add","path":"/data/SMTP_HOST","value":"'$(echo -n "${SMTP_HOST}" | base64 -w 0)'"} + ]' && echo "✅ SMTP_HOST 已注入" || echo "⚠️ SMTP_HOST patch 失敗" + fi + if [ -n "${SRE_GROUP_CHAT_ID}" ]; then + sudo kubectl patch secret awoooi-secrets -n awoooi-prod --type='json' -p='[ + {"op":"add","path":"/data/SRE_GROUP_CHAT_ID","value":"'$(echo -n "${SRE_GROUP_CHAT_ID}" | base64 -w 0)'"} + ]' && echo "✅ SRE_GROUP_CHAT_ID 已注入" || echo "⚠️ SRE_GROUP_CHAT_ID patch 失敗" + fi + # 2026-04-06 Claude Code: Sprint 3 T2 — known_hosts Secret (Security Fix A1) # 替換 StrictHostKeyChecking=no,讓 SSH 修復路徑使用已知主機指紋 ssh-keyscan -H 192.168.0.110 > /tmp/known_hosts_repair 2>/dev/null