mirror of https://github.com/Aidaho12/haproxy-wi
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
635 lines
21 KiB
635 lines
21 KiB
from flask.views import MethodView |
|
from flask_pydantic import validate |
|
from flask import render_template, jsonify, request |
|
from playhouse.shortcuts import model_to_dict |
|
from flask_jwt_extended import jwt_required |
|
|
|
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.server as server_mod |
|
from app.middleware import get_user_params, page_for_admin, check_group |
|
from app.modules.roxywi.exception import RoxywiResourceNotFound |
|
from app.modules.roxywi.class_models import BaseResponse, IdResponse, IdDataResponse, ServerRequest, GroupQuery, GroupRequest |
|
from app.modules.common.common_classes import SupportClass |
|
|
|
|
|
class ServerView(MethodView): |
|
methods = ["GET", "POST", "PUT", "DELETE"] |
|
decorators = [jwt_required(), page_for_admin(level=2), check_group()] |
|
|
|
def __init__(self, is_api=False): |
|
self.is_api = is_api |
|
|
|
@validate(query=GroupQuery) |
|
def get(self, server_id: int, query: GroupQuery): |
|
""" |
|
Retrieve server information based on GroupQuery |
|
--- |
|
tags: |
|
- 'Server' |
|
parameters: |
|
- in: 'path' |
|
name: 'server_id' |
|
description: 'ID of the Server to retrieve' |
|
required: true |
|
type: 'integer' |
|
- in: 'query' |
|
name: 'group_id' |
|
description: 'GroupQuery to filter servers. Only for superAdmin role' |
|
required: false |
|
type: 'integer' |
|
responses: |
|
200: |
|
description: Successful operation |
|
schema: |
|
type: 'object' |
|
properties: |
|
haproxy_active: |
|
type: 'integer' |
|
haproxy_alert: |
|
type: 'integer' |
|
apache: |
|
type: 'integer' |
|
apache_active: |
|
type: 'integer' |
|
apache_alert: |
|
type: 'integer' |
|
apache_metrics: |
|
type: 'integer' |
|
cred_id: |
|
type: 'integer' |
|
description: |
|
type: 'string' |
|
enabled: |
|
type: 'integer' |
|
firewall_enable: |
|
type: 'integer' |
|
group_id: |
|
type: 'integer' |
|
haproxy: |
|
type: 'integer' |
|
hostname: |
|
type: 'string' |
|
ip: |
|
type: 'string' |
|
keepalived: |
|
type: 'integer' |
|
keepalived_active: |
|
type: 'integer' |
|
keepalived_alert: |
|
type: 'integer' |
|
master: |
|
type: 'integer' |
|
haproxy_metrics: |
|
type: 'integer' |
|
nginx: |
|
type: 'integer' |
|
nginx_active: |
|
type: 'integer' |
|
nginx_alert: |
|
type: 'integer' |
|
nginx_metrics: |
|
type: 'integer' |
|
port: |
|
type: 'integer' |
|
pos: |
|
type: 'integer' |
|
protected: |
|
type: 'integer' |
|
server_id: |
|
type: 'integer' |
|
type_ip: |
|
type: 'integer' |
|
default: |
|
description: Unexpected error |
|
""" |
|
group_id = SupportClass.return_group_id(query) |
|
try: |
|
server = server_sql.get_server_with_group(server_id, group_id) |
|
except Exception as e: |
|
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot get group') |
|
return jsonify(model_to_dict(server)) |
|
|
|
@validate(body=ServerRequest) |
|
def post(self, body: ServerRequest): |
|
""" |
|
Create a new server |
|
--- |
|
tags: |
|
- Server |
|
parameters: |
|
- in: body |
|
name: body |
|
schema: |
|
id: NewServer |
|
required: |
|
- hostname |
|
- ip |
|
- cred_id |
|
- port |
|
- group_id |
|
properties: |
|
hostname: |
|
type: string |
|
description: The server name |
|
ip: |
|
type: string |
|
description: The server IP address or domain name |
|
enabled: |
|
type: integer |
|
description: If server is enabled or not |
|
cred_id: |
|
type: integer |
|
description: The ID of the credentials |
|
port: |
|
type: integer |
|
description: The port number |
|
description: |
|
type: string |
|
description: The server description |
|
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 |
|
""" |
|
group = SupportClass.return_group_id(body) |
|
|
|
try: |
|
last_id = server_mod.create_server( |
|
body.hostname, str(body.ip), group, body.type_ip, body.enabled, body.master, body.cred_id, body.port, body.description, |
|
body.haproxy, body.nginx, body.apache, body.firewall_enable |
|
) |
|
except Exception as e: |
|
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot create a server') |
|
|
|
roxywi_common.logging(body.ip, f'A new server {body.hostname} has been created', login=1, keep_history=1, service='server') |
|
try: |
|
server_mod.update_server_after_creating(body.hostname, str(body.ip)) |
|
except Exception as e: |
|
roxywi_common.logging(body.ip, f'Cannot get system info from {body.hostname}: {e}', login=1, keep_history=1, service='server', mes_type='error') |
|
|
|
if self.is_api: |
|
return IdResponse(id=last_id).model_dump(mode='json'), 201 |
|
else: |
|
try: |
|
user_subscription = roxywi_common.return_user_status() |
|
except Exception: |
|
user_subscription = roxywi_common.return_unsubscribed_user_status() |
|
lang = roxywi_common.get_user_lang_for_flask() |
|
kwargs = { |
|
'groups': group_sql.select_groups(), |
|
'servers': server_sql.select_servers(server=body.ip), |
|
'lang': lang, |
|
'masters': server_sql.select_servers(get_master_servers=1), |
|
'sshs': cred_sql.select_ssh(group=group), |
|
'user_subscription': user_subscription, |
|
'adding': 1 |
|
} |
|
data = render_template('ajax/new_server.html', **kwargs) |
|
return IdDataResponse(data=data, id=last_id), 201 |
|
|
|
@validate(body=ServerRequest) |
|
def put(self, server_id: int, body: ServerRequest): |
|
""" |
|
Update a server |
|
--- |
|
tags: |
|
- Server |
|
parameters: |
|
- in: 'path' |
|
name: 'server_id' |
|
description: 'ID of the User to retrieve' |
|
required: true |
|
type: 'integer' |
|
- in: body |
|
name: body |
|
schema: |
|
id: UpdateServer |
|
required: |
|
- hostname |
|
- ip |
|
- cred_id |
|
- port |
|
- group_id |
|
properties: |
|
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 |
|
cred_id: |
|
type: integer |
|
description: The ID of the credentials |
|
port: |
|
type: integer |
|
description: The port number |
|
description: |
|
type: string |
|
description: The server description |
|
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 |
|
""" |
|
group_id = SupportClass.return_group_id(body) |
|
|
|
try: |
|
server_sql.update_server( |
|
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) |
|
roxywi_common.logging(server_ip, f'The server {body.hostname} has been update', roxywi=1, login=1, keep_history=1, service='server') |
|
except Exception as e: |
|
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot update server') |
|
|
|
return BaseResponse().model_dump(mode='json'), 201 |
|
|
|
@staticmethod |
|
def delete(server_id: int): |
|
""" |
|
Delete a server |
|
--- |
|
tags: |
|
- Server |
|
parameters: |
|
- in: 'path' |
|
name: 'server_id' |
|
description: 'ID of server to delete' |
|
required: true |
|
type: 'integer' |
|
responses: |
|
204: |
|
description: Server deletion successful |
|
""" |
|
try: |
|
server_id = SupportClass().return_server_ip_or_id(server_id) |
|
except Exception as e: |
|
return roxywi_common.handler_exceptions_for_json_data(e, '') |
|
try: |
|
server_mod.delete_server(server_id) |
|
return BaseResponse().model_dump(mode='json'), 204 |
|
except Exception as e: |
|
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot delete server') |
|
|
|
|
|
class ServersView(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 servers information based on GroupQuery |
|
--- |
|
tags: |
|
- 'Server' |
|
parameters: |
|
- in: 'query' |
|
name: 'GroupQuery' |
|
description: 'GroupQuery to filter servers. Only for superAdmin role' |
|
required: false |
|
type: 'integer' |
|
responses: |
|
200: |
|
description: 'Servers Information' |
|
schema: |
|
type: 'array' |
|
items: |
|
type: 'object' |
|
properties: |
|
haproxy_active: |
|
type: 'integer' |
|
haproxy_alert: |
|
type: 'integer' |
|
apache: |
|
type: 'integer' |
|
apache_active: |
|
type: 'integer' |
|
apache_alert: |
|
type: 'integer' |
|
apache_metrics: |
|
type: 'integer' |
|
cred_id: |
|
type: 'integer' |
|
description: |
|
type: 'string' |
|
enabled: |
|
type: 'integer' |
|
firewall_enable: |
|
type: 'integer' |
|
group_id: |
|
type: 'integer' |
|
haproxy: |
|
type: 'integer' |
|
hostname: |
|
type: 'string' |
|
ip: |
|
type: 'string' |
|
keepalived: |
|
type: 'integer' |
|
keepalived_active: |
|
type: 'integer' |
|
keepalived_alert: |
|
type: 'integer' |
|
master: |
|
type: 'integer' |
|
haproxy_metrics: |
|
type: 'integer' |
|
nginx: |
|
type: 'integer' |
|
nginx_active: |
|
type: 'integer' |
|
nginx_alert: |
|
type: 'integer' |
|
nginx_metrics: |
|
type: 'integer' |
|
port: |
|
type: 'integer' |
|
pos: |
|
type: 'integer' |
|
protected: |
|
type: 'integer' |
|
server_id: |
|
type: 'integer' |
|
type_ip: |
|
type: 'integer' |
|
default: |
|
description: Unexpected error |
|
""" |
|
group_id = SupportClass.return_group_id(query) |
|
try: |
|
servers = server_sql.select_servers_with_group(group_id) |
|
except Exception as e: |
|
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot get group') |
|
servers_list = [model_to_dict(server) for server in servers] |
|
return jsonify(servers_list) |
|
|
|
|
|
class ServerGroupView(MethodView): |
|
methods = ["GET", "POST", "PUT", "DELETE"] |
|
decorators = [jwt_required(), get_user_params(), page_for_admin()] |
|
|
|
def __init__(self): |
|
""" |
|
Initialize ServerGroupView instance |
|
""" |
|
if request.method not in ('GET', 'DELETE'): |
|
self.json_data = request.get_json() |
|
else: |
|
self.json_data = None |
|
|
|
def get(self, group_id: int): |
|
""" |
|
Retrieve group information for a specific group_id |
|
--- |
|
tags: |
|
- 'Group' |
|
parameters: |
|
- in: 'path' |
|
name: 'group_id' |
|
description: 'ID of the group to retrieve to get the group' |
|
required: true |
|
type: 'integer' |
|
responses: |
|
200: |
|
description: 'Group Information' |
|
schema: |
|
type: 'object' |
|
properties: |
|
description: |
|
type: 'string' |
|
description: 'Description of the server group' |
|
group_id: |
|
type: 'integer' |
|
description: 'Server group ID' |
|
name: |
|
type: 'string' |
|
description: 'Name of the server group' |
|
404: |
|
description: 'Server group not found' |
|
""" |
|
try: |
|
groups = group_sql.select_groups(id=group_id) |
|
for group in groups: |
|
return model_to_dict(group) |
|
except Exception as e: |
|
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot get group') |
|
|
|
@validate(body=GroupRequest) |
|
def post(self, body: GroupRequest): |
|
""" |
|
Create a new group |
|
--- |
|
tags: |
|
- Group |
|
parameters: |
|
- in: body |
|
name: body |
|
schema: |
|
id: NewGroup |
|
required: |
|
- name |
|
- description |
|
properties: |
|
name: |
|
type: string |
|
description: The group name |
|
description: |
|
type: string |
|
description: The group description |
|
responses: |
|
201: |
|
description: Group creation successful |
|
""" |
|
try: |
|
last_id = group_sql.add_group(body.name, body.description) |
|
roxywi_common.logging('Roxy-WI server', f'A new group {body.name} has been created', roxywi=1, login=1) |
|
return IdResponse(id=last_id).model_dump(mode='json'), 201 |
|
except Exception as e: |
|
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot create group') |
|
|
|
@validate(body=GroupRequest) |
|
def put(self, group_id: int, body: GroupRequest): |
|
""" |
|
Update a group |
|
--- |
|
tags: |
|
- Group |
|
parameters: |
|
- in: 'path' |
|
name: 'group_id' |
|
description: 'Group ID to change' |
|
required: true |
|
type: 'integer' |
|
- in: body |
|
name: body |
|
schema: |
|
id: UpdateGroup |
|
required: |
|
- name |
|
- id |
|
properties: |
|
name: |
|
type: string |
|
description: The group name |
|
description: |
|
type: string |
|
description: The group description |
|
responses: |
|
201: |
|
description: Group update successful |
|
""" |
|
|
|
try: |
|
group_mod.update_group(group_id, body.name, body.description) |
|
return BaseResponse(), 201 |
|
except Exception as e: |
|
roxywi_common.handler_exceptions_for_json_data(e, 'Cannot update group') |
|
|
|
def delete(self, group_id: int): |
|
""" |
|
Delete a group |
|
--- |
|
tags: |
|
- Group |
|
parameters: |
|
- in: 'path' |
|
name: 'group_id' |
|
description: 'Group ID to delete' |
|
required: true |
|
type: 'integer' |
|
responses: |
|
204: |
|
description: Group deletion successful |
|
""" |
|
try: |
|
self._check_is_user_and_group(group_id) |
|
except Exception as e: |
|
return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot get user or group'), 404 |
|
try: |
|
group_mod.delete_group(group_id) |
|
return jsonify({'status': 'Ok'}), 204 |
|
except Exception as e: |
|
roxywi_common.handler_exceptions_for_json_data(e, 'Cannot delete group') |
|
|
|
@staticmethod |
|
def _check_is_user_and_group(group_id: int): |
|
try: |
|
groups = group_sql.get_group_name_by_id(group_id) |
|
if len(groups) == 0: |
|
raise RoxywiResourceNotFound |
|
except Exception as e: |
|
raise e |
|
|
|
|
|
class ServerGroupsView(MethodView): |
|
methods = ["GET"] |
|
decorators = [jwt_required(), get_user_params(), page_for_admin()] |
|
|
|
def get(self): |
|
""" |
|
This endpoint allows to get server groups. |
|
--- |
|
tags: |
|
- Group |
|
responses: |
|
200: |
|
description: Server groups retrieved successfully |
|
schema: |
|
type: array |
|
items: |
|
type: object |
|
properties: |
|
description: |
|
type: string |
|
group_id: |
|
type: integer |
|
name: |
|
type: string |
|
default: |
|
description: Unexpected error |
|
""" |
|
groups_list = [] |
|
groups = group_sql.select_groups() |
|
for group in groups: |
|
groups_list.append(model_to_dict(group)) |
|
return jsonify(groups_list) |
|
|
|
|
|
class ServerIPView(MethodView): |
|
class ServersView(MethodView): |
|
methods = ["GET"] |
|
decorators = [jwt_required(), get_user_params(), page_for_admin(level=3), check_group()] |
|
|
|
@staticmethod |
|
def get(server_id: int): |
|
""" |
|
Retrieves IPs associated with a certain server. |
|
--- |
|
tags: |
|
- Server |
|
parameters: |
|
- name: server_id |
|
in: path |
|
type: string |
|
required: true |
|
description: The server's identifier, it can be either server ID or server IP. |
|
responses: |
|
200: |
|
description: Server IPs returned successfully. |
|
schema: |
|
type: array |
|
items: |
|
type: string |
|
description: An IP Address attributed to the server. |
|
""" |
|
try: |
|
server_ip = SupportClass(False).return_server_ip_or_id(server_id) |
|
except Exception as e: |
|
return roxywi_common.handler_exceptions_for_json_data(e, '') |
|
|
|
ip_lists = [] |
|
cmd = 'sudo hostname -I | tr " " "\\n"|sed "/^$/d"' |
|
ips = server_mod.ssh_command(server_ip, cmd, ip="1") |
|
for ip in ips.split(' '): |
|
for i in ip.split('\r\n'): |
|
if i == '': |
|
continue |
|
ip_lists.append(i) |
|
return jsonify(ip_lists)
|
|
|