From 3849eeccf062b253a2da277330f240a9afa83fdf Mon Sep 17 00:00:00 2001 From: Moritz Date: Mon, 15 Jul 2024 17:27:51 +0200 Subject: [PATCH] refactor CLI: rename --apps to --recipe --- alakazam.py | 201 ++++++++++++++++++---------------------------------- 1 file changed, 70 insertions(+), 131 deletions(-) diff --git a/alakazam.py b/alakazam.py index b7139ea..abac8da 100755 --- a/alakazam.py +++ b/alakazam.py @@ -789,35 +789,29 @@ def cli(loglevel: str, group_path: str, exclude:Tuple[str]) -> None: @cli.command() -@click.option('-a', '--apps', multiple=True) -def show_config(apps: Tuple[str]) -> None: +@click.option('recipes', '-r', '--recipe', multiple=True, metavar='', help='Filter for selcted recipes, this option can be specified multiple times.') +def show_config(recipes: Tuple[str]) -> None: """ Show the merged instance configurations. - - Args: - apps (list): A list of application names for which the instance configurations should be shown. """ filtered_configs = INSTANCE_CONFIGS - if apps: - filtered_configs = {server: {app: app_config for app, app_config in app_configs.items() if app in apps} + if recipes: + filtered_configs = {server: {recipe_name: app_config for recipe_name, app_config in app_configs.items() if recipe_name in recipes} for server, app_configs in INSTANCE_CONFIGS.items()} print(json.dumps(filtered_configs, indent=2)) @cli.command() -@click.option('-a', '--apps', multiple=True) -def config(apps: Tuple[str]) -> None: +@click.option('recipes', '-r', '--recipe', multiple=True, metavar='', help='Filter for selcted recipes, this option can be specified multiple times.') +def config(recipes: Tuple[str]) -> None: """ Generates and updates .env configuration files for a specified list of applications. This function reads the necessary configurations from the global settings and applies these to create or update .env files for each app. - - Args: - apps (list): A list of application names for which .env files need to be generated or updated. """ for instance, instance_config in INSTANCE_CONFIGS.items(): - if apps: + if recipes: selected_apps = [] - for app in apps: + for app in recipes: if app in instance_config.keys(): selected_apps.append(app) else: @@ -839,19 +833,16 @@ def config(apps: Tuple[str]) -> None: @cli.command() -@click.option('-a', '--apps', multiple=True) -def secrets(apps: Tuple[str]) -> None: +@click.option('recipes', '-r', '--recipe', multiple=True, metavar='', help='Filter for selcted recipes, this option can be specified multiple times.') +def secrets(recipes: Tuple[str]) -> None: """ Generates and inserts secrets for specified apps. This function handles the generation of new secrets, the syncronisation of shared secrets and the insertion of existing secrets from the configuration into the appropriate locations for each application. - - Args: - apps (list): A list of application names for which secrets are to be generated and managed. """ for _, instance_config in INSTANCE_CONFIGS.items(): instance_apps = instance_config.keys() - if apps: - selected_apps = [app for app in apps if app in instance_config.keys()] + if recipes: + selected_apps = [app for app in recipes if app in instance_config.keys()] else: selected_apps = instance_config.keys() for app in selected_apps: @@ -893,27 +884,18 @@ def get_deployed_apps(apps: Tuple[str]) -> Dict[str, str]: @cli.command() -@click.option('-a', '--apps', multiple=True) -@click.option('-r', '--run-cmds', is_flag=True) -@click.option('-f', '--force', is_flag=True) -@click.option('-c', '--converge-checks', is_flag=True) -def deploy(apps: Tuple[str], run_cmds: bool, force: bool, converge_checks: bool) -> None: +@click.option('recipes', '-r', '--recipe', multiple=True, metavar='', help='Filter for selcted recipes, this option can be specified multiple times.') +@click.option('-e', '--execute-cmds', is_flag=True, help='run post-deployment commands.') +@click.option('-f', '--force', is_flag=True, help='force redeployment even if the application is already deployed.') +@click.option('-c', '--converge-checks', is_flag=True, help='perform convergence checks during deployment.') +def deploy(recipes: Tuple[str], execute_cmds: bool, force: bool, converge_checks: bool) -> None: """ Deploys applications as specified in the configuration. - - Args: - apps (list): A list of application names to be deployed. - run_cmds (bool): Flag to indicate whether to run post-deployment commands. - force (bool): Flag to force redeployment even if the application is already deployed. - converge_checks (bool): Flag to perform convergence checks during deployment. - - Returns: - None """ if force: - instance_apps = get_apps(apps) + instance_apps = get_apps(recipes) else: - instance_apps = get_apps_by_deployment(apps, deployed=False) + instance_apps = get_apps_by_deployment(recipes, deployed=False) print_all_apps(instance_apps) if not instance_apps or input(f"Do you really want to deploy these apps? Type YES: ") != "YES": return @@ -928,36 +910,28 @@ def deploy(apps: Tuple[str], run_cmds: bool, force: bool, converge_checks: bool) cmd.append("--chaos") if force: cmd.append("--force") - if not run_cmds and not converge_checks: + if not execute_cmds and not converge_checks: cmd.append("--no-converge-checks") cmd.append(domain) if version not in ['latest', 'chaos']: cmd.append(version) print(f'deploy {domain} with version "{version}"') print(abra("app", *cmd)) - if run_cmds: + if execute_cmds: logging.info(f'execute commands for {domain}') execute_cmds(app_config, deploy=True) @cli.command() -@click.option('-a', '--apps', multiple=True) -@click.option('-r', '--run-cmds', is_flag=True) -@click.option('-d', '--dry-run', is_flag=True) -def upgrade(apps: Tuple[str], run_cmds: bool, dry_run: bool) -> None: +@click.option('recipes', '-r', '--recipe', multiple=True, metavar='', help='Filter for selcted recipes, this option can be specified multiple times.') +@click.option('-e', '--execute-cmds', is_flag=True, help='run post-upgrade commands.') +@click.option('-d', '--dry-run', is_flag=True, help="don't execute the upgrade process") +def upgrade(recipes: Tuple[str], execute_cmds: bool, dry_run: bool) -> None: """ Upgrades specified applications by executing the upgrade commands via the 'abra' command-line interface. It checks the current deployment status of the apps and performs upgrades only where necessary, with options to execute additional commands or perform a dry run. It either took the target version from the configuration or it uses the latest available version. - - Args: - apps (list): List of apps to upgrade. - run_cmds (bool): If True, post-upgrade commands are executed. - dry_run (bool): If True, the upgrade process is simulated without making any changes. - - Returns: - None: Outputs the results of the upgrade process to the console. """ - deployed_instance_apps = get_apps_by_deployment(apps, deployed=True) + deployed_instance_apps = get_apps_by_deployment(recipes, deployed=True) upgrade_cmds = [] release_notes = {} for instance, deployed_apps in deployed_instance_apps.items(): @@ -971,7 +945,7 @@ def upgrade(apps: Tuple[str], run_cmds: bool, dry_run: bool) -> None: cmd = ["upgrade", "-n"] if upgrade_version == 'chaos': cmd.append("--chaos") - if not run_cmds: + if not execute_cmds: cmd.append("--no-converge-checks") cmd.append(domain) if deployed_version == 'unknown': @@ -1000,28 +974,25 @@ def upgrade(apps: Tuple[str], run_cmds: bool, dry_run: bool) -> None: if not dry_run and input(f"Do you really want to upgrade these apps? Type YES: ") == "YES": for app_config, cmd in upgrade_cmds: print(abra("app", *cmd)) - if run_cmds: + if execute_cmds: logging.info(f'execute commands for {app_config.get("subdomain")}') execute_cmds(app_config, upgrade=True) @cli.command() -@click.option('-a', '--apps', multiple=True) -def undeploy(apps: Tuple[str]) -> None: +@click.option('recipes', '-r', '--recipe', multiple=True, metavar='', help='Filter for selcted recipes, this option can be specified multiple times.') +def undeploy(recipes: Tuple[str]) -> None: """ Undeploys multiple applications at once. - - Args: - apps (list): List of apps to undeploy. """ - instance_apps = get_apps(apps) + instance_apps = get_apps(recipes) print_all_apps(instance_apps) if input(f"Do you really want to undeploy these apps? Type YES: ") != "YES": return - deployed_domains = get_deployed_apps(apps) + deployed_domains = get_deployed_apps(recipes) for _, instance_config in INSTANCE_CONFIGS.items(): - if apps: - selected_apps = [app for app in apps if app in instance_config.keys()] + if recipes: + selected_apps = [app for app in recipes if app in instance_config.keys()] else: selected_apps = instance_config.keys() for app in selected_apps: @@ -1035,20 +1006,20 @@ def undeploy(apps: Tuple[str]) -> None: @cli.command() -@click.option('-a', '--apps', metavar='', multiple=True, help='The applications, which post-deployment commands should be executed.') +@click.option('recipes', '-r', '--recipe', multiple=True, metavar='', help='Filter for selcted recipes, this option can be specified multiple times.') @click.option('commands', '-c', '--command', multiple=True, metavar="' '", help='commands that should be executed') @click.option('-i', '--initial', is_flag=True, help='execute initial-hooks from config') @click.option('-d', '--deploy', is_flag=True, help='execute deploy-hooks from config') @click.option('-u', '--upgrade', is_flag=True, help='execute upgrade-hooks from config') @click.option('-l', '--list-cmds', is_flag=True, help="only show cmds, don't execute them") -def cmd(apps: Tuple[str], commands: Tuple[str], initial: bool, deploy: bool, upgrade: bool, list_cmds: bool = False) -> None: +def cmd(recipes: Tuple[str], commands: Tuple[str], initial: bool, deploy: bool, upgrade: bool, list_cmds: bool = False) -> None: """ Execute commands for all specified applications based on the provided configuration. """ - deployed_domains = get_deployed_apps(apps) + deployed_domains = get_deployed_apps(recipes) for _, instance_config in INSTANCE_CONFIGS.items(): - if apps: - selected_apps = [app for app in apps if app in instance_config.keys()] + if recipes: + selected_apps = [app for app in recipes if app in instance_config.keys()] else: selected_apps = instance_config.keys() for app in selected_apps: @@ -1062,19 +1033,13 @@ def cmd(apps: Tuple[str], commands: Tuple[str], initial: bool, deploy: bool, upg @cli.command() -@click.option('-a', '--apps', multiple=True) -def purge(apps: Tuple[str]) -> None: +@click.option('recipes', '-r', '--recipe', multiple=True, metavar='', help='Filter for selcted recipes, this option can be specified multiple times.') +def purge(recipes: Tuple[str]) -> None: """ Completely removes applications and their configurations. This function is used to clean up all traces of an application from the server. - - Args: - apps (list): A list of application names to be purged. - - Returns: - None """ # TODO: check for deployed apps - instance_apps = get_apps(apps) + instance_apps = get_apps(recipes) print_all_apps(instance_apps) domains = list(zip(*sum(instance_apps.values(), [])))[1] if input(f"Do you really want to purge these apps? Type YES: ") == "YES": @@ -1085,26 +1050,20 @@ def purge(apps: Tuple[str]) -> None: @cli.command() -@click.option('-a', '--apps', multiple=True) -@click.option('-d', '--deployed', is_flag=True) -@click.option('-u', '--undeployed', is_flag=True) -@click.option('--domains', is_flag=True) -def ls(apps: Tuple[str], deployed: bool, undeployed: bool, domains: bool) -> None: +@click.option('recipes', '-r', '--recipe', multiple=True, metavar='', help='Filter for selcted recipes, this option can be specified multiple times.') +@click.option('-d', '--deployed', is_flag=True, help='show only deployed apps.') +@click.option('-u', '--undeployed', is_flag=True, help='show only undeployed apps.') +@click.option('--domains', is_flag=True, help='list only domains.') +def ls(recipes: Tuple[str], deployed: bool, undeployed: bool, domains: bool) -> None: """ Lists all selected applications along with their domains. - - Args: - apps (list): List of applications to list. - deployed (bool): Show only deployed apps. - undeployed (bool): Show only undeployed apps. - undeployed (bool): List only domains. """ if deployed: - instance_apps = get_apps_by_deployment(apps, deployed=True) + instance_apps = get_apps_by_deployment(recipes, deployed=True) elif undeployed: - instance_apps = get_apps_by_deployment(apps, deployed=False) + instance_apps = get_apps_by_deployment(recipes, deployed=False) else: - instance_apps = get_apps(apps) + instance_apps = get_apps(recipes) if domains: print(list(zip(*sum(instance_apps.values(), [])))[1]) else: @@ -1213,18 +1172,14 @@ def get_latest_version(app: str) -> str: return latest @cli.command() -@click.option('-a', '--apps', multiple=True) -@click.option('-s', '--secret', multiple=False) -def purge_secrets(apps: Tuple[str], secret:str) -> None: +@click.option('recipes', '-r', '--recipe', multiple=True, metavar='', help='Filter for selcted recipes, this option can be specified multiple times.') +@click.option('-s', '--secret', multiple=False, help='list of secrets to be purged.') +def purge_secrets(recipes: Tuple[str], secret:str) -> None: """ Purges all secrets associated with specified applications. - - Args: - apps (list): List of applications from which secrets are to be purged. - secrets (list): List of secrets to be purged. """ # TODO: check for deployed apps - instance_apps = get_apps(apps) + instance_apps = get_apps(recipes) print_all_apps(instance_apps) domains = list(zip(*sum(instance_apps.values(), [])))[1] if input(f"Do you really want to purge the secret {secret} for these apps? Type YES: ") == "YES": @@ -1238,16 +1193,13 @@ def purge_secrets(apps: Tuple[str], secret:str) -> None: print(f"Secret {secret} for {domain} purged") @cli.command() -@click.option('-a', '--apps', multiple=True) -def purge_volumes(apps: Tuple[str]) -> None: +@click.option('recipes', '-r', '--recipe', multiple=True, metavar='', help='Filter for selcted recipes, this option can be specified multiple times.') +def purge_volumes(recipes: Tuple[str]) -> None: """ Purges all volumes associated with specified applications, ensuring that all data stored within the app's volumes is cleanly removed. - - Args: - apps (list): List of applications from which volumes are to be purged. """ # TODO: check for deployed apps - instance_apps = get_apps(apps) + instance_apps = get_apps(recipes) print_all_apps(instance_apps) domains = list(zip(*sum(instance_apps.values(), [])))[1] if input(f"Do you really want to purge the volumes for these apps? Type YES: ") == "YES": @@ -1258,20 +1210,15 @@ def purge_volumes(apps: Tuple[str]) -> None: @cli.command() -@click.option('-a', '--apps', multiple=True) -@click.option('-w', '--watch', is_flag=True) -@click.option('-v', '--verbose', is_flag=True) -def ps(apps: Tuple[str], watch: bool, verbose: bool) -> None: +@click.option('recipes', '-r', '--recipe', multiple=True, metavar='', help='Filter for selcted recipes, this option can be specified multiple times.') +@click.option('-w', '--watch', is_flag=True, help='repeat checking.') +@click.option('-v', '--verbose', is_flag=True, help='show more info columns for each container') +def ps(recipes: Tuple[str], watch: bool, verbose: bool) -> None: """ Check the health status of all apps inside the selected group. - - Args: - apps (list): List of applications to be checked. - watch (bool): Flag to repeat checking - verbose (bool): Show more info columns for each container """ while True: - instance_apps = get_apps_by_deployment(apps, deployed=True) + instance_apps = get_apps_by_deployment(recipes, deployed=True) if not instance_apps: print("No apps deployed") break @@ -1344,15 +1291,12 @@ def commit(apps: Tuple[str], message: str, push: bool = False) -> None: @cli.command() -@click.option('-a', '--apps', multiple=True) -def diff(apps: Tuple[str]) -> None: +@click.option('recipes', '-r', '--recipe', multiple=True, metavar='', help='Filter for selcted recipes, this option can be specified multiple times.') +def diff(recipes: Tuple[str]) -> None: """ Show the changes in the .env repositories inside ~/.abra/servers. - - Args: - apps (list): List of applications. """ - servers = get_server(apps) + servers = get_server(recipes) for server in servers: server_path = Path(f"~/.abra/servers/{server}").expanduser() try: @@ -1368,17 +1312,12 @@ def diff(apps: Tuple[str]) -> None: @cli.command() -@click.option('-a', '--apps', multiple=True) -@click.option('-u', '--update', is_flag=True) -@click.option('missing', '-m', '--get-missing', is_flag=True) -def uptime(apps: Tuple[str], update: bool, missing: bool) -> None: +@click.option('recipes', '-r', '--recipe', multiple=True, metavar='', help='Filter for selcted recipes, this option can be specified multiple times.') +@click.option('-u', '--update', is_flag=True, help='update the existing uptime kuma monitors.') +@click.option('missing', '-m', '--get-missing', is_flag=True, help='only print missing uptime kuma monitors.') +def uptime(recipes: Tuple[str], update: bool, missing: bool) -> None: """ Add the app domains to an uptime kuma instance. - - Args: - apps (list): List of applications. - update (bool): Update the uptime kuma monitors - missing (bool): Only print missing uptime kuma monitors """ if not (uptime_config:= (SETTINGS.get('uptime_kuma'))): logging.error(f"No uptime kuma settings provided in {SETTINGS_PATH}") @@ -1400,7 +1339,7 @@ def uptime(apps: Tuple[str], update: bool, missing: bool) -> None: if not monitor_parameter: monitor_parameter = {} - instance_apps = get_apps(apps) + instance_apps = get_apps(recipes) if not missing: print_all_apps(instance_apps) else: