openova/platform/harbor/chart/templates/database-secret.yaml
e3mrah 8d2ba0495d
fix(bp-gitea): switch to CNPG-managed postgres, drop bitnamilegacy subchart (Closes #584) (#586)
Squash merge: fix(bp-gitea) switch to CNPG-managed postgres (Closes #584)
2026-05-02 15:18:49 +04:00

68 lines
3.6 KiB
YAML

{{- /*
Placeholder Secret that reflector (bp-reflector) populates from the CNPG-
generated `harbor-pg-app` Secret.
Harbor upstream chart reads `database.external.existingSecret` expecting a
key `HARBOR_DATABASE_PASSWORD` in the named Secret. CNPG produces
`harbor-pg-app` with a `password` key. Two problems to bridge:
1. Key name mismatch (`password` vs `HARBOR_DATABASE_PASSWORD`)
2. Timing: CNPG may not have provisioned `harbor-pg-app` when Helm renders
(Helm `lookup` only works reliably for idempotent upgrades, not fresh
installs where the Cluster boots after the chart is applied)
Solution: use the k8s-reflector (bp-reflector, slot 05a) to copy
`harbor-pg-app` into this Secret via the `reflects` annotation. The
`reflection-allowed` annotations on the SOURCE Secret (`harbor-pg-app`)
are added at runtime by the `harbor-pg-app-annotator` post-install Job
(templates/cnpg-app-annotator-job.yaml), which polls until CNPG creates
the Secret then PATCHes the annotations in. Once the source carries
`reflection-allowed: true`, Reflector propagates the full key set from
`harbor-pg-app` into `harbor-database-secret`, including `password` and
`HARBOR_DATABASE_PASSWORD`. Harbor core reads `HARBOR_DATABASE_PASSWORD`
from the secret on the next CrashLoop retry — typically within seconds
of Reflector firing.
Why not Helm `lookup`?
Helm `lookup` is evaluated only during `helm install` / `helm upgrade`
template rendering. On a fresh Sovereign, CNPG bootstraps the Cluster AFTER
the bp-harbor HelmRelease applies (CNPG takes 30-60 s to reach Ready). The
first Helm render finds `harbor-pg-app` absent and writes an empty password.
Flux then marks bp-harbor Ready (disableWait: true); harbor-core crashloops
quietly. Triggering a manual Helm upgrade after CNPG is ready would fix it,
but requires operator action. Reflector is event-driven: as soon as
`harbor-pg-app` is created (or rotated), the watch fires and the Secret is
updated — no operator action required.
Per docs/INVIOLABLE-PRINCIPLES.md #10 (credential hygiene): no plaintext
credentials appear in this committed template. The reflector copies bytes from
a live cluster Secret.
*/}}
apiVersion: v1
kind: Secret
metadata:
name: harbor-database-secret
namespace: {{ .Values.postgres.cluster.namespace | default .Release.Namespace }}
labels:
{{- include "bp-harbor.labels" . | nindent 4 }}
annotations:
# Reflector (bp-reflector) copies all keys from harbor-pg-app into this
# Secret. Harbor upstream reads HARBOR_DATABASE_PASSWORD; CNPG ships
# `password`. Both land in the Secret via the copy, and Harbor's env
# binding in the upstream chart uses `existingSecret` which maps
# harbor.database.external.existingSecret → envFrom secretRef.
reflector.v1.k8s.emberstack.com/reflects: "{{ .Values.postgres.cluster.namespace | default .Release.Namespace }}/{{ .Values.postgres.cluster.name | default "harbor-pg" }}-app"
# Helm resource-policy keep — do not delete on helm uninstall (the
# Secret is independently managed by reflector after initial creation).
helm.sh/resource-policy: keep
type: Opaque
# Bootstrap empty data — reflector overwrites these within seconds of
# harbor-pg-app being created by CNPG. The empty values prevent harbor-core
# from getting into CreateContainerConfigError (secret missing) on the
# initial render. It will still fail auth on the empty password but will
# crash-loop until reflector propagates, which happens ~seconds after CNPG
# reaches Ready — typically within the first bp-harbor upgrade remediation
# cycle (retries: 3 per HelmRelease spec).
data:
password: ""
HARBOR_DATABASE_PASSWORD: ""