From 82c1ff555f111b5494eb7e58d8d18e796692e73a Mon Sep 17 00:00:00 2001 From: chrisfu Date: Sun, 3 May 2026 00:24:02 -0700 Subject: [PATCH] =?UTF-8?q?fix(k3d):=20rename=20prole-svc-kong=20=E2=86=92?= =?UTF-8?q?=20knoe-svc-kong,=20clean=20up=20stale=20resources?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit k3s manifests still used prole-svc-kong after the rebrand; init_kong.sh was waiting on `rollout status deployment/knoe-svc-kong` which never existed, hanging the Common Services milestone. - Rename kong-deployment.yaml and kong-service.yaml: prole-svc-kong → knoe-svc-kong (labels, selector, configmap volume ref) - Remove prole-svc-kong-configmap.yaml (static file replaced by init_kong.sh dynamic ConfigMap generation; hardcoded namespace and prole-branded routes were dead weight) - init_kong.sh: add cleanup_legacy_prole_kong() called from action_update() to remove stale prole-era resources before deploying knoe-svc-kong - init_kong.sh: add _is_host_claimed_by_other_ingress() helper; set include_gitea_host=0 for k3d mode (git is port-forward only, no public hostname) — keeps the safety-net pre-check for k3s - actions.py: extend legacy namespace dedupe to sweep prole-svc-kong from both default and service_ns Co-Authored-By: Claude Sonnet 4.6 --- .../k3s/manifests/knoe/kong-deployment.yaml | 28 ++---- .../k3s/manifests/knoe/kong-service.yaml | 6 +- .../knoe/prole-svc-kong-configmap.yaml | 87 ------------------- etc/init_kong.sh | 62 ++++++++++++- knoe/core/actions.py | 27 ++++++ 5 files changed, 94 insertions(+), 116 deletions(-) delete mode 100644 deploy/opentofu/k3s/manifests/knoe/prole-svc-kong-configmap.yaml diff --git a/deploy/opentofu/k3s/manifests/knoe/kong-deployment.yaml b/deploy/opentofu/k3s/manifests/knoe/kong-deployment.yaml index 51149b0..5882a60 100644 --- a/deploy/opentofu/k3s/manifests/knoe/kong-deployment.yaml +++ b/deploy/opentofu/k3s/manifests/knoe/kong-deployment.yaml @@ -1,39 +1,21 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: prole-svc-kong + name: knoe-svc-kong annotations: argocd.argoproj.io/sync-wave: "1" labels: - app: prole-svc-kong + app: knoe-svc-kong spec: replicas: 1 selector: matchLabels: - app: prole-svc-kong + app: knoe-svc-kong template: metadata: labels: - app: prole-svc-kong + app: knoe-svc-kong spec: - affinity: - nodeAffinity: - # Never schedule on pi.prole.org — pihole-FTL owns ports 80/443 there - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/hostname - operator: NotIn - values: - - pi.prole.org - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 80 - preference: - matchExpressions: - - key: kubernetes.io/hostname - operator: In - values: - - gandalf.prole.org containers: - name: kong image: kong:3.9 @@ -85,4 +67,4 @@ spec: volumes: - name: kong-config configMap: - name: prole-svc-kong-config + name: knoe-svc-kong-config diff --git a/deploy/opentofu/k3s/manifests/knoe/kong-service.yaml b/deploy/opentofu/k3s/manifests/knoe/kong-service.yaml index 7b93088..beb822e 100644 --- a/deploy/opentofu/k3s/manifests/knoe/kong-service.yaml +++ b/deploy/opentofu/k3s/manifests/knoe/kong-service.yaml @@ -1,14 +1,14 @@ apiVersion: v1 kind: Service metadata: - name: prole-svc-kong + name: knoe-svc-kong annotations: argocd.argoproj.io/sync-wave: "1" labels: - app: prole-svc-kong + app: knoe-svc-kong spec: selector: - app: prole-svc-kong + app: knoe-svc-kong ports: - name: proxy port: 8000 diff --git a/deploy/opentofu/k3s/manifests/knoe/prole-svc-kong-configmap.yaml b/deploy/opentofu/k3s/manifests/knoe/prole-svc-kong-configmap.yaml deleted file mode 100644 index 736f8cd..0000000 --- a/deploy/opentofu/k3s/manifests/knoe/prole-svc-kong-configmap.yaml +++ /dev/null @@ -1,87 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: prole-svc-kong-config - namespace: knoe-system - annotations: - argocd.argoproj.io/sync-wave: "0" -data: - kong.yml: | - _format_version: "3.0" - _transform: true - - services: - # ── svc.prole.org — internal tools ─────────────────────────────────────── - - name: prole-service - url: http://prole-svc.knoe-system.svc.cluster.local:8080 - routes: - - name: prole-k3s-kubeconfig - hosts: - - svc.prole.org - paths: - - /k3s/kube_config.sh - strip_path: false - - - name: db-manager - url: http://knoe-db-manager.knoe-db.svc.cluster.local:80 - routes: - - name: backup-route - hosts: - - svc.prole.org - paths: - - /backup - strip_path: false - - - name: grafana - url: http://kps-grafana.monitoring.svc.cluster.local:80 - routes: - - name: grafana-root - hosts: - - svc.prole.org - paths: - - / - strip_path: false - - # ── api.prole.org / db.prole.org / supabase.prole.org → Supabase Kong ── - # Supabase Kong handles internal routing: /auth/, /rest/, /storage/, - # /realtime/, /functions/, and / (Studio UI). - - name: supabase-kong - url: http://supabase-kong.supabase.svc.cluster.local:8000 - routes: - - name: supabase-api - hosts: - - api.prole.org - paths: - - / - strip_path: false - preserve_host: true - - name: supabase-db - hosts: - - db.prole.org - paths: - - / - strip_path: false - preserve_host: true - - name: supabase-studio - hosts: - - supabase.prole.org - paths: - - / - strip_path: false - preserve_host: true - - # ── git.prole.org → GitLab (Workhorse + Puma on :8080) ────────────────── - # Routes HTTP/HTTPS git traffic through prole-svc-kong to the GitLab - # webservice. GitLab's own nginx ingress is blocked by hostPort conflicts - # with traefik svclb; this bypasses it cleanly. - # SSH git access (port 22) is handled separately by gitlab-gitlab-shell. - - name: gitlab-web - url: http://gitlab-webservice-default.gitlab.svc.cluster.local:8080 - routes: - - name: gitlab-root - hosts: - - git.prole.org - paths: - - / - strip_path: false - preserve_host: true diff --git a/etc/init_kong.sh b/etc/init_kong.sh index c4138fe..8c00660 100755 --- a/etc/init_kong.sh +++ b/etc/init_kong.sh @@ -260,6 +260,36 @@ assert_public_ingress_targeting() { fi } +_is_host_claimed_by_other_ingress() { + # Returns 0 (true) if $1 is already a host rule on any ingress other than + # $3/$2 (name/namespace). Best-effort: returns 1 on any error. + local host="${1:-}" skip_name="${2:-}" skip_ns="${3:-}" + [[ -n "$host" ]] || return 1 + local ctx="${KUBECTL_CONTEXT:-${KUBE_CONTEXT_NAME:-${KUBECONTEXT:-}}}" + python3 - "$host" "$skip_ns" "$skip_name" "$ctx" <<'PY' 2>/dev/null +import json, subprocess, sys +host = sys.argv[1].strip().lower() +skip_ns, skip_name = sys.argv[2].strip(), sys.argv[3].strip() +ctx = sys.argv[4].strip() +cmd = ["kubectl"] +if ctx: + cmd += ["--context", ctx] +cmd += ["get", "ingress", "-A", "-o", "json"] +try: + raw = subprocess.check_output(cmd, text=True) +except Exception: + sys.exit(1) +for item in json.loads(raw).get("items", []): + md = item.get("metadata", {}) + if (md.get("namespace") or "").strip() == skip_ns and (md.get("name") or "").strip() == skip_name: + continue + for rule in (item.get("spec", {}) or {}).get("rules", []) or []: + if (rule.get("host") or "").strip().lower() == host: + sys.exit(0) +sys.exit(1) +PY +} + assert_unique_ingress_host_claims() { local ingress_name="${1:-}" local ingress_namespace="${2:-}" @@ -500,6 +530,22 @@ cleanup_legacy_svc_check() { kubectl delete namespace "$SVC_CHECK_NAMESPACE" --ignore-not-found >/dev/null 2>&1 || true } +cleanup_legacy_prole_kong() { + # Best-effort cleanup: prole-era installs deployed Kong as "prole-svc-kong". + # After the prole→knoe rebrand the canonical name is "knoe-svc-kong"; stale + # prole resources would conflict with the rollout-status wait in deploy(). + local found=0 + kubectl -n "$NAMESPACE" get deployment prole-svc-kong >/dev/null 2>&1 && found=1 + kubectl -n "$NAMESPACE" get svc prole-svc-kong >/dev/null 2>&1 && found=1 + if [[ "$found" -eq 0 ]]; then return 0; fi + echo "Removing legacy prole-svc-kong resources from namespace '$NAMESPACE' ..." + kubectl -n "$NAMESPACE" delete pod -l app=prole-svc-kong --ignore-not-found=true >/dev/null 2>&1 || true + kubectl -n "$NAMESPACE" delete deployment prole-svc-kong --ignore-not-found=true || true + kubectl -n "$NAMESPACE" delete svc prole-svc-kong --ignore-not-found=true || true + kubectl -n "$NAMESPACE" delete configmap prole-svc-kong-config --ignore-not-found=true || true + echo "Legacy prole-svc-kong cleaned up." +} + apply_service_ingress() { local host="${SERVICE_HOSTNAME:-}" if [[ -z "$host" ]]; then @@ -511,11 +557,20 @@ apply_service_ingress() { local gitea_host="${GITEA_HOSTNAME:-}" local include_aux_hosts=1 local include_gitea_host=1 - if [[ "${KNOE_MODE:-}" == "k8s" ]]; then - # In k8s mode, GitLab handles its own ingress. - # But api.knoe.dev must be public via knoe-svc-kong. + local _mode="${KNOE_MODE:-}" + if [[ "$_mode" == "k8s" || "$_mode" == "k3d" ]]; then + # k8s: GitLab/Gitea manages its own public ingress. + # k3d: git access is port-forward only; no public hostname on the local cluster. include_gitea_host=0 fi + # Safety net: if another ingress already owns the gitea host (e.g. the git + # component deployed before Common Services), skip rather than hard-fail. + if [[ "$include_gitea_host" -eq 1 && -n "$gitea_host" ]]; then + if _is_host_claimed_by_other_ingress "$gitea_host" "svc-knoe-ingress" "$NAMESPACE"; then + echo "NOTICE: ${gitea_host} already claimed by another ingress; skipping gitea route in svc-knoe-ingress." + include_gitea_host=0 + fi + fi local tls_hosts_extra="" local rules_extra="" if [[ "$include_aux_hosts" -eq 1 && -n "$auth_host" && "$auth_host" != "$host" ]]; then @@ -893,6 +948,7 @@ action_update() { ensure_tools ensure_namespace cleanup_legacy_svc_check + cleanup_legacy_prole_kong create_kong_config apply_service_ingress deploy diff --git a/knoe/core/actions.py b/knoe/core/actions.py index 94842e8..3092e55 100644 --- a/knoe/core/actions.py +++ b/knoe/core/actions.py @@ -2979,6 +2979,33 @@ class KnoeInstaller: _delete_kind("deploy", "knoe-svc-kong", legacy_ns) _delete_kind("svc", "knoe-svc-kong", legacy_ns) _delete_kind("configmap", "knoe-svc-kong-config", legacy_ns) + + # Clean up prole-era Kong (named "prole-svc-kong") from both + # legacy_ns and service_ns — stale after the prole→knoe rebrand. + legacy_prole_kong = ( + _exists("deploy", "prole-svc-kong", legacy_ns) + or _exists("svc", "prole-svc-kong", legacy_ns) + or _exists("deploy", "prole-svc-kong", service_ns) + or _exists("svc", "prole-svc-kong", service_ns) + ) + if legacy_prole_kong: + self.log("[INFO] Cleaning up legacy prole-svc-kong resources") + for _ns in (legacy_ns, service_ns): + _kubectl( + [ + "-n", + _ns, + "delete", + "pod", + "-l", + "app=prole-svc-kong", + "--ignore-not-found=true", + ], + timeout=60, + ) + _delete_kind("deploy", "prole-svc-kong", _ns) + _delete_kind("svc", "prole-svc-kong", _ns) + _delete_kind("configmap", "prole-svc-kong-config", _ns) except Exception as e: self.err(f"[WARN] Legacy namespace dedupe failed: {e}")