mirror of
https://github.com/dredx/prole.git
synced 2026-09-24 16:44:33 +00:00
- Materialize required DB Kubernetes secrets from user-entered password before CNPG init - Auto-generate a temporary OpenTofu admin password in non-interactive runs when none is available - Update installer UI flows and tests to cover the new preflights/rotation Co-authored-by: Junie <junie@jetbrains.com>
165 lines
4.3 KiB
Bash
165 lines
4.3 KiB
Bash
#!/usr/bin/env bash
|
|
# Unit test for etc/init_opentofu.sh
|
|
|
|
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
PROLE_HOME=$(cd "$SCRIPT_DIR/../.." && pwd)
|
|
ETC_DIR="$PROLE_HOME/etc"
|
|
SCRIPT_UNDER_TEST="$ETC_DIR/init_opentofu.sh"
|
|
|
|
TMP_DIR=$(mktemp -d)
|
|
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
export TMP_DIR
|
|
|
|
mock_tool() {
|
|
cat <<M_EOF > "$TMP_DIR/$1"
|
|
#!/usr/bin/env bash
|
|
echo "Mocked $1 called with \$@" >> "$TMP_DIR/mock_calls.log"
|
|
exit 0
|
|
M_EOF
|
|
chmod +x "$TMP_DIR/$1"
|
|
}
|
|
|
|
# kubectl needs behavior for this script.
|
|
cat <<'K_EOF' > "$TMP_DIR/kubectl"
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
echo "Mocked kubectl called with $*" >> "${TMP_DIR}/mock_calls.log"
|
|
|
|
# Simulate OpenTofu admin secret existence checks.
|
|
if [[ "${1:-}" == "get" && "${2:-}" == "secret" && "${3:-}" == "opentofu-admin" ]]; then
|
|
if [[ "${MOCK_OPENTOFU_SECRET_EXISTS:-0}" == "1" ]]; then
|
|
# When queried for a jsonpath, output a base64-encoded password.
|
|
if [[ "$*" == *"jsonpath"* ]]; then
|
|
printf "%s" "$(printf "existingpw" | base64)"
|
|
fi
|
|
exit 0
|
|
fi
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "${1:-}" == "create" && "${2:-}" == "secret" ]]; then
|
|
# The script pipes this output into `kubectl apply -f -`.
|
|
echo "apiVersion: v1"
|
|
echo "kind: Secret"
|
|
exit 0
|
|
fi
|
|
|
|
if [[ "${1:-}" == "apply" ]]; then
|
|
# Consume stdin to avoid upstream pipe failures.
|
|
cat >/dev/null || true
|
|
exit 0
|
|
fi
|
|
|
|
exit 0
|
|
K_EOF
|
|
chmod +x "$TMP_DIR/kubectl"
|
|
|
|
# Create mocks for other tools
|
|
mock_tool curl
|
|
mock_tool docker
|
|
mock_tool k3d
|
|
mock_tool ansible-playbook
|
|
mock_tool tofu
|
|
mock_tool terraform
|
|
mock_tool ollama
|
|
mock_tool jq
|
|
|
|
# Mock prole.cfg
|
|
mkdir -p "$TMP_DIR/conf"
|
|
cat <<C_EOF > "$TMP_DIR/conf/prole.cfg"
|
|
[Global]
|
|
MODE = k3d
|
|
NAMESPACE = test-ns
|
|
|
|
[Initialize Cluster]
|
|
ENVIRONMENT = dev
|
|
C_EOF
|
|
|
|
export PATH="$TMP_DIR:$PATH"
|
|
export PROLE_HOME="$PROLE_HOME"
|
|
export PROLE_CONF="$TMP_DIR/conf"
|
|
export PROLE_SERVICE="$PROLE_HOME/etc"
|
|
export NAMESPACE="test-ns"
|
|
export PROLE_PASSWD="test-password"
|
|
|
|
run_case() {
|
|
local name="$1"; shift
|
|
: > "$TMP_DIR/mock_calls.log"
|
|
: > "$TMP_DIR/stdout"
|
|
: > "$TMP_DIR/stderr"
|
|
|
|
echo "--- $name" >> "$TMP_DIR/mock_calls.log"
|
|
bash "$SCRIPT_UNDER_TEST" "$@" > "$TMP_DIR/stdout" 2> "$TMP_DIR/stderr"
|
|
return $?
|
|
}
|
|
|
|
# Case 1: secret missing, DB_PASSWORD provided -> secret should be created.
|
|
export MOCK_OPENTOFU_SECRET_EXISTS=0
|
|
export DB_PASSWORD="root-master-password"
|
|
run_case "create_secret_from_db_password" start
|
|
RC=$?
|
|
if [[ $RC -ne 0 ]]; then
|
|
echo "FAILURE: expected RC=0, got RC=$RC"
|
|
cat "$TMP_DIR/stderr"
|
|
exit 1
|
|
fi
|
|
if ! grep -q "create secret generic opentofu-admin" "$TMP_DIR/mock_calls.log"; then
|
|
echo "FAILURE: expected opentofu-admin secret creation"
|
|
cat "$TMP_DIR/mock_calls.log"
|
|
exit 1
|
|
fi
|
|
|
|
# Case 2: secret already exists -> no creation call.
|
|
export MOCK_OPENTOFU_SECRET_EXISTS=1
|
|
unset DB_PASSWORD || true
|
|
unset OPENTOFU_ADMIN_PASSWORD || true
|
|
run_case "secret_already_exists" start
|
|
RC=$?
|
|
if [[ $RC -ne 0 ]]; then
|
|
echo "FAILURE: expected RC=0, got RC=$RC"
|
|
cat "$TMP_DIR/stderr"
|
|
exit 1
|
|
fi
|
|
if grep -q "create secret generic opentofu-admin" "$TMP_DIR/mock_calls.log"; then
|
|
echo "FAILURE: did not expect opentofu-admin secret creation when it already exists"
|
|
cat "$TMP_DIR/mock_calls.log"
|
|
exit 1
|
|
fi
|
|
|
|
# Case 3: secret missing, no password sources (non-interactive) -> must generate a temporary password and proceed.
|
|
export MOCK_OPENTOFU_SECRET_EXISTS=0
|
|
unset DB_PASSWORD || true
|
|
unset OPENTOFU_ADMIN_PASSWORD || true
|
|
run_case "missing_password_noninteractive" start
|
|
RC=$?
|
|
if [[ $RC -ne 0 ]]; then
|
|
echo "FAILURE: expected RC=0 for non-interactive missing password (generated fallback), got RC=$RC"
|
|
cat "$TMP_DIR/stderr"
|
|
exit 1
|
|
fi
|
|
if ! grep -q "create secret generic opentofu-admin" "$TMP_DIR/mock_calls.log"; then
|
|
echo "FAILURE: expected opentofu-admin secret creation using generated fallback"
|
|
cat "$TMP_DIR/mock_calls.log"
|
|
exit 1
|
|
fi
|
|
|
|
# Case 4: secret exists, DB_PASSWORD becomes available later -> secret should be updated/rotated.
|
|
export MOCK_OPENTOFU_SECRET_EXISTS=1
|
|
export DB_PASSWORD="root-master-password"
|
|
run_case "rotate_secret_when_db_password_available" start
|
|
RC=$?
|
|
if [[ $RC -ne 0 ]]; then
|
|
echo "FAILURE: expected RC=0, got RC=$RC"
|
|
cat "$TMP_DIR/stderr"
|
|
exit 1
|
|
fi
|
|
if ! grep -q "create secret generic opentofu-admin" "$TMP_DIR/mock_calls.log"; then
|
|
echo "FAILURE: expected opentofu-admin secret update when DB_PASSWORD becomes available"
|
|
cat "$TMP_DIR/mock_calls.log"
|
|
exit 1
|
|
fi
|
|
|
|
echo "SUCCESS"
|
|
exit 0
|