# bp-openbao — Catalyst bootstrap-kit Blueprint. Secret backend. 3-node Raft, region-local. No stretched cluster (per SECURITY.md §5).
#
# Wrapper chart: platform/openbao/chart/
# Catalyst-curated values: platform/openbao/chart/values.yaml
# Reconciled by: Flux on the new Sovereign's k3s control plane.

---
apiVersion: v1
kind: Namespace
metadata:
  name: openbao
  labels:
    catalyst.openova.io/sovereign: ${SOVEREIGN_FQDN}
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
  name: bp-openbao
  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-openbao
  namespace: flux-system
spec:
  interval: 15m
  releaseName: openbao
  targetNamespace: openbao
  dependsOn:
    # bp-gateway-api (issue #503): chart ships an HTTPRoute template at
    # platform/openbao/chart/templates/httproute.yaml; the
    # gateway.networking.k8s.io/v1 CRDs MUST be registered before this
    # HelmRelease applies or install fails with `no matches for kind
    # HTTPRoute`.
    - name: bp-gateway-api
    # bp-cnpg (issue #512): the OpenBao 3-node Raft post-install init Job
    # (Helm hook weight 5) runs `bao operator init` and seals/unseals via
    # Kubernetes auth; both paths require the cnpg PostgreSQL backing the
    # OpenBao audit/storage adjuncts to be Ready, otherwise the hook
    # blocks until Helm's install timeout (15m) expires. Phase-8a-preflight
    # otech16 (2026-05-02): even with timeout=15m, the hook raced cnpg
    # coming up. Adding the explicit dep makes Flux wait for bp-cnpg
    # Ready=True before starting bp-openbao install. See issue #512.
    - name: bp-cnpg
  chart:
    spec:
      chart: bp-openbao
      version: 1.2.14
      sourceRef:
        kind: HelmRepository
        name: bp-openbao
        namespace: flux-system
  # Event-driven install: OpenBao 3-node Raft cluster goes through a
  # post-install init Job (issue #316) — `bao operator init` runs at
  # Helm hook weight 5 and the Kubernetes-auth bootstrap Job at weight
  # 10. The StatefulSet pods stay sealed for ~30s while the init Job
  # runs, so we keep `disableWait: true` (Helm Ready ≠ OpenBao
  # initialised — the init hook drives that out-of-band). Replaces
  # PR #221 spec.timeout: 15m.
  install:
    disableWait: true
    timeout: 15m
    remediation:
      retries: 3
  upgrade:
    disableWait: true
    timeout: 15m
    remediation:
      retries: 3
  # Per-Sovereign overrides:
  # - gateway.host (issue #387): wires the per-Sovereign hostname into
  #   the HTTPRoute template (platform/openbao/chart/templates/httproute.yaml).
  #   The HTTPRoute attaches to cilium-gateway/kube-system installed by
  #   01-cilium.yaml.
  # - autoUnseal.enabled (issue #316): activates the post-install init
  #   Job + Kubernetes-auth bootstrap Job in the chart. Cloud-init
  #   (infra/hetzner/cloudinit-control-plane.tftpl) writes the seed
  #   Secret `openbao-recovery-seed` in the openbao namespace BEFORE
  #   Flux applies this HelmRelease, so the init Job has the seed it
  #   needs on first reconcile.
  values:
    gateway:
      host: bao.${SOVEREIGN_FQDN}
    autoUnseal:
      enabled: true
      # Issue #517 (cont): the chart's init-job.yaml + auth-bootstrap-job.yaml
      # default baoAddress to `http://<release>-openbao:8200`, but with
      # spec.releaseName=openbao the upstream openbao chart's `fullname`
      # template returns just `openbao` (not `openbao-openbao`) because
      # Release.Name CONTAINS chart name. The rendered Service is
      # `openbao` in the openbao namespace. Override the default so the
      # post-install Jobs can actually reach the server.
      baoAddress: http://openbao.openbao.svc.cluster.local:8200
    # Issue #517 (Phase-8a single-node): openbao upstream chart's
    # 3-replica StatefulSet uses required pod-anti-affinity by hostname.
    # On single-node Phase-8a Sovereigns this leaves 2/3 pods Pending
    # forever, the openbao-init Job's wait-for-Ready loop times out, and
    # the entire HR fails post-install. Drop to 1 replica until the
    # workerCount > 0 path is wired — the autoUnseal flow does not
    # require a quorum to bootstrap (Raft is still enabled, just one
    # voter).
    #
    # CRITICAL — schema nesting (issue #517 root cause): platform/openbao/
    # chart/Chart.yaml declares the upstream openbao chart as a Helm
    # SUBCHART under `dependencies:`. Helm umbrella-chart convention
    # requires subchart values to be nested under the dependency name
    # (`openbao:`). Putting `server.ha.replicas` / `server.affinity` at
    # the top level here is SILENTLY IGNORED — the upstream subchart
    # never sees them and renders 3-replica + pod-anti-affinity.
    openbao:
      server:
        ha:
          replicas: 1
        affinity: ""
