prole/etc/init_kerberos_test.sh

196 lines
5.5 KiB
Bash
Executable File

#!/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 <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: ${pod_name}
namespace: ${NAMESPACE}
labels:
app: prole-kerberos-test
spec:
${host_net_block} restartPolicy: Never
containers:
- name: kerberos-test
image: ${image}
command: ["sleep","3600"]
volumeMounts:
- name: krb5-conf
mountPath: /etc/krb5.conf
subPath: krb5.conf
volumes:
- name: krb5-conf
configMap:
name: prole-krb5-conf
items:
- key: krb5.conf
path: krb5.conf
EOF
}
run_test() {
ensure_tools
ensure_namespace
if [[ -z "$KRB5_REALM" || -z "$KRB5_USER" || -z "$KRB5_PASSWORD" || -z "$KRB5_KDC" ]]; then
echo "ERROR: Missing Kerberos configuration. Ensure KRB5_REALM, KRB5_KDC, KRB5_USER, KRB5_PASSWORD are set." >&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