Files
net-kingdom/sso-mfa/k8s/verify-t02.sh
Bernd Worsch 6d25d088d7 feat(sso-mfa): T02/T03 live apply — age-encrypted secrets, CNPG cluster (NK-WP-0001-T02/T03)
- Add encrypt-secrets.sh / decrypt-secrets.sh: age-based secrets workflow
  replaces KeePassXC dependency; encrypted .env.age files committed to repo
- Add bootstrap/secrets.enc/: all component secrets encrypted to age pubkey
- Fix .gitignore: allow secrets.enc/**/*.age while blocking plaintext
- Fix verify-t02.sh: update netpol names for Authelia+LLDAP+KeyCape stack
- Fix verify-t03.sh: remove keycloak_db/role checks; fix ((PASS++)) set-e bug
- Update postgresql/cluster.yaml: drop keycloak_db, bootstrap privacyidea_db only
- Update postgresql/create-secrets.sh: remove keycloak secret
- Fix netpol-databases.yaml: add port 8000 for CNPG instance manager HTTP API
- T02 COMPLETE: namespaces, network policies, cert-manager issuers applied
- T03 COMPLETE: CNPG operator installed, net-kingdom-pg cluster healthy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 02:57:41 +00:00

114 lines
4.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# verify-t02.sh — verify T02 (K8s foundations) completion criteria
#
# Run after applying all T02 manifests. Exits 0 if all checks pass.
#
# Usage: ./verify-t02.sh [--kubeconfig PATH]
set -euo pipefail
KUBECTL="kubectl"
if [[ "${1:-}" == "--kubeconfig" ]]; then
KUBECTL="kubectl --kubeconfig $2"
fi
PASS=0
FAIL=0
check() {
local desc="$1"
shift
if "$@" &>/dev/null; then
echo " PASS $desc"
PASS=$((PASS + 1))
else
echo " FAIL $desc"
FAIL=$((FAIL + 1))
fi
}
check_output() {
local desc="$1"
local expected="$2"
shift 2
local actual
actual="$("$@" 2>/dev/null || true)"
if echo "$actual" | grep -q "$expected"; then
echo " PASS $desc"
PASS=$((PASS + 1))
else
echo " FAIL $desc (got: $actual)"
FAIL=$((FAIL + 1))
fi
}
echo "=== T02 Verification — K8s Foundations ==="
echo ""
# ── Namespaces ────────────────────────────────────────────────────────────────
echo "[ Namespaces ]"
check "namespace sso exists" $KUBECTL get namespace sso
check "namespace mfa exists" $KUBECTL get namespace mfa
check "namespace databases exists" $KUBECTL get namespace databases
check "sso has net-kingdom/component label" \
$KUBECTL get namespace sso -o jsonpath='{.metadata.labels.net-kingdom/component}'
echo ""
# ── NetworkPolicies ───────────────────────────────────────────────────────────
echo "[ NetworkPolicies ]"
for ns in sso mfa databases; do
check "default-deny-all in $ns" \
$KUBECTL get networkpolicy default-deny-all -n "$ns"
check "allow-egress-dns in $ns" \
$KUBECTL get networkpolicy allow-egress-dns -n "$ns"
done
check "allow-traefik-to-keycape in sso" $KUBECTL get networkpolicy allow-traefik-to-keycape -n sso
check "allow-keycape-egress-to-privacyidea in sso" $KUBECTL get networkpolicy allow-keycape-egress-to-privacyidea -n sso
check "allow-ingress-from-traefik in mfa" $KUBECTL get networkpolicy allow-ingress-from-traefik -n mfa
check "allow-ingress-from-keycloak in mfa" $KUBECTL get networkpolicy allow-ingress-from-keycloak -n mfa
check "allow-egress-to-postgres in mfa" $KUBECTL get networkpolicy allow-egress-to-postgres -n mfa
check "allow-ingress-from-keycloak in databases" $KUBECTL get networkpolicy allow-ingress-from-keycloak -n databases
check "allow-ingress-from-privacyidea in databases" $KUBECTL get networkpolicy allow-ingress-from-privacyidea -n databases
echo ""
# ── cert-manager ─────────────────────────────────────────────────────────────
echo "[ cert-manager ]"
check "cert-manager namespace exists" $KUBECTL get namespace cert-manager
check "selfsigned-issuer exists" $KUBECTL get clusterissuer selfsigned-issuer
check "letsencrypt-prod issuer exists" $KUBECTL get clusterissuer letsencrypt-prod
check_output "selfsigned-issuer is Ready" "True" \
$KUBECTL get clusterissuer selfsigned-issuer -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}'
# Test certificate (applied separately — only check if present)
if $KUBECTL get namespace cert-manager-test &>/dev/null; then
check_output "test certificate is Ready" "True" \
$KUBECTL get certificate selfsigned-test -n cert-manager-test \
-o jsonpath='{.status.conditions[?(@.type=="Ready")].status}'
else
echo " SKIP test certificate (namespace cert-manager-test not found — apply test-certificate.yaml)"
fi
echo ""
# ── StorageClass ──────────────────────────────────────────────────────────────
echo "[ StorageClass ]"
check "a default StorageClass exists" \
$KUBECTL get storageclass -o jsonpath='{.items[?(@.metadata.annotations.storageclass\.kubernetes\.io/is-default-class=="true")].metadata.name}'
if $KUBECTL get namespace storage-test &>/dev/null; then
check_output "storage-test pod Completed" "Completed\|Succeeded" \
$KUBECTL get pod storage-test -n storage-test -o jsonpath='{.status.phase}'
else
echo " SKIP StorageClass PVC test (apply storage/verify-pvc.yaml first)"
fi
echo ""
# ── Summary ───────────────────────────────────────────────────────────────────
TOTAL=$((PASS + FAIL))
echo "=== Results: $PASS/$TOTAL passed ==="
if [[ $FAIL -gt 0 ]]; then
echo " $FAIL check(s) failed."
exit 1
else
echo " T02 COMPLETE — all checks passed."
fi