# Catalyst Blueprint umbrella metadata — the upstream chart is now resolved
# as a Helm subchart via Chart.yaml `dependencies:`. This values.yaml carries
# both:
#   1. The catalystBlueprint metadata block (provenance + version) so
#      observability/audit pipelines can inspect the artifact and report
#      which upstream chart + version is bundled.
#   2. The upstream subchart values overlay under the `flux2:` key
#      (umbrella-chart convention — the dependency name from Chart.yaml is
#      the values namespace).

global:
  # When set, ALL image pulls in this chart route through this registry.
  # Used post-handover when the Sovereign's own Harbor takes over the
  # proxy_cache role from contabo's central Harbor. Empty = no rewrite
  # (image references use upstream defaults). The upstream flux2 chart
  # exposes per-controller `flux2.<controller>.image.repository` knobs.
  # Per-Sovereign overlays wire those alongside this value. Tracked under #560.
  imageRegistry: ""

catalystBlueprint:
  # Pinned to flux2 2.14.1 (= upstream Flux appVersion 2.4.0). MUST match
  # `infra/hetzner/cloudinit-control-plane.tftpl`'s install.yaml URL
  # (currently v2.4.0). See Chart.yaml comment block "CRITICAL VERSION-PIN
  # INVARIANT" for the full incident replay (omantel.omani.works,
  # 2026-04-29 — Flux controllers deleted by Helm rollback after a
  # double-install version-mismatch).
  upstream: { chart: flux2, version: "2.14.1", repo: "https://fluxcd-community.github.io/helm-charts" }

# ─── Catalyst overlay values ──────────────────────────────────────────────
catalyst:
  # Namespace where the Flux controllers run. Used by
  # templates/catalyst-cluster-reconciler-rbac.yaml to subject the
  # canonical helm-controller + kustomize-controller ServiceAccounts in a
  # ClusterRoleBinding to `cluster-admin`. See that file's header for the
  # full issue #338 context.
  #
  # Per docs/INVIOLABLE-PRINCIPLES.md #4 (never hardcode), this is
  # operator-overridable. The default is `flux-system` because that's the
  # canonical Catalyst install namespace (see
  # `clusters/_template/bootstrap-kit/03-flux.yaml` + cloud-init's flux2
  # install.yaml). Changing it requires a parallel change to cloud-init.
  fluxNamespace: flux-system

  # Detect-and-recover safety net for HelmReleases stuck in Ready=Unknown
  # after a helm-controller leader-election loss (issue #925). Renders a
  # CronJob in fluxNamespace that scans every HR cluster-wide every
  # `schedule`, finds those stuck in Ready=Unknown for longer than
  # `stuckThreshold` whose underlying Helm release secret already has
  # status=deployed, and force-toggles spec.suspend to make
  # helm-controller re-evaluate the HR's Ready status. See
  # templates/helm-release-stuck-recovery.yaml for the full incident
  # context.
  #
  # Per docs/INVIOLABLE-PRINCIPLES.md #4, every parameter is operator
  # overridable. To disable entirely (e.g. once upstream helm-controller
  # ships a fix and the trigger condition is unreachable), set
  # `enabled: false` in a per-cluster overlay.
  stuckHelmReleaseRecovery:
    enabled: true
    schedule: "*/2 * * * *"
    stuckThreshold: "5m"
    # 2026-05-11 (Fix #158): switched from docker.io/bitnami/kubectl:1.31
    # because Bitnami's 2025-08 secure-images cutover deleted all
    # versioned tags. bitnamilegacy is the deprecation-fallback path.
    #
    # 2026-05-11 (Fix #163, MIRROR-EVERYTHING): explicit
    # harbor.openova.io/proxy-dockerhub/* prefix per CLAUDE.md inviolable
    # rule. Defeats upstream-deletion blast radius and satisfies the
    # Kyverno `harbor-proxy-pull` ClusterPolicy.
    image: "harbor.openova.io/proxy-dockerhub/bitnamilegacy/kubectl:1.31.4"

# ─── Upstream chart values (subchart key: flux2) ──────────────────────────
# Generated by docs/PROVISIONING-PLAN.md tickets [F] chart Pass 105+.
#
# LEADER-ELECTION LEASE DURATIONS (issue #925)
# ─────────────────────────────────────────────
# fluxcd/pkg/runtime/leaderelection defaults are lease=35s renew=30s
# retry=5s (per github.com/fluxcd/pkg runtime/leaderelection/leaderelection.go).
# On a fresh Sovereign during the bootstrap cascade (35+ HelmReleases
# install in parallel inside a 2-3 min window), kube-apiserver pressure on
# a cpx32 CP can exceed 30s — long enough that the controller fails to
# renew its lease, hands off leadership, and a follow-up leader takes over
# an in-flight Helm install transaction. The Helm release secret is then
# committed by the new leader (Status=deployed) but the HR's Ready
# condition was last set to `Unknown` by the previous leader and is never
# flipped → HelmRelease stuck in Ready=Unknown forever, blocking
# downstream Kustomizations (bootstrap-kit → sovereign-tls → cilium
# Gateway). Live verified on otech113.omani.works 2026-05-05 (issue #925).
#
# Mitigation: stretch lease=60s / renew=40s / retry=5s on the three
# Catalyst-critical controllers (helm, kustomize, source). This costs
# ~50s additional failover time on a real controller crash (acceptable —
# Sovereign control-plane HA is a Phase 2 concern), in exchange for
# eliminating spurious leader handoffs during transient API blips. The
# detect-and-recover safety net (templates/helm-release-stuck-recovery.yaml)
# handles the residual case where leader-election still flips.
#
# MEMORY HEADROOM (issue #925, secondary cause)
# ─────────────────────────────────────────────
# helm-controller's chart cache + concurrent install workers can spike to
# 300-400Mi during a 35-HR fan-out. The previous 256Mi limit caused
# OOMKills mid-install, which themselves trigger leader-election loss.
# Bumped to 512Mi (helm) and 384Mi (kustomize, source). Requests left at
# 64Mi to keep scheduler footprint small on small CPs.
flux2:
  installCRDs: true
  sourceController:
    resources:
      requests: { cpu: 50m, memory: 64Mi }
      limits: { memory: 384Mi }
    container:
      additionalArgs:
        - --leader-election-lease-duration=60s
        - --leader-election-renew-deadline=40s
        - --leader-election-retry-period=5s
  kustomizeController:
    resources:
      requests: { cpu: 50m, memory: 64Mi }
      limits: { memory: 384Mi }
    container:
      additionalArgs:
        - --leader-election-lease-duration=60s
        - --leader-election-renew-deadline=40s
        - --leader-election-retry-period=5s
  helmController:
    resources:
      requests: { cpu: 50m, memory: 64Mi }
      limits: { memory: 512Mi }
    container:
      additionalArgs:
        - --leader-election-lease-duration=60s
        - --leader-election-renew-deadline=40s
        - --leader-election-retry-period=5s
  # Prometheus PodMonitor — DEFAULT OFF.
  #
  # Per docs/INVIOLABLE-PRINCIPLES.md #4 and docs/BLUEPRINT-AUTHORING.md
  # §11.2 (Observability toggles must default false). The upstream flux2
  # chart's `prometheus.podMonitor.create` renders a
  # monitoring.coreos.com/v1 PodMonitor which the apiserver rejects on a
  # fresh Sovereign before bp-kube-prometheus-stack ships the CRD.
  # Operator opts in via per-cluster overlay (issue #182).
  prometheus:
    podMonitor:
      create: false
