Загрузка данных
#!/usr/bin/env python3
import argparse
import base64
import os
from pathlib import Path
import hvac
from jinja2 import Environment, FileSystemLoader
def log(msg):
print(f"[ОК] {msg}")
# ============================================================
# 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")
return client
# ============================================================
# VAULT READ
# ============================================================
def read_secret(client, path):
response = client.secrets.kv.v2.read_secret_version(
mount_point=os.environ["VAULT_MOUNT"],
path=path,
raise_on_deleted_version=True
)
return response["data"]["data"]
# ============================================================
# WRITE HELPERS
# ============================================================
def write_text(path: Path, content: str):
path.parent.mkdir(parents=True, exist_ok=True)
if not content:
raise ValueError(f"Пустой текст: {path}")
path.write_text(content)
def write_binary(path: Path, content: bytes):
path.parent.mkdir(parents=True, exist_ok=True)
if not content:
raise ValueError(f"Пустой бинарный файл: {path}")
path.write_bytes(content)
# ============================================================
# RENDER TEMPLATE (исправленная версия)
# ============================================================
def render_template(root: Path, template_name: str, output_path: Path, **context):
"""Рендерит шаблон относительно папки templates в APP_PATH"""
templates_dir = root / "templates"
print(f"[DEBUG] Рендерим шаблон {template_name} из {templates_dir}")
if not templates_dir.exists():
raise RuntimeError(f"Папка templates не найдена по пути: {templates_dir}")
jinja = Environment(
loader=FileSystemLoader(str(templates_dir)),
autoescape=False
)
template = jinja.get_template(template_name)
rendered = template.render(**context)
write_text(output_path, rendered)
log(f"Шаблон {template_name} успешно сгенерирован")
# ============================================================
# KERBEROS
# ============================================================
def build_kerberos(root: Path, k5: dict):
keytab_b64 = k5.get("mailarchive.keytab")
if not keytab_b64:
raise RuntimeError("Нет keytab в Vault")
# ---------------- KEYTAB ----------------
write_binary(
root / "kerberos-ma" / "mailarchive.keytab",
base64.b64decode(keytab_b64)
)
log("Kerberos keytab сохранён")
# ---------------- ENTRYPOINT ----------------
principal = k5.get("KRB_PRINCIPAL")
if not principal:
raise RuntimeError("Нет KRB_PRINCIPAL в Vault")
render_template(
root,
"entrypoint.sh.j2",
root / "kerberos-ma" / "entrypoint.sh",
KRB_PRINCIPAL=principal
)
# ============================================================
# MAIN
# ============================================================
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--env", choices=["dev", "stage", "prod"], required=True)
args = parser.parse_args()
env = args.env
# ==================== DEBUG (можно потом убрать) ====================
print("=== DEBUG INFO ===")
print("cwd:", os.getcwd())
print("APP_PATH:", os.environ.get("APP_PATH"))
root = Path(os.environ["APP_PATH"])
print("root exists:", root.exists())
print("templates exists:", (root / "templates").exists())
# =================================================================
client = vault_login()
base = f"projects/mailarchive/{env}"
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")
root = Path(os.environ["APP_PATH"])
# ============================================================
# DJANGO
# ============================================================
write_text(
root / "django-ma/src/.env",
django.get(".env")
)
log("Django .env создан")
# ============================================================
# KERBEROS
# ============================================================
build_kerberos(root, k5)
# ============================================================
# DB
# ============================================================
write_text(
root / "django-ma/pg_service.conf",
db.get("pg_service.conf")
)
log("DB конфиг создан")
# ============================================================
# WEBSERVER
# ============================================================
wd = root
apache_ssl_dir = wd / "apache-ma/ssl"
apache_keytab_dir = wd / "apache-ma/keytab"
apache_conf_dir = wd / "apache-ma/conf/sites-enabled"
# ---------------- CERTS ----------------
if webserver.get("tls.crt"):
write_text(apache_ssl_dir / "tls.crt", webserver["tls.crt"])
if webserver.get("tls.key"):
write_text(apache_ssl_dir / "tls.key", webserver["tls.key"])
log("Apache TLS сертификаты сохранены")
# ---------------- KEYTAB ----------------
keytab = webserver.get("infradev.keytab")
if keytab:
write_binary(
apache_keytab_dir / "infradev.keytab",
base64.b64decode(keytab)
)
log("Apache keytab сохранён")
# ---------------- CONFIG ----------------
render_template(
root,
"mailarchive.conf.j2",
apache_conf_dir / "mailarchive.conf",
**webserver
)
# ============================================================
# DONE
# ============================================================
log(f"Секреты получены для окружения: {env}")
if __name__ == "__main__":
main()