Some checks failed
CI / skip-ci-check (pull_request) Successful in 6s
CI / lint-and-test (pull_request) Failing after 9s
CI / ansible-validation (pull_request) Failing after 6s
CI / secret-scanning (pull_request) Successful in 5s
CI / dependency-scan (pull_request) Successful in 8s
CI / sast-scan (pull_request) Failing after 5s
CI / license-check (pull_request) Successful in 11s
CI / vault-check (pull_request) Failing after 6s
CI / playbook-test (pull_request) Failing after 6s
CI / container-scan (pull_request) Failing after 6s
CI / sonar-analysis (pull_request) Failing after 2s
CI / workflow-summary (pull_request) Successful in 4s
Document pve10 static IPs, monitoring stack, and site LXCs; add portfolio to inventory; Mailcow mailbox automation; vault import/export scripts; security audit guides and UniFi DHCP reference. Co-authored-by: Cursor <cursoragent@cursor.com>
97 lines
3.3 KiB
Bash
Executable File
97 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Merge .env into inventories/production/group_vars/all/vault.yml
|
|
# Usage: make vault-import-env [ENV_FILE=.env]
|
|
set -euo pipefail
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
ENV_FILE="${1:-${ENV_FILE:-${REPO_ROOT}/.env}}"
|
|
VAULT_FILE="${REPO_ROOT}/inventories/production/group_vars/all/vault.yml"
|
|
VAULT_PASS="${HOME}/.ansible-vault-pass"
|
|
ANSIBLE_VAULT="${REPO_ROOT}/.venv/bin/ansible-vault"
|
|
|
|
[[ -f "${ENV_FILE}" ]] || { echo "No env file: ${ENV_FILE}" >&2; exit 1; }
|
|
[[ -f "${VAULT_PASS}" ]] || { echo "Missing ${VAULT_PASS}" >&2; exit 1; }
|
|
|
|
"${REPO_ROOT}/.venv/bin/python3" - "${ENV_FILE}" "${VAULT_FILE}" "${VAULT_PASS}" "${ANSIBLE_VAULT}" <<'PY'
|
|
import os, re, subprocess, sys, tempfile, yaml
|
|
|
|
env_file, vault_file, vault_pass, ansible_vault = sys.argv[1:5]
|
|
|
|
def load_env(path):
|
|
out = {}
|
|
with open(path) as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if not line or line.startswith("#"):
|
|
continue
|
|
if line.startswith("export "):
|
|
line = line[7:].strip()
|
|
if "=" not in line:
|
|
continue
|
|
k, _, v = line.partition("=")
|
|
v = v.strip().strip("'").strip('"')
|
|
if v:
|
|
out[k.strip()] = v
|
|
return out
|
|
|
|
# .env key -> vault key (or vault_mailcow_mailbox_passwords.<name>)
|
|
MAP = {
|
|
"MAILCOW_API_KEY": "vault_mailcow_api_key",
|
|
"ALERTS_PASSWORD": ("vault_alerts_mailbox_password", "alerts"),
|
|
"KUMA_PASSWORD": "vault_uptime_kuma_password",
|
|
"KUMA_USER": "vault_uptime_kuma_user",
|
|
"KUMA_URL": "vault_uptime_kuma_url",
|
|
"UMAMI_ADMIN_PASSWORD": "vault_umami_admin_password",
|
|
"UMAMI_DB_PASS": "vault_umami_db_password",
|
|
"UMAMI_APP_SECRET": "vault_umami_app_secret",
|
|
"SMTP_HOST": "vault_kuma_smtp_host",
|
|
"SMTP_PORT": "vault_kuma_smtp_port",
|
|
"SMTP_USER": "vault_kuma_smtp_user",
|
|
"SMTP_PASS": "vault_kuma_smtp_password",
|
|
"SMTP_TO": "vault_kuma_smtp_to",
|
|
"MATTERMOST_URL": "vault_mattermost_url",
|
|
"MATTERMOST_TOKEN": "vault_mattermost_token",
|
|
"MATTERMOST_ALLOWED_USERS": "vault_mattermost_allowed_users",
|
|
"PROXMOX_PASSWORD": "vault_proxmox_password",
|
|
"LXC_ROOT_PASSWORD": "vault_lxc_root_password",
|
|
}
|
|
|
|
env = load_env(env_file)
|
|
text = subprocess.check_output(
|
|
[ansible_vault, "view", vault_file, "--vault-password-file", vault_pass],
|
|
text=True,
|
|
)
|
|
data = yaml.safe_load(text) or {}
|
|
passwords = dict(data.get("vault_mailcow_mailbox_passwords") or {})
|
|
|
|
for k, v in env.items():
|
|
m = re.match(r"^MAILBOX_(.+)_PASSWORD$", k, re.I)
|
|
if m:
|
|
passwords[m.group(1).lower()] = v
|
|
continue
|
|
target = MAP.get(k)
|
|
if not target:
|
|
continue
|
|
if isinstance(target, tuple):
|
|
data[target[0]] = v
|
|
passwords[target[1]] = v
|
|
else:
|
|
data[target] = v
|
|
|
|
if passwords:
|
|
data["vault_mailcow_mailbox_passwords"] = passwords
|
|
|
|
fd, tmp = tempfile.mkstemp(suffix=".yml")
|
|
os.close(fd)
|
|
with open(tmp, "w") as f:
|
|
yaml.dump(data, f, default_flow_style=False, sort_keys=False, allow_unicode=True)
|
|
|
|
subprocess.run(
|
|
[ansible_vault, "encrypt", tmp, "--output", vault_file,
|
|
"--vault-password-file", vault_pass, "--encrypt-vault-id", "default"],
|
|
check=True,
|
|
)
|
|
os.remove(tmp)
|
|
print(f"Updated {vault_file} from {env_file} ({len(env)} values)")
|
|
PY
|