#!/usr/bin/env bash set -euo pipefail # init_kerberos_test.sh # Purpose: # - Run Kerberos authentication checks inside a Kubernetes pod # - Uses the prole-krb5-conf ConfigMap for krb5.conf # Initialize SCRIPT_DIR SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) ACTION=${1:-test} # Load env if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then set -- # shellcheck disable=SC1090 source "$PROLE_HOME/env.sh" elif [[ -f "$HOME/.prole/env.sh" ]]; then set -- # shellcheck disable=SC1090 source "$HOME/.prole/env.sh" fi NAMESPACE=${NAMESPACE:-default} KRB5_REALM=${KRB5_REALM:-${REALM:-}} KRB5_KDC=${KRB5_KDC:-} KRB5_USER=${KRB5_USER:-${KRB5_USERNAME:-}} KRB5_PASSWORD=${KRB5_PASSWORD:-} KRB5_TEST_IMAGE=${KRB5_TEST_IMAGE:-${PROLE_KRB_TEST_IMAGE:-}} KEEP_POD=${KEEP_POD:-0} KRB5_TEST_HOST_NETWORK=${KRB5_TEST_HOST_NETWORK:-0} KRB5_TEST_DNS_POLICY=${KRB5_TEST_DNS_POLICY:-} ensure_tools() { for t in kubectl; do command -v "$t" >/dev/null || { echo "Missing required tool: $t" >&2; exit 1; } done } ensure_namespace() { if ! kubectl get namespace "$NAMESPACE" >/dev/null 2>&1; then echo "Creating namespace '$NAMESPACE' ..." kubectl create namespace "$NAMESPACE" >/dev/null 2>&1 || true fi } detect_image() { if [[ -n "$KRB5_TEST_IMAGE" ]]; then echo "$KRB5_TEST_IMAGE" return fi local version_file if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/conf/postgresql/.version" ]]; then version_file="$PROLE_HOME/conf/postgresql/.version" elif [[ -f "$SCRIPT_DIR/../conf/postgresql/.version" ]]; then version_file="$SCRIPT_DIR/../conf/postgresql/.version" else version_file="" fi if [[ -n "$version_file" && -f "$version_file" ]]; then echo "prole-db:$(cat "$version_file" | tr -d '[:space:]')" else echo "prole-db:latest" fi } ensure_configmap() { if kubectl -n "$NAMESPACE" get configmap prole-krb5-conf >/dev/null 2>&1; then return fi echo "ConfigMap prole-krb5-conf not found. Running init_openbao.sh update..." if [[ -x "$SCRIPT_DIR/init_openbao.sh" ]]; then KRB5_REALM="$KRB5_REALM" KRB5_KDC="$KRB5_KDC" "$SCRIPT_DIR/init_openbao.sh" update || true fi } create_test_pod() { local pod_name="$1" local image="$2" local host_net_block="" if [[ "$KRB5_TEST_HOST_NETWORK" == "1" ]]; then local dns_policy dns_policy=${KRB5_TEST_DNS_POLICY:-Default} host_net_block=$' hostNetwork: true\n dnsPolicy: '"$dns_policy"$'\n' fi cat <&2 exit 1 fi ensure_configmap local image pod_name image=$(detect_image) pod_name="prole-krb-test-$(date +%s)" echo "Creating Kerberos test pod '$pod_name' in namespace '$NAMESPACE' using image '$image'..." create_test_pod "$pod_name" "$image" echo "Waiting for pod to become ready..." if ! kubectl -n "$NAMESPACE" wait --for=condition=Ready pod/"$pod_name" --timeout=90s; then echo "Pod did not become ready. Describing pod:" kubectl -n "$NAMESPACE" describe pod "$pod_name" || true if [[ "$KEEP_POD" != "1" ]]; then kubectl -n "$NAMESPACE" delete pod "$pod_name" --ignore-not-found fi exit 1 fi echo "Checking for kinit in pod..." if ! kubectl -n "$NAMESPACE" exec "$pod_name" -- sh -c 'command -v kinit >/dev/null 2>&1'; then echo "ERROR: kinit not found in test pod image '$image'." >&2 if [[ "$KEEP_POD" != "1" ]]; then kubectl -n "$NAMESPACE" delete pod "$pod_name" --ignore-not-found fi exit 1 fi echo "Running kinit for ${KRB5_USER}@${KRB5_REALM} ..." if ! printf '%s\n' "$KRB5_PASSWORD" | kubectl -n "$NAMESPACE" exec -i "$pod_name" -- kinit "${KRB5_USER}@${KRB5_REALM}"; then echo "ERROR: kinit failed for ${KRB5_USER}@${KRB5_REALM}." >&2 if [[ "$KEEP_POD" != "1" ]]; then kubectl -n "$NAMESPACE" delete pod "$pod_name" --ignore-not-found fi exit 1 fi echo "Kerberos ticket cache:" kubectl -n "$NAMESPACE" exec "$pod_name" -- klist || true if [[ "${REALM_JOIN:-0}" == "1" ]]; then echo "Attempting realm join inside test pod..." if kubectl -n "$NAMESPACE" exec "$pod_name" -- sh -c 'command -v realm >/dev/null 2>&1'; then printf '%s\n' "$KRB5_PASSWORD" | kubectl -n "$NAMESPACE" exec -i "$pod_name" -- realm join --user "$KRB5_USER" "$KRB5_REALM" || true else echo "realm command not found in image; skipping realm join." fi fi if [[ "$KEEP_POD" != "1" ]]; then kubectl -n "$NAMESPACE" delete pod "$pod_name" --ignore-not-found else echo "KEEP_POD=1 set; leaving test pod running: $pod_name" fi } case "$ACTION" in test) run_test ;; cleanup) ensure_tools echo "Deleting kerberos test pods in namespace '$NAMESPACE'..." kubectl -n "$NAMESPACE" delete pod -l app=prole-kerberos-test --ignore-not-found ;; *) echo "Usage: $0 {test|cleanup}" >&2 exit 2 ;; esac