mirror of
https://github.com/dredx/prole.git
synced 2026-09-24 18:24:32 +00:00
- Consolidated and split initialization scripts in etc/:
- Removed init_prole-db.sh and init_authority.sh.
- Added init_kdc.sh for in-cluster MIT Kerberos KDC (prole-authority).
- Added init_ollama.sh for Ollama AI service integration.
- Added init_service_layer.sh for high-level service orchestration.
- Added init_k3s_registry.sh for private registry management.
- Major updates to install.py:
- Support for new Ollama and KDC configuration.
- Improved prole.cfg rendering and namespace handling.
- Updated unattended install flags.
- Infrastructure and Deployment:
- Updated K3s Ansible role with private registry support (registries.yaml template).
- Added prole-authority Dockerfile.
- Updated OpenBao Kerberos ConfigMap and other K8s manifests.
- Configuration:
- Updated prole.cfg with new sections for Ollama and Monitoring.
- Refined environment variable exports in env.sh and prole_cfg.sh.
241 lines
7.8 KiB
Bash
Executable File
241 lines
7.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
# init_kerberos_test.sh
|
|
# Purpose:
|
|
# - Run Kerberos authentication checks inside the in-cluster KDC pod
|
|
|
|
# Initialize SCRIPT_DIR
|
|
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
|
|
ORIG_ARGS=("$@")
|
|
|
|
# Load env
|
|
if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then
|
|
set --
|
|
# shellcheck disable=SC1090
|
|
source "$PROLE_HOME/env.sh"
|
|
set -- "${ORIG_ARGS[@]}"
|
|
elif [[ -f "$HOME/.prole/env.sh" ]]; then
|
|
set --
|
|
# shellcheck disable=SC1090
|
|
source "$HOME/.prole/env.sh"
|
|
set -- "${ORIG_ARGS[@]}"
|
|
fi
|
|
|
|
# Load config values from prole.cfg before applying defaults/CLI overrides.
|
|
# shellcheck disable=SC1090
|
|
source "$SCRIPT_DIR/prole_cfg.sh"
|
|
|
|
if [[ "${1:-}" == "--mode" || "${1:-}" == "-m" ]]; then
|
|
prole_set_mode "${2:-}"
|
|
shift 2
|
|
elif [[ "${1:-}" == --mode=* || "${1:-}" == -m=* ]]; then
|
|
prole_set_mode "${1#*=}"
|
|
shift
|
|
fi
|
|
|
|
ACTION=${1:-test}
|
|
|
|
NAMESPACE=${NAMESPACE:-default}
|
|
SERVICE_NAMESPACE=${SERVICE_NAMESPACE:-${NAMESPACE}}
|
|
KRB5_REALM=${KRB5_REALM:-${REALM:-}}
|
|
KRB5_KDC=${KRB5_KDC:-}
|
|
KRB5_USER=${KRB5_USER:-${KRB5_USERNAME:-}}
|
|
KRB5_PASSWORD=${KRB5_PASSWORD:-}
|
|
PROLE_KDC_NAME=${PROLE_KDC_NAME:-dog}
|
|
PROLE_KDC_SERVICE=${PROLE_KDC_SERVICE:-authority}
|
|
SAMBA_ADMIN_USER=${SAMBA_ADMIN_USER:-}
|
|
SAMBA_ADMIN_PASSWORD=${SAMBA_ADMIN_PASSWORD:-}
|
|
SAMBA_DNS_SERVER=${SAMBA_DNS_SERVER:-}
|
|
|
|
ensure_tools() {
|
|
for t in kubectl curl jq; 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
|
|
}
|
|
|
|
openbao_url() {
|
|
if [[ -n "${PROLE_OPENBAO_URL:-}" ]]; then
|
|
echo "$PROLE_OPENBAO_URL"
|
|
elif curl -sS "http://127.0.0.1:18200/v1/sys/health" >/dev/null 2>&1; then
|
|
echo "http://127.0.0.1:18200"
|
|
else
|
|
echo "http://openbao.${NAMESPACE}.svc.cluster.local:8200"
|
|
fi
|
|
}
|
|
|
|
openbao_token() {
|
|
if [[ -f "$PROLE_SERVICE/secrets/openbao-root-token" ]]; then
|
|
cat "$PROLE_SERVICE/secrets/openbao-root-token"
|
|
else
|
|
echo "${OPENBAO_ROOT_TOKEN:-}"
|
|
fi
|
|
}
|
|
|
|
fetch_openbao_secret() {
|
|
local path="$1"
|
|
local key="$2"
|
|
local token url
|
|
token=$(openbao_token)
|
|
url=$(openbao_url)
|
|
if [[ -z "$token" ]]; then
|
|
echo ""
|
|
return 0
|
|
fi
|
|
curl -sS -H "X-Vault-Token: $token" "$url/v1/kv/data/$path" | jq -r ".data.data.\"$key\"" || echo ""
|
|
}
|
|
|
|
resolve_krb5_password() {
|
|
if [[ -z "${KRB5_PASSWORD}" || "${KRB5_PASSWORD}" == '${OPENBAO:'* || "${KRB5_PASSWORD}" == '${PROLE_SECRET:'* ]]; then
|
|
local path="prole/${NAMESPACE:-default}/kerberos"
|
|
local fetched
|
|
fetched=$(fetch_openbao_secret "$path" "password")
|
|
if [[ -n "$fetched" && "$fetched" != "null" ]]; then
|
|
KRB5_PASSWORD="$fetched"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
resolve_samba_vars_from_ansible() {
|
|
if [[ -n "${SAMBA_ADMIN_USER}" && -n "${SAMBA_ADMIN_PASSWORD}" && -n "${SAMBA_DNS_SERVER}" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
local root
|
|
if [[ -n "${PROLE_HOME:-}" && -d "${PROLE_HOME}" ]]; then
|
|
root="${PROLE_HOME}"
|
|
else
|
|
root="${SCRIPT_DIR}/.."
|
|
fi
|
|
|
|
local vars_file="${root}/infrastructure/inventory/group_vars/ad_dc/vars.yml"
|
|
if [[ -f "$vars_file" ]]; then
|
|
if [[ -z "$SAMBA_DNS_SERVER" ]]; then
|
|
SAMBA_DNS_SERVER=$(awk -F: '/^[[:space:]]*samba_dns_server[[:space:]]*:/ {sub(/^[^:]+:[[:space:]]*/, "", $0); gsub(/"/, "", $0); print $0; exit}' "$vars_file")
|
|
fi
|
|
if [[ -z "$SAMBA_ADMIN_USER" ]]; then
|
|
SAMBA_ADMIN_USER=$(awk -F: '/^[[:space:]]*samba_dns_admin_user[[:space:]]*:/ {sub(/^[^:]+:[[:space:]]*/, "", $0); gsub(/"/, "", $0); print $0; exit}' "$vars_file")
|
|
fi
|
|
fi
|
|
|
|
if [[ -z "$SAMBA_ADMIN_PASSWORD" ]]; then
|
|
local vault_file="${root}/infrastructure/inventory/group_vars/ad_dc/vault.yml"
|
|
local vault_pass_file=""
|
|
if [[ -n "${ANSIBLE_VAULT_PASSWORD_FILE:-}" && -f "${ANSIBLE_VAULT_PASSWORD_FILE}" ]]; then
|
|
vault_pass_file="${ANSIBLE_VAULT_PASSWORD_FILE}"
|
|
elif [[ -n "${PROLE_HOME:-}" && -f "${PROLE_HOME}/.vault_pass" ]]; then
|
|
vault_pass_file="${PROLE_HOME}/.vault_pass"
|
|
elif [[ -f "${root}/.vault_pass" ]]; then
|
|
vault_pass_file="${root}/.vault_pass"
|
|
fi
|
|
|
|
if [[ -f "$vault_file" && -n "$vault_pass_file" && -x "$(command -v ansible-vault)" ]]; then
|
|
local vault_out
|
|
vault_out=$(ansible-vault view "$vault_file" --vault-password-file "$vault_pass_file" 2>/dev/null || true)
|
|
if [[ -n "$vault_out" ]]; then
|
|
SAMBA_ADMIN_PASSWORD=$(printf '%s\n' "$vault_out" | awk -F: '/^[[:space:]]*vault_samba_dns_admin_pass[[:space:]]*:/ {sub(/^[^:]+:[[:space:]]*/, "", $0); gsub(/"/, "", $0); print $0; exit}')
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
join_samba_realm_if_needed() {
|
|
local kdc_ns="$1"
|
|
local pod_name="$2"
|
|
local domain=""
|
|
|
|
resolve_samba_vars_from_ansible
|
|
|
|
if [[ -z "$SAMBA_ADMIN_USER" || -z "$SAMBA_ADMIN_PASSWORD" || -z "$SAMBA_DNS_SERVER" ]]; then
|
|
echo "WARN: Missing Samba join info; skipping samba-tool realm join."
|
|
return 0
|
|
fi
|
|
|
|
if [[ -n "$KRB5_REALM" ]]; then
|
|
domain=$(printf '%s' "$KRB5_REALM" | tr '[:upper:]' '[:lower:]')
|
|
fi
|
|
if [[ -z "$domain" ]]; then
|
|
domain="$SAMBA_DNS_SERVER"
|
|
fi
|
|
|
|
if kubectl -n "$kdc_ns" exec "$pod_name" -- test -f /var/lib/samba/private/secrets.tdb >/dev/null 2>&1; then
|
|
echo "Samba already joined; skipping join."
|
|
return 0
|
|
fi
|
|
|
|
echo "Joining Samba realm '${domain}' (server ${SAMBA_DNS_SERVER}) ..."
|
|
kubectl -n "$kdc_ns" exec "$pod_name" -- \
|
|
env SAMBA_ADMIN_USER="$SAMBA_ADMIN_USER" SAMBA_ADMIN_PASSWORD="$SAMBA_ADMIN_PASSWORD" \
|
|
SAMBA_DNS_SERVER="$SAMBA_DNS_SERVER" SAMBA_REALM="${KRB5_REALM:-}" \
|
|
/bin/sh -c 'realm_flag=""; [ -n "${SAMBA_REALM}" ] && realm_flag="--realm=${SAMBA_REALM}"; samba-tool domain join "'"$domain"'" MEMBER -U"${SAMBA_ADMIN_USER}%${SAMBA_ADMIN_PASSWORD}" --server="${SAMBA_DNS_SERVER}" ${realm_flag}' || {
|
|
echo "WARN: samba-tool domain join failed; continuing to Kerberos test." >&2
|
|
return 0
|
|
}
|
|
}
|
|
|
|
run_test() {
|
|
ensure_tools
|
|
ensure_namespace
|
|
resolve_krb5_password
|
|
|
|
# Support both names for the toggle from prole.cfg
|
|
local enabled="${KERBEROS_ENABLED:-${ENABLED:-false}}"
|
|
if [[ "$enabled" == "false" || "$enabled" == "0" || "$enabled" == "False" ]]; then
|
|
echo "Kerberos is disabled (KERBEROS_ENABLED=$enabled). Skipping test."
|
|
return 0
|
|
fi
|
|
|
|
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
|
|
|
|
if [[ -x "$SCRIPT_DIR/init_kdc.sh" ]]; then
|
|
SERVICE_NAMESPACE="$SERVICE_NAMESPACE" KRB5_REALM="$KRB5_REALM" KRB5_KDC="$KRB5_KDC" \
|
|
KRB5_ADMIN="$KRB5_KDC" KRB5_USER="$KRB5_USER" KRB5_PASSWORD="$KRB5_PASSWORD" \
|
|
"$SCRIPT_DIR/init_kdc.sh" update || true
|
|
fi
|
|
|
|
local kdc_ns pod_name
|
|
kdc_ns="${SERVICE_NAMESPACE:-${NAMESPACE:-default}}"
|
|
pod_name=$(kubectl -n "$kdc_ns" get pod -l "app=${PROLE_KDC_NAME}" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true)
|
|
if [[ -z "$pod_name" ]]; then
|
|
echo "ERROR: KDC pod '${PROLE_KDC_NAME}' not found in namespace '$kdc_ns'. Run init_kdc.sh update first." >&2
|
|
exit 1
|
|
fi
|
|
|
|
join_samba_realm_if_needed "$kdc_ns" "$pod_name"
|
|
|
|
echo "Running kinit for ${KRB5_USER}@${KRB5_REALM} inside ${PROLE_KDC_NAME} (${pod_name}) ..."
|
|
if ! printf '%s\n' "$KRB5_PASSWORD" | kubectl -n "$kdc_ns" exec -i "$pod_name" -- \
|
|
env KRB5_CONFIG=/opt/prole-kdc/krb5.conf kinit "${KRB5_USER}@${KRB5_REALM}"; then
|
|
echo "ERROR: kinit failed for ${KRB5_USER}@${KRB5_REALM}." >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Kerberos ticket cache:"
|
|
kubectl -n "$kdc_ns" exec "$pod_name" -- env KRB5_CONFIG=/opt/prole-kdc/krb5.conf klist || true
|
|
}
|
|
|
|
case "$ACTION" in
|
|
test)
|
|
run_test
|
|
;;
|
|
cleanup)
|
|
echo "No test pods to cleanup (KDC-based test)."
|
|
;;
|
|
*)
|
|
echo "Usage: $0 {test|cleanup}" >&2
|
|
exit 2
|
|
;;
|
|
esac
|