- overlays/encry configmaps now carry the live cluster values (runbook step 1) plus OIDC_CLIENT_ID; kubectl diff against the cluster is empty. - deploy/k8s/scripts/ensure-secrets.sh adds missing secret keys without touching existing ones (random encryption keys, empty Open-Meteo key, TELEGRAM_BOT_TOKEN=dummy) and never prints values. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
78 lines
2.8 KiB
Bash
78 lines
2.8 KiB
Bash
#!/usr/bin/env bash
|
|
# Ergaenzt fehlende Schluessel in den ApiCore-Secrets, ohne vorhandene Werte
|
|
# zu aendern. Gibt nur Schluesselnamen aus, nie Werte. Mehrfach ausfuehrbar.
|
|
#
|
|
# bash deploy/k8s/scripts/ensure-secrets.sh # Namespace apicore
|
|
# bash deploy/k8s/scripts/ensure-secrets.sh --dry-run # nur anzeigen
|
|
#
|
|
# Werte:
|
|
# - MFA_/WEBHOOK_/BACKUP_ENCRYPTION_KEY: zufaellig (48 Byte, base64url). Die
|
|
# App verlangt mindestens 32 Zeichen; "dummy" wuerde den Start abbrechen.
|
|
# Diese Schluessel nie wieder aendern ohne *_PREVIOUS (sonst sind MFA-
|
|
# Geheimnisse, Webhook-Secrets und Backups nicht mehr lesbar). Sichern!
|
|
# - OPEN_METEO_API_KEY: leer = freie Open-Meteo-API (ein Fantasiewert wuerde
|
|
# die kostenpflichtige API mit falschem Schluessel ansprechen).
|
|
# - TELEGRAM_BOT_TOKEN (Secret apicore-telegram, nur Worker): "dummy". Die App
|
|
# erkennt ein ungueltiges Format und schaltet Telegram ab, bis das echte
|
|
# Token von BotFather eingetragen ist.
|
|
set -euo pipefail
|
|
|
|
NS="${NAMESPACE:-apicore}"
|
|
DRY_RUN=false
|
|
[[ "${1:-}" == "--dry-run" ]] && DRY_RUN=true
|
|
|
|
random_key() {
|
|
node -e "process.stdout.write(require('crypto').randomBytes(48).toString('base64url'))"
|
|
}
|
|
|
|
existing_keys() {
|
|
kubectl get secret "$1" -n "$NS" -o jsonpath='{.data}' 2>/dev/null \
|
|
| node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>{try{console.log(Object.keys(JSON.parse(s||'{}')).join('\n'))}catch{}})"
|
|
}
|
|
|
|
# ensure_keys <secret> <key> <random|empty|dummy> [<key> <mode> ...]
|
|
ensure_keys() {
|
|
local secret="$1"; shift
|
|
local have
|
|
have="$(existing_keys "$secret")"
|
|
local patch="{}" added=()
|
|
while (($#)); do
|
|
local key="$1" mode="$2"; shift 2
|
|
if grep -qx "$key" <<<"$have"; then
|
|
continue
|
|
fi
|
|
local value
|
|
case "$mode" in
|
|
random) value="$(random_key)" ;;
|
|
empty) value="" ;;
|
|
dummy) value="dummy" ;;
|
|
esac
|
|
patch="$(KEY="$key" VALUE="$value" PATCH="$patch" node -e "const p=JSON.parse(process.env.PATCH);p.stringData=p.stringData||{};p.stringData[process.env.KEY]=process.env.VALUE;process.stdout.write(JSON.stringify(p))")"
|
|
added+=("$key")
|
|
done
|
|
if ((${#added[@]} == 0)); then
|
|
echo "$secret: alle Schluessel vorhanden"
|
|
return
|
|
fi
|
|
if $DRY_RUN; then
|
|
echo "$secret: wuerde ergaenzen: ${added[*]}"
|
|
return
|
|
fi
|
|
if ! kubectl get secret "$secret" -n "$NS" >/dev/null 2>&1; then
|
|
kubectl create secret generic "$secret" -n "$NS" >/dev/null
|
|
fi
|
|
kubectl patch secret "$secret" -n "$NS" --type merge -p "$patch" >/dev/null
|
|
echo "$secret: ergaenzt: ${added[*]}"
|
|
}
|
|
|
|
ensure_keys apicore-backend-secret \
|
|
MFA_ENCRYPTION_KEY random \
|
|
WEBHOOK_ENCRYPTION_KEY random \
|
|
BACKUP_ENCRYPTION_KEY random \
|
|
OPEN_METEO_API_KEY empty
|
|
|
|
ensure_keys apicore-telegram \
|
|
TELEGRAM_BOT_TOKEN dummy
|
|
|
|
echo "Fertig. Laufende Pods lesen neue Werte erst nach einem Neustart."
|