Files
ApiCore/deploy/k8s/scripts/ensure-secrets.sh
T
Nick SzaunigandClaude Opus 5.5 6e3e9aee9b chore(k8s): live config values in overlay, script to fill missing secrets
- 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]>
2026-10-15 16:38:31 +02:00

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."