#!/usr/bin/env bash # Pull secrets from live hosts into .env, then vault-import-env. # Does not print secret values. set -euo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" ENV_FILE="${REPO_ROOT}/.env" python3 - "${ENV_FILE}" <<'PY' import subprocess, sys from pathlib import Path out = Path(sys.argv[1]) lines = [] def sh(cmd): return subprocess.check_output(cmd, shell=True, text=True).strip() def parse_env(text): d = {} for line in text.splitlines(): line = line.strip() if not line or line.startswith("#") or "=" not in line: continue k, _, v = line.partition("=") d[k.strip()] = v.strip().strip("'").strip('"') return d # monitoring LXC try: raw = sh("ssh -o BatchMode=yes -o ConnectTimeout=8 root@10.0.10.22 'cat /opt/monitoring/.env 2>/dev/null'") m = parse_env(raw) if m.get("UMAMI_DB_PASS"): lines.append(f"UMAMI_DB_PASS={m['UMAMI_DB_PASS']}") if m.get("UMAMI_APP_SECRET"): lines.append(f"UMAMI_APP_SECRET={m['UMAMI_APP_SECRET']}") except Exception as e: print(f"# skip monitoring: {e}", file=sys.stderr) # hermes mattermost try: raw = sh("ssh -o BatchMode=yes -o ConnectTimeout=8 ladmin@10.0.10.36 \"sudo cat /home/hermes/.hermes/secrets/mattermost.env 2>/dev/null\"") h = parse_env(raw) for k in ("MATTERMOST_URL", "MATTERMOST_TOKEN", "MATTERMOST_ALLOWED_USERS"): if h.get(k): lines.append(f"{k}={h[k]}") except Exception as e: print(f"# skip hermes: {e}", file=sys.stderr) # merge with existing .env (preserve user-filled keys) existing = {} if out.exists(): existing = parse_env(out.read_text()) merged = {**existing} for line in lines: k, _, v = line.partition("=") merged[k] = v header = """# Auto-merged by scripts/vault-pull-infra-secrets.sh + your edits # Run: make vault-import-env """ body = "\n".join(f"{k}={v}" for k, v in sorted(merged.items())) + "\n" out.write_text(header + body) print(f"Wrote {len(merged)} keys to {out}") PY chmod 600 "${ENV_FILE}" 2>/dev/null || true "${REPO_ROOT}/scripts/vault-import-env.sh" "${ENV_FILE}"