fix(k3d): rename prole-svc-kong → knoe-svc-kong, clean up stale resources

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 <noreply@anthropic.com>
This commit is contained in:
chrisfu 2026-05-03 00:24:02 -07:00
parent dba8a2d1dc
commit 82c1ff555f
5 changed files with 94 additions and 116 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}")