From 6c19775b1c9aca173590cc8ff444c5e6fbd1be1f Mon Sep 17 00:00:00 2001 From: Luke Murphy Date: Thu, 2 Jul 2020 13:41:31 +0200 Subject: [PATCH] Nearly at the deployment then --- second.py | 61 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/second.py b/second.py index d9f38ba..c6495aa 100644 --- a/second.py +++ b/second.py @@ -1,5 +1,6 @@ """Less flashy version. More hard-coding.""" +from hashlib import md5 from json import dumps, loads from os import environ from os.path import exists @@ -21,7 +22,19 @@ app.secret_key = b'_5#y2L"F4Q8z\n\xec]/' yaml = YAML() -APPS = {"gitea": "https://git.autonomic.zone/compose-stacks/gitea"} +APPS_SPEC = { + "gitea": { + "url": "https://git.autonomic.zone/compose-stacks/gitea", + "secrets": [ + "db_passwd", + "db_root_passwd", + "internal_token", + "jwt_secret", + "secret_key", + ], + "configs": ["app_ini"], + } +} DATA_DIR = Path("./data") @@ -33,7 +46,7 @@ def get_secret(n: int) -> str: def clone_app_template(app_name: str) -> None: """Git clone an app template repository.""" clone_path = DATA_DIR / app_name - clone_url = APPS[app_name] + clone_url = APPS_SPEC[app_name]["url"] run(split(f"git clone {clone_url} {clone_path}")) @@ -52,6 +65,33 @@ def load_db() -> Dict: return {} +def get_hash(value: str) -> str: + """Hash a value for swarm versioning with good 'ol md5.""" + hasher = md5() + hasher.update(value.encode()) + return hasher.hexdigest() + + +def get_secret_names(app_name, form_data, env): + """Generate versioned names for secrets that swarm will accept""" + for secret in APPS_SPEC[app_name]["secrets"]: + if secret in form_data: + hashed = get_hash(form_data[secret]) + env_key = f"{secret.upper()}_SECRET_VERSION" + env[env_key] = f"{secret}_{hashed}" + return env + + +def get_config_names(app_name, form_data, env): + """Generate versioned names for configs that swarm will accept""" + for config in APPS_SPEC[app_name]["configs"]: + if config in form_data: + hashed = get_hash(form_data[config]) + env_key = f"{config.upper()}_CONFIG_VERSION" + env[env_key] = f"{secret}_{hashed}" + return env + + def stack_deploy(app_name, env): """Depoy an application to the swarm.""" compose_yml = DATA_DIR / app_name / "compose.yml" @@ -90,7 +130,7 @@ class GiteaInstallForm(FlaskForm): "JWT secret", validators=[DataRequired(), Length(min=43)], ) secret_key = PasswordField( - "Secret key", validators=[DataRequired(), Length(min=64),], + "Secret key", validators=[DataRequired(), Length(min=64)], ) ssh_port = StringField("SSH port", default="2222") @@ -98,7 +138,7 @@ class GiteaInstallForm(FlaskForm): @app.route("/") def index(): """Home page for app installation possibilities.""" - return render_template("second/index.html", apps=[app for app in APPS]) + return render_template("second/index.html", apps=[app for app in APPS_SPEC]) @app.route("/install/") @@ -118,14 +158,15 @@ def deploy(app_name): if not form.validate(): return render_template("second/install.html", app_name=app_name, form=form) - environment = get_loaded_env(app_name, request.form) + env = get_loaded_env(app_name, form.data) + env = get_secret_names(app_name, form.data, env) + env = get_config_names(app_name, form.data, env) - # Note(decentral1se): how to handle the following? - # configs -> ${STACK_NAME}_app_ini_${APP_INI_VERSION} - # secrets -> ${STACK_NAME}_db_passwd_${DB_PASSWD_VERSION} - # and dump it all to the db.json when we're done here too + app.logger.info(f"env -> {env}") - stack_deploy(app_name, environment) + dump_db({app_name: form.data}) + + stack_deploy(app_name, env) if __name__ == "__main__":