{{- /*
Auto-provision catalyst-organization-controller-keycloak Secret on Sovereign install
(qa-loop iter-1 Fix #14, organization-controller CrashLoopBackOff chain).

Why this template exists
========================
templates/controllers/organization-controller-deployment.yaml lines 75-86
reference a secretKeyRef on `catalyst-organization-controller-keycloak` for:
  - client-id (CATALYST_KC_SA_CLIENT_ID env, mustEnv in cmd/main.go:60)
  - client-secret (CATALYST_KC_SA_CLIENT_SECRET env, mustEnv in cmd/main.go:61)

Both env vars are mandatory on the controller binary side (`mustEnv` panics
with "required env var unset" if missing). Until this Secret exists, the
controller CrashLoopBackOffs from start-up.

On Catalyst-Zero (contabo-mkt) the canonical KC SA bytes live in
`keycloak-zero/catalyst-kc-sa-credentials` — a separate Helm release in its
own namespace. There is NO `catalyst-kc-sa-credentials` Secret in the
`keycloak` namespace there; the operator hand-rolls catalyst-organization-
controller-keycloak under clusters/contabo-mkt/apps/... if/when they enable
the controller on the mothership.

On a freshly franchised Sovereign nothing equivalent existed before this
template — the controller pod CrashLoopBackOff'd indefinitely. Caught live
on omantel during qa-loop iter-1 (2026-05-09).

Sovereign-vs-Mothership gate (load-bearing, mirrors the
catalyst-openova-kc-credentials pattern)
========================================================
The canonical KC SA source on a Sovereign is the `catalyst-kc-sa-credentials`
Secret in the `keycloak` namespace (created by bp-keycloak's openbao-bridge
post-install hook — see platform/keycloak/chart/templates/, issue #781).

We gate render on `lookup "v1" "Secret" "keycloak" "catalyst-kc-sa-credentials"`
returning non-nil. This means:
  - On a Sovereign: lookup returns the secret → template renders → the
    chart auto-provisions catalyst-organization-controller-keycloak in
    catalyst-system from the keycloak SA Secret.
  - On contabo-mkt: lookup returns nil → template renders empty bytes →
    if the operator hand-rolled the Secret under clusters/contabo-mkt/apps/...
    it is untouched (no helm-vs-kustomize ownership flap).

Why a SEPARATE Secret rather than re-using catalyst-openova-kc-credentials
==========================================================================
The two Secrets share the SAME source bytes (client-id + client-secret from
keycloak/catalyst-kc-sa-credentials) but serve different consumers:
  - catalyst-openova-kc-credentials: catalyst-api PIN-auth flow (kc-addr,
    kc-realm, kc-sa-client-id, kc-sa-client-secret, kc-audience + SMTP)
  - catalyst-organization-controller-keycloak: organization-controller
    binary (client-id, client-secret) — KEYS DIFFER (no `kc-sa-` prefix
    because the controller's mustEnv reads `CATALYST_KC_SA_CLIENT_ID` from
    secret key `client-id`, not `kc-sa-client-id`)

A single Secret with both key shapes would work but conflates two
consumers' lifecycles. Per docs/INVIOLABLE-PRINCIPLES.md #4 (one source of
truth per concern) we keep them separate; the source-of-truth is still the
single keycloak/catalyst-kc-sa-credentials Secret, both targets are
projections of it.

Persistence across reconciles
=============================
helm.sh/resource-policy: keep — survives helm uninstall so a re-install
picks up the same bytes via lookup. EXISTING TARGET WINS over source —
matches the catalyst-openova-kc-credentials KC-fields contract: openbao
auto-rotates the source Secret's client-secret on every Helm upgrade; we
must NOT thrash the controller Pod's secretKeyRef on every reconcile.
Operator forces a re-mirror by deleting the target Secret.

Per docs/INVIOLABLE-PRINCIPLES.md #10: NO plaintext credentials in this
template. All values flow through Helm `lookup` of existing K8s Secrets.
*/}}
{{- $kcSrc := lookup "v1" "Secret" "keycloak" "catalyst-kc-sa-credentials" -}}
{{- if and $kcSrc $kcSrc.data -}}
{{- $secretName := "catalyst-organization-controller-keycloak" -}}
{{- $namespace := .Release.Namespace -}}
{{- /* ---- Persistent target lookup ---- */ -}}
{{- $existing := lookup "v1" "Secret" $namespace $secretName -}}
{{- /* ---- KC fields: prefer existing target → fall back to source Secret ---- */ -}}
{{- $clientID := "" -}}
{{- $clientSecret := "" -}}
{{- if and $existing $existing.data (index $existing.data "client-id") -}}
  {{- $clientID = index $existing.data "client-id" | b64dec -}}
{{- else if (index $kcSrc.data "client-id") -}}
  {{- $clientID = index $kcSrc.data "client-id" | b64dec -}}
{{- end -}}
{{- if and $existing $existing.data (index $existing.data "client-secret") -}}
  {{- $clientSecret = index $existing.data "client-secret" | b64dec -}}
{{- else if (index $kcSrc.data "client-secret") -}}
  {{- $clientSecret = index $kcSrc.data "client-secret" | b64dec -}}
{{- end -}}
apiVersion: v1
kind: Secret
metadata:
  name: {{ $secretName }}
  namespace: {{ $namespace }}
  labels:
    catalyst.openova.io/blueprint: bp-catalyst-platform
    catalyst.openova.io/component: organization-controller
    app.kubernetes.io/part-of: catalyst
  annotations:
    # Survive helm uninstall — the Secret outlives the release. A
    # subsequent helm install picks up the bytes via lookup against the
    # source Secret (and the persisted target if still present).
    helm.sh/resource-policy: keep
type: Opaque
data:
  client-id: {{ $clientID | b64enc | quote }}
  client-secret: {{ $clientSecret | b64enc | quote }}
{{- end }}
