Загрузка данных
#!/usr/bin/env python3
import argparse
import base64
import os
import re
import tomllib
from pathlib import Path
import hvac
from jinja2 import Environment, FileSystemLoader
# ============================================================
# PATH
# ============================================================
APP_PATH = os.environ.get("APP_PATH")
if not APP_PATH:
raise RuntimeError("APP_PATH не задан")
ROOT = Path(APP_PATH).resolve()
PYPROJECT = ROOT / "django-ma/src/pyproject.toml"
TEMPLATES_DIR = ROOT / "templates"
# ============================================================
# LOG
# ============================================================
def log(msg: str):
print(f"[ОК] {msg}")
# ============================================================
# VAULT
# ============================================================
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 auth failed")
return client
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"]
# ============================================================
# VERSIONING
# ============================================================
branch = (
os.getenv("BUILD_SOURCEBRANCHNAME")
or os.getenv("BRANCH")
or "dev"
).lower()
branch = branch.replace("refs/heads/", "")
print(f"Текущая ветка: {branch}")
data = tomllib.loads(PYPROJECT.read_text(encoding="utf-8"))
current_version = data["project"]["version"]
# убираем PEP440 суффиксы
base_version = re.sub(
r"(a\d*|b\d*|rc\d*)$",
"",
current_version
)
major, minor, patch = map(int, base_version.split("."))
patch += 1
suffix_map = {
"dev": "a1",
"test": "b1",
"stage": "rc1",
"prod": "",
}
suffix = suffix_map.get(branch, "a1")
if suffix:
new_version = f"{major}.{minor}.{patch}{suffix}"
else:
new_version = f"{major}.{minor}.{patch}"
text = PYPROJECT.read_text(encoding="utf-8")
text = re.sub(
r'version\s*=\s*"[^"]+"',
f'version = "{new_version}"',
text,
count=1
)
PYPROJECT.write_text(text, encoding="utf-8")
print(f"[ОК] Версия обновлена: {current_version} → {new_version}")
# ============================================================
# JINJA
# ============================================================
def write_text(path: Path, content: str):
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(content, encoding="utf-8")
def render_template(root: Path, template_name: str, output_path: Path, **context):
templates_dir = root / "templates"
if not templates_dir.exists():
raise RuntimeError(f"templates not found: {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} rendered")
# ============================================================
# KERBEROS
# ============================================================
def build_kerberos(root: Path, k5: dict):
keytab_b64 = k5.get("mailarchive.keytab")
if not keytab_b64:
raise RuntimeError("No keytab in Vault")
keytab_path = root / "kerberos-ma" / "mailarchive.keytab"
keytab_path.parent.mkdir(parents=True, exist_ok=True)
keytab_path.write_bytes(base64.b64decode(keytab_b64))
log("Kerberos keytab saved")
principal = k5.get("KRB_PRINCIPAL")
if not principal:
raise RuntimeError("No KRB_PRINCIPAL")
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
print("=== DEBUG ===")
print("APP_PATH:", APP_PATH)
print("ROOT:", ROOT)
client = vault_login()
base = f"projects/mailarchive/{env}"
secrets = read_secret(client, base)
build_kerberos(ROOT, secrets)
print("=== DONE ===")
if __name__ == "__main__":
main()