haproxy-wi/app/views/server/backup_vews.py

680 lines
24 KiB
Python

from flask.views import MethodView
from flask_pydantic import validate
from flask import jsonify
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
from app.modules.roxywi.class_models import BackupRequest, S3BackupRequest, GitBackupRequest, BaseResponse
class BackupView(MethodView):
methods = ['GET', 'POST', 'PUT', 'DELETE']
decorators = [jwt_required(), get_user_params(), page_for_admin(), check_group()]
def __init__(self, is_api=True):
self.is_api = is_api
@staticmethod
def get(backup_id: int):
"""
Retrieves the details of a specific backup configuration.
---
tags:
- File system backup
parameters:
- in: path
name: backup_id
type: integer
required: true
description: The ID of the specific backup
responses:
200:
description: Successful operation
schema:
type: 'object'
properties:
cred_id:
type: 'integer'
description: 'Credentials ID for the backup task'
description:
type: 'string'
description: 'Description for the backup configuration'
id:
type: 'integer'
description: 'Unique identifier of the backup configuration'
rhost:
type: 'string'
description: 'The remote server where backup files should be stored'
rpath:
type: 'string'
description: 'The path on the remote server where backup files should be stored'
server:
type: 'string'
description: 'The server to be backed up'
time:
type: 'string'
description: 'The timing for the backup task'
type:
type: 'string'
description: 'Type of the operation'
default:
description: Unexpected error
"""
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, '')
return jsonify(model_to_dict(backup))
@validate(body=BackupRequest)
def post(self, body: BackupRequest):
"""
Create a new file system backup for services.
---
tags:
- File system backup
parameters:
- name: config
in: body
required: true
description: The configuration for backup service
schema:
type: 'object'
required:
- cred_id
- rhost
- rpath
- server_id
- rserver
- time
- type
properties:
server_id:
type: 'string'
description: 'The server ID to be backed up'
rserver:
type: 'string'
description: 'The remote server where backup files should be stored'
example: 10.0.0.1
rpath:
type: 'string'
description: 'The path on the remote server where backup files should be stored'
example: /var/backup/
type:
type: 'string'
description: 'Type of the operation'
enum: [backup, synchronization]
time:
type: 'string'
description: 'The timing for the backup task'
enum: [hourly, daily, weekly, monthly]
cred_id:
type: 'string'
description: 'Credentials ID for the backup task'
description:
type: 'string'
description: 'Description for the backup configuration'
responses:
201:
description: Successful operation
default:
description: Unexpected error
"""
try:
return backup_mod.create_backup(body, self.is_api)
except Exception as e:
return roxywi_common.handler_exceptions_for_json_data(e, '')
@validate(body=BackupRequest)
def put(self, backup_id: int, body: BackupRequest):
"""
Update the file system backup for services.
---
tags:
- File system backup
parameters:
- in: 'path'
name: 'backup_id'
description: 'ID of the backup to be updated'
required: true
type: 'integer'
- name: config
in: body
required: true
description: The configuration for backup service
schema:
type: 'object'
required:
- cred_id
- rhost
- rpath
- server_id
- rserver
- time
- type
properties:
server_id:
type: 'integer'
description: 'The server ID to be backed up'
rserver:
type: 'string'
description: 'The remote server where backup files should be stored'
example: 10.0.0.1
rpath:
type: 'string'
description: 'The path on the remote server where backup files should be stored'
example: /var/backup/
type:
type: 'string'
description: 'Type of the operation'
enum: [backup, synchronization]
time:
type: 'string'
description: 'The timing for the backup task'
enum: [hourly, daily, weekly, monthly]
cred_id:
type: 'string'
description: 'Credentials ID for the backup task'
description:
type: 'string'
description: 'Description for the backup configuration'
responses:
201:
description: Successful operation
default:
description: Unexpected error
"""
try:
return backup_mod.update_backup(body, backup_id)
except Exception as e:
return roxywi_common.handler_exceptions_for_json_data(e, '')
@validate(body=BackupRequest)
def delete(self, backup_id: int, body: BackupRequest):
"""
Delete the file system backup for services.
---
tags:
- File system backup
parameters:
- in: 'path'
name: 'backup_id'
description: 'ID of the backup to be deleted'
required: true
type: 'integer'
- name: config
in: body
required: true
description: The configuration for backup service
schema:
type: 'object'
properties:
server_id:
type: 'integer'
description: 'The server ID to be backed up'
cred_id:
type: 'string'
description: 'Credentials ID for the backup task'
responses:
204:
description: Successful operation
default:
description: Unexpected error
"""
try:
return backup_mod.delete_backup(body, backup_id)
except Exception as e:
return roxywi_common.handler_exceptions_for_json_data(e, '')
class S3BackupView(MethodView):
methods = ['GET', 'POST', 'DELETE']
decorators = [jwt_required(), get_user_params(), page_for_admin(), check_group()]
def __init__(self, is_api=True):
self.is_api = is_api
@staticmethod
def get(backup_id: int):
"""
Retrieves the details of a specific S3 backup configuration.
---
tags:
- S3 Backup
parameters:
- in: path
name: backup_id
type: 'integer'
required: true
description: The ID of the specific S3 backup
responses:
200:
description: Successful operation
schema:
type: 'object'
properties:
access_key:
type: 'string'
description: 'The access key for S3'
bucket:
type: 'string'
description: 'The S3 bucket where the backup is stored'
description:
type: 'string'
description: 'Description for the S3 backup configuration'
id:
type: 'integer'
description: 'Unique identifier of the S3 backup configuration'
s3_server:
type: 'string'
description: 'The S3 server where the backup is stored'
secret_key:
type: 'string'
description: 'The secret key for S3 access'
server_id:
type: 'integer'
description: 'The server ID that was backed up'
time:
type: 'string'
description: 'The timing for the S3 backup task'
default:
description: Unexpected error
"""
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, '')
return jsonify(model_to_dict(backup))
@validate(body=S3BackupRequest)
def post(self, body: S3BackupRequest):
"""
Create a new S3 backup.
---
tags:
- S3 Backup
parameters:
- name: config
in: body
required: true
description: The configuration for S3 backup service
schema:
type: 'object'
required:
- s3_server
- server_id
- bucket
- secret_key
- access_key
- time
properties:
s3_server:
type: 'string'
description: 'The S3 server where the backup should be stored'
server_id:
type: 'integer'
description: 'The server ID to be backed up'
bucket:
type: 'string'
description: 'The S3 bucket where the backup should be stored'
secret_key:
type: 'string'
description: 'The secret key for S3 access'
access_key:
type: 'string'
description: 'The access key for S3'
time:
type: 'string'
description: 'The timing for the S3 backup task'
enum: [hourly, daily, weekly, monthly]
description:
type: 'string'
description: 'Description for the S3 backup configuration'
responses:
201:
description: Successful operation
default:
description: Unexpected error
"""
try:
return backup_mod.create_s3_backup(body, self.is_api)
except Exception as e:
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot create S3 backup')
@validate(body=S3BackupRequest)
def put(self, backup_id: int, body: S3BackupRequest):
"""
Update the S3 backup.
---
tags:
- S3 Backup
parameters:
- in: path
name: backup_id
type: 'integer'
required: true
description: The ID of the specific S3 backup
- name: config
in: body
required: true
description: The configuration for S3 backup service
schema:
type: 'object'
required:
- s3_server
- server_id
- bucket
- secret_key
- access_key
- time
properties:
s3_server:
type: 'string'
description: 'The S3 server where the backup should be stored'
server_id:
type: 'integer'
description: 'The server ID to be backed up'
bucket:
type: 'string'
description: 'The S3 bucket where the backup should be stored'
secret_key:
type: 'string'
description: 'The secret key for S3 access'
access_key:
type: 'string'
description: 'The access key for S3'
time:
type: 'string'
description: 'The timing for the S3 backup task'
enum: [hourly, daily, weekly, monthly]
description:
type: 'string'
description: 'Description for the S3 backup configuration'
responses:
201:
description: Successful operation
default:
description: Unexpected error
"""
try:
backup_mod.create_s3_backup_inv(body, 'add')
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')
@validate(body=S3BackupRequest)
def delete(self, backup_id: int, body: S3BackupRequest):
"""
Deletes a specific S3 based backup configuration.
---
tags:
- S3 Backup
parameters:
- in: path
name: backup_id
type: 'integer'
required: true
description: The ID of the specific S3 backup
- in: body
name: s3_details
required: true
description: The details of the S3 backup to be deleted
schema:
type: 'object'
properties:
bucket:
type: 'string'
description: 'The S3 bucket where the backup is stored'
server_id:
type: 'integer'
description: 'The server ID that was backed up'
responses:
200:
description: Successful operation
default:
description: Unexpected error
"""
try:
backup_mod.delete_s3_backup(body, backup_id)
return BaseResponse().model_dump(mode='json'), 204
except Exception as e:
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot delete S3 backup')
class GitBackupView(MethodView):
methods = ['GET', 'POST', 'DELETE']
decorators = [jwt_required(), get_user_params(), page_for_admin(), check_group()]
def __init__(self, is_api=True):
self.is_api = is_api
@staticmethod
def get(backup_id: int):
"""
Retrieves the details of a specific Git backup configuration.
---
tags:
- Git Backup
parameters:
- in: path
name: backup_id
type: 'integer'
required: true
description: The ID of the specific Git backup
responses:
200:
description: Successful operation
schema:
type: 'object'
properties:
branch:
type: 'string'
description: 'The branch the backup is on'
cred_id:
type: 'integer'
description: 'The ID of the credentials used for the backup'
description:
type: 'string'
description: 'Description for the Git backup configuration'
id:
type: 'integer'
description: 'The ID of the backup'
period:
type: 'string'
description: 'The timing for the Git backup task'
repo:
type: 'string'
description: 'The repository URL for the backup'
server_id:
type: 'integer'
description: 'The ID of the server that was backed up'
service_id:
type: 'integer'
description: 'The service ID of the backup'
default:
description: Unexpected error
"""
try:
backup = backup_sql.get_backup(backup_id, 'git')
except Exception as e:
return roxywi_common.handler_exceptions_for_json_data(e, '')
return jsonify(model_to_dict(backup, recurse=False))
@validate(body=GitBackupRequest)
def post(self, body: GitBackupRequest):
"""
Create 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:
return backup_mod.create_git_backup(body, self.is_api)
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):
"""
Deletes a specific Git based backup configuration.
---
tags:
- Git Backup
parameters:
- in: path
name: backup_id
type: 'integer'
required: true
description: The ID of the specific Git backup
- name: config
in: body
required: true
description: The configuration for Git backup service delete operation
schema:
type: 'object'
properties:
server_id:
type: 'integer'
description: 'ID of the server from where the backup is to be deleted'
service_id:
type: 'integer'
description: 'Service ID of the backup to be deleted'
responses:
204:
description: Successful operation
default:
description: Unexpected error
"""
try:
return backup_mod.delete_git_backup(body, backup_id)
except Exception as e:
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot delete GIT backup')