Загрузка данных
#!/usr/bin/env python3
"""
Получение секретов MailArchive из Vault.
Запуск:
python vault_sync.py --env dev
Подготовить .env:
VAULT_ADDR=https://vault.company.ru
VAULT_USERNAME=svc_mailarchive_builder
VAULT_PASSWORD=super_secret_password
"""
import argparse
import base64
import os
from pathlib import Path
import hvac
from dotenv import load_dotenv
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"
)
#
# Итоговая структура:
#
# build/
# ├── django
# ├── webserver
# └── k5-ma-client
#
build_dir = Path("build")
####################################################################
# DJANGO
####################################################################
#
# Предполагается что в Vault лежит поле:
#
# env
#
write_text(
build_dir /
"django" /
".env",
django["env"]
)
####################################################################
# K5 CLIENT
####################################################################
#
# Предполагается:
#
# principal
# keytab
#
write_text(
build_dir /
"k5-ma-client" /
"principal",
k5["principal"]
)
write_binary(
build_dir /
"k5-ma-client" /
"service.keytab",
base64.b64decode(
k5["keytab"]
)
)
####################################################################
# WEBSERVER
####################################################################
#
# НАЗВАНИЯ ПОЛЕЙ ПРИДЁТСЯ
# ПОДОГНАТЬ ПОД ТВОЙ VAULT
#
write_text(
build_dir /
"webserver" /
"server.crt",
webserver["ssl_cert"]
)
write_text(
build_dir /
"webserver" /
"server.key",
webserver["ssl_key"]
)
write_binary(
build_dir /
"webserver" /
"ldap.keytab",
base64.b64decode(
webserver["ldap_keytab"]
)
)
#
# Тут пока просто пример.
#
# Я бы потом заменил на Jinja2.
#
vhost = f"""
<VirtualHost *:443>
ServerName {webserver['server_name']}
SSLEngine on
SSLCertificateFile /etc/httpd/ssl/server.crt
SSLCertificateKeyFile /etc/httpd/ssl/server.key
</VirtualHost>
"""
write_text(
build_dir /
"webserver" /
"vhost.conf",
vhost
)
print()
print("Secrets downloaded successfully")
print(f"Environment: {env}")
print(f"Output dir: {build_dir.resolve()}")
if __name__ == "__main__":
main()