openova/platform/guacamole/chart/values.yaml
e3mrah 74d23ab3dc
fix(charts): explicit harbor.openova.io/proxy-dockerhub prefix on all chart-hook images (#163) (#1367)
Per CLAUDE.md MIRROR-EVERYTHING inviolable rule: every chart-hook
image reference (pre/post-install Jobs, helper Pods) must use the
explicit Harbor proxy-cache form. Fix #158's bitnami → bitnamilegacy
swap was a band-aid; the architecturally correct fix is to defeat
upstream-deletion blast radius entirely by routing through Harbor.

The node-level containerd mirror in infra/hetzner/cloudinit-control-
plane.tftpl (line 706) already redirects docker.io/* →
harbor.openova.io/proxy-dockerhub/* implicitly, but implicit routing:
  - Hides the routing from SBOM scans
  - Bypasses the Kyverno harbor-proxy-pull ClusterPolicy
  - Means a chart audit (`grep docker.io`) misses a real dependency
  - Was the proximate cause of prov #27 wedging when Bitnami deleted
    docker.io/bitnami/kubectl:1.30.4 (Fix #158 had to chase the
    deletion mid-flight instead of being insulated by Harbor cache)

19 chart-hook image: refs + 5 chart values.yaml repository: defaults
now carry the explicit harbor.openova.io/proxy-dockerhub prefix.
Application/subchart images (keycloak, postgresql, mongodb in
keycloak+litmus subcharts) are intentionally out of scope for this
PR — those go through the node-level containerd mirror still.

Affected blueprints + chart version bumps:
  bp-cert-manager            1.2.1  -> 1.2.2
  bp-external-secrets-stores 1.0.4  -> 1.0.5
  bp-crossplane-claims       1.1.4  -> 1.1.5
  bp-flux                    1.2.1  -> 1.2.2
  bp-guacamole               0.1.16 -> 0.1.17
  bp-self-sovereign-cutover  0.1.28 -> 0.1.29
  bp-k8s-ws-proxy            0.1.9  -> 0.1.10
  bp-harbor                  1.2.15 -> 1.2.16
  bp-gitea                   1.2.5  -> 1.2.6
  bp-newapi                  1.4.5  -> 1.4.6
  bp-wordpress-tenant        0.2.0  -> 0.2.1
  catalyst-platform          1.4.138 -> 1.4.139

Co-authored-by: e3mrah <1234567+e3mrah@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 11:32:21 +04:00

218 lines
10 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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