From 9520868cc35914322edde441f8e3ead5e6ed69e7 Mon Sep 17 00:00:00 2001 From: Luke Murphy Date: Mon, 13 Apr 2020 17:40:07 +0200 Subject: [PATCH] Add first stab at decrypt command --- CHANGELOG.rst | 9 ++++ autonomic/command/coophost.py | 84 +++++++++++++++++++++++++++-------- 2 files changed, 75 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6b76bfd..d060c6c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,12 @@ +Autonomic 0.0.5 (2020-04-13) +============================ + +Features +-------- + +- Add CoopHost decrypt command. (#5) + + Autonomic 0.0.4 (2020-04-12) ============================ diff --git a/autonomic/command/coophost.py b/autonomic/command/coophost.py index 81f8a01..402e85f 100644 --- a/autonomic/command/coophost.py +++ b/autonomic/command/coophost.py @@ -3,6 +3,7 @@ from os import chdir, mkdir from os.path import basename, exists from pathlib import Path +from socket import gethostname import click @@ -12,6 +13,7 @@ from autonomic.settings import add, get from autonomic.utils import ( ensure_config_dir, ensure_deploy_d_dir, + exit, input_ask, pass_ask, question_ask, @@ -20,40 +22,86 @@ from autonomic.utils import ( yaml_load, ) +hostname = gethostname() + @click.command() @click.pass_context def coophost(ctx): """Manage CoopHost resources.""" ensure_config_dir() - - choices = ["encrypt"] - operation = question_ask("operation", "Which operation?", choices) - - if operation == "encrypt": - encrypt() - - -def encrypt(): - """Encrypt a secret for a CoopHost package.""" ensure_deploy_d_dir() app_dir = Path(".").absolute() - - app = basename(Path(".").absolute()) + app = basename(app_dir) log.info("Auto-detected the {} application".format(app)) + choices = ["encrypt", "decrypt"] + operation = question_ask("operation", "Which operation?", choices) + + if operation == "encrypt": + encrypt(app, app_dir) + elif operation == "decrypt": + decrypt(app, app_dir) + + +def get_vault_pass(app): + """Retrieve or set the app vault password.""" app_settings = get(app) + if app_settings is not None and "vault-password" in app_settings: log.info("Using app vault password stored in {}".format(CONFIG_YAML)) - vault_password = app_settings["vault-password"] - else: - log.info("No app vault password configured") - vault_password = pass_ask("Vault password?") + return app_settings["vault-password"] - log.info("App vault password stored in {}".format(CONFIG_YAML)) - add({app: {"vault-password": 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?") + + vault_path = (Path(".") / "deploy.d" / "vault").absolute() + var_path = (vault_path / "{}.yml".format(name)).absolute() + + 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?")