EPIC-4 Slice K+P+X1+G — bundled backend infrastructure for the
"k9s-on-web" Cloud Resources experience:
K1 — core/cmd/k8s-ws-proxy/ — per-node WebSocket exec proxy.
HMAC-signed (X-Catalyst-HMAC: SHA256({timestamp}:{path})) WebSocket
upgrades on /proxy/exec/{ns}/{pod}/{container} bridged to the local
kube-apiserver via in-cluster ServiceAccount. v4.channel.k8s.io
subprotocol echo. Optional TMUX_CASCADE wraps in a shared
catalyst-ops tmux session. Shipped as a DaemonSet + Service with
internalTrafficPolicy=Local in platform/k8s-ws-proxy/chart/.
P1 — core/cmd/projector/ — NATS catalyst.events JetStream → Valkey
KV projector. Canonical key shape:
cluster:{cluster-id}:kind:{kind}:{namespace}/{name}
Cold-start does a full LIST across DefaultKinds, then catches up on
the 24h replay window. Multi-replica safe (durable consumer queue
group, last-write-wins on namespacedName). Shipped as a default-OFF
Deployment + RBAC under products/catalyst/chart/templates/services/projector/.
X1 — products/catalyst/bootstrap/api/internal/handler/k8s_logs.go —
WebSocket Pod-log streaming endpoint:
GET /api/v1/sovereigns/{id}/k8s/logs/{ns}/{pod}/{container}
?follow&tailLines&since=<rfc3339>&previous
Reads from kubelet via client-go GetLogs().Stream(); each WS frame =
one log line. Supports `since` resume. Reuses RequireSession middleware
+ chroot cluster-id resolver. New k8scache.Factory.CoreClient(id)
accessor exposes the per-cluster typed client without duplicating
kubeconfig parsing.
G1 — platform/guacamole/chart/ — full Apache Guacamole chart:
guacd Deployment + Service, Tomcat webapp Deployment + Service,
Cilium Gateway HTTPRoute, SeaweedFS-PVC for recordings (RWO,
hcloud-volumes), SealedSecret placeholder for Keycloak OIDC client
secret, NetworkPolicy (default-deny + selective egress to KC +
k8s-ws-proxy + SeaweedFS + NATS), and ConfigMap consumed by
keycloak-config-cli post-deploy Job (mirrors platform/keycloak
realm-config pattern). Default-OFF gate; full-ON renders 9
resources. Empty image.tag / hostname / oidc.issuer fail-fast at
helm template time per INVIOLABLE-PRINCIPLES #4a/#5. ONE Guacamole
per Sovereign per ADR-0001 §11. Blueprint manifest uses
v1alpha1 + version "0.1.0" + upgrades.from ["0.x"].
Tests:
- k8s-ws-proxy: HMAC happy/expired-old/expired-future/malformed/
bad-signature, path-only signature, WS upgrade + protocol echo,
bad path, bad HMAC, denied namespace via httptest.
- projector: Apply ADD/MOD/DEL/validation, key shape (ns-scoped +
cluster-scoped), handleOne ack/nak/term routing with fakeMsg,
cold-start LIST + project + error continuation via dynamicfake.
- X1: parseLogOptions defaults + edge cases + bad query params,
503/404/400 paths + full WS happy-path with kfake clientset.
- G1: chart/tests/render.sh — default-OFF=0, empty-tag fail-fast,
full-ON=9 resources, every required kind present, realm-config
wires OIDC client.
- bp-k8s-ws-proxy chart: chart/tests/render.sh — default-OFF=0,
empty-tag fail-fast, full-ON=5 resources.
Pre-existing test status: TestPinIssue and TestBootstrapKit/gitea
remain flaky on main per canon §7 — verified not introduced by
this slice.
Co-authored-by: hatiyildiz <hati.yildiz@openova.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
52 lines
1.5 KiB
YAML
52 lines
1.5 KiB
YAML
apiVersion: catalyst.openova.io/v1alpha1
|
|
kind: Blueprint
|
|
metadata:
|
|
name: bp-guacamole
|
|
labels:
|
|
catalyst.openova.io/section: pts-3-1-networking-and-service-mesh
|
|
catalyst.openova.io/category: platform
|
|
spec:
|
|
version: 0.1.0
|
|
card:
|
|
title: Apache Guacamole
|
|
summary: Clientless HTML5 remote-desktop gateway. Browser-based RDP / VNC / SSH and kubectl-exec into Pods, with Keycloak SSO and full session recording to SeaweedFS. One Guacamole per Sovereign per ADR-0001 §11.
|
|
icon: guacamole.svg
|
|
category: platform
|
|
visibility: listed
|
|
configSchema:
|
|
type: object
|
|
properties:
|
|
enabled:
|
|
type: boolean
|
|
default: false
|
|
description: Default-OFF gate. Operator opts in via per-Sovereign overlay.
|
|
hostname:
|
|
type: string
|
|
description: Browser-facing hostname (e.g. guacamole.<sovereign-fqdn>). Required when enabled.
|
|
oidcIssuer:
|
|
type: string
|
|
description: Keycloak realm issuer URL. Required when enabled.
|
|
recordingsSize:
|
|
type: string
|
|
default: "50Gi"
|
|
description: Per-Sovereign session-recording PVC size.
|
|
placementSchema:
|
|
modes: [single-region]
|
|
minRegions: 1
|
|
maxRegions: 1
|
|
upgrades:
|
|
from: ["0.x"]
|
|
manifests:
|
|
chart: ./chart
|
|
depends:
|
|
- blueprint: bp-keycloak
|
|
version: ^1
|
|
- blueprint: bp-cilium
|
|
version: ^1
|
|
- blueprint: bp-seaweedfs
|
|
version: ^1
|
|
- blueprint: bp-sealed-secrets
|
|
version: ^1
|
|
- blueprint: bp-k8s-ws-proxy
|
|
version: ^0
|