# bp-keycloak — Catalyst bootstrap-kit Blueprint. User identity. Topology decided by Sovereign CRD spec.keycloakTopology.
#
# Wrapper chart: platform/keycloak/chart/
# Catalyst-curated values: platform/keycloak/chart/values.yaml
# Reconciled by: Flux on the new Sovereign's k3s control plane.

---
apiVersion: v1
kind: Namespace
metadata:
  name: keycloak
  labels:
    catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
  name: bp-keycloak
  namespace: flux-system
spec:
  type: oci
  interval: 15m
  url: oci://ghcr.io/openova-io
  secretRef:
    name: ghcr-pull
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: bp-keycloak
  namespace: flux-system
  labels:
    catalyst.openova.io/slot: "09"
spec:
  interval: 15m
  releaseName: keycloak
  targetNamespace: keycloak
  dependsOn:
    - name: bp-cert-manager
    # bp-gateway-api (issue #503): chart ships an HTTPRoute template;
    # gateway.networking.k8s.io/v1 CRDs must be registered first.
    - name: bp-gateway-api
  chart:
    spec:
      chart: bp-keycloak
      # 1.5.0 (qa-loop iter-12 Fix #53A): adds .Values.sovereignRealm.name
      # parameter so each Sovereign owns its KC realm named after the tenant
      # short-name (omantel chroot → "omantel"). Default `sovereign` is kept
      # in the chart for backward compat with overlays not yet migrated.
      # 1.4.5 (issue #146, prov #21+#22 hung 30+ min on bp-keycloak install):
      # post-#140 retune. (a) availabilityCheck.timeout 900s → 300s — coarser
      # retry was busting HR window before backoff could retry; faster
      # failure means more attempts fit. (b) startupProbe enabled with 30m
      # budget so slow Liquibase doesn't get killed by livenessProbe mid-
      # migration. (c) livenessProbe.initialDelaySeconds 300 → 60 (cold-
      # start protection now lives in startupProbe). Coupled HR change
      # below: install/upgrade.remediation.retries 3 → 1 (Job's own
      # backoffLimit handles retries without losing state across Helm
      # restarts). Together: ≤ 30m wall-clock vs. 90m+ before.
      # 1.4.4 (issue #140, post-upgrade hook regression on prov #21): bumps
      # keycloakConfigCli.availabilityCheck.timeout 600s → 900s + adds
      # cleanupAfterFinished (1h TTL) so stale hook Pods don't race
      # before-hook-creation deletes on subsequent upgrades. Coupled with
      # the install/upgrade timeout bump below (15m → 30m) so Helm's
      # outer hook-wait accommodates the inner 15m availability window.
      # 1.4.3 (issue #129): bumped keycloakConfigCli.availabilityCheck.timeout
      # 120s → 600s + backoffLimit 1 → 5 (fresh-install wedge).
      version: 1.4.6
      sourceRef:
        kind: HelmRepository
        name: bp-keycloak
        namespace: flux-system
  # Event-driven install: Keycloak DB schema migration + realm import is
  # legitimately multi-minute on first install (PostgreSQL backend +
  # 100+ Liquibase changesets). Helm install completes when manifests
  # apply; downstream dependsOn checks Ready=True independently.
  # Replaces PR #221 spec.timeout: 15m.
  #
  # 15m → 30m bump (issue #140, post-upgrade hook regression on prov #21):
  # `disableWait: true` skips Pod-Ready waits but does NOT skip Helm hook
  # waits — Helm always blocks on hook-Pod completion bounded by this
  # timeout. The bp-keycloak chart's keycloak-config-cli post-install/
  # post-upgrade hook now has an inner availabilityCheck.timeout of 900s
  # (15m), and on chart-roll-triggered upgrades the keycloak StatefulSet
  # rolling-restart + Liquibase re-validation can consume that full
  # window. 30m gives Helm room to wait out one full inner attempt plus
  # exponential backoff if needed, without blowing past Flux's HR timer.
  # If you bump availabilityCheck.timeout further, bump THIS too.
  # remediation.retries 3 → 1 (issue #146, prov #21+#22 hung 30+ min):
  # Flux HR remediation does a full Helm uninstall+reinstall on each retry,
  # losing all hook-Pod state and restarting Liquibase from zero. With 3
  # retries × 30m HR timeout = up to 90m of wasted work before Flux gives
  # up. The keycloak-config-cli Job already retries internally via
  # `backoffLimit: 5` (set in chart values.yaml) — Job-level backoff
  # preserves Keycloak's state and only re-runs the realm-import sidecar.
  # HR-level remediation is reserved for genuine release-failure (e.g.
  # invalid manifest) where a clean reinstall is the right answer; one
  # retry is sufficient for that. Job-level vs. HR-level retry is the
  # correct separation per the bitnami subchart's design.
  install:
    disableWait: true
    timeout: 30m
    remediation:
      retries: 1
  upgrade:
    disableWait: true
    timeout: 30m
    remediation:
      retries: 1
  # Per-Sovereign overrides — issue #387 + #604 + qa-loop iter-12 Fix #53A:
  # Wire the per-Sovereign hostname into the HTTPRoute template and
  # sovereign realm ConfigMap (catalyst-ui redirect URIs). The HTTPRoute
  # attaches to cilium-gateway/kube-system installed by 01-cilium.yaml.
  #
  # sovereignRealm.name: per `feedback_no_mvp_no_workarounds.md` target-state
  # rule, each Sovereign owns its KC realm named after the tenant short-name.
  # The bootstrap-kit Kustomization's postBuild.substitute supplies
  # SOVEREIGN_REALM_NAME (canonical: first label of SOVEREIGN_FQDN, e.g.
  # `omantel` for omantel.biz). When unset the envsubst rule
  # ${VAR:=default} resolves to "sovereign" — backward-compat with
  # overlays that haven't been migrated.
  values:
    sovereignFQDN: ${SOVEREIGN_FQDN}
    sovereignRealm:
      name: ${SOVEREIGN_REALM_NAME:=sovereign}
    gateway:
      host: auth.${SOVEREIGN_FQDN}
