ibo/infra/RUNBOOK-ibo.md
timu c54485dd6f
Some checks failed
Momentrum CI / Version (aus PR-ID / SHA) (push) Successful in 2s
Momentrum CI / Test (compile + pytest) (push) Failing after 12s
Momentrum CI / Build & Push image (push) Has been skipped
Momentrum CI / Helm lint + template (push) Successful in 8s
Momentrum CI / Deploy PROD (Image-Tag -> CD-Repo) (push) Has been skipped
ibo: Org myapps statt momentrum (Image myapps/ibo-web, CI-IMAGE)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 01:24:29 +02:00

176 lines
8.1 KiB
Markdown

# Runbook — ibo (Immo-Bot): CI/CD, PR-Preview-dev + prod, Zitadel-SSO
Immo-Bot = Flask-Web-App + Selenium-Chrome-Sidecar (noVNC-Live-Ansicht).
Umgebungs-Modell **wie momentrum-kanban**: ephemere PR-Previews als „dev" + eine
stehende prod. Beide hinter Zitadel-SSO (die App selbst hat KEINE eigene Auth).
| Umgebung | Host | SSO-Proxy | Deploy |
|----------|----------------------------------|-------------------|-------------------------------------------------|
| dev | `ibo-pr-<nr>.dev.momentrum.de` | generisches `dev-sso` | ephemer pro PR mit Label `preview` (ApplicationSet) |
| prod | `ibo.momentrum.de` | per-App `ibo-sso` | **automatisch** bei jedem main-Merge (CI → CD-Repo) |
Die Muster spiegeln kanban/luxly (CI/Chart/CD/ApplicationSet) und dev-sso/ibo-sso
(oauth2-proxy). Cluster-, Zitadel- und DNS-Schritte sind **manuell** — dieses
Runbook ist die Anleitung. Reihenfolge unten einhalten.
---
## 0. Repo nach Gitea bringen
```sh
cd projekte/ibo
git add -A && git commit -m "ibo: PR-Preview-dev + prod, Zitadel-SSO"
git remote add origin momentrum-gitea:momentrum/ibo.git # SSH-Alias wie andere Repos
git push -u origin main
```
**Gitea-Actions-Secrets** am Repo `momentrum/ibo` (Settings → Actions → Secrets):
- `REGISTRY_USER`, `REGISTRY_TOKEN` — Push in die Gitea-Registry.
- `DEPLOY_TOKEN` — Gitea-Token mit **Write auf `momentrum/momentrum-deploy`**
(Write-back des prod-Image-Tags bei main-Merge).
---
## 1. Zitadel-Clients + Sealed-Secret
- **prod (`ibo-sso`)** nutzt einen **eigenen** Zitadel-Web-Client. Dessen
ClientId/ClientSecret liegen im (nicht committeten) `.env` des ibo-Repos und
werden als SealedSecret **`oauth2-proxy-ibo`** (ns `iam`) in den Cluster gelegt:
```sh
# dort ausfuehren, wo Cluster-Zugriff besteht (Tunnel localhost:16443 / Bastion):
cd contabo-infra/platform/manifests/ibo-sso
IBO_ENV=../../../../projekte/ibo/.env ./seal-oauth2-proxy-ibo.sh
# -> erzeugt sealed-oauth2-proxy-ibo.yaml (committen & pushen -> ArgoCD entsiegelt)
# offline-Variante (ohne Cluster) mit Public-Cert:
# kubeseal --controller-namespace sealed-secrets --fetch-cert > pub.pem # einmal, mit Cluster
# SEALED_CERT=pub.pem IBO_ENV=.../.env ./seal-oauth2-proxy-ibo.sh
```
Am ibo-Client in Zitadel (`https://auth.momentrum.de`) die Redirect-URI
registrieren: `https://sso.ibo.momentrum.de/oauth2/callback`
(Post-Logout optional: `https://sso.ibo.momentrum.de`).
- **dev (Previews)** laufen weiter hinter dem **geteilten** `dev-sso`
(Client-Secret `oauth2-proxy-dev`). Dessen Redirect
`https://sso.dev.momentrum.de/oauth2/callback` existiert i. d. R. schon
(kanban/luxly nutzen es) — nichts zu tun.
---
## 2. Cluster-Voraussetzungen (contabo-infra) — muessen laufen
Fuer **prod** (`platform/manifests/ibo-sso/`, ArgoCD-App `platform/apps/ibo-sso.yaml`):
- oauth2-proxy `ibo-sso` (Deployment/Service, ns `iam`).
- Middlewares `iam-oauth2-ibo-auth@kubernetescrd` / `iam-oauth2-ibo-errors@kubernetescrd`.
- Ingress `sso.ibo.momentrum.de` (Login-Host, ohne Auth davor).
- **Geteilte** stripPrefix-Middleware `iam-strip-novnc@kubernetescrd` (`strip-novnc.yaml`)
— die Previews referenzieren sie cross-namespace (s. §4).
Fuer **dev/Previews** (bereits vorhanden, von kanban/luxly geteilt):
- `dev-sso` (generischer oauth2-proxy `*.dev.momentrum.de`, Middlewares
`iam-oauth2-auth`/`iam-oauth2-errors`, Login `sso.dev.momentrum.de`).
- SealedSecret `gitea-appset-token` (ns `argocd`) — Gitea-Read fuer den PR-Generator.
- AppProject `previews` — erlaubt Source `momentrum/*` (deckt ibo ab) und
begrenzt Previews auf `preview-*`-Namespaces. **Blockt bewusst
traefik.io/Middleware im Preview-ns** → deshalb die geteilte `strip-novnc` in §2.
App-of-Apps nimmt `ibo-sso.yaml` automatisch auf — committen & pushen genuegt;
alternativ einmalig `kubectl apply -f platform/manifests/ibo-sso/`. Das ibo-Repo
ist in `platform/manifests/argocd-projects/internal.yaml` (sourceRepos) bereits
erlaubt (sonst lehnt ArgoCD die prod-App-Source ab).
---
## 3. DNS
A/AAAA-Records auf die Cluster-Ingress-IP:
- `ibo.momentrum.de` (prod)
- `sso.ibo.momentrum.de` (prod-Login)
Previews brauchen **keinen eigenen Record** — sie laufen unter dem bestehenden
Wildcard `*.dev.momentrum.de` (wie kanban/luxly). cert-manager
(`letsencrypt-prod`, HTTP-01) stellt `ibo-tls`, `ibo-sso-tls` und die per-Preview-
Certs (`ibo-pr-<nr>-tls`) automatisch aus, sobald DNS/Ingress stehen.
---
## 4. CD-Apps im `momentrum-deploy` (bereits angelegt)
- `apps/internal/ibo/app.yaml` — prod-Application (`ibo.momentrum.de`,
ns `apps-internal`, SSO `iam-oauth2-ibo-*`). Auto-Sync; `image.tag` bumpt die CI.
- `apps/internal/ibo/preview.yaml` — PR-Preview-ApplicationSet (Gitea-PR-Generator,
Label-Gate `preview`). Rendert ibos Chart aus dem **PR-Branch** und setzt pro PR:
Host `ibo-pr-<nr>.dev.momentrum.de`, `priorityClassName: preview`, gedeckelte
Resources (preview-ns-Quota: ≤2 CPU / 1536Mi Limits gesamt),
`ssoMiddlewares: iam-oauth2-errors,iam-oauth2-auth` (dev-sso) und
`novncStripPrefixRef: iam-strip-novnc@kubernetescrd` (statt eigener Middleware).
committen & pushen → ArgoCD legt die prod-App + das ApplicationSet an.
---
## 5. Deploy-Flows
**dev / Preview (pro PR):**
1. PR gegen `main` oeffnen → CI baut `pr-<nr>-<sha7>` (Job build-push).
2. Am PR das Gitea-Label **`preview`** setzen (Opt-in-Gate = Concurrency-Deckel).
3. ArgoCD-ApplicationSet (Polling 120 s) legt `ibo-pr-<nr>` + ns
`preview-ibo-pr-<nr>` an → `https://ibo-pr-<nr>.dev.momentrum.de`.
4. PR schliessen/mergen oder Label entfernen → Application + Namespace kaskadieren
weg (finalizer + gemanagter Namespace, KEIN CreateNamespace).
**prod (bei main-Merge):**
- CI-Job `deploy` schreibt den neuen `image.tag` in `apps/internal/ibo/app.yaml`
zurueck → ArgoCD synct prod automatisch. Kein manueller Schritt.
- **Rollback:** `git revert` des CI-Commits im `momentrum-deploy` (ArgoCD synct
zurueck). Alternativ `image.tag` in `app.yaml` auf einen aelteren Tag setzen.
> Wer prod bewusst manuell freigeben will statt Auto-Deploy: den `deploy`-Job in
> `.gitea/workflows/momentrum-ci.yml` entfernen und den Tag per Hand nach
> `app.yaml` committen. Aktuell ist Auto-Deploy aktiv (wie kanban).
---
## 6. Browser-Live-Ansicht (noVNC)
Der Automations-Chrome laeuft im `selenium`-Sidecar; sein Bild wird per noVNC
gestreamt und in der Web-App eingebettet (Button „👁️ Browser live ansehen").
Routing:
- App-Container → Chrome via `SELENIUM_REMOTE_URL=http://localhost:4444`.
- Client-Browser → `https://<host>/novnc/…` → Ingress-Pfad `/novnc`
→ stripPrefix-Middleware → Sidecar-Port 7900 (noVNC/websockify).
- prod: chart-eigene Middleware `<ns>-ibo-novnc` (App-ns).
- Preview: geteilte `iam-strip-novnc` (weil das `previews`-Project eigene
Middlewares im Preview-ns blockt).
- Zugriff durch die SSO-Cookie (gleicher Host, gleiche Middleware-Kette).
Der Browser laeuft **serverseitig** im Container — es wird NICHT der lokale
Browser des Nutzers ferngesteuert.
---
## 7. Break-glass (Notzugang)
Faellt Zitadel aus: die SSO-Middlewares temporaer aus `ingress.ssoMiddlewares`
in `apps/internal/ibo/app.yaml` (prod) entfernen (die App selbst hat keine eigene
Auth → sie ist dann OFFEN). Nur kurz, danach sofort zuruecksetzen. Nie
ungeschuetzt lassen.
---
## 8. Verifikationscheckliste
- [ ] `docker compose up -d` lokal → `http://localhost:5000` UI, „Browser live
ansehen" zeigt den Chrome im iframe (localhost:7900).
- [ ] `curl -s localhost:5000/healthz` → `{"ok":true}`.
- [ ] PR + Label `preview` → CI gruen (version→test→build-push→helm-validate),
ArgoCD legt `ibo-pr-<nr>` an, `https://ibo-pr-<nr>.dev.momentrum.de`
redirected zu `auth.momentrum.de`, nach Login landet man in der App.
- [ ] Im Preview eingebettetes `/novnc/` zeigt den Live-Browser.
- [ ] PR schliessen → Preview + Namespace verschwinden (ArgoCD prune).
- [ ] main-Merge → CI-Job `deploy` bumpt `app.yaml`, ArgoCD rollt prod,
`https://ibo.momentrum.de` hinter Zitadel erreichbar.
- [ ] Ohne SSO-Session → Login-Redirect (kein rohes 401).