This repository has been archived on 2020-06-17. You can view files and clone it, but cannot push or open issues or pull requests.
autonomic/autonomic/command/coophost.py

137 lines
3.5 KiB
Python
Raw Normal View History

"""CoopHost module."""
from os import chdir, mkdir
from os.path import basename, exists
from pathlib import Path
2020-04-13 15:40:07 +00:00
from socket import gethostname
import click
from autonomic.config import CONFIG_YAML, INFRA_DIR
from autonomic.logger import log
from autonomic.settings import add, get
from autonomic.utils import (
ensure_config_dir,
ensure_deploy_d_dir,
2020-04-13 15:40:07 +00:00
exit,
input_ask,
pass_ask,
question_ask,
run,
yaml_dump,
yaml_load,
)
2020-04-13 15:40:07 +00:00
hostname = gethostname()
@click.command()
@click.pass_context
def coophost(ctx):
"""Manage CoopHost resources."""
ensure_config_dir()
2020-04-13 15:40:07 +00:00
ensure_deploy_d_dir()
app_dir = Path(".").absolute()
app = basename(app_dir)
log.info("Auto-detected the {} application".format(app))
2020-04-13 15:40:07 +00:00
choices = ["encrypt", "decrypt"]
operation = question_ask("operation", "Which operation?", choices)
if operation == "encrypt":
2020-04-13 15:40:07 +00:00
encrypt(app, app_dir)
elif operation == "decrypt":
decrypt(app, app_dir)
2020-04-13 15:40:07 +00:00
def get_vault_pass(app):
"""Retrieve or set the app vault password."""
app_settings = get(app)
2020-04-13 15:40:07 +00:00
if app_settings is not None and "vault-password" in app_settings:
log.info("Using app vault password stored in {}".format(CONFIG_YAML))
2020-04-13 15:40:07 +00:00
return app_settings["vault-password"]
log.info("No app vault password configured")
vault_password = pass_ask("Vault password?")
log.info("App vault password stored in {}".format(CONFIG_YAML))
add({app: {"vault-password": vault_password}})
return vault_password
def decrypt(app, app_dir):
"""Decrypt a secret."""
vault_password = get_vault_pass(app)
name = input_ask("Which variable do you want to decrypt?")
2020-04-13 15:40:07 +00:00
vault_path = (Path(".") / "deploy.d" / "vault").absolute()
var_path = (vault_path / "{}.yml".format(name)).absolute()
2020-04-13 15:40:07 +00:00
if not exists(var_path):
exit("{}.yml is missing?".format(name))
cmd = [
".venv/bin/ansible",
hostname,
"--inventory",
"{},".format(hostname),
"-m",
"debug",
"-a",
"var='{}'".format(name),
"-e @{}".format(var_path),
"--ask-vault-pass",
"-e",
"ansible_user={}".format(get("username")),
]
decrypted = run(
cmd,
cwd=INFRA_DIR,
output=True,
pexpect=True,
pexpected={"(?i)vault password:": vault_password},
)
log.info(decrypted)
def encrypt(app, app_dir):
"""Encrypt a secret for a CoopHost package."""
vault_password = get_vault_pass(app)
name = input_ask("Which variable do you want to encrypt?")
value = pass_ask("Variable value to encrypt?")
cmd = [".venv/bin/ansible-vault", "encrypt_string", "--name", name, value]
encrypted = run(
cmd,
cwd=INFRA_DIR,
pexpect=True,
pexpected={
"(?i)new vault password:": vault_password,
"(?i)confirm new vault password:": vault_password,
},
)
encrypted = (
encrypted.strip()
.replace("\r", "")
.replace("\nEncryption successful", "")
)
chdir(app_dir)
2020-04-12 13:52:05 +00:00
log.info("Changed directory back to {}".format(app_dir))
vault_path = (Path(".") / "deploy.d" / "vault").absolute()
if not exists(vault_path):
log.info("Creating {}".format(vault_path))
mkdir(vault_path)
var_path = (vault_path / "{}.yml".format(name)).absolute()
with open(var_path, "w"):
loaded = yaml_load(encrypted, text=True)
yaml_dump(var_path, loaded)
log.success("Encrypted and saved {} in {}".format(name, var_path))