mirror of https://github.com/Aidaho12/haproxy-wi
v8.0: Delete check_version.html and refactor version checking logic
Removed the `check_version.html` template and moved version checking to `script.js`. This refactoring simplifies the codebase by consolidating version check handling into JavaScript, removing deprecated HTML templates, and enhancing the backend logic and API routes.pull/399/head
parent
7fb1ad4b69
commit
a7a8b4b10d
|
@ -2,13 +2,12 @@ from flask_swagger import swagger
|
|||
from flask import jsonify, render_template, abort
|
||||
from flask_pydantic import validate
|
||||
|
||||
from app import app, jwt
|
||||
from app import app
|
||||
from app.api.routes import bp
|
||||
from app.views.install.views import InstallView
|
||||
from app.views.server.views import (
|
||||
ServerView, CredView, CredsView, ServerGroupView, ServerGroupsView, ServersView, ServerIPView
|
||||
)
|
||||
from app.views.server.backup_vews import BackupView, S3BackupView
|
||||
from app.views.server.views import ServerView, ServerGroupView, ServerGroupsView, ServersView, ServerIPView
|
||||
from app.views.server.cred_views import CredView, CredsView
|
||||
from app.views.server.backup_vews import BackupView, S3BackupView, GitBackupView
|
||||
from app.views.service.views import ServiceView, ServiceActionView, ServiceBackendView, ServiceConfigView, ServiceConfigVersionsView
|
||||
from app.views.ha.views import HAView, HAVIPView, HAVIPsView
|
||||
from app.views.user.views import UserView, UserGroupView, UserRoles
|
||||
|
@ -30,20 +29,10 @@ def before_request():
|
|||
pass
|
||||
|
||||
|
||||
@jwt.expired_token_loader
|
||||
def my_expired_token_callback(jwt_header, jwt_payload):
|
||||
return jsonify(error="Token is expired"), 401
|
||||
|
||||
|
||||
@jwt.unauthorized_loader
|
||||
def custom_unauthorized_response(_err):
|
||||
return jsonify(error="Authorize first"), 401
|
||||
|
||||
|
||||
def register_api(view, endpoint, url, pk='listener_id', pk_type='int'):
|
||||
view_func = view.as_view(endpoint)
|
||||
bp.add_url_rule(url, view_func=view_func, methods=['POST'])
|
||||
bp.add_url_rule(f'{url}/<{pk_type}:{pk}>', view_func=view_func, methods=['GET', 'PUT', 'DELETE'])
|
||||
bp.add_url_rule(f'{url}/<{pk_type}:{pk}>', view_func=view_func, methods=['GET', 'PUT', 'PATCH', 'DELETE'])
|
||||
|
||||
|
||||
def register_api_id_ip(view, endpoint, url: str = '', methods: list = ['GET', 'POST']):
|
||||
|
@ -73,9 +62,10 @@ register_api_id_ip(ServiceActionView, 'service_action', '/<any(start, stop, relo
|
|||
register_api(ServerView, 'server', '/server', 'server_id')
|
||||
register_api(BackupView, 'backup_fs', '/server/backup/fs', 'backup_id')
|
||||
register_api(S3BackupView, 'backup_s3', '/server/backup/s3', 'backup_id')
|
||||
register_api(GitBackupView, 'backup_git', '/server/backup/git', 'backup_id')
|
||||
bp.add_url_rule('/server/<server_id>/ip', view_func=ServerIPView.as_view('server_ip_ip'), methods=['GET'])
|
||||
bp.add_url_rule('/server/<int:server_id>/ip', view_func=ServerIPView.as_view('server_ip'), methods=['GET'])
|
||||
register_api(CredView, 'cred', '/server/cred', 'creds_id')
|
||||
register_api(CredView, 'cred', '/server/cred', 'cred_id')
|
||||
bp.add_url_rule('/server/creds', view_func=CredsView.as_view('creds'), methods=['GET'])
|
||||
bp.add_url_rule('/servers', view_func=ServersView.as_view('servers'), methods=['GET'])
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ def default_values():
|
|||
print(str(e))
|
||||
|
||||
try:
|
||||
Groups.insert(name='Default', description='All servers are included in this group by default', group_id=1).on_conflict_ignore().execute()
|
||||
Groups.insert(name='Default', description='All servers are included in this group by default', id=1).on_conflict_ignore().execute()
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import datetime
|
|||
|
||||
from app import scheduler
|
||||
import app.modules.db.sql as sql
|
||||
import app.modules.db.user as user_sql
|
||||
import app.modules.db.roxy as roxy_sql
|
||||
import app.modules.db.history as history_sql
|
||||
import app.modules.roxywi.roxy as roxy
|
||||
|
|
|
@ -4,7 +4,6 @@ from flask import g
|
|||
|
||||
import app.modules.db.server as server_sql
|
||||
import app.modules.roxywi.common as roxywi_common
|
||||
from app.modules.roxywi.exception import RoxywiResourceNotFound
|
||||
from app.modules.roxywi.class_models import ServerRequest, GroupQuery, CredRequest, ChannelRequest
|
||||
from app.middleware import get_user_params
|
||||
|
||||
|
|
|
@ -48,9 +48,9 @@ def delete_s3_backups(backup_id: int) -> bool:
|
|||
return True
|
||||
|
||||
|
||||
def insert_new_git(server_id, service_id, repo, branch, period, cred, description) -> None:
|
||||
def insert_new_git(server_id, service_id, repo, branch, period, cred, description) -> int:
|
||||
try:
|
||||
GitSetting.insert(
|
||||
return GitSetting.insert(
|
||||
server_id=server_id, service_id=service_id, repo=repo, branch=branch, period=period,
|
||||
cred_id=cred, description=description
|
||||
).execute()
|
||||
|
@ -58,15 +58,11 @@ def insert_new_git(server_id, service_id, repo, branch, period, cred, descriptio
|
|||
out_error(e)
|
||||
|
||||
|
||||
def delete_git(git_id):
|
||||
query = GitSetting.delete().where(GitSetting.id == git_id)
|
||||
def delete_git(git_id: int) -> None:
|
||||
try:
|
||||
query.execute()
|
||||
GitSetting.delete().where(GitSetting.id == git_id).execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def select_gits(**kwargs):
|
||||
|
|
|
@ -4,7 +4,9 @@ from app.modules.roxywi.exception import RoxywiResourceNotFound
|
|||
|
||||
|
||||
def select_ssh(**kwargs):
|
||||
if kwargs.get("name") is not None:
|
||||
if kwargs.get("group") and kwargs.get("cred_id"):
|
||||
query = Cred.select().where((Cred.id == kwargs.get('cred_id')) & (Cred.group_id == kwargs.get('group')))
|
||||
elif kwargs.get("name") is not None:
|
||||
query = Cred.select().where(Cred.name == kwargs.get('name'))
|
||||
elif kwargs.get("id") is not None:
|
||||
query = Cred.select().where(Cred.id == kwargs.get('id'))
|
||||
|
@ -16,6 +18,8 @@ def select_ssh(**kwargs):
|
|||
query = Cred.select()
|
||||
try:
|
||||
query_res = query.execute()
|
||||
except Cred.DoesNotExist:
|
||||
raise RoxywiResourceNotFound
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
else:
|
||||
|
|
|
@ -25,10 +25,10 @@ def delete_server(server_id):
|
|||
return True
|
||||
|
||||
|
||||
def update_server(hostname, group, type_ip, enable, master, server_id, cred, port, desc, firewall, protected):
|
||||
def update_server(hostname, ip, group, type_ip, enable, master, server_id, cred, port, desc, firewall, protected):
|
||||
try:
|
||||
server_update = Server.update(
|
||||
hostname=hostname, group_id=group, type_ip=type_ip, enabled=enable, master=master, cred_id=cred,
|
||||
hostname=hostname, ip=ip, group_id=group, type_ip=type_ip, enabled=enable, master=master, cred_id=cred,
|
||||
port=port, description=desc, firewall_enable=firewall, protected=protected
|
||||
).where(Server.server_id == server_id)
|
||||
server_update.execute()
|
||||
|
|
|
@ -4,7 +4,7 @@ from typing import Optional, Annotated, Union, Literal, Any, Dict, List
|
|||
|
||||
from shlex import quote
|
||||
from pydantic_core import CoreSchema, core_schema
|
||||
from pydantic import BaseModel, field_validator, StringConstraints, IPvAnyAddress, AnyUrl, root_validator, GetCoreSchemaHandler
|
||||
from pydantic import BaseModel, Base64Str, StringConstraints, IPvAnyAddress, AnyUrl, root_validator, GetCoreSchemaHandler
|
||||
|
||||
DomainName = Annotated[str, StringConstraints(pattern=r"^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z][a-z0-9-]{0,61}[a-z0-9]$")]
|
||||
|
||||
|
@ -110,7 +110,7 @@ class ServerRequest(BaseModel):
|
|||
description: Optional[EscapedString] = None
|
||||
group_id: Optional[int] = None
|
||||
protected: Optional[bool] = 0
|
||||
master: Optional[int] = None
|
||||
master: Optional[int] = 0
|
||||
port: Annotated[int, Gt(1), Le(65535)] = 22
|
||||
haproxy: Optional[bool] = 0
|
||||
nginx: Optional[bool] = 0
|
||||
|
@ -137,7 +137,7 @@ class CredRequest(BaseModel):
|
|||
|
||||
|
||||
class CredUploadRequest(BaseModel):
|
||||
private_key: str
|
||||
private_key: Union[Base64Str, str]
|
||||
passphrase: Optional[EscapedString] = None
|
||||
|
||||
|
||||
|
@ -252,3 +252,14 @@ class S3BackupRequest(BaseModel):
|
|||
access_key: Optional[EscapedString] = None
|
||||
time: Optional[EscapedString] = None
|
||||
description: Optional[EscapedString] = None
|
||||
|
||||
|
||||
class GitBackupRequest(BaseModel):
|
||||
server_id: int
|
||||
service_id: int
|
||||
init: Optional[bool] = 0
|
||||
repo: Optional[EscapedString] = None
|
||||
branch: Optional[EscapedString] = 'main'
|
||||
time: Optional[EscapedString] = 'weekly'
|
||||
cred_id: Optional[int] = None
|
||||
description: Optional[EscapedString] = None
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import os
|
||||
import re
|
||||
from packaging import version
|
||||
|
||||
import distro
|
||||
import requests
|
||||
|
@ -26,33 +27,31 @@ def is_docker() -> bool:
|
|||
return True
|
||||
return False
|
||||
|
||||
|
||||
def check_ver():
|
||||
return roxy_sql.get_ver()
|
||||
|
||||
|
||||
def versions():
|
||||
json_data = {
|
||||
'need_update': 0
|
||||
}
|
||||
try:
|
||||
current_ver = check_ver()
|
||||
current_ver_without_dots = current_ver.split('.')
|
||||
current_ver_without_dots = ''.join(current_ver_without_dots)
|
||||
current_ver_without_dots = current_ver_without_dots.replace('\n', '')
|
||||
current_ver_without_dots = int(current_ver_without_dots)
|
||||
except Exception:
|
||||
current_ver = "Cannot get current version"
|
||||
current_ver_without_dots = 0
|
||||
current_ver = roxy_sql.get_ver()
|
||||
json_data['current_ver'] = roxy_sql.get_ver()
|
||||
except Exception as e:
|
||||
raise Exception(f'Cannot get current version: {e}')
|
||||
|
||||
try:
|
||||
new_ver = check_new_version('roxy-wi')
|
||||
new_ver_without_dots = new_ver.split('.')
|
||||
new_ver_without_dots = ''.join(new_ver_without_dots)
|
||||
new_ver_without_dots = new_ver_without_dots.replace('\n', '')
|
||||
new_ver_without_dots = int(new_ver_without_dots)
|
||||
json_data['new_ver'] = new_ver
|
||||
except Exception as e:
|
||||
new_ver = "Cannot get a new version"
|
||||
new_ver_without_dots = 0
|
||||
roxywi_common.logging('Roxy-WI server', f' {e}', roxywi=1)
|
||||
raise Exception(f'Cannot get new version: {e}')
|
||||
|
||||
return current_ver, new_ver, current_ver_without_dots, new_ver_without_dots
|
||||
if version.parse(current_ver) < version.parse(new_ver):
|
||||
json_data['need_update'] = 1
|
||||
|
||||
return json_data
|
||||
|
||||
|
||||
def check_new_version(service):
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import os
|
||||
import base64
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
import paramiko
|
||||
from flask import render_template
|
||||
from playhouse.shortcuts import model_to_dict
|
||||
|
||||
import app.modules.db.cred as cred_sql
|
||||
import app.modules.db.group as group_sql
|
||||
|
@ -153,7 +155,7 @@ def upload_ssh_key(ssh_id: int, key: str, passphrase: str) -> None:
|
|||
roxywi_common.logging('RMON server', e.args[0], roxywi=1)
|
||||
raise Exception(e)
|
||||
|
||||
if passphrase != "''":
|
||||
if passphrase:
|
||||
try:
|
||||
passphrase = crypt_password(passphrase)
|
||||
except Exception as e:
|
||||
|
@ -244,3 +246,31 @@ def decrypt_password(password: str) -> str:
|
|||
except Exception as e:
|
||||
raise Exception(f'error: Cannot decrypt password: {e}')
|
||||
return decryp_pass
|
||||
|
||||
|
||||
def get_creds(group_id: int = None, cred_id: int = None) -> list:
|
||||
json_data = []
|
||||
lib_path = get_config.get_config_var('main', 'lib_path')
|
||||
|
||||
if group_id and cred_id:
|
||||
creds = cred_sql.select_ssh(group=group_id, cred_id=cred_id)
|
||||
elif group_id:
|
||||
creds = cred_sql.select_ssh(group=group_id)
|
||||
else:
|
||||
creds = cred_sql.select_ssh()
|
||||
|
||||
for cred in creds:
|
||||
cred_dict = model_to_dict(cred)
|
||||
cred_dict['name'] = cred_dict['name'].replace("'", "")
|
||||
ssh_key_file = f'{lib_path}/keys/{cred_dict["name"]}.pem'
|
||||
if os.path.isfile(ssh_key_file):
|
||||
with open(ssh_key_file, 'rb') as key:
|
||||
cred_dict['private_key'] = base64.b64encode(key.read()).decode('utf-8')
|
||||
else:
|
||||
cred_dict['private_key'] = ''
|
||||
if cred_dict['password']:
|
||||
cred_dict['password'] = decrypt_password(cred_dict['password'])
|
||||
if cred_dict['passphrase']:
|
||||
cred_dict['passphrase'] = decrypt_password(cred_dict['passphrase'])
|
||||
json_data.append(cred_dict)
|
||||
return json_data
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from docutils.parsers.rst.directives import body
|
||||
from flask import render_template
|
||||
|
||||
import app.modules.db.sql as sql
|
||||
|
@ -8,7 +9,7 @@ import app.modules.db.service as service_sql
|
|||
import app.modules.server.ssh as ssh_mod
|
||||
import app.modules.roxywi.common as roxywi_common
|
||||
import app.modules.service.installation as installation_mod
|
||||
from app.modules.roxywi.class_models import BackupRequest, IdResponse, IdDataResponse, BaseResponse, S3BackupRequest
|
||||
from app.modules.roxywi.class_models import BackupRequest, IdResponse, IdDataResponse, BaseResponse, S3BackupRequest, GitBackupRequest
|
||||
|
||||
|
||||
def create_backup_inv(json_data: BackupRequest, del_id: int = 0) -> None:
|
||||
|
@ -51,6 +52,29 @@ def create_s3_backup_inv(data: S3BackupRequest, tag: str) -> None:
|
|||
raise Exception(f'error: {e}')
|
||||
|
||||
|
||||
def create_git_backup_inv(data: GitBackupRequest, server_ip: str, service: str, del_job: int = 0) -> None:
|
||||
service_config_dir = sql.get_setting(service + '_dir')
|
||||
ssh_settings = ssh_mod.return_ssh_keys_path(server_ip, id=data.cred_id)
|
||||
print('del_job',del_job)
|
||||
inv = {"server": {"hosts": {}}}
|
||||
inv["server"]["hosts"][server_ip] = {
|
||||
"REPO": data.repo,
|
||||
"CONFIG_DIR": service_config_dir,
|
||||
"PERIOD": data.time,
|
||||
"INIT": data.init,
|
||||
"BRANCH": data.branch,
|
||||
"SERVICE": service,
|
||||
"DELJOB": del_job,
|
||||
"KEY": ssh_settings['key']
|
||||
}
|
||||
|
||||
try:
|
||||
installation_mod.run_ansible(inv, [server_ip], 'git_backup')
|
||||
except Exception as e:
|
||||
raise Exception(f'error: {e}')
|
||||
|
||||
|
||||
|
||||
def create_backup(json_data: BackupRequest, is_api: bool) -> tuple:
|
||||
if backup_sql.check_exists_backup(json_data.server):
|
||||
raise Exception(f'warning: Backup job for {json_data.server} already exists')
|
||||
|
@ -71,7 +95,6 @@ def create_backup(json_data: BackupRequest, is_api: bool) -> tuple:
|
|||
return IdDataResponse(data=data, id=last_id).model_dump(mode='json'), 201
|
||||
|
||||
|
||||
|
||||
def delete_backup(json_data: BackupRequest, backup_id: int) -> tuple:
|
||||
create_backup_inv(json_data, backup_id)
|
||||
backup_sql.delete_backups(backup_id)
|
||||
|
@ -88,13 +111,6 @@ def update_backup(json_data: BackupRequest, backup_id: int) -> tuple:
|
|||
|
||||
|
||||
def create_s3_backup(data: S3BackupRequest, is_api: bool) -> tuple:
|
||||
# if deljob:
|
||||
# time = ''
|
||||
# secret_key = ''
|
||||
# access_key = ''
|
||||
# tag = 'delete'
|
||||
# else:
|
||||
# tag = 'add'
|
||||
if backup_sql.check_exists_s3_backup(data.server):
|
||||
raise Exception(f'Backup job for {data.server} already exists')
|
||||
|
||||
|
@ -103,7 +119,6 @@ def create_s3_backup(data: S3BackupRequest, is_api: bool) -> tuple:
|
|||
except Exception as e:
|
||||
raise e
|
||||
|
||||
# if not deljob:
|
||||
try:
|
||||
last_id = backup_sql.insert_s3_backup_job(**data.model_dump(mode='json'))
|
||||
roxywi_common.logging('backup ', f'a new S3 backup job for server {data.server} has been created', roxywi=1, login=1)
|
||||
|
@ -115,11 +130,6 @@ def create_s3_backup(data: S3BackupRequest, is_api: bool) -> tuple:
|
|||
else:
|
||||
temp = render_template('ajax/new_s3_backup.html', backups=backup_sql.select_s3_backups(**data.model_dump(mode='json')))
|
||||
return IdDataResponse(id=last_id, data=temp).model_dump(mode='json'), 201
|
||||
# elif deljob:
|
||||
# backup_sql.delete_s3_backups(deljob)
|
||||
# roxywi_common.logging('backup ', f' a S3 backup job for server {server} has been deleted', roxywi=1, login=1)
|
||||
# return 'ok'
|
||||
|
||||
|
||||
|
||||
def delete_s3_backup(data: S3BackupRequest, backup_id: int) -> None:
|
||||
|
@ -131,46 +141,49 @@ def delete_s3_backup(data: S3BackupRequest, backup_id: int) -> None:
|
|||
raise e
|
||||
|
||||
|
||||
def git_backup(server_id, service_id, git_init, repo, branch, period, cred, del_job, description, backup_id) -> str:
|
||||
server_ip = server_sql.select_server_ip_by_id(server_id)
|
||||
service_name = service_sql.select_service_name_by_id(service_id).lower()
|
||||
service_config_dir = sql.get_setting(service_name + '_dir')
|
||||
ssh_settings = ssh_mod.return_ssh_keys_path(server_ip, id=cred)
|
||||
|
||||
if repo is None or git_init == '0':
|
||||
repo = ''
|
||||
if branch is None or branch == '0':
|
||||
branch = 'main'
|
||||
|
||||
inv = {"server": {"hosts": {}}}
|
||||
inv["server"]["hosts"][server_ip] = {
|
||||
"REPO": repo,
|
||||
"CONFIG_DIR": service_config_dir,
|
||||
"PERIOD": period,
|
||||
"INIT": git_init,
|
||||
"BRANCH": branch,
|
||||
"SERVICE": service_name,
|
||||
"DELJOB": del_job,
|
||||
"KEY": ssh_settings['key']
|
||||
}
|
||||
def create_git_backup(data: GitBackupRequest, is_api: bool) -> tuple:
|
||||
server_ip = server_sql.select_server_ip_by_id(data.server_id)
|
||||
service_name = service_sql.select_service_name_by_id(data.service_id).lower()
|
||||
try:
|
||||
create_git_backup_inv(data, server_ip, service_name)
|
||||
except Exception as e:
|
||||
raise Exception(e)
|
||||
|
||||
try:
|
||||
installation_mod.run_ansible(inv, [server_ip], 'git_backup')
|
||||
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,
|
||||
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)
|
||||
except Exception as e:
|
||||
raise Exception(f'error: {e}')
|
||||
raise Exception(e)
|
||||
|
||||
if not del_job:
|
||||
backup_sql.insert_new_git(server_id=server_id, service_id=service_id, repo=repo, branch=branch, period=period, cred=cred, description=description)
|
||||
if is_api:
|
||||
return IdResponse(id=last_id).model_dump(mode='json'), 201
|
||||
else:
|
||||
kwargs = {
|
||||
"gits": backup_sql.select_gits(server_id=server_id, service_id=service_id),
|
||||
"gits": backup_sql.select_gits(server_id=data.server_id, service_id=data.service_id),
|
||||
"sshs": cred_sql.select_ssh(),
|
||||
"servers": roxywi_common.get_dick_permit(),
|
||||
"services": service_sql.select_services(),
|
||||
"new_add": 1,
|
||||
"lang": roxywi_common.get_user_lang_for_flask()
|
||||
}
|
||||
roxywi_common.logging(server_ip, 'A new git job has been created', roxywi=1, login=1, keep_history=1, service=service_name)
|
||||
return render_template('ajax/new_git.html', **kwargs)
|
||||
else:
|
||||
if backup_sql.delete_git(backup_id):
|
||||
return 'ok'
|
||||
|
||||
temp = render_template('ajax/new_git.html', **kwargs)
|
||||
return IdDataResponse(id=last_id, data=temp).model_dump(mode='json'), 201
|
||||
|
||||
|
||||
def delete_git_backup(data: GitBackupRequest, backup_id: int) -> tuple:
|
||||
server_ip = server_sql.select_server_ip_by_id(data.server_id)
|
||||
service_name = service_sql.select_service_name_by_id(data.service_id).lower()
|
||||
try:
|
||||
create_git_backup_inv(data, server_ip, service_name, 1)
|
||||
except Exception as e:
|
||||
raise Exception(e)
|
||||
|
||||
try:
|
||||
backup_sql.delete_git(backup_id)
|
||||
except Exception as e:
|
||||
raise Exception(e)
|
||||
|
||||
return BaseResponse().model_dump(mode='json'), 204
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import os
|
||||
import json
|
||||
from typing import Union
|
||||
|
||||
from packaging import version
|
||||
|
||||
import distro
|
||||
import ansible
|
||||
import ansible_runner
|
||||
|
||||
|
@ -212,6 +212,8 @@ def run_ansible(inv: dict, server_ips: list, ansible_role: str) -> dict:
|
|||
proxy = sql.get_setting('proxy')
|
||||
proxy_serv = ''
|
||||
tags = ''
|
||||
python_int = '/usr/bin/python3' if distro.id() == 'ubuntu' else '/usr/bin/python3.11'
|
||||
|
||||
try:
|
||||
agent_pid = server_mod.start_ssh_agent()
|
||||
except Exception as e:
|
||||
|
@ -261,7 +263,7 @@ def run_ansible(inv: dict, server_ips: list, ansible_role: str) -> dict:
|
|||
'AWX_DISPLAY': False,
|
||||
'SSH_AUTH_PID': agent_pid['pid'],
|
||||
'SSH_AUTH_SOCK': agent_pid['socket'],
|
||||
'ANSIBLE_PYTHON_INTERPRETER': '/usr/bin/python3'
|
||||
'ANSIBLE_PYTHON_INTERPRETER': python_int
|
||||
}
|
||||
kwargs = {
|
||||
'private_data_dir': '/var/www/haproxy-wi/app/scripts/ansible/',
|
||||
|
|
|
@ -171,6 +171,7 @@ def send_email(email_to: str, subject: str, message: str) -> None:
|
|||
def telegram_send_mess(mess, level, **kwargs):
|
||||
token_bot = ''
|
||||
channel_name = ''
|
||||
proxy = sql.get_setting('proxy')
|
||||
|
||||
if kwargs.get('channel_id') == 0:
|
||||
return
|
||||
|
@ -180,8 +181,6 @@ def telegram_send_mess(mess, level, **kwargs):
|
|||
else:
|
||||
telegrams = channel_sql.get_receiver_by_ip('telegram', kwargs.get('ip'))
|
||||
|
||||
proxy = sql.get_setting('proxy')
|
||||
|
||||
for telegram in telegrams:
|
||||
token_bot = telegram.token
|
||||
channel_name = telegram.chanel_name
|
||||
|
|
|
@ -16,6 +16,7 @@ import app.modules.roxywi.auth as roxywi_auth
|
|||
import app.modules.roxywi.common as roxywi_common
|
||||
import app.modules.tools.smon as smon_mod
|
||||
import app.modules.tools.common as tools_common
|
||||
import app.modules.server.ssh as ssh_mod
|
||||
from app.views.admin.views import SettingsView
|
||||
|
||||
bp.add_url_rule(
|
||||
|
@ -41,12 +42,12 @@ def admin():
|
|||
users = user_sql.select_users()
|
||||
servers = server_sql.select_servers(full=1)
|
||||
masters = server_sql.select_servers(get_master_servers=1)
|
||||
sshs = cred_sql.select_ssh()
|
||||
sshs = ssh_mod.get_creds()
|
||||
else:
|
||||
users = user_sql.select_users(group=user_group)
|
||||
servers = roxywi_common.get_dick_permit(virt=1, disable=0, only_group=1)
|
||||
masters = server_sql.select_servers(get_master_servers=1, uuid=g.user_params['user_id'])
|
||||
sshs = cred_sql.select_ssh(group=user_group)
|
||||
sshs = ssh_mod.get_creds(group_id=user_group)
|
||||
|
||||
kwargs = {
|
||||
'lang': g.user_params['lang'],
|
||||
|
|
|
@ -4,7 +4,7 @@ from flask import render_template, request, g, abort, jsonify, redirect, url_for
|
|||
from flask_jwt_extended import jwt_required
|
||||
from flask_pydantic.exceptions import ValidationError
|
||||
|
||||
from app import app, cache
|
||||
from app import app, cache, jwt
|
||||
from app.routes.main import bp
|
||||
import app.modules.db.user as user_sql
|
||||
import app.modules.db.server as server_sql
|
||||
|
@ -26,6 +26,16 @@ def _jinja2_filter_datetime(date, fmt=None):
|
|||
return common.get_time_zoned_date(date, fmt)
|
||||
|
||||
|
||||
@jwt.expired_token_loader
|
||||
def my_expired_token_callback(jwt_header, jwt_payload):
|
||||
return jsonify(error="Token is expired"), 401
|
||||
|
||||
|
||||
@jwt.unauthorized_loader
|
||||
def custom_unauthorized_response(_err):
|
||||
return jsonify(error="Authorize first"), 401
|
||||
|
||||
|
||||
@app.errorhandler(ValidationError)
|
||||
def handle_pydantic_validation_errors1(e):
|
||||
errors = []
|
||||
|
@ -70,6 +80,7 @@ def page_is_forbidden(e):
|
|||
def page_not_found(e):
|
||||
if 'api' in request.url:
|
||||
return jsonify({'error': str(e)}), 404
|
||||
get_user_params()
|
||||
kwargs = {
|
||||
'user_params': g.user_params,
|
||||
'title': e,
|
||||
|
@ -79,23 +90,15 @@ def page_not_found(e):
|
|||
|
||||
|
||||
@app.errorhandler(405)
|
||||
@get_user_params()
|
||||
def method_not_allowed(e):
|
||||
if 'api' in request.url:
|
||||
return jsonify({'error': str(e)}), 405
|
||||
kwargs = {
|
||||
'user_params': g.user_params,
|
||||
'title': e,
|
||||
'e': e
|
||||
}
|
||||
return render_template('error.html', **kwargs), 405
|
||||
|
||||
|
||||
@app.errorhandler(500)
|
||||
@get_user_params()
|
||||
def internal_error(e):
|
||||
if 'api' in request.url:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
get_user_params()
|
||||
kwargs = {
|
||||
'user_params': g.user_params,
|
||||
'title': e,
|
||||
|
@ -224,4 +227,4 @@ def service_history(service, server_ip):
|
|||
@bp.route('/internal/show_version')
|
||||
@cache.cached()
|
||||
def show_roxywi_version():
|
||||
return render_template('ajax/check_version.html', versions=roxy.versions())
|
||||
return jsonify(roxy.versions())
|
||||
|
|
|
@ -7,14 +7,15 @@ from app.routes.server import bp
|
|||
import app.modules.db.cred as cred_sql
|
||||
import app.modules.db.server as server_sql
|
||||
import app.modules.db.backup as backup_sql
|
||||
import app.modules.db.service as service_sql
|
||||
import app.modules.common.common as common
|
||||
import app.modules.roxywi.auth as roxywi_auth
|
||||
import app.modules.roxywi.common as roxywi_common
|
||||
import app.modules.server.server as server_mod
|
||||
import app.modules.service.backup as backup_mod
|
||||
from app.middleware import get_user_params
|
||||
from app.views.server.views import ServerView, CredView, CredsView, ServerGroupView, ServerGroupsView, ServerIPView
|
||||
from app.views.server.backup_vews import BackupView, S3BackupView
|
||||
from app.views.server.views import ServerView, ServerGroupView, ServerGroupsView, ServerIPView
|
||||
from app.views.server.cred_views import CredView, CredsView
|
||||
from app.views.server.backup_vews import BackupView, S3BackupView, GitBackupView
|
||||
|
||||
|
||||
def register_api(view, endpoint, url, pk='listener_id', pk_type='int'):
|
||||
|
@ -33,6 +34,7 @@ bp.add_url_rule('/<server_id>/ip', view_func=ServerIPView.as_view('server_ip_ip'
|
|||
bp.add_url_rule('/<int:server_id>/ip', view_func=ServerIPView.as_view('server_ip'), methods=['GET'])
|
||||
bp.add_url_rule('/backup', view_func=BackupView.as_view('backup', False), methods=['POST'])
|
||||
bp.add_url_rule('/backup/s3', view_func=S3BackupView.as_view('backup_s3', False), methods=['POST'])
|
||||
bp.add_url_rule('/backup/git', view_func=GitBackupView.as_view('backup_git', False), methods=['POST'])
|
||||
|
||||
error_mess = roxywi_common.return_error_message()
|
||||
|
||||
|
@ -137,6 +139,7 @@ def load_backup():
|
|||
kwargs = {
|
||||
'sshs': cred_sql.select_ssh(group=user_group),
|
||||
'servers': roxywi_common.get_dick_permit(virt=1, disable=0, only_group=1),
|
||||
'services': service_sql.select_services(),
|
||||
'backups': backup_sql.select_backups(),
|
||||
's3_backups': backup_sql.select_s3_backups(),
|
||||
'gits': backup_sql.select_gits(),
|
||||
|
@ -145,26 +148,3 @@ def load_backup():
|
|||
'user_subscription': roxywi_common.return_user_subscription(),
|
||||
}
|
||||
return render_template('include/admin_backup.html', **kwargs)
|
||||
|
||||
|
||||
@bp.route('/git', methods=['DELETE', 'POST'])
|
||||
def create_git_backup():
|
||||
json_data = request.get_json()
|
||||
server_id = int(json_data['server'])
|
||||
service_id = int(json_data['service'])
|
||||
git_init = int(json_data['init'])
|
||||
repo = common.checkAjaxInput(json_data['repo'])
|
||||
branch = common.checkAjaxInput(json_data['branch'])
|
||||
period = common.checkAjaxInput(json_data['time'])
|
||||
cred = int(json_data['cred'])
|
||||
del_job = int(json_data['del_job'])
|
||||
description = common.checkAjaxInput(json_data['desc'])
|
||||
backup_id = ''
|
||||
if request.method == 'DELETE':
|
||||
backup_id = json_data['backup_id']
|
||||
|
||||
try:
|
||||
data = backup_mod.git_backup(server_id, service_id, git_init, repo, branch, period, cred, del_job, description, backup_id)
|
||||
return jsonify({'status': 'ok', 'data': data})
|
||||
except Exception as e:
|
||||
return roxywi_common.handle_json_exceptions(e, f'Cannot {request.method} git backup')
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
---
|
||||
- name: restart rsyslog
|
||||
service: name=rsyslog state=restarted
|
||||
|
||||
- name: restart docker
|
||||
service: "name=docker state={{ docker_restart_handler_state }}"
|
||||
ignore_errors: "{{ ansible_check_mode }}"
|
|
@ -11,7 +11,7 @@
|
|||
- name: Fail if has been installed
|
||||
fail:
|
||||
msg="Git configuration not found. Initialize git at the beginning"
|
||||
when: not register_name.stat.exists and not INIT and DELJOB
|
||||
when: not register_name.stat.exists and not INIT and not DELJOB
|
||||
|
||||
- name: Install git
|
||||
package:
|
||||
|
@ -34,15 +34,16 @@
|
|||
- name: Copy ssh file
|
||||
copy:
|
||||
src: '{{ KEY }}'
|
||||
dest: '/home/{{ ansible_user }}/.ssh/id_rsa'
|
||||
dest: '/home/{{ ansible_user }}/.ssh/git_{{ SERVICE }}_key'
|
||||
mode: 0600
|
||||
group: '{{ ansible_user }}'
|
||||
owner: '{{ ansible_user }}'
|
||||
force: no
|
||||
force: yes
|
||||
when: INIT
|
||||
|
||||
- name: Add write permissions
|
||||
shell: "chmod o+wr -R {{ CONFIG_DIR }}"
|
||||
when: not DELJOB
|
||||
|
||||
- name: Git init
|
||||
shell: 'cd {{ CONFIG_DIR }} && git init'
|
||||
|
@ -58,13 +59,18 @@
|
|||
email = roxy-wi@.com
|
||||
when: INIT
|
||||
|
||||
- name: Add dir exception
|
||||
shell: 'git config --global --add safe.directory {{ CONFIG_DIR }}'
|
||||
when: INIT
|
||||
become: no
|
||||
|
||||
- name: Git add remote
|
||||
shell: 'cd {{ CONFIG_DIR }} && git add --all . && git commit -m "Roxy-WI init repo" && git branch -M {{ BRANCH }} && git remote add origin {{ REPO }}'
|
||||
when: INIT
|
||||
become: no
|
||||
|
||||
- name: Git add push
|
||||
shell: 'cd {{ CONFIG_DIR }} && GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=no" git push -u origin {{ BRANCH }}'
|
||||
shell: 'cd {{ CONFIG_DIR }} && GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=no -i /home/{{ ansible_user }}/.ssh/git_{{ SERVICE }}_key" git push -u origin {{ BRANCH }}'
|
||||
when: INIT
|
||||
become: no
|
||||
|
||||
|
|
|
@ -219,18 +219,17 @@ function addGit(dialog_id) {
|
|||
valid = valid && checkLength(branch_div, "Branch name", 1);
|
||||
if (valid) {
|
||||
let jsonData = {
|
||||
"server": server_div.val(),
|
||||
"service": service_div.val(),
|
||||
"server_id": server_div.val(),
|
||||
"service_id": service_div.val(),
|
||||
"init": git_init,
|
||||
"repo": $('#git-repo').val(),
|
||||
"branch": branch_div.val(),
|
||||
"time": time_div.val(),
|
||||
"cred": cred_div.val(),
|
||||
"del_job": 0,
|
||||
"cred_id": cred_div.val(),
|
||||
"desc": $('#git-description').text(),
|
||||
}
|
||||
$.ajax({
|
||||
url: "/server/git",
|
||||
url: "/server/backup/git",
|
||||
data: JSON.stringify(jsonData),
|
||||
contentType: "application/json; charset=utf-8",
|
||||
type: "POST",
|
||||
|
@ -388,34 +387,35 @@ function removeS3Backup(id) {
|
|||
function removeGit(id) {
|
||||
$("#git-table-" + id).css("background-color", "#f2dede");
|
||||
let jsonData = {
|
||||
"backup_id": id,
|
||||
"del_job": 1,
|
||||
"init": 0,
|
||||
"repo": 0,
|
||||
"branch": 0,
|
||||
"time": 0,
|
||||
"cred": $('#git-credentials-id-' + id).text(),
|
||||
"server": $('#git-server-id-' + id).text(),
|
||||
"service": $('#git-service-id-' + id).text(),
|
||||
"desc": '',
|
||||
"cred_id": $('#git-credentials-id-' + id).text(),
|
||||
"server_id": $('#git-server-id-' + id).text(),
|
||||
"service_id": $('#git-service-id-' + id).text(),
|
||||
}
|
||||
$.ajax({
|
||||
url: "/server/git",
|
||||
url: api_prefix + "/server/backup/git/" + id,
|
||||
data: JSON.stringify(jsonData),
|
||||
contentType: "application/json; charset=utf-8",
|
||||
type: "DELETE",
|
||||
success: function (data) {
|
||||
if (data.status === 'failed') {
|
||||
toastr.error(data.error);
|
||||
} else {
|
||||
statusCode: {
|
||||
204: function (xhr) {
|
||||
$("#git-table-" + id).remove();
|
||||
},
|
||||
404: function (xhr) {
|
||||
$("#git-table-" + id).remove();
|
||||
}
|
||||
},
|
||||
success: function (data) {
|
||||
if (data) {
|
||||
if (data.status === "failed") {
|
||||
toastr.error(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function updateBackup(id) {
|
||||
toastr.clear();
|
||||
if ($("#backup-type-" + id + " option:selected").val() == "-------" || $('#backup-rserver-' + id).val() == '' || $('#backup-rpath-' + id).val() == '') {
|
||||
if ($("#backup-type-" + id + " option:selected").val() === "-------" || $('#backup-rserver-' + id).val() === '' || $('#backup-rpath-' + id).val() === '') {
|
||||
toastr.error('All fields must be completed');
|
||||
} else {
|
||||
let jsonData = {
|
||||
|
|
|
@ -1163,21 +1163,26 @@ function show_version() {
|
|||
NProgress.configure({showSpinner: false});
|
||||
$.ajax( {
|
||||
url: "/internal/show_version",
|
||||
contentType: "application/json; charset=utf-8",
|
||||
success: function( data ) {
|
||||
$('#version').html(data);
|
||||
var showUpdates = $( "#show-updates" ).dialog({
|
||||
if (data.need_update) {
|
||||
$('#version').html('<span id="show-updates-button" class="new-version-exists" style="cursor: pointer;">v' + data.current_ver + '</span>');
|
||||
} else {
|
||||
$('#version').html('v' + data.current_ver);
|
||||
}
|
||||
let showUpdates = $("#show-updates").dialog({
|
||||
autoOpen: false,
|
||||
width: 600,
|
||||
modal: true,
|
||||
title: 'There is a new Roxy-WI version',
|
||||
buttons: {
|
||||
Close: function() {
|
||||
$( this ).dialog( "close" );
|
||||
Close: function () {
|
||||
$(this).dialog("close");
|
||||
clearTips();
|
||||
}
|
||||
}
|
||||
});
|
||||
$('#show-updates-button').click(function() {
|
||||
$('#show-updates-button').click(function () {
|
||||
showUpdates.dialog('open');
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
{%- if versions is defined -%}
|
||||
{%- set current_ver = versions.0 -%}
|
||||
{%- set new_ver = versions.1 %}
|
||||
{%- set current_ver_without_dots = versions.2 %}
|
||||
{%- set new_ver_without_dots = versions.3 %}
|
||||
{%- endif -%}
|
||||
{%- if new_ver_without_dots is defined and current_ver_without_dots is defined and new_ver is defined and new_ver_without_dots is defined -%}
|
||||
<a style="color: #000; cursor: pointer;">
|
||||
{%- if new_ver_without_dots > current_ver_without_dots and new_ver != "Sorry cannot get current version" %}
|
||||
<span id="show-updates-button" class="new-version-exists">v{{current_ver}}</span>
|
||||
<script defer src="/static/js/fontawesome.min.js"></script>
|
||||
{%- else %}
|
||||
<a href="/admin#updatehapwi" title="Update center" style="color: black;">v{{current_ver}}</a>
|
||||
{%- endif %}
|
||||
</a>
|
||||
{%- else %}
|
||||
<a href="/admin#updatehapwi" title="Update center" style="color: black;">v{{current_ver}}</a>
|
||||
{% endif -%}
|
|
@ -1,8 +1,4 @@
|
|||
{% import 'languages/'+lang|default('en')+'.html' as lang %}
|
||||
{% set current_ver = versions.0 %}
|
||||
{% set new_ver = versions.1 %}
|
||||
{% set current_ver_without_dots = versions.2 %}
|
||||
{% set new_ver_without_dots = versions.3 %}
|
||||
{% set services_name = {
|
||||
'roxy-wi-checker': { 'link': 'checker', 'name': 'Checker', 'desc': lang.admin_page.desc.checker_desc },
|
||||
'roxy-wi-keep_alive': { 'link': 'auto_start', 'name': 'Auto start', 'desc': lang.admin_page.desc.auto_start_desc },
|
||||
|
@ -19,7 +15,7 @@
|
|||
</td>
|
||||
<td>
|
||||
<b
|
||||
{% if new_ver_without_dots > current_ver_without_dots and new_ver != "Sorry cannot get current version" %}
|
||||
{% if versions.need_update %}
|
||||
title=lang.admin_page.desc.a_new_version+" Roxy-WI"
|
||||
style="color: var(--red-color)"
|
||||
{% else %}
|
||||
|
@ -27,14 +23,14 @@
|
|||
style="color: var(--green-color)"
|
||||
{% endif %}
|
||||
>
|
||||
{{current_ver}}
|
||||
{{versions.current_ver}}
|
||||
</b>
|
||||
</td>
|
||||
<td class="padding10">
|
||||
<b>{{new_ver}}</b>
|
||||
<b>{{versions.new_ver}}</b>
|
||||
</td>
|
||||
<td>
|
||||
{% if new_ver_without_dots > current_ver_without_dots and new_ver != "Sorry cannot get current version" %}
|
||||
{% if versions.need_update %}
|
||||
<a class="ui-button ui-widget ui-corner-all" onclick="updateService('roxy-wi')" title="{{lang.words.w_update|title()}} Roxy-WI">{{lang.words.w_update|title()}}</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
</td>
|
||||
<td style="width: 10%">
|
||||
{% for ssh in sshs %}
|
||||
{% if ssh.enable == 1 %}
|
||||
{% if ssh.key_enabled == 1 %}
|
||||
{% if ssh.id == b.cred_id %}
|
||||
<span id="git-credentials-id-{{b.id}}" style="display: none">{{ ssh.id }}</span>
|
||||
<span id="git-credentials-{{b.id}}">{{ ssh.name }}</span>
|
||||
|
@ -47,7 +47,7 @@
|
|||
{% endfor %}
|
||||
</td>
|
||||
<td style="width: 100%">
|
||||
<span type="text" id="git-description-{{b.id}}">
|
||||
<span id="git-description-{{b.id}}">
|
||||
{% if b.description %}
|
||||
{{b.description}}
|
||||
{% endif %}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<tr style="width: 50%;" id="ssh-table-{{ssh.id}}" class="{{ loop.cycle('odd', 'even') }}">
|
||||
<td class="first-collumn padding10">
|
||||
{% set id = 'ssh_name-' + ssh.id|string() %}
|
||||
{{ input(id, value=ssh.name, size='15') }}
|
||||
{{ input(id, value=ssh.name.replace("'", ""), size='15') }}
|
||||
</td>
|
||||
<td class="first-collumn" valign="top" style="padding-top: 15px;">
|
||||
{% if ssh.key_enabled == 1 %}
|
||||
|
@ -48,9 +48,9 @@
|
|||
{{ input(id, value=ssh.username, title='SSH user name') }}
|
||||
</p>
|
||||
{% if ssh.key_enabled == 1 %}
|
||||
<input type="password" id="ssh_pass-{{ssh.id}}" class="form-control" title="User password, if SSH key is disabled" placeholder="*****" style="display: none;" autocomplete="new-password">
|
||||
<input type="password" id="ssh_pass-{{ssh.id}}" class="form-control" title="User password, if SSH key is disabled" value="{{ ssh.password }}" style="display: none;" autocomplete="new-password">
|
||||
{% else %}
|
||||
<input type="password" id="ssh_pass-{{ssh.id}}" class="form-control" title="User password, if SSH key is disabled" placeholder="*****" autocomplete="new-password">
|
||||
<input type="password" id="ssh_pass-{{ssh.id}}" class="form-control" title="User password, if SSH key is disabled" value="{{ ssh.password }}" autocomplete="new-password">
|
||||
{% endif %}
|
||||
<br>
|
||||
</td>
|
||||
|
|
|
@ -8,7 +8,7 @@ import app.modules.db.backup as backup_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, BaseResponse
|
||||
from app.modules.roxywi.class_models import BackupRequest, S3BackupRequest, GitBackupRequest, BaseResponse
|
||||
|
||||
|
||||
class BackupView(MethodView):
|
||||
|
@ -209,7 +209,7 @@ class BackupView(MethodView):
|
|||
|
||||
|
||||
class S3BackupView(MethodView):
|
||||
methods = ['GET', 'POST', 'PUT', 'DELETE']
|
||||
methods = ['GET', 'POST', 'DELETE']
|
||||
decorators = [jwt_required(), get_user_params(), page_for_admin(), check_group()]
|
||||
|
||||
def __init__(self, is_api=True):
|
||||
|
@ -352,3 +352,151 @@ class S3BackupView(MethodView):
|
|||
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'
|
||||
properties:
|
||||
server_id:
|
||||
type: 'integer'
|
||||
description: 'The ID of the server to backed up'
|
||||
service_id:
|
||||
type: 'integer'
|
||||
description: 'Service ID'
|
||||
init:
|
||||
type: 'integer'
|
||||
description: 'Indicates whether to initialize the repository'
|
||||
repo:
|
||||
type: 'string'
|
||||
description: 'The repository from where to fetch the data for backup'
|
||||
branch:
|
||||
type: 'string'
|
||||
description: 'The branch to pull for backup'
|
||||
time:
|
||||
type: 'string'
|
||||
description: 'The timing for the Git backup task'
|
||||
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 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')
|
||||
|
|
|
@ -0,0 +1,319 @@
|
|||
import base64
|
||||
|
||||
from flask.views import MethodView
|
||||
from flask_pydantic import validate
|
||||
from flask import jsonify, g
|
||||
from flask_jwt_extended import jwt_required
|
||||
|
||||
import app.modules.db.cred as cred_sql
|
||||
import app.modules.roxywi.common as roxywi_common
|
||||
import app.modules.server.ssh as ssh_mod
|
||||
from app.middleware import get_user_params, page_for_admin, check_group
|
||||
from app.modules.roxywi.exception import RoxywiGroupMismatch, RoxywiResourceNotFound
|
||||
from app.modules.roxywi.class_models import BaseResponse, GroupQuery, CredRequest, CredUploadRequest
|
||||
from app.modules.common.common_classes import SupportClass
|
||||
|
||||
class CredView(MethodView):
|
||||
methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']
|
||||
decorators = [jwt_required(), get_user_params(), page_for_admin(level=2), check_group()]
|
||||
|
||||
def __init__(self, is_api=False):
|
||||
self.is_api = is_api
|
||||
|
||||
@staticmethod
|
||||
@validate(query=GroupQuery)
|
||||
def get(cred_id: int, query: GroupQuery):
|
||||
"""
|
||||
Retrieve credential information for a specific ID
|
||||
---
|
||||
tags:
|
||||
- 'SSH credentials'
|
||||
parameters:
|
||||
- in: 'path'
|
||||
name: 'cred_id'
|
||||
description: 'ID of the credential to retrieve'
|
||||
required: true
|
||||
type: 'integer'
|
||||
responses:
|
||||
200:
|
||||
description: 'Individual Credential Information'
|
||||
schema:
|
||||
type: 'object'
|
||||
properties:
|
||||
group_id:
|
||||
type: 'integer'
|
||||
description: 'Group ID the credential belongs to'
|
||||
id:
|
||||
type: 'integer'
|
||||
description: 'Credential ID'
|
||||
key_enabled:
|
||||
type: 'integer'
|
||||
description: 'Key status of the credential'
|
||||
name:
|
||||
type: 'string'
|
||||
description: 'Name of the credential'
|
||||
username:
|
||||
type: 'string'
|
||||
description: 'Username associated with the credential'
|
||||
password:
|
||||
type: 'string'
|
||||
description: 'Password associated with the credential'
|
||||
passphrase:
|
||||
type: 'string'
|
||||
description: 'Password for the SSH private key'
|
||||
private_key:
|
||||
type: 'string'
|
||||
description: 'SSH private key in base64 encoded format'
|
||||
404:
|
||||
description: 'Credential not found'
|
||||
"""
|
||||
group_id = SupportClass.return_group_id(query)
|
||||
try:
|
||||
creds = ssh_mod.get_creds(group_id=group_id, cred_id=cred_id)
|
||||
return jsonify(creds), 200
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot get credentials')
|
||||
|
||||
@validate(body=CredRequest)
|
||||
def post(self, body: CredRequest):
|
||||
"""
|
||||
Create a new credential entry
|
||||
---
|
||||
tags:
|
||||
- SSH credentials
|
||||
parameters:
|
||||
- in: 'path'
|
||||
name: 'creds_id'
|
||||
description: 'ID of the credential to retrieve'
|
||||
required: true
|
||||
type: 'integer'
|
||||
- in: body
|
||||
name: body
|
||||
schema:
|
||||
id: AddCredentials
|
||||
required:
|
||||
- group_шв
|
||||
- name
|
||||
- username
|
||||
- key_enabled
|
||||
- password
|
||||
properties:
|
||||
group_id:
|
||||
type: integer
|
||||
description: The ID of the group to create the credential for. Only for superAdmin role
|
||||
name:
|
||||
type: string
|
||||
description: The credential name
|
||||
username:
|
||||
type: string
|
||||
description: The username
|
||||
key_enabled:
|
||||
type: integer
|
||||
description: If key is enabled or not
|
||||
password:
|
||||
type: string
|
||||
description: The password
|
||||
responses:
|
||||
201:
|
||||
description: Credential addition successful
|
||||
"""
|
||||
group_id = SupportClass.return_group_id(body)
|
||||
try:
|
||||
return ssh_mod.create_ssh_cred(body.name, body.password, group_id, body.username, body.key_enabled, self.is_api)
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot create new cred')
|
||||
|
||||
@validate(body=CredRequest)
|
||||
def put(self, creds_id: int, body: CredRequest):
|
||||
"""
|
||||
Update a credential entry
|
||||
---
|
||||
tags:
|
||||
- SSH credentials
|
||||
parameters:
|
||||
- in: 'path'
|
||||
name: 'creds_id'
|
||||
description: 'ID of the credential to retrieve'
|
||||
required: true
|
||||
type: 'integer'
|
||||
- in: body
|
||||
name: body
|
||||
schema:
|
||||
id: UpdateCredentials
|
||||
required:
|
||||
- name
|
||||
- username
|
||||
- key_enabled
|
||||
- password
|
||||
properties:
|
||||
group_id:
|
||||
type: integer
|
||||
description: The ID of the group to create the credential for. Only for superAdmin role
|
||||
name:
|
||||
type: string
|
||||
description: The credential name
|
||||
username:
|
||||
type: string
|
||||
description: The username
|
||||
key_enabled:
|
||||
type: integer
|
||||
description: If key is enabled or not
|
||||
password:
|
||||
type: string
|
||||
description: The password
|
||||
responses:
|
||||
201:
|
||||
description: Credential update successful
|
||||
"""
|
||||
group_id = SupportClass.return_group_id(body)
|
||||
try:
|
||||
self._check_is_correct_group(creds_id)
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, ''), 404
|
||||
|
||||
try:
|
||||
ssh_mod.update_ssh_key(creds_id, body.name, body.password, body.key_enabled, body.username, group_id)
|
||||
return BaseResponse().model_dump(mode='json'), 201
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot update SSH key')
|
||||
|
||||
def delete(self, creds_id: int):
|
||||
"""
|
||||
Delete a credential entry
|
||||
---
|
||||
tags:
|
||||
- SSH credentials
|
||||
parameters:
|
||||
- in: 'path'
|
||||
name: 'creds_id'
|
||||
description: 'ID of the credential to retrieve'
|
||||
required: true
|
||||
type: 'integer'
|
||||
responses:
|
||||
204:
|
||||
description: Credential deletion successful
|
||||
"""
|
||||
try:
|
||||
self._check_is_correct_group(creds_id)
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, ''), 404
|
||||
|
||||
try:
|
||||
ssh_mod.delete_ssh_key(creds_id)
|
||||
return BaseResponse().model_dump(mode='json'), 204
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot delete SSH key')
|
||||
|
||||
@validate(body=CredUploadRequest)
|
||||
def patch(self, creds_id: int, body: CredUploadRequest):
|
||||
"""
|
||||
Upload an SSH private key
|
||||
---
|
||||
tags:
|
||||
- SSH credentials
|
||||
parameters:
|
||||
- in: 'path'
|
||||
name: 'creds_id'
|
||||
description: 'ID of the credential to retrieve'
|
||||
required: true
|
||||
type: 'integer'
|
||||
- in: body
|
||||
name: body
|
||||
schema:
|
||||
id: UploadSSHKey
|
||||
required:
|
||||
- private_key
|
||||
- passphrase
|
||||
properties:
|
||||
private_key:
|
||||
type: string
|
||||
description: The private key string or base64 encoded string
|
||||
passphrase:
|
||||
type: string
|
||||
description: The passphrase
|
||||
responses:
|
||||
201:
|
||||
description: SSH key upload successful
|
||||
"""
|
||||
try:
|
||||
self._check_is_correct_group(creds_id)
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, ''), 404
|
||||
try:
|
||||
body.private_key = base64.b64decode(body.private_key).decode("ascii")
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
ssh_mod.upload_ssh_key(creds_id, body.private_key, body.passphrase)
|
||||
return BaseResponse().model_dump(mode='json'), 201
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot upload SSH key')
|
||||
|
||||
@staticmethod
|
||||
def _check_is_correct_group(creds_id: int):
|
||||
if g.user_params['role'] == 1:
|
||||
return True
|
||||
try:
|
||||
ssh = cred_sql.get_ssh(creds_id)
|
||||
except RoxywiResourceNotFound:
|
||||
raise RoxywiResourceNotFound
|
||||
if ssh.group_id != g.user_params['group_id']:
|
||||
raise RoxywiGroupMismatch
|
||||
|
||||
|
||||
class CredsView(MethodView):
|
||||
methods = ['GET']
|
||||
decorators = [jwt_required(), get_user_params(), page_for_admin(level=2), check_group()]
|
||||
|
||||
@validate(query=GroupQuery)
|
||||
def get(self, query: GroupQuery):
|
||||
"""
|
||||
Retrieve credential information based on group_id
|
||||
---
|
||||
tags:
|
||||
- 'SSH credentials'
|
||||
parameters:
|
||||
- in: 'query'
|
||||
name: 'group_id'
|
||||
description: 'GroupQuery to filter servers. Only for superAdmin role'
|
||||
required: false
|
||||
type: 'integer'
|
||||
responses:
|
||||
200:
|
||||
description: 'Credentials Information'
|
||||
schema:
|
||||
type: 'array'
|
||||
items:
|
||||
type: 'object'
|
||||
properties:
|
||||
group_id:
|
||||
type: 'integer'
|
||||
description: 'Group ID the credential belongs to'
|
||||
id:
|
||||
type: 'integer'
|
||||
description: 'Credential ID'
|
||||
key_enabled:
|
||||
type: 'integer'
|
||||
description: 'Key status of the credential'
|
||||
name:
|
||||
type: 'string'
|
||||
description: 'Name of the credential'
|
||||
username:
|
||||
type: 'string'
|
||||
description: 'Username of the credential'
|
||||
password:
|
||||
type: 'string'
|
||||
description: 'Password associated with the credential'
|
||||
passphrase:
|
||||
type: 'string'
|
||||
description: 'Password for the SSH private key'
|
||||
private_key:
|
||||
type: 'string'
|
||||
description: 'SSH private key in base64 encoded format'
|
||||
"""
|
||||
group_id = SupportClass.return_group_id(query)
|
||||
try:
|
||||
creds = ssh_mod.get_creds(group_id=group_id)
|
||||
return jsonify(creds), 200
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot get credentials')
|
|
@ -1,19 +1,17 @@
|
|||
from flask.views import MethodView
|
||||
from flask_pydantic import validate
|
||||
from flask import render_template, jsonify, request, g
|
||||
from flask import render_template, jsonify, request
|
||||
from playhouse.shortcuts import model_to_dict
|
||||
from flask_jwt_extended import jwt_required
|
||||
|
||||
from app.modules.db.db_model import Cred
|
||||
import app.modules.db.cred as cred_sql
|
||||
import app.modules.db.group as group_sql
|
||||
import app.modules.db.server as server_sql
|
||||
import app.modules.roxywi.group as group_mod
|
||||
import app.modules.roxywi.common as roxywi_common
|
||||
import app.modules.server.ssh as ssh_mod
|
||||
import app.modules.server.server as server_mod
|
||||
from app.middleware import get_user_params, page_for_admin, check_group
|
||||
from app.modules.roxywi.exception import RoxywiGroupMismatch, RoxywiResourceNotFound
|
||||
from app.modules.roxywi.exception import RoxywiResourceNotFound
|
||||
from app.modules.roxywi.class_models import (
|
||||
BaseResponse, IdResponse, IdDataResponse, ServerRequest, GroupQuery, GroupRequest, CredRequest, CredUploadRequest
|
||||
)
|
||||
|
@ -132,21 +130,20 @@ class ServerView(MethodView):
|
|||
required:
|
||||
- hostname
|
||||
- ip
|
||||
- enabled
|
||||
- creds_id
|
||||
- cred_id
|
||||
- port
|
||||
- description
|
||||
- group_id
|
||||
properties:
|
||||
hostname:
|
||||
type: string
|
||||
description: The server name
|
||||
ip:
|
||||
type: string
|
||||
description: The server IP address
|
||||
description: The server IP address or domain name
|
||||
enabled:
|
||||
type: integer
|
||||
description: If server is enabled or not
|
||||
creds_id:
|
||||
cred_id:
|
||||
type: integer
|
||||
description: The ID of the credentials
|
||||
port:
|
||||
|
@ -158,6 +155,18 @@ class ServerView(MethodView):
|
|||
group_id:
|
||||
type: integer
|
||||
description: The ID of the group to create the server for. Only for superAdmin role
|
||||
type_ip:
|
||||
type: integer
|
||||
description: Is server virtual (VIP address) or not
|
||||
master:
|
||||
type: integer
|
||||
description: Server id of the master server
|
||||
firewall_enable:
|
||||
type: integer
|
||||
description: Is firewalld enabled or not
|
||||
protected:
|
||||
type: integer
|
||||
description: Is the server protected from changes by a non-admin role
|
||||
responses:
|
||||
201:
|
||||
description: Server creation successful
|
||||
|
@ -216,19 +225,22 @@ class ServerView(MethodView):
|
|||
schema:
|
||||
id: UpdateServer
|
||||
required:
|
||||
- name
|
||||
- enabled
|
||||
- creds_id
|
||||
- hostname
|
||||
- ip
|
||||
- cred_id
|
||||
- port
|
||||
- description
|
||||
- group_id
|
||||
properties:
|
||||
name:
|
||||
hostname:
|
||||
type: string
|
||||
description: The server name
|
||||
ip:
|
||||
type: string
|
||||
description: The server IP or domain name
|
||||
enabled:
|
||||
type: integer
|
||||
description: If server is enabled or not
|
||||
creds_id:
|
||||
cred_id:
|
||||
type: integer
|
||||
description: The ID of the credentials
|
||||
port:
|
||||
|
@ -240,6 +252,18 @@ class ServerView(MethodView):
|
|||
group_id:
|
||||
type: integer
|
||||
description: The ID of the group to update the server for. Only for superAdmin role
|
||||
type_ip:
|
||||
type: integer
|
||||
description: Is server virtual (VIP address) or not
|
||||
master:
|
||||
type: integer
|
||||
description: Server id of the master server
|
||||
firewall_enable:
|
||||
type: integer
|
||||
description: Is firewalld enabled or not
|
||||
protected:
|
||||
type: integer
|
||||
description: Is the server protected from changes by a non-admin role
|
||||
responses:
|
||||
201:
|
||||
description: Server update successful
|
||||
|
@ -248,7 +272,7 @@ class ServerView(MethodView):
|
|||
|
||||
try:
|
||||
server_sql.update_server(
|
||||
body.hostname, group_id, body.type_ip, body.enabled, body.master, server_id, body.cred_id, body.port, body.description,
|
||||
body.hostname, body.ip, group_id, body.type_ip, body.enabled, body.master, server_id, body.cred_id, body.port, body.description,
|
||||
body.firewall_enable, body.protected
|
||||
)
|
||||
server_ip = server_sql.select_server_ip_by_id(server_id)
|
||||
|
@ -570,294 +594,6 @@ class ServerGroupsView(MethodView):
|
|||
return jsonify(groups_list)
|
||||
|
||||
|
||||
class CredView(MethodView):
|
||||
methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']
|
||||
decorators = [jwt_required(), get_user_params(), page_for_admin(level=2), check_group()]
|
||||
|
||||
def __init__(self, is_api=False):
|
||||
self.is_api = is_api
|
||||
|
||||
@staticmethod
|
||||
def get(creds_id: int):
|
||||
"""
|
||||
Retrieve credential information for a specific ID
|
||||
---
|
||||
tags:
|
||||
- 'SSH credentials'
|
||||
parameters:
|
||||
- in: 'path'
|
||||
name: 'creds_id'
|
||||
description: 'ID of the credential to retrieve'
|
||||
required: true
|
||||
type: 'integer'
|
||||
responses:
|
||||
200:
|
||||
description: 'Individual Credential Information'
|
||||
schema:
|
||||
type: 'object'
|
||||
properties:
|
||||
group_id:
|
||||
type: 'integer'
|
||||
description: 'Group ID the credential belongs to'
|
||||
id:
|
||||
type: 'integer'
|
||||
description: 'Credential ID'
|
||||
key_enabled:
|
||||
type: 'integer'
|
||||
description: 'Key status of the credential'
|
||||
name:
|
||||
type: 'string'
|
||||
description: 'Name of the credential'
|
||||
username:
|
||||
type: 'string'
|
||||
description: 'Username associated with the credential'
|
||||
404:
|
||||
description: 'Credential not found'
|
||||
"""
|
||||
group_id = int(g.user_params['group_id'])
|
||||
try:
|
||||
creds = cred_sql.get_ssh_by_id_and_group(creds_id, group_id)
|
||||
for cred in creds:
|
||||
return jsonify(model_to_dict(cred, exclude=[Cred.password, Cred.passphrase])), 200
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot get credentials')
|
||||
|
||||
@validate(body=CredRequest)
|
||||
def post(self, body: CredRequest):
|
||||
"""
|
||||
Create a new credential entry
|
||||
---
|
||||
tags:
|
||||
- SSH credentials
|
||||
parameters:
|
||||
- in: 'path'
|
||||
name: 'creds_id'
|
||||
description: 'ID of the credential to retrieve'
|
||||
required: true
|
||||
type: 'integer'
|
||||
- in: body
|
||||
name: body
|
||||
schema:
|
||||
id: AddCredentials
|
||||
required:
|
||||
- group_шв
|
||||
- name
|
||||
- username
|
||||
- key_enabled
|
||||
- password
|
||||
properties:
|
||||
group_id:
|
||||
type: integer
|
||||
description: The ID of the group to create the credential for. Only for superAdmin role
|
||||
name:
|
||||
type: string
|
||||
description: The credential name
|
||||
username:
|
||||
type: string
|
||||
description: The username
|
||||
key_enabled:
|
||||
type: integer
|
||||
description: If key is enabled or not
|
||||
password:
|
||||
type: string
|
||||
description: The password
|
||||
responses:
|
||||
201:
|
||||
description: Credential addition successful
|
||||
"""
|
||||
group_id = SupportClass.return_group_id(body)
|
||||
try:
|
||||
return ssh_mod.create_ssh_cred(body.name, body.password, group_id, body.username, body.key_enabled, self.is_api)
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot create new cred')
|
||||
|
||||
@validate(body=CredRequest)
|
||||
def put(self, creds_id: int, body: CredRequest):
|
||||
"""
|
||||
Update a credential entry
|
||||
---
|
||||
tags:
|
||||
- SSH credentials
|
||||
parameters:
|
||||
- in: 'path'
|
||||
name: 'creds_id'
|
||||
description: 'ID of the credential to retrieve'
|
||||
required: true
|
||||
type: 'integer'
|
||||
- in: body
|
||||
name: body
|
||||
schema:
|
||||
id: UpdateCredentials
|
||||
required:
|
||||
- name
|
||||
- username
|
||||
- key_enabled
|
||||
- password
|
||||
properties:
|
||||
group_id:
|
||||
type: integer
|
||||
description: The ID of the group to create the credential for. Only for superAdmin role
|
||||
name:
|
||||
type: string
|
||||
description: The credential name
|
||||
username:
|
||||
type: string
|
||||
description: The username
|
||||
key_enabled:
|
||||
type: integer
|
||||
description: If key is enabled or not
|
||||
password:
|
||||
type: string
|
||||
description: The password
|
||||
responses:
|
||||
201:
|
||||
description: Credential update successful
|
||||
"""
|
||||
group_id = SupportClass.return_group_id(body)
|
||||
try:
|
||||
self._check_is_correct_group(creds_id)
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, ''), 404
|
||||
|
||||
try:
|
||||
ssh_mod.update_ssh_key(creds_id, body.name, body.password, body.key_enabled, body.username, group_id)
|
||||
return BaseResponse().model_dump(mode='json'), 201
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot update SSH key')
|
||||
|
||||
def delete(self, creds_id: int):
|
||||
"""
|
||||
Delete a credential entry
|
||||
---
|
||||
tags:
|
||||
- SSH credentials
|
||||
parameters:
|
||||
- in: 'path'
|
||||
name: 'creds_id'
|
||||
description: 'ID of the credential to retrieve'
|
||||
required: true
|
||||
type: 'integer'
|
||||
responses:
|
||||
204:
|
||||
description: Credential deletion successful
|
||||
"""
|
||||
try:
|
||||
self._check_is_correct_group(creds_id)
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, ''), 404
|
||||
|
||||
try:
|
||||
ssh_mod.delete_ssh_key(creds_id)
|
||||
return BaseResponse().model_dump(mode='json'), 204
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot delete SSH key')
|
||||
|
||||
@validate(body=CredUploadRequest)
|
||||
def patch(self, creds_id: int, body: CredUploadRequest):
|
||||
"""
|
||||
Upload an SSH private key
|
||||
---
|
||||
tags:
|
||||
- SSH credentials
|
||||
parameters:
|
||||
- in: 'path'
|
||||
name: 'creds_id'
|
||||
description: 'ID of the credential to retrieve'
|
||||
required: true
|
||||
type: 'integer'
|
||||
- in: body
|
||||
name: body
|
||||
schema:
|
||||
id: UploadSSHKey
|
||||
required:
|
||||
- private_key
|
||||
- passphrase
|
||||
properties:
|
||||
private_key:
|
||||
type: string
|
||||
description: The private key string
|
||||
passphrase:
|
||||
type: string
|
||||
description: The passphrase
|
||||
responses:
|
||||
201:
|
||||
description: SSH key upload successful
|
||||
"""
|
||||
try:
|
||||
self._check_is_correct_group(creds_id)
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, ''), 404
|
||||
|
||||
try:
|
||||
ssh_mod.upload_ssh_key(creds_id, body.private_key, body.passphrase)
|
||||
return BaseResponse().model_dump(mode='json'), 201
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot upload SSH key')
|
||||
|
||||
@staticmethod
|
||||
def _check_is_correct_group(creds_id: int):
|
||||
if g.user_params['role'] == 1:
|
||||
return True
|
||||
try:
|
||||
ssh = cred_sql.get_ssh(creds_id)
|
||||
except RoxywiResourceNotFound:
|
||||
raise RoxywiResourceNotFound
|
||||
if ssh.group_id != g.user_params['group_id']:
|
||||
raise RoxywiGroupMismatch
|
||||
|
||||
|
||||
class CredsView(MethodView):
|
||||
methods = ['GET']
|
||||
decorators = [jwt_required(), get_user_params(), page_for_admin(level=2), check_group()]
|
||||
|
||||
@validate(query=GroupQuery)
|
||||
def get(self, query: GroupQuery):
|
||||
"""
|
||||
Retrieve credential information based on group_id
|
||||
---
|
||||
tags:
|
||||
- 'SSH credentials'
|
||||
parameters:
|
||||
- in: 'query'
|
||||
name: 'group_id'
|
||||
description: 'GroupQuery to filter servers. Only for superAdmin role'
|
||||
required: false
|
||||
type: 'integer'
|
||||
responses:
|
||||
200:
|
||||
description: 'Credentials Information'
|
||||
schema:
|
||||
type: 'array'
|
||||
items:
|
||||
type: 'object'
|
||||
properties:
|
||||
group_id:
|
||||
type: 'integer'
|
||||
description: 'Group ID the credential belongs to'
|
||||
id:
|
||||
type: 'integer'
|
||||
description: 'Credential ID'
|
||||
key_enabled:
|
||||
type: 'integer'
|
||||
description: 'Key status of the credential'
|
||||
name:
|
||||
type: 'string'
|
||||
description: 'Name of the credential'
|
||||
username:
|
||||
type: 'string'
|
||||
description: 'Username of the credential'
|
||||
"""
|
||||
group_id = SupportClass.return_group_id(query)
|
||||
try:
|
||||
creds = cred_sql.select_ssh(group=group_id)
|
||||
json_data = []
|
||||
for cred in creds:
|
||||
json_data.append(model_to_dict(cred, exclude=[Cred.password, Cred.passphrase]))
|
||||
return jsonify(json_data), 200
|
||||
except Exception as e:
|
||||
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot get credentials')
|
||||
|
||||
|
||||
class ServerIPView(MethodView):
|
||||
class ServersView(MethodView):
|
||||
methods = ["GET"]
|
||||
|
|
|
@ -12,7 +12,6 @@ slack-sdk>=3.4.0
|
|||
peewee>=3.14.10
|
||||
PyMySQL>=1.0.2
|
||||
distro>=1.2.0
|
||||
bottle>=0.12.20
|
||||
psutil>=5.9.1
|
||||
pdpyras>=4.5.2
|
||||
pika>=1.3.1
|
||||
|
|
Loading…
Reference in New Issue