From 3a9c18392bc9b9a1438a4cc27b7c8407acccb7a9 Mon Sep 17 00:00:00 2001 From: Aidaho Date: Sat, 12 Oct 2024 08:43:32 +0300 Subject: [PATCH] v8.2: Update service settings, backup models, and DB schema Added support for managing Docker settings and improved the handling of service-specific configurations. Updated various backup methods and database columns to ensure consistency and clarity. Included new database migration scripts to handle renamed columns. --- app/create_db.py | 31 ++++++++++++++ app/modules/db/backup.py | 25 ++++------- app/modules/db/db_model.py | 4 +- app/modules/service/backup.py | 5 +-- app/views/install/views.py | 1 + app/views/server/backup_vews.py | 74 ++++++++++++++++++++++++++++++++- app/views/service/views.py | 15 +++++++ 7 files changed, 132 insertions(+), 23 deletions(-) diff --git a/app/create_db.py b/app/create_db.py index da9190e1..0a2de27c 100644 --- a/app/create_db.py +++ b/app/create_db.py @@ -635,6 +635,7 @@ def update_db_v_8_1(): else: print("An error occurred:", e) + def update_db_v_8_1_0_1(): try: migrate( @@ -649,6 +650,34 @@ def update_db_v_8_1_0_1(): print("An error occurred:", e) +def update_db_v_8_1_0_2(): + try: + migrate( + migrator.rename_column('backups', 'rhost', 'rserver') + ) + except Exception as e: + if e.args[0] == 'no such column: "rhost"' or str(e) == '(1060, no such column: "rhost")': + print("Updating... DB has been updated to version 8.2") + elif e.args[0] == "'bool' object has no attribute 'sql'": + print("Updating... DB has been updated to version 8.2") + else: + print("An error occurred:", e) + + +def update_db_v_8_1_0_3(): + try: + migrate( + migrator.rename_column('git_setting', 'period', 'time') + ) + except Exception as e: + if e.args[0] == 'no such column: "period"' or str(e) == '(1060, no such column: "period")': + print("Updating... DB has been updated to version 8.2") + elif e.args[0] == "'bool' object has no attribute 'sql'": + print("Updating... DB has been updated to version 8.2") + else: + print("An error occurred:", e) + + def update_ver(): try: Version.update(version='8.1.0').execute() @@ -679,4 +708,6 @@ def update_all(): update_db_v_8_0_2_1() update_db_v_8_1() update_db_v_8_1_0_1() + update_db_v_8_1_0_2() + update_db_v_8_1_0_3() update_ver() diff --git a/app/modules/db/backup.py b/app/modules/db/backup.py index 62aa38cf..46a63b91 100644 --- a/app/modules/db/backup.py +++ b/app/modules/db/backup.py @@ -12,7 +12,7 @@ models = { def insert_backup_job(server_id, rserver, rpath, backup_type, time, cred, description): try: return Backup.insert( - server_id=server_id, rhost=rserver, rpath=rpath, type=backup_type, time=time, + server_id=server_id, rserver=rserver, rpath=rpath, type=backup_type, time=time, cred_id=cred, description=description ).execute() except Exception as e: @@ -26,21 +26,12 @@ def insert_s3_backup_job(**kwargs): out_error(e) -def update_s3_backup_job(backup_id: int, model: str, **kwargs): +def update_backup_job(backup_id: int, model: str, **kwargs): model = models[model] try: - return model.update(**kwargs).where(model.id == backup_id).execute() - except Exception as e: - out_error(e) - - -def update_backup(server_id, rserver, rpath, backup_type, time, cred, description, backup_id): - backup_update = Backup.update( - server_id=server_id, rhost=rserver, rpath=rpath, type=backup_type, time=time, - cred_id=cred, description=description - ).where(Backup.id == backup_id) - try: - backup_update.execute() + model.update(**kwargs).where(model.id == backup_id).execute() + except model.DoesNotExist: + raise RoxywiResourceNotFound except Exception as e: out_error(e) @@ -53,10 +44,10 @@ def delete_backup(backup_id: int, model: str) -> None: out_error(e) -def insert_new_git(server_id, service_id, repo, branch, period, cred, description) -> int: +def insert_new_git(server_id, service_id, repo, branch, time, cred, description) -> int: try: return GitSetting.insert( - server_id=server_id, service_id=service_id, repo=repo, branch=branch, period=period, + server_id=server_id, service_id=service_id, repo=repo, branch=branch, time=time, cred_id=cred, description=description ).execute() except Exception as e: @@ -93,7 +84,7 @@ def select_backups(**kwargs): def select_s3_backups(**kwargs): if kwargs.get("server") is not None and kwargs.get("bucket") is not None: query = S3Backup.select().where( - (S3Backup.server == kwargs.get("server")) & + (S3Backup.server_id == kwargs.get("server")) & (S3Backup.s3_server == kwargs.get("s3_server")) & (S3Backup.bucket == kwargs.get("bucket")) ) diff --git a/app/modules/db/db_model.py b/app/modules/db/db_model.py index 6970b9fe..7a673d36 100644 --- a/app/modules/db/db_model.py +++ b/app/modules/db/db_model.py @@ -211,7 +211,7 @@ class Cred(BaseModel): class Backup(BaseModel): id = AutoField() server_id = CharField() - rhost = CharField() + rserver = CharField() rpath = CharField() type = CharField(column_name='type') time = CharField() @@ -514,7 +514,7 @@ class GitSetting(BaseModel): id = AutoField() server_id = ForeignKeyField(Server, on_delete='Cascade') service_id = IntegerField() - period = CharField() + time = CharField() repo = CharField(null=True) branch = CharField(null=True) cred_id = IntegerField() diff --git a/app/modules/service/backup.py b/app/modules/service/backup.py index aef5f1a0..6033ce83 100644 --- a/app/modules/service/backup.py +++ b/app/modules/service/backup.py @@ -105,8 +105,7 @@ def delete_backup(json_data: BackupRequest, backup_id: int) -> tuple: def update_backup(json_data: BackupRequest, backup_id: int) -> tuple: create_backup_inv(json_data) - backup_sql.update_backup(json_data.server_id, json_data.rserver, json_data.rpath, json_data.type, - json_data.time, json_data.cred_id, json_data.description, backup_id) + backup_sql.update_backup_job(backup_id, 'fs', **json_data.model_dump(mode='json')) roxywi_common.logging('backup ', f'A backup job for server {json_data.server_id} has been updated', roxywi=1, login=1) return BaseResponse().model_dump(mode='json'), 201 @@ -151,7 +150,7 @@ def create_git_backup(data: GitBackupRequest, is_api: bool) -> tuple: raise Exception(e) try: - last_id = backup_sql.insert_new_git(server_id=data.server_id, service_id=data.service_id, repo=data.repo, branch=data.branch, period=data.time, + last_id = backup_sql.insert_new_git(server_id=data.server_id, service_id=data.service_id, repo=data.repo, branch=data.branch, time=data.time, cred=data.cred_id, description=data.description) roxywi_common.logging(server_ip, 'A new git job has been created', roxywi=1, login=1, keep_history=1, service=service_name) diff --git a/app/views/install/views.py b/app/views/install/views.py index 954508d4..8c9e350f 100644 --- a/app/views/install/views.py +++ b/app/views/install/views.py @@ -190,6 +190,7 @@ class InstallView(MethodView): """ try: service_sql.update_hapwi_server(server_id, body.checker, body.metrics, body.auto_start, service) + service_sql.insert_or_update_service_setting(server_id, service, 'dockerized', int(body.docker)) except Exception as e: return roxywi_common.handler_exceptions_for_json_data(e, f'Cannot update Tools settings for {service.title()}') return IdStrResponse(id=f'{server_id}-{service}').model_dump(mode='json'), 201 diff --git a/app/views/server/backup_vews.py b/app/views/server/backup_vews.py index 64ee793e..84290c76 100644 --- a/app/views/server/backup_vews.py +++ b/app/views/server/backup_vews.py @@ -5,6 +5,8 @@ from playhouse.shortcuts import model_to_dict from flask_jwt_extended import jwt_required import app.modules.db.backup as backup_sql +import app.modules.db.server as server_sql +import app.modules.db.service as service_sql import app.modules.service.backup as backup_mod import app.modules.roxywi.common as roxywi_common from app.middleware import get_user_params, page_for_admin, check_group @@ -66,6 +68,8 @@ class BackupView(MethodView): """ try: backup = backup_sql.get_backup(backup_id, 'fs') + backup.server_id = int(backup.server_id) + backup.description = str(backup.description).replace("'", "") except Exception as e: return roxywi_common.handler_exceptions_for_json_data(e, '') @@ -287,6 +291,8 @@ class S3BackupView(MethodView): """ try: backup = backup_sql.get_backup(backup_id, 's3') + backup.server_id = int(backup.server_id) + backup.description = str(backup.description).replace("'", "") except Exception as e: return roxywi_common.handler_exceptions_for_json_data(e, '') @@ -404,7 +410,7 @@ class S3BackupView(MethodView): """ try: backup_mod.create_s3_backup_inv(body, 'add') - backup_sql.update_s3_backup_job(backup_id, 's3') + backup_sql.update_backup_job(backup_id, 's3', **body.model_dump(mode='json')) except Exception as e: return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot update S3 backup') @@ -569,6 +575,72 @@ class GitBackupView(MethodView): except Exception as e: return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot create GIT backup') + @validate(body=GitBackupRequest) + def put(self, backup_id: int, body: GitBackupRequest): + """ + Update a new Git backup. + --- + tags: + - Git Backup + parameters: + - name: config + in: body + required: true + description: The configuration for Git backup service + schema: + type: 'object' + required: + - cred_id + - server_id + - service_id + - init + - repo + - branch + - time + properties: + server_id: + type: 'integer' + description: 'The ID of the server to backed up' + service_id: + type: 'integer' + description: 'Service ID: 1: HAProxy, 2: NGINX, 3: Keepalived, 4: Apache' + example: 1 + init: + type: 'integer' + description: 'Indicates whether to initialize the repository' + repo: + type: 'string' + description: 'The repository from where to fetch the data for backup' + example: git@github.com:Example/haproxy_configs + branch: + type: 'string' + description: 'The branch to pull for backup' + example: 'master' + time: + type: 'string' + description: 'The timing for the Git backup task' + enum: [hourly, daily, weekly, monthly] + cred_id: + type: 'integer' + description: 'The ID of the credentials to be used for backup' + description: + type: 'string' + description: 'Description for the Git backup configuration' + responses: + 201: + description: Successful operation + default: + description: Unexpected error + """ + try: + server = server_sql.get_server_by_id(body.server_id) + service_name = service_sql.select_service_name_by_id(body.service_id).lower() + backup_mod.create_git_backup_inv(body, server.ip, service_name) + backup_sql.update_backup_job(backup_id, 'git', **body.model_dump(mode='json', exclude={'init'})) + except Exception as e: + return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot update GIT backup') + return BaseResponse().model_dump(mode='json'), 201 + @validate(body=GitBackupRequest) def delete(self, backup_id: int, body: GitBackupRequest): """ diff --git a/app/views/service/views.py b/app/views/service/views.py index d9c21378..a499c3dc 100644 --- a/app/views/service/views.py +++ b/app/views/service/views.py @@ -103,6 +103,10 @@ class ServiceView(MethodView): data = ErrorResponse(error='Cannot get information').model_dump(mode='json') else: data['Status'] = self._service_status(data['Process']) + data['auto_start'] = int(server.haproxy_active) + data['checker'] = int(server.haproxy_alert) + data['metrics'] = int(server.haproxy_metrics) + data['docker'] = int(service_sql.select_service_setting(server_id, service, 'dockerized')) elif service == 'nginx': is_dockerized = service_sql.select_service_setting(server_id, service, 'dockerized') if is_dockerized == '1': @@ -141,6 +145,10 @@ class ServiceView(MethodView): return ErrorResponse(error='NGINX service not found').model_dump(mode='json'), 404 except Exception as e: data = ErrorResponse(error=str(e)).model_dump(mode='json') + data['auto_start'] = int(server.nginx_active) + data['checker'] = int(server.nginx_alert) + data['metrics'] = int(server.nginx_metrics) + data['docker'] = int(is_dockerized) elif service == 'apache': apache_stats_user = sql.get_setting('apache_stats_user') apache_stats_password = sql.get_setting('apache_stats_password') @@ -169,6 +177,11 @@ class ServiceView(MethodView): } except Exception as e: data = ErrorResponse(error=str(e)).model_dump(mode='json') + + data['auto_start'] = int(server.apache_active) + data['checker'] = int(server.apache_alert) + data['metrics'] = int(server.apache_metrics) + data['docker'] = int(service_sql.select_service_setting(server_id, service, 'dockerized')) elif service == 'keepalived': cmd = ("sudo /usr/sbin/keepalived -v 2>&1|head -1|awk '{print $2}' && sudo systemctl status keepalived |grep -e 'Active'" "|awk '{print $2, $9$10$11$12$13}' && ps ax |grep 'keepalived '|grep -v udp|grep -v grep |wc -l") @@ -182,6 +195,8 @@ class ServiceView(MethodView): return ErrorResponse(error='Keepalived service not found').model_dump(mode='json'), 404 except Exception as e: return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot get version') + data['service'] = service + data['server_id'] = server_id data['id'] = f'{server_id}-{service}' return jsonify(data)