Update: dockerize app, rename pkg to mgrctl, fix imports

This commit is contained in:
2024-06-03 18:58:27 +09:00
parent 34e8118327
commit 0f96d0f956
50 changed files with 309 additions and 94 deletions

15
mgrctl/__init__.py Normal file
View File

@@ -0,0 +1,15 @@
# █▀▄▀█ █▀▀ ▀█▀ ▄▀█ ▀
# █░▀░█ ██▄ ░█░ █▀█ ▄
# -- -- -- -- -- -- -
__author__ = "MOIS3Y, a.garaev, Failak3, Ann_M"
__credits__ = [
"Stepan Zhukovsky",
"Arthur Garaev",
"Vladislav Shmidt",
"Anna Moskovkina"
]
__license__ = "MIT"
__version__ = "0.1.0"
__maintainer__ = "Stepan Zhukovsky"
__email__ = "stepan@zhukovsky.me"
__status__ = "Development"

0
mgrctl/api/__init__.py Normal file
View File

163
mgrctl/api/base.py Normal file
View File

@@ -0,0 +1,163 @@
import sys
import json
import urllib
import requests
from mgrctl.settings.api import INPUT_HOSTNAME, INPUT_PORT, HEADERS
class BaseAPI(object):
def __init__(self, api_url=None, verify_ssl=True):
"""Announces required parameters"""
internal_api_url = f'http://{INPUT_HOSTNAME}:{INPUT_PORT}'
self.API_URL = api_url if api_url else internal_api_url
self.API_VERSION = 'v3'
self.API_DEFINITION = 'api'
self.HEADERS = HEADERS
self.VERIFY_SSL = verify_ssl
def _gen_request_url(self, url):
return f'{self.API_URL}/{self.API_DEFINITION}/{self.API_VERSION}{url}'
def call_api(self, url, method='GET', headers={}, data={}):
# Open session
with requests.Session() as session:
try:
url = self._gen_request_url(url)
headers = self.HEADERS if not headers else headers
params_str = urllib.parse.urlencode(data, safe="+'()")
if method == 'POST':
api_request = session.post(
url=url,
json=data,
headers=headers,
verify=self.VERIFY_SSL
)
if method == 'GET':
url = f'{url}?{params_str}' if params_str else url
api_request = session.get(
url=url,
headers=headers,
verify=self.VERIFY_SSL
)
except Exception as error:
api_request = {
'result': False,
'error': type(error).__name__
}
return api_request
finally:
session.close()
# Get response
try:
response = json.loads(api_request.text)
if 'error' in response and response['error']:
print(response['error'])
raise sys.exit()
return response
except json.decoder.JSONDecodeError:
response = {'error': 'Can not parse response'}
print(response)
raise sys.exit()
def get(self, url, headers={}, data={}):
return self.call_api(url, headers, data, method='GET')
def post(self, url, headers={}, data={}):
return self.call_api(url, headers, data, method='POST')
class BaseAuthAPI(BaseAPI):
def __init__(self, api_url=None, verify_ssl=True):
"""
Init class for /auth/v4 requests
Args:
api_url (str, optional): url api host. Defaults to None.
If None will use from settings.api.INPUT_HOSTNAME:INPUT_PORT
verify_ssl (bool, optional): Isn't recommended. Defaults to True.
Use only for testing if you don't have root sign SSL cert.
"""
super().__init__(api_url, verify_ssl)
self.API_VERSION = 'v4'
self.API_DEFINITION = 'auth'
def get_auth_token(self, email: str, password: str) -> dict:
"""
Get auth token for authentication
Arg:
email (str): user email
password (str): user password
Returns:
response (dict): {
"confirmed": true,
"expires_at": "date time",
"id": "int",
"token": "str"
}
"""
return self.call_api(
url='/public/token',
method='POST',
data={'email': email, 'password': password}
)
def get_auth_key(self, token: str, user, auth_type='Internal') -> dict:
"""
Key authentication
Args:
token (str): auth token
user (str or int): user id or email
auth_type (str, optional): May be Public for public auth.
Defaults to 'Internal'.
Returns:
response (dict): {
"id": "int",
"key": "str"
}
"""
headers = {}
if auth_type == 'Public':
headers = self.make_auth_header(token)
return self.call_api(
url=f'/user/{user}/key',
method='POST',
headers=headers
)
def make_auth_header(self, token: str) -> dict:
"""
Generate dict for auth header
Args:
token (str): auth token
Returns:
dict: {'x-xsrf-token': token} use it for request headers
"""
return {'x-xsrf-token': token}
def whoami(self, token: str) -> dict:
return self.call_api(
url='/whoami',
method='GET',
headers=self.make_auth_header(token)
)
class BaseIpAPI(BaseAPI):
def __init__(self, api_url=None, verify_ssl=True):
super().__init__(api_url, verify_ssl)
self.API_DEFINITION = 'ip'
class BaseDnsProxyAPI(BaseAPI):
def __init__(self, api_url=None, verify_ssl=True):
super().__init__(api_url, verify_ssl)
self.API_DEFINITION = 'dnsproxy'

51
mgrctl/api/dci6.py Normal file
View File

@@ -0,0 +1,51 @@
from mgrctl.api.base import BaseAPI, BaseAuthAPI, BaseDnsProxyAPI, BaseIpAPI
class AuthAPI(BaseAuthAPI):
pass
class BackupAPI(BaseAPI):
def __init__(self, api_url=None, verify_ssl=True):
super().__init__(api_url, verify_ssl)
self.API_VERSION = 'v4'
self.API_DEFINITION = 'backup'
class DnsProxyAPI(BaseDnsProxyAPI):
pass
class EserviceAPI(BaseAPI):
def __init__(self, api_url=None, verify_ssl=True):
super().__init__(api_url, verify_ssl)
self.API_DEFINITION = 'eservice'
class IsoAPI(BaseAPI):
def __init__(self, api_url=None, verify_ssl=True):
super().__init__(api_url, verify_ssl)
self.API_DEFINITION = 'iso'
class IpmiAPI(BaseAPI):
def __init__(self, api_url=None, verify_ssl=True):
super().__init__(api_url, verify_ssl)
self.API_DEFINITION = 'ipmiproxy'
class IpAPI(BaseIpAPI):
pass
class ReportAPI(BaseAPI):
def __init__(self, api_url=None, verify_ssl=True):
super().__init__(api_url, verify_ssl)
self.API_VERSION = 'v4'
self.API_DEFINITION = 'report'
class UpdaterAPI(BaseAPI):
def __init__(self, api_url=None, verify_ssl=True):
super().__init__(api_url, verify_ssl)
self.API_DEFINITION = 'updater'

19
mgrctl/api/vm6.py Normal file
View File

@@ -0,0 +1,19 @@
from mgrctl.api.base import BaseAPI, BaseAuthAPI, BaseDnsProxyAPI, BaseIpAPI
class AuthAPI(BaseAuthAPI):
pass
class DnsProxyAPI(BaseDnsProxyAPI):
pass
class IpAPI(BaseIpAPI):
pass
class VmAPI(BaseAPI):
def __init__(self, api_url=None, verify_ssl=True):
super().__init__(api_url, verify_ssl)
self.API_DEFINITION = 'vm'

15
mgrctl/apps/__init__.py Normal file
View File

@@ -0,0 +1,15 @@
# █▀▄▀█ █▀▀ ▀█▀ ▄▀█ ▀
# █░▀░█ ██▄ ░█░ █▀█ ▄
# -- -- -- -- -- -- -
__author__ = "MOIS3Y, a.garaev, Failak3, Ann_M"
__credits__ = [
"Stepan Zhukovsky",
"Arthur Garaev",
"Vladislav Shmidt",
"Anna Moskovkina"
]
__license__ = "MIT"
__version__ = "0.1.0"
__maintainer__ = "Stepan Zhukovsky"
__email__ = "stepan@zhukovsky.me"
__status__ = "Development"

View File

@@ -0,0 +1,15 @@
# █▀▄▀█ █▀▀ ▀█▀ ▄▀█ ▀
# █░▀░█ ██▄ ░█░ █▀█ ▄
# -- -- -- -- -- -- -
__author__ = "MOIS3Y, a.garaev, Failak3, Ann_M"
__credits__ = [
"Stepan Zhukovsky",
"Arthur Garaev",
"Vladislav Shmidt",
"Anna Moskovkina"
]
__license__ = "MIT"
__version__ = "0.1.0"
__maintainer__ = "Stepan Zhukovsky"
__email__ = "stepan@zhukovsky.me"
__status__ = "Development"

View File

View 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')

View File

@@ -0,0 +1,13 @@
import click
from mgrctl.cli.lazy_group import LazyGroup
from mgrctl.settings.general import INSTALLED_APPS
@click.group(
cls=LazyGroup,
lazy_subcommands=INSTALLED_APPS['dci6'],
help='dci6 command for lazy example',
)
def cli():
pass

View File

@@ -0,0 +1,15 @@
# █▀▄▀█ █▀▀ ▀█▀ ▄▀█ ▀
# █░▀░█ ██▄ ░█░ █▀█ ▄
# -- -- -- -- -- -- -
__author__ = "MOIS3Y, a.garaev, Failak3, Ann_M"
__credits__ = [
"Stepan Zhukovsky",
"Arthur Garaev",
"Vladislav Shmidt",
"Anna Moskovkina"
]
__license__ = "MIT"
__version__ = "0.1.0"
__maintainer__ = "Stepan Zhukovsky"
__email__ = "stepan@zhukovsky.me"
__status__ = "Development"

View File

@@ -0,0 +1,10 @@
# █▀▄▀█ █▀▀ ▀█▀ ▄▀█ ▀
# █░▀░█ ██▄ ░█░ █▀█ ▄
# -- -- -- -- -- -- -
__author__ = "MOIS3Y"
__credits__ = ["Stepan Zhukovsky"]
__license__ = "MIT"
__version__ = "0.1.0"
__maintainer__ = "Stepan Zhukovsky"
__email__ = "stepan@zhukovsky.me"
__status__ = "Development"

View File

@@ -0,0 +1,31 @@
import click
from mgrctl.db.vm6.databases import isp_database
from mgrctl.db.vm6.models import AuthUser
from mgrctl.apps.vm6.auth import __version__
@click.group(help='auth cmd for auth in VMmanager 6')
@click.version_option(
version=__version__,
package_name='mgrctl.apps.vm6.auth',
message=__version__
)
def cli():
pass
@cli.command(help='show all users and their roles on platform (DEMO EXAMPLE)')
def users():
# check and init connection to db:
isp_database.connect()
# get all fields from auth_user table
# SELECT * FROM auth_user;
all_users = AuthUser.select()
# Iterate fields and print to console users' email and role
for user in all_users:
result = f'{user.email} | {user.roles[0]}'
click.echo(result)
# Close connection
isp_database.close()

View File

@@ -0,0 +1,19 @@
import click
from mgrctl.cli.lazy_group import LazyGroup
from mgrctl.settings.general import INSTALLED_APPS
from mgrctl.apps.vm6 import __version__
@click.group(
cls=LazyGroup,
lazy_subcommands=INSTALLED_APPS['vm6'],
help='vm6 command for lazy example',
)
@click.version_option(
version=__version__,
package_name='mgrctl',
message=__version__
)
def cli():
pass

0
mgrctl/cli/__init__.py Normal file
View File

39
mgrctl/cli/lazy_group.py Normal file
View 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

0
mgrctl/db/__init__.py Normal file
View File

20
mgrctl/db/common.py Normal file
View File

@@ -0,0 +1,20 @@
import json
from peewee import TextField
class JSONField(TextField):
"""
Class to "fake" a JSON field with a text field.
Not efficient but works nicely
"""
def db_value(self, value):
"""Convert the python value for storage in the database."""
return value if value is None else json.dumps(value)
def python_value(self, value):
"""Convert the database value to a pythonic value."""
return value if value is None else json.loads(value)
class UnknownField(object):
def __init__(self, *_, **__): pass

46
mgrctl/db/connection.py Normal file
View File

@@ -0,0 +1,46 @@
from peewee import MySQLDatabase, PostgresqlDatabase
from mgrctl.settings.db import (
DB_ENGINE,
DB_HOST,
DB_PORT,
DB_USER,
DB_PASSWORD
)
def guess_database(db_name):
"""
function checks DB_ENGINE and set correct connection class
with connection params. Expected database name in input.
Args:
db_name (_str_): database name
Returns:
(_MySQLDatabase_or_PostgresqlDatabase_ class):
contains db connection params
"""
if DB_ENGINE == 'mysql':
return MySQLDatabase(
db_name, **{
'charset': 'utf8',
'sql_mode': 'PIPES_AS_CONCAT',
'use_unicode': True,
'host': DB_HOST,
'port': DB_PORT,
'user': DB_USER,
'password': DB_PASSWORD
}
)
if DB_ENGINE == 'psql':
return PostgresqlDatabase(
db_name, **{
'charset': 'utf8',
'sql_mode': 'PIPES_AS_CONCAT',
'use_unicode': True,
'host': DB_HOST,
'port': DB_PORT,
'user': DB_USER,
'password': DB_PASSWORD
}
)

View File

View File

@@ -0,0 +1,9 @@
from mgrctl.db.connection import guess_database
# The variable will contain an object of
# the MySQLDatabase or PostgresqlDatabase class as well as all connection data
# If in the future there will be more databases in the platform,
# they should be added here
auth_database = guess_database('auth')
dci_1_database = guess_database('dci_1')

980
mgrctl/db/dci6/models.py Normal file
View File

@@ -0,0 +1,980 @@
from peewee import (
AutoField,
BigIntegerField,
CharField,
CompositeKey,
DateTimeField,
FloatField,
ForeignKeyField,
IntegerField,
Model,
TextField,
SQL
)
from mgrctl.db.common import UnknownField
from mgrctl.db.dci6.databases import auth_database
class BaseModel(Model):
class Meta:
database = auth_database
class AlertSetting(BaseModel):
channel = UnknownField(null=True) # json
enabled = IntegerField(constraints=[SQL("DEFAULT 1")])
metric = UnknownField(null=True) # json
metric_id = CharField(null=True)
name = CharField(null=True)
class Meta:
table_name = 'alert_setting'
class AuthAcl(BaseModel):
ip_list = UnknownField() # json
name = CharField(constraints=[SQL("DEFAULT ''")], unique=True)
class Meta:
table_name = 'auth_acl'
class AuthUser(BaseModel):
auth_source = CharField(constraints=[SQL("DEFAULT 'local'")])
avatar = TextField(null=True)
avatar_content_type = CharField(null=True)
avatar_filename = CharField(null=True)
created_date = DateTimeField(null=True)
email = CharField(constraints=[SQL("DEFAULT ''")], unique=True)
email_confirm = IntegerField(constraints=[SQL("DEFAULT 0")])
full_name = CharField(null=True)
ip_list = UnknownField(null=True) # json
lang = CharField(constraints=[SQL("DEFAULT 'en'")])
password = CharField(null=True)
phone_number = CharField(null=True)
property = UnknownField(null=True) # json
reserve_codes = UnknownField(null=True) # json
roles = UnknownField() # json
ssh_priv_key = TextField(null=True)
ssh_pub_key = TextField(null=True)
state = CharField(constraints=[SQL("DEFAULT 'active'")])
timezone = CharField(null=True)
totp = CharField(null=True)
uuid = CharField(null=True, unique=True)
class Meta:
table_name = 'auth_user'
class AuthConfirmToken(BaseModel):
expires_at = DateTimeField(null=True)
resend_token_after = DateTimeField(null=True)
token = CharField(null=True, unique=True)
user = ForeignKeyField(
column_name='user',
field='id',
model=AuthUser,
null=True,
unique=True
)
class Meta:
table_name = 'auth_confirm_token'
class AuthGdprDoc(BaseModel):
change_date = DateTimeField(null=True)
desc_condition = CharField(null=True)
entry_date = DateTimeField(null=True)
locale = CharField(null=True)
name = CharField(unique=True)
required = IntegerField(constraints=[SQL("DEFAULT 0")])
state = CharField()
url = CharField(null=True)
class Meta:
table_name = 'auth_gdpr_doc'
class AuthGdprJournal(BaseModel):
action_date = DateTimeField(null=True)
action_type = CharField()
doc = ForeignKeyField(
column_name='doc',
field='id',
model=AuthGdprDoc,
null=True
)
ip = CharField(null=True)
user_email = CharField()
class Meta:
table_name = 'auth_gdpr_journal'
class AuthGeneratedSshkey(BaseModel):
generation_date = DateTimeField(null=True)
privkey = TextField(null=True)
pubkey = TextField(null=True)
class Meta:
table_name = 'auth_generated_sshkey'
class AuthProduct(BaseModel):
docker_compose_file = TextField(null=True)
name = CharField(null=True)
script = TextField(null=True)
version = CharField(null=True)
class Meta:
table_name = 'auth_product'
indexes = (
(('name', 'version'), True),
)
class AuthInstance(BaseModel):
conn_params = UnknownField(null=True) # json
dbkey = TextField(null=True)
demo = IntegerField(constraints=[SQL("DEFAULT 0")])
failure_reason = UnknownField(null=True) # json
limits = UnknownField(null=True) # json
name = CharField(null=True)
owner = ForeignKeyField(
column_name='owner',
field='id',
model=AuthUser,
null=True
)
product = ForeignKeyField(
column_name='product',
field='id',
model=AuthProduct,
null=True
)
roles = UnknownField(null=True) # json
started = DateTimeField(null=True)
status = CharField()
class Meta:
table_name = 'auth_instance'
class AuthInstanceHistory(BaseModel):
create_time = DateTimeField(constraints=[SQL("DEFAULT CURRENT_TIMESTAMP")])
event_info = UnknownField(null=True) # json
event_type = CharField(null=True)
prev_time = DateTimeField(null=True)
ref = ForeignKeyField(
column_name='ref',
field='id',
model=AuthInstance,
null=True
)
request_id = CharField(null=True)
request_ip = CharField(null=True)
request_owner = CharField(null=True)
request_user = CharField(null=True)
class Meta:
table_name = 'auth_instance_history'
class AuthKey(BaseModel):
expires_at = DateTimeField(null=True)
name = CharField(constraints=[SQL("DEFAULT ''")], unique=True)
user = ForeignKeyField(column_name='user', field='id', model=AuthUser)
class Meta:
table_name = 'auth_key'
class AuthLicense(BaseModel):
instance = ForeignKeyField(
column_name='instance',
field='id',
model=AuthInstance,
null=True,
unique=True
)
last_update = DateTimeField(null=True)
lic_data = UnknownField(null=True) # json
lic_request = UnknownField(null=True) # json
product = CharField(null=True)
signature_expire_date = DateTimeField(null=True)
status = CharField()
class Meta:
table_name = 'auth_license'
class AuthPermission(BaseModel):
data = UnknownField() # json
plugin = CharField(constraints=[SQL("DEFAULT ''")])
service = CharField(constraints=[SQL("DEFAULT ''")])
class Meta:
table_name = 'auth_permission'
indexes = (
(('service', 'plugin'), True),
)
class AuthPricelist(BaseModel):
bill_id = IntegerField(null=True, unique=True)
name = CharField(null=True)
params = UnknownField(null=True) # json
class Meta:
table_name = 'auth_pricelist'
class AuthRestrictions(BaseModel):
attempts_counting_duration = BigIntegerField()
attempts_max_count = IntegerField(null=True)
role = CharField(constraints=[SQL("DEFAULT ''")], unique=True)
time_between_attempts = BigIntegerField()
time_to_unban = BigIntegerField()
class Meta:
table_name = 'auth_restrictions'
class AuthRestrictionsBans(BaseModel):
banned_until = DateTimeField()
user = ForeignKeyField(column_name='user', field='id', model=AuthUser)
user_ip = CharField(null=True)
class Meta:
table_name = 'auth_restrictions_bans'
indexes = (
(('user', 'user_ip'), True),
)
class AuthRole(BaseModel):
data = UnknownField() # json
human_descr = CharField(null=True)
human_name = CharField(null=True)
name = CharField(constraints=[SQL("DEFAULT ''")], unique=True)
class Meta:
table_name = 'auth_role'
class AuthServer(BaseModel):
demo = IntegerField(constraints=[SQL("DEFAULT 0")])
host = CharField(null=True)
instance = ForeignKeyField(
column_name='instance',
field='id',
model=AuthInstance,
null=True,
unique=True
)
login = CharField(null=True)
machine_id = CharField(null=True)
password = CharField(null=True)
port = IntegerField(null=True)
class Meta:
table_name = 'auth_server'
indexes = (
(('host', 'port'), True),
)
class AuthService(BaseModel):
bill_id = IntegerField(null=True, unique=True)
info = UnknownField(null=True) # json
instance = ForeignKeyField(
column_name='instance',
field='id',
model=AuthInstance,
null=True,
unique=True
)
params = UnknownField(null=True) # json
payment_form = TextField(null=True)
status = CharField(null=True)
class Meta:
table_name = 'auth_service'
indexes = (
(('instance', 'bill_id'), True),
)
class AuthServiceDbkey(BaseModel):
dbkey = TextField(null=True)
name = CharField(null=True, unique=True)
class Meta:
table_name = 'auth_service_dbkey'
class AuthSession(BaseModel):
expires_at = DateTimeField(null=True)
is_internal = IntegerField(constraints=[SQL("DEFAULT 0")])
name = CharField(null=True, unique=True)
owner = ForeignKeyField(
column_name='owner',
field='id',
model=AuthUser,
null=True
)
trustee = ForeignKeyField(
backref='auth_user_trustee_set',
column_name='trustee',
field='id',
model=AuthUser,
null=True
)
updated_at = DateTimeField(null=True)
xsrf_token = CharField(null=True)
class Meta:
table_name = 'auth_session'
class AuthToken(BaseModel):
client_ip = CharField(null=True)
description = CharField(constraints=[SQL("DEFAULT ''")])
expires_at = DateTimeField(null=True)
last_used = DateTimeField()
name = CharField(constraints=[SQL("DEFAULT ''")], unique=True)
need_2fa = IntegerField(constraints=[SQL("DEFAULT 0")])
owner = ForeignKeyField(column_name='owner', field='id', model=AuthUser)
trustee = ForeignKeyField(
backref='auth_user_trustee_set',
column_name='trustee',
field='id',
model=AuthUser
)
class Meta:
table_name = 'auth_token'
class AuthTrusteeUser(BaseModel):
instance = ForeignKeyField(
column_name='instance',
field='id',
model=AuthInstance,
null=True
)
role = CharField(null=True)
trustee = ForeignKeyField(
column_name='trustee',
field='id',
model=AuthUser,
null=True
)
user = ForeignKeyField(
backref='auth_user_user_set',
column_name='user',
field='id',
model=AuthUser,
null=True
)
class Meta:
table_name = 'auth_trustee_user'
indexes = (
(('user', 'trustee', 'instance'), True),
)
class AuthUser2Acl(BaseModel):
acl = ForeignKeyField(column_name='acl', field='id', model=AuthAcl)
user = ForeignKeyField(column_name='user', field='id', model=AuthUser)
class Meta:
table_name = 'auth_user2acl'
indexes = (
(('user', 'acl'), True),
)
class AuthUserRole(BaseModel):
instance = ForeignKeyField(
column_name='instance',
field='id',
model=AuthInstance,
null=True
)
roles = UnknownField() # json
state = CharField(constraints=[SQL("DEFAULT 'active'")])
trustee = ForeignKeyField(
column_name='trustee',
field='id',
model=AuthUser
)
user = ForeignKeyField(
backref='auth_user_user_set',
column_name='user',
field='id',
model=AuthUser
)
class Meta:
table_name = 'auth_user_role'
indexes = (
(('user', 'trustee', 'instance'), True),
)
class AuthUserSetting(BaseModel):
data = UnknownField(null=True) # json
instance = ForeignKeyField(
column_name='instance',
field='id',
model=AuthInstance,
null=True
)
name = CharField(null=True)
user = ForeignKeyField(
column_name='user',
field='id',
model=AuthUser
)
class Meta:
table_name = 'auth_user_setting'
indexes = (
(('user', 'name', 'instance'), True),
)
class AuthUserSshkey(BaseModel):
name = CharField(constraints=[SQL("DEFAULT ''")])
owner = ForeignKeyField(
column_name='owner',
field='id',
model=AuthUser,
null=True
)
ssh_pub_key = TextField()
class Meta:
table_name = 'auth_user_sshkey'
indexes = (
(('name', 'owner'), True),
)
class AuthUsersLocks(BaseModel):
description = CharField(constraints=[SQL("DEFAULT ''")])
service_name = CharField()
user = ForeignKeyField(column_name='user', field='id', model=AuthUser)
class Meta:
table_name = 'auth_users_locks'
indexes = (
(('user', 'service_name'), True),
)
primary_key = CompositeKey('service_name', 'user')
class BackupAlembicVersion(BaseModel):
version_num = CharField(primary_key=True)
class Meta:
table_name = 'backup_alembic_version'
class BackupTask(BaseModel):
connection_params = TextField()
cron_expression = CharField()
enabled = IntegerField()
limit_count = IntegerField()
limit_size_mib = IntegerField(null=True)
name = CharField()
note = TextField()
schedule_type = CharField()
storage_type = CharField()
class Meta:
table_name = 'backup_task'
class BackupFile(BaseModel):
date = DateTimeField()
downloadable = IntegerField()
name = CharField()
size = FloatField()
storage_type = CharField()
task = ForeignKeyField(
column_name='task',
field='id',
model=BackupTask,
null=True
)
class Meta:
table_name = 'backup_file'
class CsDocuments(BaseModel):
lang = CharField(constraints=[SQL("DEFAULT ''")])
name = CharField(constraints=[SQL("DEFAULT ''")])
product = CharField(constraints=[SQL("DEFAULT ''")])
required = IntegerField(constraints=[SQL("DEFAULT 0")])
url = CharField(constraints=[SQL("DEFAULT ''")])
class Meta:
table_name = 'cs_documents'
indexes = (
(('product', 'lang', 'name'), True),
)
class CsSettings(BaseModel):
lang = CharField(constraints=[SQL("DEFAULT ''")])
product = CharField(constraints=[SQL("DEFAULT ''")])
prop_key = CharField(constraints=[SQL("DEFAULT ''")])
prop_value = CharField(constraints=[SQL("DEFAULT ''")])
class Meta:
table_name = 'cs_settings'
indexes = (
(('product', 'lang', 'prop_key'), True),
)
class EserviceAlembicVersion(BaseModel):
version_num = CharField(primary_key=True)
class Meta:
table_name = 'eservice_alembic_version'
class EserviceCustomEquipment(BaseModel):
data = TextField(null=True)
device_type = CharField()
features = UnknownField(null=True) # json
handler = CharField(unique=True)
handler_import = CharField(null=True)
name = CharField(unique=True)
protocol = UnknownField(null=True) # json
update_time = DateTimeField()
version = CharField()
class Meta:
table_name = 'eservice_custom_equipment'
class EserviceIpmiFru(BaseModel):
fru_info = UnknownField(null=True) # json
ipmi_id = AutoField()
update_time = DateTimeField()
class Meta:
table_name = 'eservice_ipmi_fru'
class EserviceIpmiInfo(BaseModel):
ipmi_id = AutoField()
model = CharField()
class Meta:
table_name = 'eservice_ipmi_info'
class EserviceIpmiSensors(BaseModel):
ipmi_id = AutoField()
sensors_info = UnknownField(null=True) # json
update_time = DateTimeField()
class Meta:
table_name = 'eservice_ipmi_sensors'
class IpmiProxyLocation(BaseModel):
docker_compose = TextField(null=True)
instance = IntegerField(null=True)
location = IntegerField(null=True)
status = CharField(constraints=[SQL("DEFAULT 'setting_up'")])
status_info = UnknownField(null=True) # json
supported_ipmi_consoles = UnknownField(null=True) # json
class Meta:
table_name = 'ipmi_proxy_location'
indexes = (
(('instance', 'location'), True),
)
class IpmiProxyConnection(BaseModel):
close_time = DateTimeField(null=True)
connection_data = UnknownField(null=True) # json
device_data = UnknownField(null=True) # json
intel_amt = IntegerField(null=True)
ipmi = IntegerField(null=True)
listen_web_port = IntegerField(null=True, unique=True)
location = ForeignKeyField(
column_name='location_id',
field='id',
model=IpmiProxyLocation
)
type = CharField(constraints=[SQL("DEFAULT 'web'")])
user = IntegerField(null=True)
vnc_port = IntegerField(null=True)
class Meta:
table_name = 'ipmi_proxy_connection'
class IpmiProxyJavaAgreement(BaseModel):
instance = IntegerField(null=True, unique=True)
java_agree = IntegerField(constraints=[SQL("DEFAULT 1")])
class Meta:
table_name = 'ipmi_proxy_java_agreement'
class IpmiProxyPlugin(BaseModel):
instance = IntegerField(null=True, unique=True)
class Meta:
table_name = 'ipmi_proxy_plugin'
class IspSettings(BaseModel):
name = CharField(primary_key=True)
value = TextField()
class Meta:
table_name = 'isp_settings'
class JournalAlembicVersion(BaseModel):
version_num = CharField(primary_key=True)
class Meta:
table_name = 'journal_alembic_version'
class JournalEvents(BaseModel):
data = UnknownField(null=True) # json
date_time = DateTimeField(
constraints=[SQL("DEFAULT CURRENT_TIMESTAMP(3)")]
)
entity_id = IntegerField()
entity_name = CharField()
entity_owner = IntegerField()
entity_type = CharField()
ip = CharField()
roles = UnknownField(null=True) # json
trustee_email = CharField(index=True)
trustee_id = IntegerField()
type = CharField()
user_email = CharField(index=True)
user_id = IntegerField()
class Meta:
table_name = 'journal_events'
class MsgsChannel(BaseModel):
comment = TextField(null=True)
creation_date = DateTimeField(null=True)
delivery_method = CharField()
enabled = IntegerField(constraints=[SQL("DEFAULT 1")])
language = CharField()
name = CharField()
params = UnknownField(null=True) # json
state = CharField(null=True)
class Meta:
table_name = 'msgs_channel'
class MsgsDeliveryMethod(BaseModel):
delivery_method = CharField(primary_key=True)
dm_params = UnknownField(null=True) # json
class Meta:
table_name = 'msgs_delivery_method'
class MsgsMessageDesign(BaseModel):
design = CharField(primary_key=True)
class Meta:
table_name = 'msgs_message_design'
class MsgsMessageDesignVariant(BaseModel):
delivery_method = CharField()
design = CharField()
design_content = TextField(null=True)
language = CharField()
class Meta:
table_name = 'msgs_message_design_variant'
indexes = (
(('design', 'delivery_method', 'language'), True),
(('design', 'delivery_method', 'language'), True),
)
primary_key = CompositeKey('delivery_method', 'design', 'language')
class MsgsNoticeReceiver(BaseModel):
delivery_method = CharField()
receivers = UnknownField(null=True) # json
user = IntegerField(null=True)
class Meta:
table_name = 'msgs_notice_receiver'
indexes = (
(('user', 'delivery_method'), True),
)
class MsgsTemplate(BaseModel):
priority = CharField()
template = CharField(primary_key=True)
class Meta:
table_name = 'msgs_template'
class MsgsTemplate2Category(BaseModel):
category = CharField()
template = CharField()
class Meta:
table_name = 'msgs_template2category'
indexes = (
(('template', 'category'), True),
(('template', 'category'), True),
)
primary_key = CompositeKey('category', 'template')
class MsgsTemplateVariant(BaseModel):
delivery_method = CharField()
language = CharField()
template = CharField()
tv_params = UnknownField(null=True) # json
class Meta:
table_name = 'msgs_template_variant'
indexes = (
(('template', 'delivery_method', 'language'), True),
(('template', 'delivery_method', 'language'), True),
)
primary_key = CompositeKey('delivery_method', 'language', 'template')
class MsgsUser(BaseModel):
language = CharField()
user = AutoField()
class Meta:
table_name = 'msgs_user'
class MsgsUser2DeliveryMethod(BaseModel):
delivery_method = CharField()
u2dm_params = UnknownField(null=True) # json
user = IntegerField()
class Meta:
table_name = 'msgs_user2delivery_method'
indexes = (
(('user', 'delivery_method'), True),
(('user', 'delivery_method'), True),
)
primary_key = CompositeKey('delivery_method', 'user')
class MsgsUserSubscription(BaseModel):
category = CharField()
delivery_method = CharField()
user = IntegerField()
class Meta:
table_name = 'msgs_user_subscription'
indexes = (
(('user', 'delivery_method', 'category'), True),
)
primary_key = CompositeKey('category', 'delivery_method', 'user')
class NcNotice(BaseModel):
create_timestamp = IntegerField(null=True)
entity = UnknownField(null=True) # json
params = UnknownField(null=True) # json
status = CharField(constraints=[SQL("DEFAULT 'sended'")])
timestamp = IntegerField(null=True)
type = CharField(null=True)
class Meta:
table_name = 'nc_notice'
class NcUser(BaseModel):
last_notice_timestamp = IntegerField(constraints=[SQL("DEFAULT 0")])
read_timestamp = IntegerField(constraints=[SQL("DEFAULT 0")])
class Meta:
table_name = 'nc_user'
class NcNotice2User(BaseModel):
notice = ForeignKeyField(
column_name='notice',
field='id',
model=NcNotice,
null=True
)
read_timestamp = IntegerField(constraints=[SQL("DEFAULT 0")])
user = ForeignKeyField(
column_name='user',
field='id',
model=NcUser,
null=True
)
class Meta:
table_name = 'nc_notice2user'
indexes = (
(('user', 'notice'), True),
)
class NotifierNotify(BaseModel):
additional_info = UnknownField() # json
description = UnknownField() # json
instance_id = IntegerField(null=True)
modify_index = BigIntegerField()
name = CharField(null=True)
notify_type = CharField()
owner = IntegerField(null=True)
request_id = CharField(null=True)
request_ip = CharField(null=True)
time = DateTimeField(
constraints=[SQL("DEFAULT CURRENT_TIMESTAMP")],
index=True
)
trustee = IntegerField(null=True)
class Meta:
table_name = 'notifier_notify'
class PsPlugin(BaseModel):
content = TextField()
current_version = CharField(null=True)
deprecated = IntegerField(constraints=[SQL("DEFAULT 0")])
filename = CharField(null=True)
intname = CharField(null=True, unique=True)
metadata = UnknownField() # json
name = CharField(null=True, unique=True)
obsoletes = UnknownField(null=True) # json
plugin_requirement = UnknownField(null=True) # json
product = CharField()
remote = IntegerField(constraints=[SQL("DEFAULT 0")])
status = CharField(constraints=[SQL("DEFAULT 'disabled'")])
version = CharField(null=True)
class Meta:
table_name = 'ps_plugin'
class PsPluginLicense(BaseModel):
instance = IntegerField(null=True)
license = UnknownField(null=True) # json
plugin = IntegerField(null=True)
class Meta:
table_name = 'ps_plugin_license'
indexes = (
(('instance', 'plugin'), True),
)
class ReportAlembicVersion(BaseModel):
version_num = CharField(primary_key=True)
class Meta:
table_name = 'report_alembic_version'
class ReportFile(BaseModel):
additional_info = UnknownField(null=True) # json
content = TextField(null=True)
create_datetime = DateTimeField()
entity = CharField()
entity_ids = UnknownField() # json
filename = CharField(null=True)
is_read = IntegerField()
status = CharField()
status_info = UnknownField(null=True) # json
type = CharField()
class Meta:
table_name = 'report_file'
class TaskmgrTask(BaseModel):
before_execute = UnknownField(null=True) # json
bin_args = UnknownField(null=True) # json
bin_path = CharField(constraints=[SQL("DEFAULT ''")])
callback_params = UnknownField(null=True) # json
defer_resolve = UnknownField(null=True) # json
defer_wait = UnknownField(null=True) # json
depends_on = UnknownField(null=True) # json
env = UnknownField(null=True) # json
instance_id = CharField(null=True)
lock_tag = UnknownField(null=True) # json
name = CharField(constraints=[SQL("DEFAULT ''")])
notify = UnknownField(null=True) # json
on_start = UnknownField(null=True) # json
output = TextField()
queue = UnknownField(null=True) # json
registration_time = DateTimeField(
constraints=[SQL("DEFAULT CURRENT_TIMESTAMP")]
)
request_info = UnknownField(null=True) # json
return_code = IntegerField()
service = CharField(constraints=[SQL("DEFAULT ''")])
status = CharField(constraints=[SQL("DEFAULT 'created'")], index=True)
stdin = UnknownField(null=True) # json
ttl = IntegerField()
work_dir = CharField(constraints=[SQL("DEFAULT ''")])
worker_id = CharField(null=True)
class Meta:
table_name = 'taskmgr_task'
class Vault(BaseModel):
key = CharField(unique=True)
value = TextField()
class Meta:
table_name = 'vault'
class VaultAlembicVersion(BaseModel):
version_num = CharField(primary_key=True)
class Meta:
table_name = 'vault_alembic_version'
class VaultQueryLog(BaseModel):
date = DateTimeField()
owner_email = CharField()
owner_id = IntegerField()
request_id = CharField()
request_ip = CharField()
service = CharField()
trustee_id = IntegerField()
class Meta:
table_name = 'vault_query_log'

View File

View File

@@ -0,0 +1,8 @@
from mgrctl.db.connection import guess_database
# The variable will contain an object of
# the MySQLDatabase or PostgresqlDatabase class as well as all connection data
# If in the future there will be more databases in the platform,
# they should be added here
isp_database = guess_database('isp')

3156
mgrctl/db/vm6/models.py Normal file

File diff suppressed because it is too large Load Diff

32
mgrctl/mgrctl.py Executable file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# █▀▄▀█ █▀▀ █▀█ █▀▀ ▀█▀ █░░ ▀
# █░▀░█ █▄█ █▀▄ █▄▄ ░█░ █▄▄ ▄
# -- -- -- -- -- -- -- -- --
import click
from mgrctl import __version__
from mgrctl.cli.lazy_group import LazyGroup
@click.group(
cls=LazyGroup,
lazy_subcommands={
'vm6': 'mgrctl.apps.vm6.commands.cli',
'dci6': 'mgrctl.apps.dci6.commands.cli',
},
help='main CLI command for lazy example',
)
@click.version_option(
version=__version__,
package_name='mgrctl',
message=__version__
)
def cli():
pass
if __name__ == '__main__':
cli()

View File

@@ -0,0 +1,15 @@
from mgrctl.settings.general import BASE_DIR
from mgrctl.settings.platform import (
PLATFORM_TYPE,
PLATFORM_URL,
PLATFORM_CONFIG
)
from mgrctl.settings.db import(
DB_ENGINE,
DB_HOST,
DB_PORT,
DB_USER,
DB_PASSWORD
)

10
mgrctl/settings/api.py Normal file
View File

@@ -0,0 +1,10 @@
from mgrctl.settings.platform import PLATFORM_TYPE
# Name of nginx container:
INPUT_HOSTNAME = 'input' if PLATFORM_TYPE == 'vm' else 'dci_input_1'
# Port that nginx container is listening:
INPUT_PORT = '1500'
# Headers for internal auth:
HEADERS = {"Internal-Auth": "on", "Accept": "application/json"}

23
mgrctl/settings/db.py Normal file
View File

@@ -0,0 +1,23 @@
from mgrctl.settings.environment import env
from mgrctl.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', '')
)

View 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()

View File

@@ -0,0 +1,14 @@
import pathlib
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = pathlib.Path(__file__).resolve().parent.parent
INSTALLED_APPS = {
'vm6': {
'auth': 'mgrctl.apps.vm6.auth.commands.cli',
},
'dci6': {
'auth': 'mgrctl.apps.dci6.auth.commands.cli',
},
}

View File

@@ -0,0 +1,17 @@
from mgrctl.settings.environment import env
from mgrctl.utils.helpers import parse_json_file
PLATFORM_TYPE = env.str('PLATFORM_TYPE', 'vm')
PLATFORM_CONFIG = env.str(
'PLATFORM_CONFIG',
f'/opt/ispsystem/{PLATFORM_TYPE}/config.json'
)
PLATFORM_CONFIG = parse_json_file(PLATFORM_CONFIG)
PLATFORM_URL = env.url(
'PLATFORM_URL',
f"https://{PLATFORM_CONFIG.get('DomainName' ,'replace.me')}"
)

0
mgrctl/utils/__init__.py Normal file
View File

23
mgrctl/utils/helpers.py Normal file
View File

@@ -0,0 +1,23 @@
import json
import sys
import click
def parse_json_file(file_path: str) -> dict:
"""
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:
click.echo(error)
click.echo("Required: /opt/ispsystem/PLATFORM_TYPE/config.json")
click.echo("Note: don't forget to mount this file into the container")
sys.exit(1)