Загрузка данных
#!/usr/bin/env python3
import argparse
import base64
import os
import hvac
from dotenv import load_dotenv
from pathlib import Path
from jinja2 import Environment, FileSystemLoader
from pathlib import Path
VAULT_MOUNT = "it-infradev"
def vault_login():
"""
LDAP login в Vault.
"""
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
def read_secret(client, path):
response = (
client.secrets.kv.v2.read_secret_version(
mount_point=VAULT_MOUNT,
path=path
)
)
return response["data"]["data"]
def write_text(path, content):
path.parent.mkdir(
parents=True,
exist_ok=True
)
with open(path, "w") as f:
f.write(content)
def write_binary(path, content):
path.parent.mkdir(
parents=True,
exist_ok=True
)
with open(path, "wb") as f:
f.write(content)
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}"
django = read_secret(
client,
f"{base}/django"
)
webserver = read_secret(
client,
f"{base}/webserver"
)
k5 = read_secret(
client,
f"{base}/k5-ma-client"
)
k5 = read_secret(
client,
f"{base}/db"
)
build_dir = Path("build")
####################################################################
# DJANGO
####################################################################
#
# Предполагается что в Vault лежит поле:
#
# env
#
write_text(
build_dir /
"django-ma/src" /
".env",
django["env"]
)
####################################################################
# K5 CLIENT
####################################################################
#
# Предполагается:
#
# principal
# keytab
#
write_text(
build_dir /
"kerberos-ma" /
"KRB_PRINCIPAL",
k5["mailarchive.keytab"]
)
write_binary(
build_dir /
"k5-ma-client" /
"mailarchive.keytab",
base64.b64decode(
k5["mailarchive.keytab"]
)
)
def prepare_webserver(repo_dir, webserver: dict):
"""
Webserver build assets:
Vault структура:
- ssl_cert (PEM text)
- ssl_key (PEM text)
- ssl_ca (PEM text, optional)
- ldap_keytab (base64)
- gssapi_keytab (base64, optional)
- все остальные поля = для vhost.j2
"""
build_dir = Path(repo_dir) / ".build" / "webserver"
build_dir.mkdir(parents=True, exist_ok=True)
####################################################################
# 1. CERTS
####################################################################
if webserver.get("tls.crt"):
(build_dir / "tls.crt").write_text(
webserver["tls.crt"]
)
if webserver.get("tls.key"):
(build_dir / "tls.key").write_text(
webserver["tls.key"]
)
if webserver.get("ssl_ca"):
(build_dir / "ca-bundle.pem").write_text(
webserver["ssl_ca"]
)
####################################################################
# 2. KEYTAB
####################################################################
if webserver.get("infradev.keytab"):
(build_dir / "infradev.keytab").write_bytes(
base64.b64decode(webserver["infradev.keytab"])
)
####################################################################
# 3. VHOST TEMPLATE RENDER
####################################################################
templates_dir = Path(repo_dir) / "templates"
env = Environment(
loader=FileSystemLoader(str(templates_dir)),
autoescape=False
)
template = env.get_template("vhost.conf.j2")
rendered = template.render(**webserver)
(build_dir / "vhost.conf").write_text(rendered)
####################################################################
# 4. DEBUG
####################################################################
print("\n[webserver] vault keys:")
for k in webserver.keys():
print(" -", k)
print(f"\n[webserver] build output: {build_dir}")
print()
print("Secrets downloaded successfully")
print(f"Environment: {env}")
print(f"Output dir: {build_dir.resolve()}")
if __name__ == "__main__":
main()