From c7766321956e7307b4196c66735497a4b07af01b Mon Sep 17 00:00:00 2001 From: MOIS3Y Date: Sun, 11 Feb 2024 03:01:18 +0900 Subject: [PATCH] Add: core cli, lazy_group, example apps --- isp_maintenance/apps/dci6/access/commands.py | 12 ++++++ isp_maintenance/apps/dci6/commands.py | 13 +++++++ isp_maintenance/apps/vm6/access/commands.py | 12 ++++++ isp_maintenance/apps/vm6/commands.py | 12 ++++++ isp_maintenance/apps/vm6/nodes/commands.py | 13 +++++++ isp_maintenance/core/cli/__init__.py | 0 isp_maintenance/core/cli/lazy_group.py | 39 ++++++++++++++++++++ isp_maintenance/ispmgr.py | 22 ++++++++--- isp_maintenance/settings/__init__.py | 2 +- isp_maintenance/settings/db.py | 9 +++-- isp_maintenance/settings/environment.py | 5 --- isp_maintenance/settings/general.py | 15 ++++++++ isp_maintenance/settings/platform.py | 3 +- 13 files changed, 142 insertions(+), 15 deletions(-) create mode 100644 isp_maintenance/apps/dci6/access/commands.py create mode 100644 isp_maintenance/apps/dci6/commands.py create mode 100644 isp_maintenance/apps/vm6/access/commands.py create mode 100644 isp_maintenance/apps/vm6/commands.py create mode 100644 isp_maintenance/apps/vm6/nodes/commands.py create mode 100644 isp_maintenance/core/cli/__init__.py create mode 100644 isp_maintenance/core/cli/lazy_group.py create mode 100644 isp_maintenance/settings/general.py diff --git a/isp_maintenance/apps/dci6/access/commands.py b/isp_maintenance/apps/dci6/access/commands.py new file mode 100644 index 0000000..495d7f5 --- /dev/null +++ b/isp_maintenance/apps/dci6/access/commands.py @@ -0,0 +1,12 @@ +import click + + +@click.group(help='access command for lazy example') +@click.option('--debug/--no-debug', default=False) +def cli(debug): + click.echo(f"Debug mode is {'on' if debug else 'off'}") + + +@cli.command() +def enable(): + click.echo('Access granted') diff --git a/isp_maintenance/apps/dci6/commands.py b/isp_maintenance/apps/dci6/commands.py new file mode 100644 index 0000000..33964af --- /dev/null +++ b/isp_maintenance/apps/dci6/commands.py @@ -0,0 +1,13 @@ +import click + +from core.cli.lazy_group import LazyGroup +from settings.general import INSTALLED_APPS + + +@click.group( + cls=LazyGroup, + lazy_subcommands=INSTALLED_APPS['dci6'], + help='dci6 command for lazy example', +) +def cli(): + pass diff --git a/isp_maintenance/apps/vm6/access/commands.py b/isp_maintenance/apps/vm6/access/commands.py new file mode 100644 index 0000000..495d7f5 --- /dev/null +++ b/isp_maintenance/apps/vm6/access/commands.py @@ -0,0 +1,12 @@ +import click + + +@click.group(help='access command for lazy example') +@click.option('--debug/--no-debug', default=False) +def cli(debug): + click.echo(f"Debug mode is {'on' if debug else 'off'}") + + +@cli.command() +def enable(): + click.echo('Access granted') diff --git a/isp_maintenance/apps/vm6/commands.py b/isp_maintenance/apps/vm6/commands.py new file mode 100644 index 0000000..cc17cd8 --- /dev/null +++ b/isp_maintenance/apps/vm6/commands.py @@ -0,0 +1,12 @@ +import click +from core.cli.lazy_group import LazyGroup +from settings.general import INSTALLED_APPS + + +@click.group( + cls=LazyGroup, + lazy_subcommands=INSTALLED_APPS['vm6'], + help='vm6 command for lazy example', +) +def cli(): + pass diff --git a/isp_maintenance/apps/vm6/nodes/commands.py b/isp_maintenance/apps/vm6/nodes/commands.py new file mode 100644 index 0000000..014b468 --- /dev/null +++ b/isp_maintenance/apps/vm6/nodes/commands.py @@ -0,0 +1,13 @@ +import click + + +@click.group(help='nodes command for lazy example') +def cli(): + pass + + +@cli.command(name='list') +def nodes_list(): + click.echo('NODES LIST: etc...') + for num in range(1, 10): + click.echo(num) diff --git a/isp_maintenance/core/cli/__init__.py b/isp_maintenance/core/cli/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/isp_maintenance/core/cli/lazy_group.py b/isp_maintenance/core/cli/lazy_group.py new file mode 100644 index 0000000..fce9085 --- /dev/null +++ b/isp_maintenance/core/cli/lazy_group.py @@ -0,0 +1,39 @@ +import importlib +import click + + +class LazyGroup(click.Group): + def __init__(self, *args, lazy_subcommands=None, **kwargs): + super().__init__(*args, **kwargs) + # lazy_subcommands is a map of the form: + # + # {command-name} -> {module-name}.{command-object-name} + # + self.lazy_subcommands = lazy_subcommands or {} + + def list_commands(self, ctx): + base = super().list_commands(ctx) + lazy = sorted(self.lazy_subcommands.keys()) + return base + lazy + + def get_command(self, ctx, cmd_name): + if cmd_name in self.lazy_subcommands: + return self._lazy_load(cmd_name) + return super().get_command(ctx, cmd_name) + + def _lazy_load(self, cmd_name): + # lazily loading a command, + # first get the module name and attribute name + import_path = self.lazy_subcommands[cmd_name] + modname, cmd_object_name = import_path.rsplit(".", 1) + # do the import + mod = importlib.import_module(modname) + # get the Command object from that module + cmd_object = getattr(mod, cmd_object_name) + # check the result to make debugging easier + if not isinstance(cmd_object, click.BaseCommand): + raise ValueError( + f"Lazy loading of {import_path} failed by returning " + "a non-command object" + ) + return cmd_object diff --git a/isp_maintenance/ispmgr.py b/isp_maintenance/ispmgr.py index b6b6ea1..53e99af 100755 --- a/isp_maintenance/ispmgr.py +++ b/isp_maintenance/ispmgr.py @@ -1,9 +1,21 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -from settings.environment import env +import click + +from core.cli.lazy_group import LazyGroup -# TODO: delete this demo -# Just show you which env get application or default values -for key, value in env.dump().items(): - print(key, '|', value) +@click.group( + cls=LazyGroup, + lazy_subcommands={ + 'vm6': 'apps.vm6.commands.cli', + 'dci6': 'apps.dci6.commands.cli', + }, + help='main CLI command for lazy example', +) +def cli(): + pass + + +if __name__ == '__main__': + cli() diff --git a/isp_maintenance/settings/__init__.py b/isp_maintenance/settings/__init__.py index 33b615d..a108dad 100644 --- a/isp_maintenance/settings/__init__.py +++ b/isp_maintenance/settings/__init__.py @@ -1,4 +1,4 @@ -from settings.environment import BASE_DIR +from settings.general import BASE_DIR from settings.platform import ( PLATFORM_TYPE, diff --git a/isp_maintenance/settings/db.py b/isp_maintenance/settings/db.py index 504bc6f..c6bb73e 100644 --- a/isp_maintenance/settings/db.py +++ b/isp_maintenance/settings/db.py @@ -2,18 +2,21 @@ from settings.environment import env from settings.platform import PLATFORM_CONFIG -#! Required because some instance use psql db: +# ! Required because some instance use psql db: DB_ENGINE = env.str( 'DB_ENGINE', PLATFORM_CONFIG.get('DatabaseType', 'mysql') ) # Connection parameters: -DB_HOST = env.str('DB_HOST', 'mysql') +DB_HOST = env.str( + 'DB_HOST', + PLATFORM_CONFIG.get('DatabaseType', 'mysql') +) DB_PORT = env.int('DB_PORT', 3306) DB_USER = env.str('DB_USER', 'root') -#! Do not pass password on production. Use value from config.json +# ! Do not pass password on production. Use value from config.json DB_PASSWORD = env.str( 'DB_PASSWORD', PLATFORM_CONFIG.get('MysqlRootPassword', '') diff --git a/isp_maintenance/settings/environment.py b/isp_maintenance/settings/environment.py index e20551a..b107300 100644 --- a/isp_maintenance/settings/environment.py +++ b/isp_maintenance/settings/environment.py @@ -1,11 +1,6 @@ -import pathlib from environs import Env -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = pathlib.Path(__file__).resolve().parent.parent - - # Init environment: env = Env() diff --git a/isp_maintenance/settings/general.py b/isp_maintenance/settings/general.py new file mode 100644 index 0000000..433df37 --- /dev/null +++ b/isp_maintenance/settings/general.py @@ -0,0 +1,15 @@ +import pathlib + + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = pathlib.Path(__file__).resolve().parent.parent + +INSTALLED_APPS = { + 'vm6': { + 'access': 'apps.vm6.access.commands.cli', + 'nodes': 'apps.vm6.nodes.commands.cli', + }, + 'dci6': { + 'access': 'apps.dci6.access.commands.cli', + }, +} diff --git a/isp_maintenance/settings/platform.py b/isp_maintenance/settings/platform.py index 2165522..0bf34ae 100644 --- a/isp_maintenance/settings/platform.py +++ b/isp_maintenance/settings/platform.py @@ -1,4 +1,5 @@ -from settings.environment import env, BASE_DIR +from settings.environment import env +from settings.general import BASE_DIR from utils.helpers import parse_json_file -- 2.45.2