#!/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-keycape in mfa" $KUBECTL get networkpolicy allow-ingress-from-keycape -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