prole/scripts/k3d-knoe-smoke.sh
chrisfu 5d3600845d feat(k3d): laptop dev loop for knoe-auth — CNPG + KDC + port-forward
Brings up the smallest k3d-resident stack that lets a host-side knoe-auth
(run via `mvn spring-boot:run` or IntelliJ) iterate against real Postgres
+ Kerberos. Closes Phase 1 of the k3d-gke-mirror plan (docs/plans/k3d-gke-mirror.md).

Scope:
  - k8s/knoe/knoe-kdc-{configmap,deployment,service,pvc,init-job}.yaml
    NEW; standalone KDC, realm KNOE.LOCAL (distinct from KNOE.DEV).
  - etc/init_knoe_auth.sh: --mode k3d flag added; swaps realm + skips
    GCP-specific steps. GKE behavior unchanged when flag absent.
  - Makefile: k3d-knoe-up, k3d-knoe-pf, k3d-knoe-down (delegate to
    scripts/k3d-knoe-{up,pf,down}.sh).
  - scripts/k3d-knoe-{up,pf,down,smoke}.sh NEW; up = full bring-up,
    pf = three port-forwards (5432/88/464) + JDBC URL + ^C cleanup,
    down = teardown, smoke = sanity check.
  - etc/krb5.local.conf NEW; checked-in libdefaults+realms config
    pointing at localhost:88. udp_preference_limit=1 to dodge
    kubectl port-forward UDP flakiness on macOS.
  - docs/local-dev-knoe-auth.md NEW; one-time setup + daily loop +
    IntelliJ run config.
  - docs/knoe-system.md NEW; unified reference for the knoe-auth
    service (GKE deployment + k3d dev loop + schema overview +
    source map + open work items).

Verified per the brief's Definition of done: fresh-clone laptop can
`make k3d-knoe-up` + `make k3d-knoe-pf` + `mvn -pl authority spring-boot:run`
and hit /health, /.well-known/openid-configuration in <8 minutes.

Out of scope (parent plan docs/plans/k3d-gke-mirror.md §6):
  - SPNEGO from host browsers (Phase 2)
  - knoe-auth-as-pod / image build/load (Phase 3)
  - Supabase stack on k3d (Phase 4)
  - OidcCodeService DB persistence (separate track)

docs/plans/junie/README.md — k3d brief moved from Active to Shipped.
docs/TODO.md — In-progress now empty; Phase 2 pg_oauth notes that the
local dev loop is in place so it can resume.

Closes Phase 1; Phase 2+ briefs filed as needed.

Co-authored-by: Junie <junie@jetbrains.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 11:47:09 -07:00

103 lines
3.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# scripts/k3d-knoe-smoke.sh
# Smoke-test the k3d-knoe dev cluster.
#
# Requires: make k3d-knoe-up completed successfully.
# Does NOT require make k3d-knoe-pf (uses kubectl exec for DB check).
#
# Checks:
# 1. CNPG cluster knoe-db is in healthy state
# 2. knoe.* schema has ≥6 tables
# 3. KDC deployment is 1/1 ready
# 4. admin/admin@KNOE.LOCAL principal exists in the KDC
set -euo pipefail
ctx=k3d-k3d-knoe
ns_db=knoe-db-0
ns_sys=knoe-system
PASS=0
FAIL=0
ok() { echo "$*"; PASS=$((PASS+1)); }
fail() { echo "$*" >&2; FAIL=$((FAIL+1)); }
echo ""
echo "=== k3d-knoe smoke test ==="
echo ""
# 1. CNPG cluster healthy
echo "1. CNPG cluster phase..."
phase=$(kubectl --context="$ctx" -n "$ns_db" get cluster knoe-db \
-o jsonpath='{.status.phase}' 2>/dev/null || echo "")
if [[ "$phase" == "Cluster in healthy state" ]]; then
ok "CNPG cluster: $phase"
else
fail "CNPG cluster phase: '$phase' (expected 'Cluster in healthy state')"
fi
# 2. knoe.* schema present (≥6 tables)
echo "2. knoe.* schema tables..."
pod=$(kubectl --context="$ctx" -n "$ns_db" \
get pod -l cnpg.io/cluster=knoe-db,role=primary \
-o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
if [[ -z "$pod" ]]; then
fail "Cannot find CNPG primary pod"
else
tables=$(kubectl --context="$ctx" -n "$ns_db" exec "$pod" -c postgres -- \
psql -U postgres -tAc \
"SELECT count(*) FROM information_schema.tables WHERE table_schema='knoe'" \
2>/dev/null || echo "0")
tables="${tables//[[:space:]]/}"
if [[ "$tables" =~ ^[0-9]+$ ]] && [[ "$tables" -ge 6 ]]; then
ok "knoe.* tables: $tables (≥6)"
else
fail "knoe.* tables: $tables (expected ≥6) — schema may not be applied yet"
fi
fi
# 3. KDC deployment ready
echo "3. KDC deployment readiness..."
ready=$(kubectl --context="$ctx" -n "$ns_sys" get deploy knoe-kdc \
-o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0")
if [[ "${ready:-0}" -ge 1 ]]; then
ok "knoe-kdc deployment: ${ready}/1 ready"
else
fail "knoe-kdc deployment: ${ready:-0}/1 ready"
fi
# 4. admin/admin@KNOE.LOCAL principal exists
echo "4. KDC admin principal..."
kdc_pod=$(kubectl --context="$ctx" -n "$ns_sys" \
get pod -l app=knoe-kdc \
-o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
if [[ -z "$kdc_pod" ]]; then
fail "Cannot find knoe-kdc pod"
else
if kubectl --context="$ctx" -n "$ns_sys" exec "$kdc_pod" -- \
kadmin.local listprincs 2>/dev/null | grep -q 'admin/admin@KNOE.LOCAL'; then
ok "admin/admin@KNOE.LOCAL principal exists"
else
fail "admin/admin@KNOE.LOCAL principal not found in KDC"
fi
fi
# ── Summary ───────────────────────────────────────────────────────────────────
echo ""
echo "=== Results: $PASS passed, $FAIL failed ==="
echo ""
if [[ $FAIL -gt 0 ]]; then
echo "Some checks failed. See above for details." >&2
exit 1
fi
echo "k3d-knoe-smoke: PASS"
echo ""
echo "Next steps:"
echo " make k3d-knoe-pf &"
echo " export KRB5_CONFIG=\$PWD/etc/krb5.local.conf"
echo " mvn -pl authority spring-boot:run"