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

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:
timu 2026-07-17 23:49:27 +02:00
parent 650d7f3394
commit d1ccf17b5f
6 changed files with 143 additions and 103 deletions

View File

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

View File

@ -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).

View File

@ -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 -}}

View File

@ -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

View File

@ -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:

View File

@ -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: