Загрузка данных
#!/usr/bin/env python3
import argparse
import base64
import os
import json
import hvac
from dotenv import load_dotenv
from pathlib import Path
from jinja2 import Environment, FileSystemLoader
VAULT_MOUNT = "it-infradev"
# ============================================================
# VAULT LOGIN
# ============================================================
def vault_login():
client = hvac.Client(
url=os.environ["VAULT_ADDR"]
)
login = client.auth.ldap.login(
username=os.environ["VAULT_USERNAME"],
password=os.environ["VAULT_PASSWORD"]
)
client.token = login["auth"]["client_token"]
if not client.is_authenticated():
raise RuntimeError("Vault authentication failed")
return client
# ============================================================
# VAULT READ (DEBUG VERSION)
# ============================================================
def read_secret(client, path):
response = client.secrets.kv.v2.read_secret_version(
mount_point=VAULT_MOUNT,
path=path
)
data = response["data"]["data"]
print("\n==============================")
print(f"[VAULT PATH] {path}")
print("KEYS:", list(data.keys()))
for k, v in data.items():
if isinstance(v, str):
print(f" - {k}: str(len={len(v)}) preview={v[:80]}")
else:
print(f" - {k}: {type(v)} value={v}")
print("==============================\n")
return data
# ============================================================
# WRITE HELPERS
# ============================================================
def write_text(path, content):
path.parent.mkdir(parents=True, exist_ok=True)
if content is None:
raise ValueError(f"Trying to write None to {path}")
with open(path, "w") as f:
f.write(content)
def write_binary(path, content):
path.parent.mkdir(parents=True, exist_ok=True)
if content is None:
raise ValueError(f"Trying to write None to {path}")
with open(path, "wb") as f:
f.write(content)
# ============================================================
# MAIN
# ============================================================
def main():
load_dotenv()
parser = argparse.ArgumentParser()
parser.add_argument("--env", choices=["dev", "stage", "prod"], required=True)
args = parser.parse_args()
env = args.env
client = vault_login()
base = f"projects/mailarchive/{env}"
# ============================================================
# READ SECRETS
# ============================================================
django = read_secret(client, f"{base}/django")
webserver = read_secret(client, f"{base}/webserver")
k5 = read_secret(client, f"{base}/k5-ma-client")
db = read_secret(client, f"{base}/db")
# ============================================================
# BUILD DIR
# ============================================================
build_dir = Path("build")
# ============================================================
# DJANGO
# ============================================================
django_env = django.get(".env")
print("[DJANGO] using key: .env")
print("[DJANGO] value exists:", django_env is not None)
if not django_env:
raise RuntimeError(f"Django missing .env, keys={list(django.keys())}")
write_text(
build_dir / "django-ma/src" / ".env",
django_env
)
# ============================================================
# KERBEROS
# ============================================================
print("\n[K5 DEBUG]")
print("keys:", k5.keys())
principal = k5.get("KRB_PRINCIPAL")
keytab_b64 = k5.get("keytab") or k5.get("mailarchive.keytab")
if not principal:
raise RuntimeError("Missing principal in k5")
if not keytab_b64:
raise RuntimeError("Missing keytab in k5")
write_text(
build_dir / "k5-ma-client" / "KRB_PRINCIPAL",
principal
)
write_binary(
build_dir / "k5-ma-client" / "mailarchive.keytab",
base64.b64decode(keytab_b64)
)
# ============================================================
# WEBSERVER
# ============================================================
prepare_webserver(build_dir, webserver)
print("\nDONE")
print(f"Output: {build_dir.resolve()}")
# ============================================================
# WEBSERVER
# ============================================================
def prepare_webserver(build_dir, webserver):
wd = build_dir / "webserver"
wd.mkdir(parents=True, exist_ok=True)
print("\n[WEBSERVER DEBUG]")
print("keys:", list(webserver.keys()))
# certs
if "tls.crt" in webserver:
write_text(wd / "tls.crt", webserver["tls.crt"])
if "tls.key" in webserver:
write_text(wd / "tls.key", webserver["tls.key"])
# keytab
keytab = webserver.get("infradev.keytab")
if keytab:
write_binary(
wd / "infradev.keytab",
base64.b64decode(keytab)
)
# template render
templates_dir = Path("apache-ma/conf/sites-enabled")
env = Environment(
loader=FileSystemLoader(str(templates_dir)),
autoescape=False
)
template = env.get_template("mailarchive.conf.j2")
rendered = template.render(**webserver)
write_text(wd / "mailarchive.conf", rendered)
if __name__ == "__main__":
main()