ibo-CI: PR-Preview-dev statt fixer Dev-Env, prod Auto-Deploy bei main-Merge
Some checks failed
Momentrum CI / Version (aus PR-ID / SHA) (push) Successful in 2s
Momentrum CI / Test (compile + pytest) (push) Failing after 43s
Momentrum CI / Build & Push image (push) Has been skipped
Momentrum CI / Helm lint + template (push) Successful in 9s
Momentrum CI / Deploy PROD (Image-Tag -> CD-Repo) (push) Has been skipped
Some checks failed
Momentrum CI / Version (aus PR-ID / SHA) (push) Successful in 2s
Momentrum CI / Test (compile + pytest) (push) Failing after 43s
Momentrum CI / Build & Push image (push) Has been skipped
Momentrum CI / Helm lint + template (push) Successful in 9s
Momentrum CI / Deploy PROD (Image-Tag -> CD-Repo) (push) Has been skipped
Umstellung auf das kanban-Modell (PR-Preview-dev + prod), Zitadel-SSO vor beiden. - CI: Job deploy-dev -> deploy; Write-back bei main-Merge jetzt nach app.yaml (prod) statt dev.yaml. dev braucht keinen Write-back (ApplicationSet liest den PR-Tag direkt). - Chart: ingress.novncStripPrefixRef (Preview referenziert die geteilte externe strip-novnc-Middleware statt eine eigene anzulegen -> vom previews-AppProject erlaubt); priorityClassName (Preview-Pods sterben bei Memory-Pressure zuerst). - RUNBOOK-ibo.md: auf PR-Preview-dev + prod-Auto-Deploy umgeschrieben. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
650d7f3394
commit
d1ccf17b5f
@ -1,11 +1,14 @@
|
|||||||
# Momentrum CI (Contabo-Gitea) — build · test · push · deploy(dev)
|
# Momentrum CI (Contabo-Gitea) — build · test · push · deploy(prod)
|
||||||
# Zielt auf das Gitea auf momentrum-k3s-01 (org: momentrum).
|
# Zielt auf das Gitea auf momentrum-k3s-01 (org: momentrum).
|
||||||
#
|
#
|
||||||
# Umgebungs-Modell fuer ibo (bewusst NUR dev+prod, keine PR-Previews):
|
# Umgebungs-Modell fuer ibo (wie momentrum-kanban: PR-Preview-dev + prod):
|
||||||
# - dev = deployt AUTOMATISCH bei jedem main-Push (dieser Deploy-Step bumpt
|
# - dev = EPHEMERE PR-Previews. Kein Deploy-Step noetig: das ArgoCD-
|
||||||
# apps/internal/ibo/dev.yaml im CD-Repo -> ArgoCD synct dev).
|
# ApplicationSet (momentrum-deploy apps/internal/ibo/preview.yaml) liest
|
||||||
# - prod = wird MANUELL promotet (Tag aus dev.yaml -> app.yaml committen,
|
# den Tag pr-<nr>-<sha7> direkt aus dem PR -> https://ibo-pr-<nr>.dev.momentrum.de.
|
||||||
# siehe infra/RUNBOOK-ibo.md). Die CI fasst prod NICHT an.
|
# PR braucht das Gitea-Label "preview" (Opt-in-Gate).
|
||||||
|
# - prod = deployt AUTOMATISCH bei jedem main-Push (Job "deploy" bumpt
|
||||||
|
# apps/internal/ibo/app.yaml im CD-Repo -> ArgoCD synct prod).
|
||||||
|
# Rollback = git revert im CD-Repo (siehe infra/RUNBOOK-ibo.md).
|
||||||
#
|
#
|
||||||
# Image-Tag ist immutable pro Commit:
|
# Image-Tag ist immutable pro Commit:
|
||||||
# - Pull Request: pr-<nummer>-<shortsha>
|
# - Pull Request: pr-<nummer>-<shortsha>
|
||||||
@ -102,26 +105,26 @@ jobs:
|
|||||||
helm lint "${{ env.CHART_PATH }}"
|
helm lint "${{ env.CHART_PATH }}"
|
||||||
helm template ibo "${{ env.CHART_PATH }}" >/dev/null
|
helm template ibo "${{ env.CHART_PATH }}" >/dev/null
|
||||||
|
|
||||||
# CD-Write-back: nur auf main. Bumpt den Image-Tag in apps/internal/ibo/dev.yaml
|
# CD-Write-back: nur auf main (= PR-Merge). Bumpt den Image-Tag in
|
||||||
# im CD-Repo -> ArgoCD deployt DEV automatisch. Prod bleibt unberuehrt (Promote
|
# apps/internal/ibo/app.yaml im CD-Repo -> ArgoCD deployt PROD automatisch.
|
||||||
# ist ein bewusster manueller Commit, siehe RUNBOOK). DEPLOY_TOKEN = Gitea-Token
|
# PR-Previews deployen NICHT hierueber (die treibt das ApplicationSet direkt aus
|
||||||
# mit Write auf momentrum-deploy.
|
# dem PR). DEPLOY_TOKEN = Gitea-Token mit Write auf momentrum-deploy.
|
||||||
deploy-dev:
|
deploy:
|
||||||
name: Deploy DEV (Image-Tag -> CD-Repo)
|
name: Deploy PROD (Image-Tag -> CD-Repo)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||||
needs: [version, build-push, helm-validate]
|
needs: [version, build-push, helm-validate]
|
||||||
steps:
|
steps:
|
||||||
- name: Write-back image.tag nach momentrum-deploy (dev.yaml)
|
- name: Write-back image.tag nach momentrum-deploy (app.yaml)
|
||||||
run: |
|
run: |
|
||||||
TAG="${{ needs.version.outputs.tag }}"
|
TAG="${{ needs.version.outputs.tag }}"
|
||||||
git clone -q "http://ci:${{ secrets.DEPLOY_TOKEN }}@100.111.27.99:3000/momentrum/momentrum-deploy.git" /tmp/deploy
|
git clone -q "http://ci:${{ secrets.DEPLOY_TOKEN }}@100.111.27.99:3000/momentrum/momentrum-deploy.git" /tmp/deploy
|
||||||
cd /tmp/deploy
|
cd /tmp/deploy
|
||||||
APP_FILE="apps/internal/ibo/dev.yaml"
|
APP_FILE="apps/internal/ibo/app.yaml"
|
||||||
grep -qE '^ tag: ' "$APP_FILE" || { echo "FEHLER: 'tag:'-Zeile nicht in $APP_FILE gefunden"; exit 1; }
|
grep -qE '^ tag: ' "$APP_FILE" || { echo "FEHLER: 'tag:'-Zeile nicht in $APP_FILE gefunden"; exit 1; }
|
||||||
sed -i "s|^ tag: .*| tag: ${TAG}|" "$APP_FILE"
|
sed -i "s|^ tag: .*| tag: ${TAG}|" "$APP_FILE"
|
||||||
git config user.email "ci@momentrum.local"
|
git config user.email "ci@momentrum.local"
|
||||||
git config user.name "Momentrum CI"
|
git config user.name "Momentrum CI"
|
||||||
git commit -am "ibo: deploy dev ${TAG}" || { echo "kein Change - Tag identisch"; exit 0; }
|
git commit -am "ibo: deploy prod ${TAG}" || { echo "kein Change - Tag identisch"; exit 0; }
|
||||||
git push origin HEAD:main
|
git push origin HEAD:main
|
||||||
echo "Deployed dev tag ${TAG} -> momentrum-deploy"
|
echo "Deployed prod tag ${TAG} -> momentrum-deploy"
|
||||||
|
|||||||
@ -1,19 +1,17 @@
|
|||||||
# Runbook — ibo (Immo-Bot) containerisieren, deployen, Zitadel-SSO davorschalten
|
# Runbook — ibo (Immo-Bot): CI/CD, PR-Preview-dev + prod, Zitadel-SSO
|
||||||
|
|
||||||
Immo-Bot = Flask-Web-App + Selenium-Chrome-Sidecar (noVNC-Live-Ansicht). Zwei
|
Immo-Bot = Flask-Web-App + Selenium-Chrome-Sidecar (noVNC-Live-Ansicht).
|
||||||
feste Umgebungen (KEINE PR-Previews):
|
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 | TLS-Secret | Deploy |
|
| Umgebung | Host | SSO-Proxy | Deploy |
|
||||||
|----------|------------------------|--------------|------------------------------------------|
|
|----------|----------------------------------|-------------------|-------------------------------------------------|
|
||||||
| dev | `dev.ibo.momentrum.de` | `ibo-dev-tls`| **automatisch** bei jedem main-Push (CI) |
|
| dev | `ibo-pr-<nr>.dev.momentrum.de` | generisches `dev-sso` | ephemer pro PR mit Label `preview` (ApplicationSet) |
|
||||||
| prod | `ibo.momentrum.de` | `ibo-tls` | **manuell promotet** (Tag-Copy, s. u.) |
|
| prod | `ibo.momentrum.de` | per-App `ibo-sso` | **automatisch** bei jedem main-Merge (CI → CD-Repo) |
|
||||||
|
|
||||||
Beide hinter demselben Zitadel-oauth2-proxy `ibo-sso`
|
Die Muster spiegeln kanban/luxly (CI/Chart/CD/ApplicationSet) und dev-sso/ibo-sso
|
||||||
(`cookie-domain .ibo.momentrum.de` deckt dev **und** prod ab).
|
(oauth2-proxy). Cluster-, Zitadel- und DNS-Schritte sind **manuell** — dieses
|
||||||
|
Runbook ist die Anleitung. Reihenfolge unten einhalten.
|
||||||
Die Muster spiegeln kanban (CI/Chart/CD) und luxly-sso/dev-sso (oauth2-proxy).
|
|
||||||
Cluster-, Zitadel- und DNS-Schritte sind **manuell** — dieses Runbook ist die
|
|
||||||
Anleitung. Reihenfolge unten einhalten.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -21,116 +19,130 @@ Anleitung. Reihenfolge unten einhalten.
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd projekte/ibo
|
cd projekte/ibo
|
||||||
git init && git add -A && git commit -m "ibo: containerize + CI + infra"
|
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 remote add origin momentrum-gitea:momentrum/ibo.git # SSH-Alias wie andere Repos
|
||||||
git push -u origin main # push-create legt momentrum/ibo an, falls aktiviert
|
git push -u origin main
|
||||||
```
|
```
|
||||||
|
|
||||||
**Gitea-Actions-Secrets** am Repo `momentrum/ibo` setzen (Settings → Actions → Secrets):
|
**Gitea-Actions-Secrets** am Repo `momentrum/ibo` (Settings → Actions → Secrets):
|
||||||
- `REGISTRY_USER`, `REGISTRY_TOKEN` — Push in die Gitea-Registry.
|
- `REGISTRY_USER`, `REGISTRY_TOKEN` — Push in die Gitea-Registry.
|
||||||
- `DEPLOY_TOKEN` — Gitea-Token mit **Write auf `momentrum/momentrum-deploy`**
|
- `DEPLOY_TOKEN` — Gitea-Token mit **Write auf `momentrum/momentrum-deploy`**
|
||||||
(Write-back des dev-Image-Tags).
|
(Write-back des prod-Image-Tags bei main-Merge).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Zitadel: Redirect-URI ergaenzen (KEIN neuer Client)
|
## 1. Zitadel: Redirect-URIs (KEIN neuer Client)
|
||||||
|
|
||||||
`ibo-sso` nutzt — wie `luxly-sso` — den **bestehenden geteilten** Zitadel-Client
|
`ibo-sso` und `dev-sso` nutzen — wie `luxly-sso` — den **bestehenden geteilten**
|
||||||
(K8s-Secret `oauth2-proxy-dev` in ns `iam`). Es ist **kein neuer Client** und
|
Zitadel-Client (K8s-Secret `oauth2-proxy-dev` in ns `iam`). **Kein neuer Client,
|
||||||
**kein neues Secret** noetig. Nur am vorhandenen Client im Zitadel-Console
|
kein neues Secret.** Nur am vorhandenen Client (`https://auth.momentrum.de`) die
|
||||||
(`https://auth.momentrum.de`) die Redirect-URI ergaenzen:
|
Redirect-URI ergaenzen:
|
||||||
|
|
||||||
- Redirect-URI **hinzufuegen**: `https://sso.ibo.momentrum.de/oauth2/callback`
|
- prod: `https://sso.ibo.momentrum.de/oauth2/callback` ← nur diese ist ibo-spezifisch
|
||||||
|
- dev (Previews): `https://sso.dev.momentrum.de/oauth2/callback` ← existiert i. d. R.
|
||||||
(EIN Login-Host `sso.ibo.momentrum.de` deckt per `cookie-domain .ibo.momentrum.de`
|
schon (kanban/luxly-Previews nutzen dasselbe dev-sso). Nichts zu tun, falls vorhanden.
|
||||||
dev **und** prod ab. Wer prod spaeter mit eigenem Blast-Radius trennen will:
|
|
||||||
eigenen Client + eigenes SealedSecret anlegen und im `ibo-sso`-Deployment
|
|
||||||
referenzieren — die `oauth2-proxy-dev`-Secret-Refs dort ersetzen.)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. oauth2-proxy `ibo-sso` (contabo-infra) — deployen
|
## 2. Cluster-Voraussetzungen (contabo-infra) — muessen laufen
|
||||||
|
|
||||||
Manifeste liegen in `contabo-infra/platform/manifests/ibo-sso/`
|
Fuer **prod** (`platform/manifests/ibo-sso/`, ArgoCD-App `platform/apps/ibo-sso.yaml`):
|
||||||
(Deployment/Service, Middlewares `oauth2-ibo-auth`/`oauth2-ibo-errors`, Ingress
|
- oauth2-proxy `ibo-sso` (Deployment/Service, ns `iam`).
|
||||||
`sso.ibo.momentrum.de`, oauth2-Passthrough-Route). Sie referenzieren das
|
- Middlewares `iam-oauth2-ibo-auth@kubernetescrd` / `iam-oauth2-ibo-errors@kubernetescrd`.
|
||||||
bestehende Secret `oauth2-proxy-dev` + die ConfigMap `oauth2-proxy-dev-templates`
|
- Ingress `sso.ibo.momentrum.de` (Login-Host, ohne Auth davor).
|
||||||
— **nichts einzusealen**.
|
- **Geteilte** stripPrefix-Middleware `iam-strip-novnc@kubernetescrd` (`strip-novnc.yaml`)
|
||||||
|
— die Previews referenzieren sie cross-namespace (s. §4).
|
||||||
|
|
||||||
Die ArgoCD-App `platform/apps/ibo-sso.yaml` wird vom platform-App-of-Apps
|
Fuer **dev/Previews** (bereits vorhanden, von kanban/luxly geteilt):
|
||||||
automatisch aufgenommen (gleiche Ablage wie `luxly-sso.yaml`) — committen &
|
- `dev-sso` (generischer oauth2-proxy `*.dev.momentrum.de`, Middlewares
|
||||||
pushen genuegt; alternativ einmalig `kubectl apply -f platform/manifests/ibo-sso/`.
|
`iam-oauth2-auth`/`iam-oauth2-errors`, Login `sso.dev.momentrum.de`).
|
||||||
Ausserdem ist das ibo-Repo in `platform/manifests/argocd-projects/internal.yaml`
|
- SealedSecret `gitea-appset-token` (ns `argocd`) — Gitea-Read fuer den PR-Generator.
|
||||||
(sourceRepos) bereits ergaenzt — sonst lehnt ArgoCD die App-Source ab.
|
- 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.
|
||||||
|
|
||||||
Ergebnis:
|
App-of-Apps nimmt `ibo-sso.yaml` automatisch auf — committen & pushen genuegt;
|
||||||
- Middlewares `iam-oauth2-ibo-auth@kubernetescrd` / `iam-oauth2-ibo-errors@kubernetescrd`
|
alternativ einmalig `kubectl apply -f platform/manifests/ibo-sso/`. Das ibo-Repo
|
||||||
stehen bereit (die App-Ingresses referenzieren sie).
|
ist in `platform/manifests/argocd-projects/internal.yaml` (sourceRepos) bereits
|
||||||
- `https://sso.ibo.momentrum.de` liefert die Login-Seite (kein Auth davor).
|
erlaubt (sonst lehnt ArgoCD die prod-App-Source ab).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. DNS
|
## 3. DNS
|
||||||
|
|
||||||
A/AAAA-Records auf die Cluster-Ingress-IP zeigen lassen:
|
A/AAAA-Records auf die Cluster-Ingress-IP:
|
||||||
- `ibo.momentrum.de`
|
- `ibo.momentrum.de` (prod)
|
||||||
- `dev.ibo.momentrum.de`
|
- `sso.ibo.momentrum.de` (prod-Login)
|
||||||
- `sso.ibo.momentrum.de`
|
|
||||||
|
|
||||||
cert-manager (`letsencrypt-prod`, HTTP-01) stellt die Zertifikate `ibo-tls`,
|
Previews brauchen **keinen eigenen Record** — sie laufen unter dem bestehenden
|
||||||
`ibo-dev-tls`, `ibo-sso-tls` automatisch aus, sobald DNS steht.
|
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. Deploy-Reihenfolge
|
## 4. CD-Apps im `momentrum-deploy` (bereits angelegt)
|
||||||
|
|
||||||
1. Repo gepusht (Schritt 0) → CI baut das erste Image und bumpt
|
- `apps/internal/ibo/app.yaml` — prod-Application (`ibo.momentrum.de`,
|
||||||
`apps/internal/ibo/dev.yaml` (`image.tag`).
|
ns `apps-internal`, SSO `iam-oauth2-ibo-*`). Auto-Sync; `image.tag` bumpt die CI.
|
||||||
2. `ibo-sso` laeuft (Schritt 2), DNS steht (Schritt 3).
|
- `apps/internal/ibo/preview.yaml` — PR-Preview-ApplicationSet (Gitea-PR-Generator,
|
||||||
3. CD-Apps im `momentrum-deploy` committen: `apps/internal/ibo/dev.yaml` +
|
Label-Gate `preview`). Rendert ibos Chart aus dem **PR-Branch** und setzt pro PR:
|
||||||
`apps/internal/ibo/app.yaml`. ArgoCD legt Namespace `apps-ibo` an und synct.
|
Host `ibo-pr-<nr>.dev.momentrum.de`, `priorityClassName: preview`, gedeckelte
|
||||||
4. **Erstes Prod-Promote:** den von der CI in `dev.yaml` gesetzten `image.tag`
|
Resources (preview-ns-Quota: ≤2 CPU / 1536Mi Limits gesamt),
|
||||||
nach `app.yaml` kopieren (siehe unten) — sonst hat prod noch `tag: latest`.
|
`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. Prod promoten (Routine)
|
## 5. Deploy-Flows
|
||||||
|
|
||||||
Prod bekommt bewusst NUR den Tag, den man freigibt:
|
**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).
|
||||||
|
|
||||||
```sh
|
**prod (bei main-Merge):**
|
||||||
cd momentrum-deploy
|
- CI-Job `deploy` schreibt den neuen `image.tag` in `apps/internal/ibo/app.yaml`
|
||||||
DEVTAG=$(grep -E '^ tag: ' apps/internal/ibo/dev.yaml | awk '{print $2}')
|
zurueck → ArgoCD synct prod automatisch. Kein manueller Schritt.
|
||||||
sed -i "s|^ tag: .*| tag: ${DEVTAG}|" apps/internal/ibo/app.yaml
|
- **Rollback:** `git revert` des CI-Commits im `momentrum-deploy` (ArgoCD synct
|
||||||
git commit -am "ibo: promote ${DEVTAG} -> prod" && git push
|
zurueck). Alternativ `image.tag` in `app.yaml` auf einen aelteren Tag setzen.
|
||||||
```
|
|
||||||
|
|
||||||
ArgoCD synct prod auf den neuen Tag. Rollback = `git revert` dieses Commits.
|
> 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)
|
## 6. Browser-Live-Ansicht (noVNC)
|
||||||
|
|
||||||
Der Automations-Chrome laeuft im `selenium`-Sidecar; sein Bild wird per noVNC
|
Der Automations-Chrome laeuft im `selenium`-Sidecar; sein Bild wird per noVNC
|
||||||
gestreamt und in der Web-App eingebettet (Button „👁️ Browser live ansehen",
|
gestreamt und in der Web-App eingebettet (Button „👁️ Browser live ansehen").
|
||||||
oeffnet auch automatisch beim Consent-Browser). Routing:
|
Routing:
|
||||||
|
|
||||||
- App-Container → Chrome via `SELENIUM_REMOTE_URL=http://localhost:4444`.
|
- App-Container → Chrome via `SELENIUM_REMOTE_URL=http://localhost:4444`.
|
||||||
- Client-Browser → `https://<host>/novnc/…` → Ingress-Pfad `/novnc`
|
- Client-Browser → `https://<host>/novnc/…` → Ingress-Pfad `/novnc`
|
||||||
→ stripPrefix-Middleware → Sidecar-Port 7900 (noVNC/websockify).
|
→ stripPrefix-Middleware → Sidecar-Port 7900 (noVNC/websockify).
|
||||||
- Steuerbar durch die SSO-Cookie (gleicher Host, gleiche Middlewares).
|
- 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
|
Der Browser laeuft **serverseitig** im Container — es wird NICHT der lokale
|
||||||
Browser des Nutzers ferngesteuert (das ginge von einer gehosteten App aus nicht).
|
Browser des Nutzers ferngesteuert.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7. Break-glass (Notzugang)
|
## 7. Break-glass (Notzugang)
|
||||||
|
|
||||||
Faellt Zitadel aus: die SSO-Middlewares temporaer aus `ingress.ssoMiddlewares`
|
Faellt Zitadel aus: die SSO-Middlewares temporaer aus `ingress.ssoMiddlewares`
|
||||||
im jeweiligen CD-App-YAML entfernen (die App selbst hat keine eigene Auth →
|
in `apps/internal/ibo/app.yaml` (prod) entfernen (die App selbst hat keine eigene
|
||||||
sie ist dann OFFEN). Nur kurz, danach sofort zuruecksetzen. Nie ungeschuetzt
|
Auth → sie ist dann OFFEN). Nur kurz, danach sofort zuruecksetzen. Nie
|
||||||
lassen.
|
ungeschuetzt lassen.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -139,10 +151,11 @@ lassen.
|
|||||||
- [ ] `docker compose up -d` lokal → `http://localhost:5000` UI, „Browser live
|
- [ ] `docker compose up -d` lokal → `http://localhost:5000` UI, „Browser live
|
||||||
ansehen" zeigt den Chrome im iframe (localhost:7900).
|
ansehen" zeigt den Chrome im iframe (localhost:7900).
|
||||||
- [ ] `curl -s localhost:5000/healthz` → `{"ok":true}`.
|
- [ ] `curl -s localhost:5000/healthz` → `{"ok":true}`.
|
||||||
- [ ] main-Push → CI gruen (version→test→build-push→helm-validate→deploy-dev),
|
- [ ] PR + Label `preview` → CI gruen (version→test→build-push→helm-validate),
|
||||||
`dev.yaml`-Tag gebumpt, ArgoCD rollt dev.
|
ArgoCD legt `ibo-pr-<nr>` an, `https://ibo-pr-<nr>.dev.momentrum.de`
|
||||||
- [ ] `https://dev.ibo.momentrum.de` → Redirect zu `auth.momentrum.de`, nach
|
redirected zu `auth.momentrum.de`, nach Login landet man in der App.
|
||||||
Login landet man in der App.
|
- [ ] Im Preview eingebettetes `/novnc/` zeigt den Live-Browser.
|
||||||
- [ ] In der App eingebettetes `/novnc/` zeigt den Live-Browser.
|
- [ ] PR schliessen → Preview + Namespace verschwinden (ArgoCD prune).
|
||||||
- [ ] `https://ibo.momentrum.de` nach Promote ebenso hinter Zitadel.
|
- [ ] 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).
|
- [ ] Ohne SSO-Session → Login-Redirect (kein rohes 401).
|
||||||
|
|||||||
@ -15,12 +15,19 @@ app.kubernetes.io/instance: {{ .Release.Name }}
|
|||||||
|
|
||||||
{{- /*
|
{{- /*
|
||||||
Middleware-Kette fuer die Ingress-Annotation: erst die SSO-Middlewares aus dem
|
Middleware-Kette fuer die Ingress-Annotation: erst die SSO-Middlewares aus dem
|
||||||
CD-Repo (errors VOR auth), dann die same-namespace stripPrefix fuer /novnc.
|
CD-Repo (errors VOR auth), dann die stripPrefix fuer /novnc. Traefik-Ingress-Refs
|
||||||
Traefik-Ingress-Refs sind "<namespace>-<name>@kubernetescrd".
|
sind "<namespace>-<name>@kubernetescrd".
|
||||||
|
Die stripPrefix-Middleware ist normalerweise die vom Chart im Release-Namespace
|
||||||
|
angelegte; ist novncStripPrefixRef gesetzt (Previews), wird stattdessen diese
|
||||||
|
EXTERNE (geteilte) Middleware referenziert und das Chart legt keine eigene an.
|
||||||
*/ -}}
|
*/ -}}
|
||||||
{{- define "ibo.middlewares" -}}
|
{{- define "ibo.middlewares" -}}
|
||||||
{{- $mw := list -}}
|
{{- $mw := list -}}
|
||||||
{{- if .Values.ingress.ssoMiddlewares -}}{{- $mw = append $mw .Values.ingress.ssoMiddlewares -}}{{- end -}}
|
{{- if .Values.ingress.ssoMiddlewares -}}{{- $mw = append $mw .Values.ingress.ssoMiddlewares -}}{{- end -}}
|
||||||
|
{{- if .Values.ingress.novncStripPrefixRef -}}
|
||||||
|
{{- $mw = append $mw .Values.ingress.novncStripPrefixRef -}}
|
||||||
|
{{- else -}}
|
||||||
{{- $mw = append $mw (printf "%s-%s-novnc@kubernetescrd" .Release.Namespace (include "ibo.name" .)) -}}
|
{{- $mw = append $mw (printf "%s-%s-novnc@kubernetescrd" .Release.Namespace (include "ibo.name" .)) -}}
|
||||||
|
{{- end -}}
|
||||||
{{- join "," $mw -}}
|
{{- join "," $mw -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|||||||
@ -17,6 +17,9 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
{{- include "ibo.selectorLabels" . | nindent 8 }}
|
{{- include "ibo.selectorLabels" . | nindent 8 }}
|
||||||
spec:
|
spec:
|
||||||
|
{{- with .Values.priorityClassName }}
|
||||||
|
priorityClassName: {{ . }}
|
||||||
|
{{- end }}
|
||||||
containers:
|
containers:
|
||||||
# --- Flask-Web-App ---------------------------------------------------
|
# --- Flask-Web-App ---------------------------------------------------
|
||||||
- name: app
|
- name: app
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
{{- if .Values.ingress.enabled }}
|
{{- if and .Values.ingress.enabled (not .Values.ingress.novncStripPrefixRef) }}
|
||||||
# Strippt den /novnc-Prefix, bevor der Request an den Selenium-noVNC (7900) geht:
|
# Strippt den /novnc-Prefix, bevor der Request an den Selenium-noVNC (7900) geht:
|
||||||
# der Ingress-Pfad /novnc/vnc.html -> selenium sieht /vnc.html, /novnc/websockify
|
# der Ingress-Pfad /novnc/vnc.html -> selenium sieht /vnc.html, /novnc/websockify
|
||||||
# -> /websockify. Same-namespace, wird in _helpers.tpl an die Middleware-Kette
|
# -> /websockify. Same-namespace, wird in _helpers.tpl an die Middleware-Kette
|
||||||
# der Ingress-Annotation angehaengt.
|
# der Ingress-Annotation angehaengt.
|
||||||
|
# NUR wenn ingress.novncStripPrefixRef leer ist — Previews referenzieren eine
|
||||||
|
# geteilte externe Middleware (iam-strip-novnc), weil das "previews"-AppProject
|
||||||
|
# das Anlegen von traefik.io/Middleware im Preview-ns blockt.
|
||||||
apiVersion: traefik.io/v1alpha1
|
apiVersion: traefik.io/v1alpha1
|
||||||
kind: Middleware
|
kind: Middleware
|
||||||
metadata:
|
metadata:
|
||||||
|
|||||||
@ -12,6 +12,11 @@ image:
|
|||||||
# offener Consent-Browser) — mehrere Replicas wuerden ihn nicht teilen.
|
# offener Consent-Browser) — mehrere Replicas wuerden ihn nicht teilen.
|
||||||
replicaCount: 1
|
replicaCount: 1
|
||||||
|
|
||||||
|
# Previews setzen "preview" (niedrige PriorityClass, definiert in contabo-infra):
|
||||||
|
# unter Memory-Pressure auf der 12-GB-Box sterben Preview-Pods zuerst, nie Prod.
|
||||||
|
# Prod laesst das leer.
|
||||||
|
priorityClassName: ""
|
||||||
|
|
||||||
service:
|
service:
|
||||||
# Nach aussen (ClusterIP) sichtbare Ports; targetPorts sind die Container-Ports.
|
# Nach aussen (ClusterIP) sichtbare Ports; targetPorts sind die Container-Ports.
|
||||||
appPort: 80
|
appPort: 80
|
||||||
@ -41,12 +46,18 @@ ingress:
|
|||||||
secretName: ibo-tls
|
secretName: ibo-tls
|
||||||
annotations:
|
annotations:
|
||||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
# Zitadel-SSO davor (oauth2-proxy "ibo-sso" in contabo-infra). Reihenfolge:
|
# Zitadel-SSO davor. Reihenfolge: errors VOR auth, damit 401 zum Login-Redirect
|
||||||
# errors VOR auth, damit 401 zum Login-Redirect wird. Die stripPrefix-Middleware
|
# wird. Die stripPrefix-Middleware fuer /novnc haengt das Chart hinten an
|
||||||
# fuer /novnc haengt das Chart selbst hinten an (siehe _helpers.tpl).
|
# (siehe _helpers.tpl). Vom CD-Repo gesetzt:
|
||||||
# Vom CD-Repo gesetzt, z.B.:
|
# prod -> "iam-oauth2-ibo-errors@kubernetescrd,iam-oauth2-ibo-auth@kubernetescrd" (per-App ibo-sso)
|
||||||
# "iam-oauth2-ibo-errors@kubernetescrd,iam-oauth2-ibo-auth@kubernetescrd"
|
# preview -> "iam-oauth2-errors@kubernetescrd,iam-oauth2-auth@kubernetescrd" (generisches dev-sso)
|
||||||
ssoMiddlewares: ""
|
ssoMiddlewares: ""
|
||||||
|
# Referenz auf eine EXTERNE /novnc-stripPrefix-Middleware ("<ns>-<name>@kubernetescrd").
|
||||||
|
# Leer = das Chart legt die Middleware selbst im Release-Namespace an (Prod/Default).
|
||||||
|
# Gesetzt = Chart legt KEINE eigene an, haengt stattdessen diese Referenz an die Kette.
|
||||||
|
# PR-Previews MUESSEN das setzen: das ArgoCD-"previews"-Project blockt das Anlegen von
|
||||||
|
# traefik.io/Middleware im Preview-ns (Anti-Auth-Faelschung) -> geteilte iam-strip-novnc.
|
||||||
|
novncStripPrefixRef: ""
|
||||||
|
|
||||||
resources:
|
resources:
|
||||||
app:
|
app:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user