# Catalyst Blueprint values for bp-guacamole.
#
# Per docs/INVIOLABLE-PRINCIPLES.md:
#   #1   waterfall — chart ships the full target shape (guacd + web +
#        OIDC + recordings + NetworkPolicy + Keycloak realm-config)
#        on the first cut; no "for now" subset.
#   #4   never hardcode — every operationally-meaningful value is
#        configurable via per-Sovereign overlay.
#   #4a  SHA-pinned images; CI fills .tag at promotion time. Empty
#        tag fails fast (see _helpers.tpl).
#   #5   credentials live in K8s Secrets, never in values.yaml.
#
# Default-OFF: `enabled: false` per the standard CC3 gate. Operators
# opt in via per-Sovereign overlay.

catalystBlueprint:
  upstream:
    chart: "" # scratch chart — no upstream Helm chart
    version: ""
    repo: ""
# Top-level enable gate. When false, NO resources render. Verified by
# `helm template` test in tests/.
guacamole:
  enabled: false
  # ── guacd: protocol backend ─────────────────────────────────────
  guacd:
    # Resource name. Defaults to `guacd` so the catalyst-api shells/issue
    # handler + qa-loop test matrix (TC-228 / TC-230 / TC-245 / TC-246)
    # can address the Deployment + Service by canonical short name.
    # Override only when running >1 Guacamole in the same namespace
    # (rare; ADR-0001 §11 caps at one Guacamole per Sovereign).
    name: guacd
    image:
      # Mirrored to GHCR by .github/workflows/build-bp-guacamole.yaml so
      # every Sovereign pulls from a registry we own (no Docker Hub rate
      # limits, no upstream availability risk). Bumped automatically by
      # CI when the upstream Apache Guacamole version is rolled.
      repository: ghcr.io/openova-io/openova/guacd
      # SHA-pinned per INVIOLABLE-PRINCIPLES #4a. CI populates this via
      # `yq eval -i ...`. Empty value fails the helm template render
      # (see _helpers.tpl `bp-guacamole.guacdImage`). Initial seed is
      # the upstream-tagged GHCR mirror; CI may pin to a digest tag.
      tag: "1.5.5"
      pullPolicy: IfNotPresent
    replicas: 1
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        memory: 512Mi
    port: 4822
  # ── guacamole webapp: Tomcat front-end ─────────────────────────
  webapp:
    # Resource name. Defaults to `guacamole-server` per the qa-loop test
    # matrix + catalyst-api shells/issue handler.
    name: guacamole-server
    image:
      # GHCR mirror of docker.io/guacamole/guacamole; see guacd.image
      # comment for the mirror rationale.
      repository: ghcr.io/openova-io/openova/guacamole-server
      tag: "1.5.5"
      pullPolicy: IfNotPresent
    # Single replica + 256Mi request: omantel chroot single-node-per-region
    # capacity profile. catalyst-api PVC pins it to one worker (w3 on
    # omantel), and 2× 512Mi guacamole webapp replicas saturated w3 so
    # catalyst-api Pod couldn't reschedule on chart roll. Sovereigns with
    # >1 worker per region can override via values.guacamole.webapp.replicas.
    replicas: 1
    resources:
      requests:
        cpu: 100m
        memory: 256Mi
      limits:
        memory: 768Mi
    port: 8080
  # ── Recording (SeaweedFS PVC) ──────────────────────────────────
  recordings:
    # PVC name. Defaults to `guacamole-recordings`. Override only when
    # multiple Guacamole instances share a namespace.
    pvcName: guacamole-recordings
    pvcSize: 50Gi
    # hcloud-volumes is the canonical Hetzner CSI storageClass per
    # H6 (issue #1118 — `hcloud-volumes` standardisation across
    # Sovereigns). Override per-Sovereign for non-Hetzner clouds.
    storageClass: hcloud-volumes
    mountPath: /recordings
    # qa-loop iter-11 Fix #45 Cluster-A: when an existing PVC is bound
    # to a storageClass different from .storageClass above, the chart's
    # pre-upgrade hook deletes the PVC + bound PV so the new chart-side
    # PVC can be recreated cleanly. PersistentVolumeClaim.spec is K8s-
    # immutable on storageClassName, so without this hook a per-Sovereign
    # overlay flip (e.g. `local-path` → `seaweedfs-storage` after
    # bp-seaweedfs lands) would wedge the bp-guacamole HelmRelease in
    # `Failed to perform remediation: missing target release for rollback`.
    # Default ON because session-recording state on omantel today is
    # ephemeral; flip OFF on Sovereigns with long-lived recording data
    # (operator should snapshot first then re-enable for the upgrade).
    allowMigration: true
    # Image used by the migration hook. The canonical kubectl image
    # surface across OpenOva Sovereigns is docker.io/bitnamilegacy/kubectl
    # (the same one bp-keycloak's realm-config-cli post-deploy Job
    # pulls). Bitnami's 2025-08 secure-images cutover deleted all
    # versioned tags from docker.io/bitnami/kubectl (only :latest +
    # sha256-named tags remain) — bitnamilegacy is the deprecation-
    # fallback path which retains versioned tags AND bash/sh
    # (rancher/kubectl is distroless, would break inline shell). Operator
    # overrides for non-Hetzner Sovereigns by re-mirroring through
    # their own registry (per docs/INVIOLABLE-PRINCIPLES.md #4a — every
    # image traceable to a known-good SHA).
    # Fix #158 (2026-05-11): bumped 1.29.3 -> 1.30.7 to align with
    # k3s 1.30 server version on Hetzner Sovereigns.
    # Fix #163 (2026-05-11, MIRROR-EVERYTHING): explicit
    # harbor.openova.io/proxy-dockerhub prefix per CLAUDE.md inviolable
    # rule.
    migrationImage: harbor.openova.io/proxy-dockerhub/bitnamilegacy/kubectl:1.30.7
  # ── Keycloak OIDC ──────────────────────────────────────────────
  oidc:
    # Issuer URL — render in per-Sovereign overlay as
    # `https://keycloak.<sovereign-fqdn>/realms/catalyst`. Empty
    # value fails the helm template render (see _helpers.tpl
    # `bp-guacamole.oidcIssuer`).
    issuer: ""
    clientId: guacamole
    # Client secret comes from a SealedSecret. The chart materializes
    # the SealedSecret manifest with an empty placeholder; the
    # operator seals the real value via kubeseal.
    clientSecretRef:
      name: guacamole-oidc
      key: client-secret
    # Default-redirect URL — defaults to https://guacamole.<sovereign>/
    # but operator overlay sets the canonical hostname.
    redirectURI: ""
    # Optional groups claim from the IdP — Guacamole reads roles
    # from this claim and maps them to per-connection ACLs.
    groupsClaim: groups
  # ── HTTPRoute (Cilium Gateway) ─────────────────────────────────
  httproute:
    enabled: true
    # Gateway reference. Defaults to the Sovereign's well-known
    # `cilium-gateway` in namespace `gateway-system`; per-Sovereign
    # overlay can rebind.
    parentRef:
      name: cilium-gateway
      namespace: gateway-system
    # Hostname this Guacamole answers on. Empty value fails the
    # helm template render (see _helpers.tpl `bp-guacamole.host`).
    hostname: ""
  # ── NetworkPolicy ─────────────────────────────────────────────
  # When enabled (default), a default-deny baseline is augmented with
  # selective egress to: keycloak (443), k8s-ws-proxy DaemonSet (8080),
  # SeaweedFS S3 endpoint (8333), and the kube-apiserver (443) for
  # the Pod-listing JSP shipped with Guacamole.
  networkPolicy:
    enabled: true
    keycloak:
      namespace: keycloak
      podSelector:
        app: keycloak
    k8sWsProxy:
      namespace: catalyst-system
      podSelector:
        app.kubernetes.io/name: bp-k8s-ws-proxy
    seaweedfs:
      namespace: seaweedfs
      podSelector:
        app: seaweedfs
        component: s3
  # ── NATS audit trail ──────────────────────────────────────────
  audit:
    nats:
      # JetStream subject Guacamole publishes session-open / session-close
      # events to. Consumed by the Sovereign's audit indexer (EPIC-1
      # compliance evaluators) — see canon §3 events bus.
      subject: catalyst.audit
      auditType: guacamole-session
      url: nats://nats-jetstream.nats-jetstream.svc.cluster.local:4222
  # ── Keycloak realm-config integration ─────────────────────────
  # When enabled, the chart emits a ConfigMap that the bp-keycloak
  # post-deploy keycloak-config-cli Job picks up. The ConfigMap
  # patches the `catalyst` realm to add the `guacamole` client +
  # role + group mappings. Operator opt-in to keep
  # bp-guacamole installable in test environments without bp-keycloak.
  realmConfig:
    enabled: true
    # Realm name in Keycloak. Default `catalyst` per existing
    # platform/keycloak realm-config pattern.
    realm: catalyst
    # Namespace where bp-keycloak's keycloak-config-cli post-deploy Job
    # runs. The realm-patch ConfigMap MUST land in this namespace so the
    # Job's label-selector picks it up. Defaults to `keycloak` per the
    # canonical bp-keycloak namespace; override when bp-keycloak runs
    # under a different namespace.
    namespace: keycloak
  # ── Pod-level security context ─────────────────────────────────
  # Both pods run as non-root with read-only root FS — only /tmp
  # and /recordings are writable.
  podSecurityContext:
    runAsNonRoot: true
    runAsUser: 1001
    runAsGroup: 1001
    fsGroup: 1001
    seccompProfile:
      type: RuntimeDefault
  containerSecurityContext:
    allowPrivilegeEscalation: false
    readOnlyRootFilesystem: true
    capabilities:
      drop: [ALL]
  # ── Image pull secret ─────────────────────────────────────────
  # GHCR pull credentials. The catalyst-system namespace's `ghcr-pull`
  # secret is the canonical pull-credential surface across every
  # Sovereign (catalyst-api / catalyst-ui / guacd / guacamole-server /
  # all mount it), so the chart defaults to it. Operator overrides per
  # Sovereign for non-canonical credential names.
  imagePullSecrets:
    - name: ghcr-pull
