forked from ISPsystem/isp-maintenance
Compare commits
3 Commits
6e882e82c6
...
c776632195
Author | SHA1 | Date | |
---|---|---|---|
c776632195 | |||
c8c7060201 | |||
961180a006 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -160,3 +160,5 @@ cython_debug/
|
|||||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
#.idea/
|
#.idea/
|
||||||
|
|
||||||
|
# Project specific
|
||||||
|
config.json
|
||||||
|
12
isp_maintenance/apps/dci6/access/commands.py
Normal file
12
isp_maintenance/apps/dci6/access/commands.py
Normal file
@ -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')
|
13
isp_maintenance/apps/dci6/commands.py
Normal file
13
isp_maintenance/apps/dci6/commands.py
Normal file
@ -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
|
12
isp_maintenance/apps/vm6/access/commands.py
Normal file
12
isp_maintenance/apps/vm6/access/commands.py
Normal file
@ -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')
|
12
isp_maintenance/apps/vm6/commands.py
Normal file
12
isp_maintenance/apps/vm6/commands.py
Normal file
@ -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
|
13
isp_maintenance/apps/vm6/nodes/commands.py
Normal file
13
isp_maintenance/apps/vm6/nodes/commands.py
Normal file
@ -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)
|
0
isp_maintenance/core/cli/__init__.py
Normal file
0
isp_maintenance/core/cli/__init__.py
Normal file
39
isp_maintenance/core/cli/lazy_group.py
Normal file
39
isp_maintenance/core/cli/lazy_group.py
Normal file
@ -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
|
21
isp_maintenance/ispmgr.py
Normal file → Executable file
21
isp_maintenance/ispmgr.py
Normal file → Executable file
@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import click
|
||||||
|
|
||||||
|
from core.cli.lazy_group import LazyGroup
|
||||||
|
|
||||||
|
|
||||||
|
@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()
|
@ -0,0 +1,15 @@
|
|||||||
|
from settings.general import BASE_DIR
|
||||||
|
|
||||||
|
from settings.platform import (
|
||||||
|
PLATFORM_TYPE,
|
||||||
|
PLATFORM_URL,
|
||||||
|
PLATFORM_CONFIG
|
||||||
|
)
|
||||||
|
|
||||||
|
from settings.db import(
|
||||||
|
DB_ENGINE,
|
||||||
|
DB_HOST,
|
||||||
|
DB_PORT,
|
||||||
|
DB_USER,
|
||||||
|
DB_PASSWORD
|
||||||
|
)
|
23
isp_maintenance/settings/db.py
Normal file
23
isp_maintenance/settings/db.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
from settings.environment import env
|
||||||
|
from settings.platform import PLATFORM_CONFIG
|
||||||
|
|
||||||
|
|
||||||
|
# ! 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',
|
||||||
|
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
|
||||||
|
DB_PASSWORD = env.str(
|
||||||
|
'DB_PASSWORD',
|
||||||
|
PLATFORM_CONFIG.get('MysqlRootPassword', '')
|
||||||
|
)
|
9
isp_maintenance/settings/environment.py
Normal file
9
isp_maintenance/settings/environment.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from environs import Env
|
||||||
|
|
||||||
|
|
||||||
|
# Init environment:
|
||||||
|
env = Env()
|
||||||
|
|
||||||
|
# read .env file, if it exists
|
||||||
|
# reed more about .env file here: https://github.com/sloria/environs
|
||||||
|
env.read_env()
|
15
isp_maintenance/settings/general.py
Normal file
15
isp_maintenance/settings/general.py
Normal file
@ -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',
|
||||||
|
},
|
||||||
|
}
|
13
isp_maintenance/settings/platform.py
Normal file
13
isp_maintenance/settings/platform.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from settings.environment import env
|
||||||
|
from settings.general import BASE_DIR
|
||||||
|
from utils.helpers import parse_json_file
|
||||||
|
|
||||||
|
|
||||||
|
PLATFORM_TYPE = env.str('PLATFORM_TYPE', 'vm')
|
||||||
|
|
||||||
|
PLATFORM_CONFIG = parse_json_file(f'{BASE_DIR}/config.json')
|
||||||
|
|
||||||
|
PLATFORM_URL = env.url(
|
||||||
|
'PLATFORM_URL',
|
||||||
|
f"https://{PLATFORM_CONFIG.get('DomainName' ,'replace.me')}"
|
||||||
|
)
|
20
isp_maintenance/utils/helpers.py
Normal file
20
isp_maintenance/utils/helpers.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def parse_json_file(file_path):
|
||||||
|
"""
|
||||||
|
Function read json file as usual config.json then parse it to python dict
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config_file_path (str): path to config file
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: contains parse json content
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with open(file_path, 'r') as f:
|
||||||
|
return json.load(f)
|
||||||
|
except Exception as error:
|
||||||
|
print(error)
|
||||||
|
sys.exit(1)
|
68
poetry.lock
generated
68
poetry.lock
generated
@ -135,6 +135,27 @@ files = [
|
|||||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "environs"
|
||||||
|
version = "10.3.0"
|
||||||
|
description = "simplified environment variable parsing"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "environs-10.3.0-py3-none-any.whl", hash = "sha256:feeaf28f17fd0499f9cd7c0fcf408c6d82c308e69e335eb92d09322fc9ed8138"},
|
||||||
|
{file = "environs-10.3.0.tar.gz", hash = "sha256:cc421ddb143fa30183568164755aa113a160e555cd19e97e664c478662032c24"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
marshmallow = ">=3.0.0"
|
||||||
|
python-dotenv = "*"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["environs[lint,tests]", "tox"]
|
||||||
|
django = ["dj-database-url", "dj-email-url", "django-cache-url"]
|
||||||
|
lint = ["flake8 (==7.0.0)", "flake8-bugbear (==23.11.28)", "mypy (==1.8.0)", "pre-commit (>=3.6,<4.0)"]
|
||||||
|
tests = ["environs[django]", "pytest"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flake8"
|
name = "flake8"
|
||||||
version = "7.0.0"
|
version = "7.0.0"
|
||||||
@ -162,6 +183,26 @@ files = [
|
|||||||
{file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"},
|
{file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "marshmallow"
|
||||||
|
version = "3.20.2"
|
||||||
|
description = "A lightweight library for converting complex datatypes to and from native Python datatypes."
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "marshmallow-3.20.2-py3-none-any.whl", hash = "sha256:c21d4b98fee747c130e6bc8f45c4b3199ea66bc00c12ee1f639f0aeca034d5e9"},
|
||||||
|
{file = "marshmallow-3.20.2.tar.gz", hash = "sha256:4c1daff273513dc5eb24b219a8035559dc573c8f322558ef85f5438ddd1236dd"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
packaging = ">=17.0"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["pre-commit (>=2.4,<4.0)", "pytest", "pytz", "simplejson", "tox"]
|
||||||
|
docs = ["alabaster (==0.7.15)", "autodocsumm (==0.2.12)", "sphinx (==7.2.6)", "sphinx-issues (==3.0.1)", "sphinx-version-warning (==1.1.2)"]
|
||||||
|
lint = ["pre-commit (>=2.4,<4.0)"]
|
||||||
|
tests = ["pytest", "pytz", "simplejson"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mccabe"
|
name = "mccabe"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -173,6 +214,17 @@ files = [
|
|||||||
{file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
|
{file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "packaging"
|
||||||
|
version = "23.2"
|
||||||
|
description = "Core utilities for Python packages"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
|
||||||
|
{file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "peewee"
|
name = "peewee"
|
||||||
version = "3.17.1"
|
version = "3.17.1"
|
||||||
@ -205,6 +257,20 @@ files = [
|
|||||||
{file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"},
|
{file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-dotenv"
|
||||||
|
version = "1.0.1"
|
||||||
|
description = "Read key-value pairs from a .env file and set them as environment variables"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"},
|
||||||
|
{file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
cli = ["click (>=5.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "requests"
|
name = "requests"
|
||||||
version = "2.31.0"
|
version = "2.31.0"
|
||||||
@ -246,4 +312,4 @@ zstd = ["zstandard (>=0.18.0)"]
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.11"
|
python-versions = "^3.11"
|
||||||
content-hash = "a4dcf387610a52d2dc26db60e270175ed4fae32cafd717a70337cecc367c066e"
|
content-hash = "f031f9e86074966762fb83b3386f11c109c7a17ea31937dd03f66701676b632e"
|
||||||
|
@ -11,6 +11,7 @@ python = "^3.11"
|
|||||||
peewee = "^3.17.0"
|
peewee = "^3.17.0"
|
||||||
click = "^8.1.7"
|
click = "^8.1.7"
|
||||||
requests = "^2.31.0"
|
requests = "^2.31.0"
|
||||||
|
environs = "^10.3.0"
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
flake8 = "^7.0.0"
|
flake8 = "^7.0.0"
|
||||||
|
@ -98,11 +98,23 @@ click==8.1.7 ; python_version >= "3.11" and python_version < "4.0" \
|
|||||||
colorama==0.4.6 ; python_version >= "3.11" and python_version < "4.0" and platform_system == "Windows" \
|
colorama==0.4.6 ; python_version >= "3.11" and python_version < "4.0" and platform_system == "Windows" \
|
||||||
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
|
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
|
||||||
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
|
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
|
||||||
|
environs==10.3.0 ; python_version >= "3.11" and python_version < "4.0" \
|
||||||
|
--hash=sha256:cc421ddb143fa30183568164755aa113a160e555cd19e97e664c478662032c24 \
|
||||||
|
--hash=sha256:feeaf28f17fd0499f9cd7c0fcf408c6d82c308e69e335eb92d09322fc9ed8138
|
||||||
idna==3.6 ; python_version >= "3.11" and python_version < "4.0" \
|
idna==3.6 ; python_version >= "3.11" and python_version < "4.0" \
|
||||||
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
|
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
|
||||||
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
|
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
|
||||||
|
marshmallow==3.20.2 ; python_version >= "3.11" and python_version < "4.0" \
|
||||||
|
--hash=sha256:4c1daff273513dc5eb24b219a8035559dc573c8f322558ef85f5438ddd1236dd \
|
||||||
|
--hash=sha256:c21d4b98fee747c130e6bc8f45c4b3199ea66bc00c12ee1f639f0aeca034d5e9
|
||||||
|
packaging==23.2 ; python_version >= "3.11" and python_version < "4.0" \
|
||||||
|
--hash=sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5 \
|
||||||
|
--hash=sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7
|
||||||
peewee==3.17.1 ; python_version >= "3.11" and python_version < "4.0" \
|
peewee==3.17.1 ; python_version >= "3.11" and python_version < "4.0" \
|
||||||
--hash=sha256:e009ac4227c4fdc0058a56e822ad5987684f0a1fbb20fed577200785102581c3
|
--hash=sha256:e009ac4227c4fdc0058a56e822ad5987684f0a1fbb20fed577200785102581c3
|
||||||
|
python-dotenv==1.0.1 ; python_version >= "3.11" and python_version < "4.0" \
|
||||||
|
--hash=sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca \
|
||||||
|
--hash=sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a
|
||||||
requests==2.31.0 ; python_version >= "3.11" and python_version < "4.0" \
|
requests==2.31.0 ; python_version >= "3.11" and python_version < "4.0" \
|
||||||
--hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
|
--hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
|
||||||
--hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1
|
--hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1
|
||||||
|
Loading…
Reference in New Issue
Block a user