Replace Helm lookup in database-secret.yaml with reflector annotation: harbor-database-secret now reflects harbor-pg-app via reflector.v1.k8s.emberstack.com/reflects. This fixes the race between Helm rendering (fresh install) and CNPG cluster bootstrap — reflector is event-driven and propagates the CNPG password within seconds of harbor-pg-app being created, with no operator action required. Also includes: - templates/cnpg-cluster.yaml: harbor-pg CNPG Cluster (1 inst, 5Gi, pg16) - values.yaml: postgres: block + database.external.host = harbor-pg-rw - Chart 1.2.0 → 1.2.1; bootstrap-kit refs updated (_template, otech, omantel) Co-authored-by: alierenbaysal <alierenbaysal@openova.io> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
66 lines
3.5 KiB
YAML
66 lines
3.5 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 `reflect-from-namespace/name`
|
|
annotation. The `reflect-allowed-namespaces` annotation on the source
|
|
Secret is set by the CNPG Cluster via the `cnpg-cluster.yaml` template's
|
|
extra annotations. Reflector propagates the full key set from `harbor-pg-app`
|
|
into `harbor-database-secret`, including `password`. Harbor core reads
|
|
`HARBOR_DATABASE_PASSWORD` from the secret — since reflector copies ALL keys,
|
|
we also explicitly alias it below via a second strategy using
|
|
`reflect-from-namespace/name` so the upstream key set arrives whole.
|
|
|
|
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: ""
|