Adding haproxy pass as secret managed in pipeline

This commit is contained in:
juvdiaz 2026-07-02 12:42:46 -06:00
parent d278355d68
commit 8865ab9d18
2 changed files with 111 additions and 12 deletions

View File

@ -595,8 +595,14 @@ Raspberry Pi when Docker is missing. Default is to fail.
missing. Default is to fail.
`TF_VAR_haproxy_stats_password`
: Required HAProxy stats password for the edge stack. It must be set explicitly
and must not use the old default.
: HAProxy stats password for the edge stack. If unset, Jeannie loads it from
`LAB_EDGE_HAPROXY_STATS_CREDENTIALS_FILE`, recovers it from the live edge host's
rendered HAProxy config when available, or generates and stores a new value.
It must not use the old default.
`LAB_EDGE_HAPROXY_STATS_CREDENTIALS_FILE`
: Local Debian-host credentials file for the edge HAProxy stats password.
Defaults to `~/.config/homelab/edge-haproxy.env`.
`LAB_CONFIRM_NUKE=homelab`
: Required confirmation for direct `./jeannie nuke`.

113
jeannie
View File

@ -481,6 +481,9 @@ run_tofu_stack() {
if [[ "${stack}" == "bootstrap/cluster" ]]; then
ensure_cluster_worker_var_file
fi
if [[ "${stack}" == "bootstrap/edge" ]]; then
ensure_edge_haproxy_stats_password
fi
if truthy "${auto_approve}"; then
apply_args+=("-auto-approve")
@ -4916,19 +4919,109 @@ apps() {
edge_apply() {
require_debian_server "edge"
if [[ -z "${TF_VAR_haproxy_stats_password:-}" ]] ||
((${#TF_VAR_haproxy_stats_password} < 12)) ||
[[ "${TF_VAR_haproxy_stats_password}" == "adminpassword" ]]; then
cat >&2 <<'EOF'
TF_VAR_haproxy_stats_password must be set to a non-default value with at least 12 characters before applying the edge stack.
Example:
export TF_VAR_haproxy_stats_password='<existing-edge-stats-password>'
./jeannie edge
EOF
run_tofu_stack "bootstrap/edge"
}
edge_haproxy_stats_password_valid() {
local password="${1:-}"
[[ -n "${password}" ]] && ((${#password} >= 12)) && [[ "${password}" != "adminpassword" ]]
}
edge_haproxy_stats_credentials_file() {
printf '%s\n' "${LAB_EDGE_HAPROXY_STATS_CREDENTIALS_FILE:-${HOME}/.config/homelab/edge-haproxy.env}"
}
generate_edge_haproxy_stats_password() {
if command -v openssl >/dev/null 2>&1; then
openssl rand -hex 24
elif command -v python3 >/dev/null 2>&1; then
python3 - <<'PY'
import secrets
print(secrets.token_hex(24))
PY
else
echo "openssl or python3 is required to generate an edge HAProxy stats password." >&2
exit 1
fi
}
run_tofu_stack "bootstrap/edge"
write_edge_haproxy_stats_credentials() {
local credentials_file="$1"
local password="$2"
local credentials_dir
credentials_dir="$(dirname "${credentials_file}")"
mkdir -p "${credentials_dir}"
chmod 0700 "${credentials_dir}"
{
printf 'TF_VAR_haproxy_stats_password='
printf '%q' "${password}"
printf '\n'
} > "${credentials_file}"
chmod 0600 "${credentials_file}"
}
recover_edge_haproxy_stats_password() {
local edge_host="${TF_VAR_edge_host:-${LAB_EDGE_HOST:-}}"
local edge_user="${TF_VAR_edge_user:-${LAB_EDGE_USER:-ubuntu}}"
local edge_key="${TF_VAR_edge_ssh_key_path:-${LAB_EDGE_SSH_KEY_PATH:-/home/jv/.ssh/id_ed25519}}"
local edge_install_dir="${TF_VAR_edge_install_dir:-${LAB_EDGE_INSTALL_DIR:-/opt/homelab-edge}}"
local remote_auth
local remote_password
if [[ -z "${edge_host}" || "${edge_install_dir}" == *"'"* ]]; then
return 1
fi
remote_auth="$(ssh -i "${edge_key}" -o BatchMode=yes -o ConnectTimeout=10 -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new "${edge_user}@${edge_host}" \
"sudo sed -n 's/^[[:space:]]*stats auth //p' '${edge_install_dir}/config_files/haproxy.cfg' | head -n 1" 2>/dev/null || true)"
remote_auth="${remote_auth//$'\r'/}"
if [[ "${remote_auth}" != *:* ]]; then
return 1
fi
remote_password="${remote_auth#*:}"
if ! edge_haproxy_stats_password_valid "${remote_password}"; then
return 1
fi
printf '%s\n' "${remote_password}"
}
ensure_edge_haproxy_stats_password() {
local credentials_file
local recovered_password
if edge_haproxy_stats_password_valid "${TF_VAR_haproxy_stats_password:-}"; then
export TF_VAR_haproxy_stats_password
return 0
fi
credentials_file="$(edge_haproxy_stats_credentials_file)"
if [[ -r "${credentials_file}" ]]; then
# shellcheck disable=SC1090
source "${credentials_file}"
if edge_haproxy_stats_password_valid "${TF_VAR_haproxy_stats_password:-}"; then
export TF_VAR_haproxy_stats_password
return 0
fi
echo "Ignoring invalid edge HAProxy stats credentials in ${credentials_file}." >&2
fi
if recovered_password="$(recover_edge_haproxy_stats_password)"; then
TF_VAR_haproxy_stats_password="${recovered_password}"
export TF_VAR_haproxy_stats_password
write_edge_haproxy_stats_credentials "${credentials_file}" "${TF_VAR_haproxy_stats_password}"
echo "Recovered edge HAProxy stats password from the live edge host and stored it at ${credentials_file}."
return 0
fi
TF_VAR_haproxy_stats_password="$(generate_edge_haproxy_stats_password)"
export TF_VAR_haproxy_stats_password
write_edge_haproxy_stats_credentials "${credentials_file}" "${TF_VAR_haproxy_stats_password}"
echo "Generated edge HAProxy stats password at ${credentials_file}."
}
ensure_cluster_worker_var_file() {