diff --git a/app/create_db.py b/app/create_db.py index 5c1df4e6..cbc7cc00 100644 --- a/app/create_db.py +++ b/app/create_db.py @@ -723,7 +723,7 @@ def update_db_v_8_1_6(): def update_ver(): try: - Version.update(version='8.1.6.1').execute() + Version.update(version='8.1.7').execute() except Exception: print('Cannot update version') diff --git a/app/modules/config/config.py b/app/modules/config/config.py index 3af779c3..ba41611a 100644 --- a/app/modules/config/config.py +++ b/app/modules/config/config.py @@ -3,8 +3,6 @@ from pathlib import Path from typing import Any from flask import render_template, g -from flask_jwt_extended import get_jwt -from flask_jwt_extended import verify_jwt_in_request import app.modules.db.sql as sql import app.modules.db.user as user_sql @@ -36,7 +34,7 @@ def _replace_config_path_to_correct(config_path: str) -> str: try: return config_path.replace('92', '/') except Exception as e: - roxywi_common.handle_exceptions(e, 'Roxy-WI server', 'Cannot sanitize config file', roxywi=1) + roxywi_common.handle_exceptions(e, 'Roxy-WI server', 'Cannot sanitize config file') def get_config(server_ip, cfg, service='haproxy', **kwargs): @@ -82,7 +80,7 @@ def get_config(server_ip, cfg, service='haproxy', **kwargs): with mod_ssh.ssh_connect(server_ip) as ssh: ssh.get_sftp(config_path, cfg) except Exception as e: - roxywi_common.handle_exceptions(e, 'Roxy-WI server', 'Cannot get config', roxywi=1) + roxywi_common.handle_exceptions(e, 'Roxy-WI server', 'Cannot get config') def upload(server_ip: str, path: str, file: str) -> None: @@ -98,7 +96,7 @@ def upload(server_ip: str, path: str, file: str) -> None: with mod_ssh.ssh_connect(server_ip) as ssh: ssh.put_sftp(file, path) except Exception as e: - roxywi_common.handle_exceptions(e, 'Roxy-WI server', f'Cannot upload {file} to {path} to server: {server_ip}', roxywi=1) + roxywi_common.handle_exceptions(e, 'Roxy-WI server', f'Cannot upload {file} to {path} to server: {server_ip}') def _generate_command(service: str, server_id: int, just_save: str, config_path: str, tmp_file: str, cfg: str, server_ip: str) -> str: @@ -153,7 +151,7 @@ def _generate_command(service: str, server_id: int, just_save: str, config_path: return commands -def _create_config_version(server_id: int, server_ip: str, service: str, config_path: str, login: str, cfg: str, old_cfg: str, tmp_file: str) -> None: +def _create_config_version(server_id: int, server_ip: str, service: str, config_path: str, user_id: int, cfg: str, old_cfg: str, tmp_file: str) -> None: """ Create a new version of the configuration file. @@ -181,17 +179,16 @@ def _create_config_version(server_id: int, server_ip: str, service: str, config_ try: get_config(server_ip, old_cfg, service=service, config_file_name=config_path) except Exception: - roxywi_common.logging('Roxy-WI server', 'Cannot download config for diff', roxywi=1) + roxywi_common.logging('Roxy-WI server', 'Cannot download config for diff') try: - diff = diff_config(old_cfg, cfg, return_diff=1) + diff = diff_config(old_cfg, cfg) except Exception as e: - roxywi_common.logging('Roxy-WI server', f'error: Cannot create diff config version: {e}', roxywi=1) + roxywi_common.logging('Roxy-WI server', f'error: Cannot create diff config version: {e}') try: - user = user_sql.get_user_id_by_username(login) - config_sql.insert_config_version(server_id, user.user_id, service, cfg, config_path, diff) + config_sql.insert_config_version(server_id, user_id, service, cfg, config_path, diff) except Exception as e: - roxywi_common.logging('Roxy-WI server', f'error: Cannot insert config version: {e}', roxywi=1) + roxywi_common.logging('Roxy-WI server', f'error: Cannot insert config version: {e}') def upload_and_restart(server_ip: str, cfg: str, just_save: str, service: str, **kwargs): @@ -221,16 +218,16 @@ def upload_and_restart(server_ip: str, cfg: str, just_save: str, service: str, * try: os.system(f"dos2unix -q {cfg}") except OSError as e: - roxywi_common.handle_exceptions(e, 'Roxy-WI server', 'There is no dos2unix', login=user.username) + roxywi_common.handle_exceptions(e, 'Roxy-WI server', 'There is no dos2unix') try: upload(server_ip, tmp_file, cfg) except Exception as e: - roxywi_common.handle_exceptions(e, 'Roxy-WI server', 'Cannot upload config', login=user.username) + roxywi_common.handle_exceptions(e, 'Roxy-WI server', 'Cannot upload config') # If master then save a version of config in a new way if not kwargs.get('slave') and service != 'waf': - _create_config_version(server_id, server_ip, service, config_path, user.username, cfg, kwargs.get('oldcfg'), tmp_file) + _create_config_version(server_id, server_ip, service, config_path, user.user_id, cfg, kwargs.get('oldcfg'), tmp_file) try: commands = _generate_command(service, server_id, just_save, config_path, tmp_file, cfg, server_ip) @@ -240,12 +237,12 @@ def upload_and_restart(server_ip: str, cfg: str, just_save: str, service: str, * try: error = server_mod.ssh_command(server_ip, commands) except Exception as e: - roxywi_common.handle_exceptions(e, 'Roxy-WI server', f'Cannot {just_save} {service}', roxywi=1) + roxywi_common.handle_exceptions(e, 'Roxy-WI server', f'Cannot {just_save} {service}') if just_save in ('reload', 'restart'): - roxywi_common.logging(server_ip, f'Service has been {just_save}ed', login=user.username, keep_history=1, service=service) + roxywi_common.logging(server_ip, f'Service {service.title()} has been {just_save}ed', keep_history=1, service=service) if just_save != 'test': - roxywi_common.logging(server_ip, 'A new config file has been uploaded', login=user.username, keep_history=1, service=service) + roxywi_common.logging(server_ip, 'A new config file has been uploaded', keep_history=1, service=service) if error.strip() != 'haproxy' and error.strip() != 'nginx': return error.strip() or service.title() @@ -349,46 +346,27 @@ def _open_port_firewalld(cfg: str, server_ip: str, service: str) -> str: return firewalld_commands -def diff_config(old_cfg, cfg, **kwargs): +def diff_config(old_cfg, cfg) -> str: """ - Function to compare two configuration files and log the differences. + Compute the difference between two configuration files and return the result as a string. - :param old_cfg: The path of the old configuration file. - :param cfg: The path of the new configuration file. - :param kwargs: Additional keyword arguments. Currently, supports: - - return_diff: If True, returns the difference between the two files as a string. - :return: If kwargs['return_diff'] is True, returns the difference between the two files as a string. - Otherwise, logs the differences with user information and writes it to a log file. + This function executes the `diff` command to compare two configuration files, + specified by their paths, and retrieves the resulting differences. The output + contains the line-by-line difference between `old_cfg` and `cfg` using the + unified diff format. This function is useful for auditing and comparing + configuration changes. + + :param old_cfg: Path to the old configuration file to compare. + :param cfg: Path to the new configuration file to compare. + :return: Unified diff output showing the differences between `old_cfg` and `cfg`. """ - log_path = get_config_var.get_config_var('main', 'log_path') - user_group = roxywi_common.get_user_group() diff = "" - date = get_date.return_date('date_in_log') - log_date = get_date.return_date('logs') cmd = f"/bin/diff -ub {old_cfg} {cfg}" - log_file = f"{log_path}/config_edit-{log_date}" output, stderr = server_mod.subprocess_execute(cmd) - if kwargs.get('return_diff'): - for line in output: - diff += line + "\n" - return diff - - try: - verify_jwt_in_request() - claims = get_jwt() - login = user_sql.get_user_id(claims['user_id']) - except Exception: - login = '' - for line in output: - diff += f"{date} user: {login.username}, group: {user_group} {line}\n" - - try: - with open(log_file, 'a') as log: - log.write(diff) - except IOError as e: - roxywi_common.logging('Roxy-WI server', f'error: Cannot write a diff config to the log file: {e}, {stderr}', login=login.username, roxywi=1) + diff += line + "\n" + return diff def _classify_line(line: str) -> str: diff --git a/app/modules/config/runtime.py b/app/modules/config/runtime.py index 838c3372..0850b3fc 100644 --- a/app/modules/config/runtime.py +++ b/app/modules/config/runtime.py @@ -132,7 +132,7 @@ def change_ip_and_port(serv, backend_backend, backend_server, backend_ip, backen lines += output[0] roxywi_common.logging( master[0], f'IP address and port have been changed. On: {backend_backend}/{backend_server} to {backend_ip}:{backend_port}', - login=1, keep_history=1, service='haproxy' + keep_history=1, service='haproxy' ) cmd = f'echo "set server {backend_backend}/{backend_server} addr {backend_ip} port {backend_port} ' \ @@ -140,7 +140,7 @@ def change_ip_and_port(serv, backend_backend, backend_server, backend_ip, backen roxywi_common.logging( serv, f'IP address and port have been changed. On: {backend_backend}/{backend_server} to {backend_ip}:{backend_port}', - login=1, keep_history=1, service='haproxy' + keep_history=1, service='haproxy' ) output, stderr = server_mod.subprocess_execute(cmd) @@ -218,14 +218,14 @@ def add_server( lines += f'{master[0]}: {line}
' stderr += error roxywi_common.logging( - master[0], f'A new backend server has been add: {backend}/{server}', login=1, keep_history=1, service='haproxy' + master[0], f'A new backend server has been add: {backend}/{server}', keep_history=1, service='haproxy' ) line, error = add_server_via_runtime(server_ip, backend, server, backend_ip, backend_port, check, port_check) lines += f'{server_ip}: {line}
' stderr += error roxywi_common.logging( - server_ip, f'A new backend server has been add: {backend}/{server}', login=1, keep_history=1, service='haproxy' + server_ip, f'A new backend server has been add: {backend}/{server}', keep_history=1, service='haproxy' ) if 'Already exists a server' in lines: @@ -272,14 +272,14 @@ def delete_server(server_ip: str, backend: str, server: str) -> str: lines += f'{master[0]}: {line}
' stderr += error roxywi_common.logging( - master[0], f'Server has been deleted: {backend}/{server}', login=1, keep_history=1, service='haproxy' + master[0], f'Server has been deleted: {backend}/{server}', keep_history=1, service='haproxy' ) line, error = delete_server_via_runtime(server_ip, backend, server) lines += f'{server_ip}: {line}
' stderr += error roxywi_common.logging( - server_ip, f'Server has been deleted: {backend}/{server}', login=1, keep_history=1, service='haproxy' + server_ip, f'Server has been deleted: {backend}/{server}', keep_history=1, service='haproxy' ) if stderr != '': @@ -309,10 +309,10 @@ def change_maxconn_global(serv: str, maxconn: int) -> str: if master[0] is not None: cmd = f'echo "set maxconn global {maxconn}" |nc {master[0]} {haproxy_sock_port}' server_mod.subprocess_execute(cmd) - roxywi_common.logging(master[0], f'Maxconn has been changed. Globally to {maxconn}', login=1, keep_history=1, service='haproxy') + roxywi_common.logging(master[0], f'Maxconn has been changed. Globally to {maxconn}', keep_history=1, service='haproxy') cmd = f'echo "set maxconn global {maxconn}" |nc {serv} {haproxy_sock_port}' - roxywi_common.logging(serv, f'Maxconn has been changed. Globally to {maxconn}', login=1, keep_history=1, service='haproxy') + roxywi_common.logging(serv, f'Maxconn has been changed. Globally to {maxconn}', keep_history=1, service='haproxy') output, stderr = server_mod.subprocess_execute(cmd) if stderr != '': @@ -341,10 +341,10 @@ def change_maxconn_frontend(serv, maxconn, frontend) -> str: if master[0] is not None: cmd = f'echo "set maxconn frontend {frontend} {maxconn}" |nc {master[0]} {haproxy_sock_port}' server_mod.subprocess_execute(cmd) - roxywi_common.logging(master[0], f'Maxconn has been changed. On: {frontend} to {maxconn}', login=1, keep_history=1, service='haproxy') + roxywi_common.logging(master[0], f'Maxconn has been changed. On: {frontend} to {maxconn}', keep_history=1, service='haproxy') cmd = f'echo "set maxconn frontend {frontend} {maxconn}" |nc {serv} {haproxy_sock_port}' - roxywi_common.logging(serv, f'Maxconn has been changed. On: {frontend} to {maxconn}', login=1, keep_history=1, service='haproxy') + roxywi_common.logging(serv, f'Maxconn has been changed. On: {frontend} to {maxconn}', keep_history=1, service='haproxy') output, stderr = server_mod.subprocess_execute(cmd) if stderr != '': @@ -373,10 +373,10 @@ def change_maxconn_backend(serv, backend, backend_server, maxconn) -> str: if master[0] is not None: cmd = f'echo "set maxconn server {backend}/{backend_server} {maxconn}" |nc {master[0]} {haproxy_sock_port}' server_mod.subprocess_execute(cmd) - roxywi_common.logging(master[0], f'Maxconn has been changed. On: {backend}/{backend_server} to {maxconn}', login=1, keep_history=1, service='haproxy') + roxywi_common.logging(master[0], f'Maxconn has been changed. On: {backend}/{backend_server} to {maxconn}', keep_history=1, service='haproxy') cmd = f'echo "set maxconn server {backend}/{backend_server} {maxconn}" |nc {serv} {haproxy_sock_port}' - roxywi_common.logging(serv, f'Maxconn has been changed. On: {backend} to {maxconn}', login=1, keep_history=1, service='haproxy') + roxywi_common.logging(serv, f'Maxconn has been changed. On: {backend} to {maxconn}', keep_history=1, service='haproxy') output, stderr = server_mod.subprocess_execute(cmd) if stderr != '': @@ -472,7 +472,7 @@ def delete_ip_from_list(serv, ip_id, ip, list_id, list_name) -> str: cmd = f'echo "del acl #{list_id} #{ip_id}" |nc {serv} {haproxy_sock_port}' output, stderr = server_mod.subprocess_execute(cmd) - roxywi_common.logging(serv, f'{ip_id} has been delete from list {list_id}', login=1, keep_history=1, service='haproxy') + roxywi_common.logging(serv, f'{ip_id} has been delete from list {list_id}', keep_history=1, service='haproxy') if output[0] != '': return f'error: {output[0]}' if stderr != '': @@ -495,7 +495,7 @@ def add_ip_to_list(serv, ip, list_id, list_name) -> str: if 'is not a valid IPv4 or IPv6 address' not in output[0]: cmd = f'echo "{ip}" >> {lib_path}/lists/{user_group}/{list_name}' output, stderr = server_mod.subprocess_execute(cmd) - roxywi_common.logging(serv, f'{ip} has been added to list {list_id}', login=1, keep_history=1, service='haproxy') + roxywi_common.logging(serv, f'{ip} has been added to list {list_id}', keep_history=1, service='haproxy') if output: return f'error: {output}' if stderr: diff --git a/app/modules/config/section.py b/app/modules/config/section.py index e586c19f..fe225afa 100644 --- a/app/modules/config/section.py +++ b/app/modules/config/section.py @@ -7,7 +7,7 @@ from app.modules.common.common import return_nice_path SECTION_NAMES = ( 'global', 'listen', 'frontend', 'backend', 'cache', 'defaults', '#HideBlockStart', - '#HideBlockEnd', 'peers', 'resolvers', 'userlist', 'http-errors' + '#HideBlockEnd', 'peers', 'resolvers', 'userlist', 'http-errors', 'log-forward' ) diff --git a/app/modules/db/user.py b/app/modules/db/user.py index 7cc879d9..e75dfc07 100644 --- a/app/modules/db/user.py +++ b/app/modules/db/user.py @@ -11,22 +11,18 @@ def add_user(user, email, password, role, enabled, group): if password != 'aduser': try: hashed_pass = roxy_wi_tools.Tools.get_hash(password) - last_id = User.insert( + return User.insert( username=user, email=email, password=hashed_pass, role_id=role, enabled=enabled, group_id=group ).execute() except Exception as e: out_error(e) - else: - return last_id else: try: - last_id = User.insert( + return User.insert( username=user, email=email, role=role, ldap_user=1, enabled=enabled, group_id=group ).execute() except Exception as e: out_error(e) - else: - return last_id def update_user_from_admin_area(user_id, **kwargs): @@ -214,13 +210,6 @@ def get_user_role_in_group(user_id, group_id): return int(user_id.user_role_id) -def get_user_id_by_username(username: str) -> User: - try: - return User.get(User.username == username) - except Exception as e: - out_error(e) - - def select_user_services(user_id): try: query_res = User.get(User.user_id == user_id).user_services diff --git a/app/modules/roxywi/auth.py b/app/modules/roxywi/auth.py index 5616497f..1df47a19 100644 --- a/app/modules/roxywi/auth.py +++ b/app/modules/roxywi/auth.py @@ -1,3 +1,5 @@ +from typing import Union + from flask import request, abort, url_for, jsonify from flask_jwt_extended import create_access_token, set_access_cookies from flask_jwt_extended import get_jwt @@ -10,7 +12,7 @@ import app.modules.roxywi.common as roxywi_common import app.modules.roxy_wi_tools as roxy_wi_tools -def check_login(user_id: int) -> str: +def check_login(user_id: int) -> Union[str, None]: if user_id is None: return 'login_page' @@ -24,8 +26,6 @@ def check_login(user_id: int) -> str: user_sql.update_last_act_user(user_id, ip) - return 'ok' - def is_access_permit_to_service(service: str) -> bool: service_id = service_sql.select_service_id_by_slug(service) diff --git a/app/modules/roxywi/class_models.py b/app/modules/roxywi/class_models.py index abbb1fe4..f1eac83e 100644 --- a/app/modules/roxywi/class_models.py +++ b/app/modules/roxywi/class_models.py @@ -542,3 +542,7 @@ class ListRequest(BaseModel): action: Optional[Literal['reload', 'restart', 'save']] = None content: Optional[str] = '' group_id: Optional[int] = None + + +class IpRequest(BaseModel): + ip: Union[IPvAnyAddress, DomainName] diff --git a/app/modules/roxywi/common.py b/app/modules/roxywi/common.py index e977304e..9a0c9d80 100644 --- a/app/modules/roxywi/common.py +++ b/app/modules/roxywi/common.py @@ -1,12 +1,12 @@ import os import glob +import logging as logger from typing import Any, Union from flask import request, g from flask_jwt_extended import get_jwt from flask_jwt_extended import verify_jwt_in_request -from app.modules.db.sql import get_setting import app.modules.db.udp as udp_sql import app.modules.db.roxy as roxy_sql import app.modules.db.user as user_sql @@ -22,13 +22,7 @@ from app.modules.roxywi.exception import RoxywiResourceNotFound, RoxywiGroupMism get_config_var = roxy_wi_tools.GetConfigVar() -def return_error_message(): - return 'error: All fields must be completed' - - def get_user_group(**kwargs) -> int: - user_group = '' - try: verify_jwt_in_request() claims = get_jwt() @@ -39,6 +33,8 @@ def get_user_group(**kwargs) -> int: user_group = group.group_id else: user_group = group.name + else: + user_group = '' except Exception as e: raise Exception(f'error: {e}') return user_group @@ -55,7 +51,7 @@ def check_user_group_for_flask(api_token: bool = False): if user_sql.check_user_group(user_id, group_id): return True else: - logging('RMON server', 'has tried to actions in not his group', login=1) + logging('Roxy-WI server', 'warning: has tried to actions in not his group') return False @@ -63,7 +59,7 @@ def check_user_group_for_socket(user_id: int, group_id: int) -> bool: if user_sql.check_user_group(user_id, group_id): return True else: - logging('RMON server', 'has tried to actions in not his group', login=1) + logging('Roxy-WI server', 'warning: has tried to actions in not his group') return False @@ -73,7 +69,7 @@ def check_is_server_in_group(server_ip: str) -> bool: if (server.ip == server_ip and int(server.group_id) == int(group_id)) or group_id == 1: return True else: - logging('Roxy-WI server', 'has tried to actions in not his group server', roxywi=1, login=1) + logging('Roxy-WI server', 'warning: has tried to actions in not his group server') return False @@ -105,56 +101,50 @@ def get_files(folder, file_format, server_ip=None) -> list: def logging(server_ip: Union[str, int], action: str, **kwargs) -> None: - get_date = roxy_wi_tools.GetDate(get_setting('time_zone')) - cur_date_in_log = get_date.return_date('date_in_log') + def setup_logger(log_file: str) -> None: + """Helper function to set up the logger configuration.""" + logger.basicConfig( + filename=log_file, + format='%(asctime)s %(levelname)s: %(message)s', + level=logger.INFO, + datefmt='%b %d %H:%M:%S' + ) + logger.getLogger("paramiko").setLevel(logger.WARNING) + + # Extracted log path and file configuration log_path = get_config_var.get_config_var('main', 'log_path') + log_file = f"{log_path}/roxy-wi.log" + setup_logger(log_file) + + # JWT validation and extracting user's information verify_jwt_in_request() claims = get_jwt() user_id = claims['user_id'] - login = user_sql.get_user_id(user_id=user_id) + user = user_sql.get_user_id(user_id=user_id) + user_group = get_user_group() + ip = request.remote_addr - if not os.path.exists(log_path): - os.makedirs(log_path) - - try: - user_group = get_user_group() - except Exception: - user_group = '' - - try: - ip = request.remote_addr - except Exception: - ip = '' - - if kwargs.get('roxywi') == 1: - if kwargs.get('login'): - mess = f"{cur_date_in_log} from {ip} user: {login.username}, group: {user_group}, {action} on: {server_ip}\n" - else: - mess = f"{cur_date_in_log} {action} from {ip}\n" - log_file = f"{log_path}/roxy-wi.log" + if 'error' in action: + log_level = logger.error + action = action.replace('error: : ', '') + action = action.replace('error: ', '') + elif 'warning' in action: + log_level = logger.warning + action = action.replace('warning: ', '') else: - mess = f"{cur_date_in_log} from {ip} user: {login.username}, group: {user_group}, {action} on: {server_ip} {kwargs.get('service')}\n" - log_file = f"{log_path}/config_edit.log" + log_level = logger.info + + log_message = f"from {ip} user: {user.username}, group: {user_group}, message: {action} on: {server_ip}" + log_level(log_message) if kwargs.get('keep_history'): try: - keep_action_history(kwargs.get('service'), action, server_ip, login.username, ip) + keep_action_history(kwargs.get('service'), action, server_ip, user.user_id, ip) except Exception as e: - print(f'error: Cannot save history: {e}') - - try: - with open(log_file, 'a') as log: - log.write(mess) - except IOError as e: - print(f'Cannot write log. Please check log_path in config {e}') + logger.error(f'Cannot save history: {e}') -def keep_action_history(service: str, action: str, server_ip: str, login: str, user_ip: str): - if login != '': - user = user_sql.get_user_id_by_username(login) - user_id = user.user_id - else: - user_id = 0 +def keep_action_history(service: str, action: str, server_ip: str, user_id: int, user_ip: str): if user_ip == '': user_ip = 'localhost' @@ -163,7 +153,7 @@ def keep_action_history(service: str, action: str, server_ip: str, login: str, u server_id = server_ip hostname = ha_sql.select_cluster_name(int(server_id)) except Exception as e: - logging('Roxy-WI server', f'Cannot get info about cluster {server_ip} for history: {e}', roxywi=1) + logging('Roxy-WI server', f'error: cannot get info about cluster {server_ip} for history: {e}') return elif service == 'UDP listener': try: @@ -171,7 +161,7 @@ def keep_action_history(service: str, action: str, server_ip: str, login: str, u listener = udp_sql.get_listener(server_id) hostname = listener.name except Exception as e: - logging('Roxy-WI server', f'Cannot get info about Listener {server_ip} for history: {e}', roxywi=1) + logging('Roxy-WI server', f'error: cannot get info about Listener {server_ip} for history: {e}') return else: try: @@ -179,13 +169,13 @@ def keep_action_history(service: str, action: str, server_ip: str, login: str, u server_id = server.server_id hostname = server.hostname except Exception as e: - logging('Roxy-WI server', f'Cannot get info about {server_ip} for history: {e}', roxywi=1) + logging('Roxy-WI server', f'error: cannot get info about {server_ip} for history: {e}') return try: history_sql.insert_action_history(service, action, server_id, user_id, user_ip, server_ip, hostname) except Exception as e: - logging('Roxy-WI server', f'Cannot save a history: {e}', roxywi=1) + logging('Roxy-WI server', f'error: cannot save a history: {e}') def get_dick_permit(**kwargs): @@ -289,7 +279,7 @@ def return_user_subscription(): user_subscription = return_user_status() except Exception as e: user_subscription = return_unsubscribed_user_status() - logging('Roxy-WI server', f'Cannot get a user plan: {e}', roxywi=1) + logging('Roxy-WI server', f'Cannot get a user plan: {e}') return user_subscription @@ -318,7 +308,7 @@ def is_user_has_access_to_group(user_id: int, group_id: int) -> None: def handle_json_exceptions(ex: Exception, message: str, server_ip='Roxy-WI server') -> dict: - logging(server_ip, f'{message}: {ex}', login=1, roxywi=1) + logging(server_ip, f'{message}: {ex}') return ErrorResponse(error=f'{message}: {ex}').model_dump(mode='json') diff --git a/app/modules/roxywi/group.py b/app/modules/roxywi/group.py index 77339f7c..f731a63c 100644 --- a/app/modules/roxywi/group.py +++ b/app/modules/roxywi/group.py @@ -3,14 +3,11 @@ import app.modules.roxywi.common as roxywi_common def update_group(group_id: int, group_name: str, desc: str) -> None: - if group_name == '': - return roxywi_common.return_error_message() - else: - try: - group_sql.update_group(group_name, desc, group_id) - roxywi_common.logging('Roxy-WI server', f'The {group_name} has been updated', roxywi=1, login=1) - except Exception as e: - raise Exception(e) + try: + group_sql.update_group(group_name, desc, group_id) + roxywi_common.logging('Roxy-WI server', f'The {group_name} has been updated') + except Exception as e: + raise Exception(e) def delete_group(group_id: int) -> None: @@ -18,6 +15,6 @@ def delete_group(group_id: int) -> None: try: group_sql.delete_group(group_id) - roxywi_common.logging('Roxy-WI server', f'The {group_name} has been deleted', roxywi=1, login=1) + roxywi_common.logging('Roxy-WI server', f'The {group_name} has been deleted') except Exception as e: raise e diff --git a/app/modules/roxywi/metrics.py b/app/modules/roxywi/metrics.py index 08e29d46..f8ddc239 100644 --- a/app/modules/roxywi/metrics.py +++ b/app/modules/roxywi/metrics.py @@ -5,54 +5,38 @@ import app.modules.common.common as common import app.modules.server.server as server_mod -def show_ram_metrics(metrics_type: str) -> dict: +def show_ram_metrics(server_ip: str) -> dict: metrics = {'chartData': {}} rams = '' - if metrics_type == '1': + if str(server_ip) == '127.0.0.1': rams_list = psutil.virtual_memory() - rams += str(round(rams_list.used / 1048576, 2)) + ' ' - rams += str(round(rams_list.free / 1048576, 2)) + ' ' - rams += str(round(rams_list.shared / 1048576, 2)) + ' ' - rams += str(round(rams_list.cached / 1048576, 2)) + ' ' - rams += str(round(rams_list.available / 1048576, 2)) + ' ' - rams += str(round(rams_list.total / 1048576, 2)) + ' ' + for i in (rams_list.used, rams_list.free, rams_list.shared, rams_list.cached, rams_list.available, rams_list.total): + rams += str(round(i / 1048576, 2)) + ' ' else: - commands = ["free -m |grep Mem |awk '{print $3,$4,$5,$6,$7,$2}'"] - metric, error = server_mod.subprocess_execute(commands[0]) - - for i in metric: - rams = i + commands = "sudo free -m |grep Mem |awk '{print $3,$4,$5,$6,$7,$2}'" + rams = server_mod.ssh_command(server_ip, commands).replace('\r', '').replace('\n', '') metrics['chartData']['rams'] = rams return metrics -def show_cpu_metrics(metrics_type: str) -> dict: +def show_cpu_metrics(server_ip: str) -> dict: metrics = {'chartData': {}} cpus = '' - - if metrics_type == '1': + if str(server_ip) == '127.0.0.1': total = psutil.cpu_percent(0.5) cpus_list = psutil.cpu_times_percent(interval=0.5, percpu=False) - cpus += str(cpus_list.user) + ' ' - cpus += str(cpus_list.system) + ' ' - cpus += str(cpus_list.nice) + ' ' - cpus += str(cpus_list.idle) + ' ' - cpus += str(cpus_list.iowait) + ' ' - cpus += str(cpus_list.irq) + ' ' - cpus += str(cpus_list.softirq) + ' ' - cpus += str(cpus_list.steal) + ' ' + for i in (cpus_list.user, cpus_list.system, cpus_list.nice, cpus_list.idle, cpus_list.iowait, cpus_list.irq, cpus_list.softirq, cpus_list.steal): + cpus += str(round(i, 2)) + ' ' cpus += str(total) + ' ' else: cmd = "top -d 0.5 -b -n2 | grep 'Cpu(s)'|tail -n 1 | awk '{print $2 + $4}'" - total, error = server_mod.subprocess_execute(cmd) - cmd = "top -b -n 1 |grep Cpu |awk -F':' '{print $2}'|awk -F' ' 'BEGIN{ORS=\" \";} { for (i=1;i<=NF;i+=2) print $i}'" - metric, error = server_mod.subprocess_execute(cmd) - for i in metric: - cpus = i - cpus += f'{total[0]}' + total = server_mod.ssh_command(server_ip, cmd).replace('\r', '').replace('\n', '') + cmd = "sudo top -b -n 1 |grep Cpu |awk -F':' '{print $2}'|awk -F' ' 'BEGIN{ORS=\" \";} { for (i=1;i<=NF;i+=2) print $i}'" + cpus = server_mod.ssh_command(server_ip, cmd) + cpus += total metrics['chartData']['cpus'] = cpus diff --git a/app/modules/service/action.py b/app/modules/service/action.py index cf75ff39..7ca581cd 100644 --- a/app/modules/service/action.py +++ b/app/modules/service/action.py @@ -47,7 +47,7 @@ def service_action(server_ip: str, action: str, service: str) -> None: command = get_action_command(service, action, server_id) server_mod.ssh_command(server_ip, command) - roxywi_common.logging(server_ip, f'Service has been {action}ed', roxywi=1, login=1, keep_history=1, service=service) + roxywi_common.logging(server_ip, f'Service {service.title()} has been {action}ed', keep_history=1, service=service) def get_action_command(service: str, action: str, server_id: int) -> str: @@ -78,7 +78,7 @@ def action_haproxy_waf(server_ip: str, action: str, service: str) -> None: raise e roxywi_common.logging( - server_ip, f'HAProxy WAF service has been {action}ed', roxywi=1, login=1, keep_history=1, service='haproxy' + server_ip, f'HAProxy WAF service has been {action}ed', keep_history=1, service='haproxy' ) command = f"sudo systemctl {action} waf" server_mod.ssh_command(server_ip, command) @@ -95,36 +95,8 @@ def action_nginx_waf(server_ip: str, action: str, service: str) -> None: waf_new_state = 'on' if action == 'start' else 'off' waf_old_state = 'off' if action == 'start' else 'on' - roxywi_common.logging(server_ip, f'NGINX WAF service has been {action}ed', roxywi=1, login=1, keep_history=1, service='nginx') + roxywi_common.logging(server_ip, f'NGINX WAF service has been {action}ed', keep_history=1, service='nginx') command = (f"sudo sed -i 's/modsecurity {waf_old_state}/modsecurity {waf_new_state}/g' {config_dir}nginx.conf " f"&& sudo systemctl reload nginx") server_mod.ssh_command(server_ip, command) - - -# def check_service(server_ip: str, user_id: int, service: str) -> str: -# user_services = user_sql.select_user_services(user_id) -# -# if '1' in user_services: -# if service == 'haproxy': -# haproxy_sock_port = sql.get_setting('haproxy_sock_port') -# cmd = 'echo "show info" |nc %s %s -w 1 -v|grep Name' % (server_ip, haproxy_sock_port) -# out = server_mod.subprocess_execute(cmd) -# for k in out[0]: -# if "Name" in k: -# return 'up' -# else: -# return 'down' -# if ('2' in user_services and service == 'nginx') or ('4' in user_services and service == 'apache'): -# stats_port = sql.get_setting(f'{service}_stats_port') -# -# with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock: -# sock.settimeout(5) -# -# try: -# if sock.connect_ex((server_ip, stats_port)) == 0: -# return 'up' -# else: -# return 'down' -# except Exception as e: -# return f'down {e}' diff --git a/app/routes/config/routes.py b/app/routes/config/routes.py index 109a55cc..69677e5c 100644 --- a/app/routes/config/routes.py +++ b/app/routes/config/routes.py @@ -286,8 +286,6 @@ def haproxy_section_save(server_ip): stderr = config_mod.master_slave_upload_and_restart(server_ip, cfg, save, 'haproxy', oldcfg=oldcfg) - config_mod.diff_config(oldcfg, cfg) - try: os.remove(f"{hap_configs_dir}*.old") except IOError: diff --git a/app/routes/metric/routes.py b/app/routes/metric/routes.py index ca835e01..72fa9fe0 100644 --- a/app/routes/metric/routes.py +++ b/app/routes/metric/routes.py @@ -17,7 +17,7 @@ import app.modules.common.common as common import app.modules.server.server as server_mod import app.modules.roxywi.metrics as metric import app.modules.roxywi.common as roxywi_common -from app.modules.roxywi.class_models import DomainName +from app.modules.roxywi.class_models import DomainName, IpRequest @bp.before_request @@ -68,17 +68,16 @@ def metrics(service): @bp.route('/cpu', methods=['POST']) -def metrics_cpu(): - metrics_type = common.checkAjaxInput(request.form.get('ip')) - - return jsonify(metric.show_cpu_metrics(metrics_type)) +@get_user_params() +@validate() +def metrics_cpu(body: IpRequest): + return jsonify(metric.show_cpu_metrics(body.ip)) @bp.route('/ram', methods=['POST']) -def metrics_ram(): - metrics_type = common.checkAjaxInput(request.form.get('ip')) - - return jsonify(metric.show_ram_metrics(metrics_type)) +@validate() +def metrics_ram(body: IpRequest): + return jsonify(metric.show_ram_metrics(body.ip)) @bp.route('//table-metrics') diff --git a/app/routes/server/routes.py b/app/routes/server/routes.py index 2a2ea19f..af8998e1 100644 --- a/app/routes/server/routes.py +++ b/app/routes/server/routes.py @@ -40,8 +40,6 @@ bp.add_url_rule('/backup', view_func=BackupView.as_view('backup', False), method 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() - @bp.before_request @jwt_required() diff --git a/app/routes/waf/routes.py b/app/routes/waf/routes.py index 5f62c5dc..e0c2b120 100644 --- a/app/routes/waf/routes.py +++ b/app/routes/waf/routes.py @@ -153,8 +153,6 @@ def waf_save_config(service, server_ip, rule_id): stderr = config_mod.master_slave_upload_and_restart(server_ip, cfg, save, 'waf', oldcfg=oldcfg, config_file_name=config_file_name) - config_mod.diff_config(oldcfg, cfg) - try: os.system(f"/bin/rm -f {configs_dir}*.old") except Exception as e: diff --git a/app/scripts/ansible/roles/letsencrypt/tasks/install.yml b/app/scripts/ansible/roles/letsencrypt/tasks/install.yml index 57f01d78..56a70c18 100644 --- a/app/scripts/ansible/roles/letsencrypt/tasks/install.yml +++ b/app/scripts/ansible/roles/letsencrypt/tasks/install.yml @@ -34,7 +34,7 @@ https_proxy: "{{PROXY}}" - name: Get cert - command: "certbot certonly --standalone {{domains_command}} --non-interactive --agree-tos --email {{email}} --http-01-port=8888" + command: "certbot certonly --standalone {{domains_command}} --non-interactive --agree-tos --email {{email}} --http-01-port=8888 --cert-name {{main_domain}}" - name: Combine into pem file shell: "cat /etc/letsencrypt/live/{{main_domain}}/fullchain.pem /etc/letsencrypt/live/{{main_domain}}/privkey.pem > {{ssl_path}}/{{main_domain}}.pem" diff --git a/app/static/js/metrics.js b/app/static/js/metrics.js index 182e07a2..7acb44bc 100644 --- a/app/static/js/metrics.js +++ b/app/static/js/metrics.js @@ -403,13 +403,13 @@ function loadMetrics() { }); } function getChartDataHapWiRam(ip) { + let json_data = { + 'ip': ip + } $.ajax({ url: "/metrics/ram", - data: { - metrics_hapwi_ram: '1', - ip: ip, - token: $('#token').val() - }, + data: JSON.stringify(json_data), + contentType: "application/json", beforeSend: function() { $('#ram').html('loading...') }, @@ -481,13 +481,13 @@ function renderChartHapWiRam(data) { charts.push(myChart); } function getChartDataHapWiCpu(ip) { + let json_data = { + 'ip': ip + } $.ajax({ url: "/metrics/cpu", - data: { - metrics_hapwi_cpu: '1', - ip: ip, - token: $('#token').val() - }, + data: JSON.stringify(json_data), + contentType: "application/json", type: "POST", success: function (result) { // Получение значений из строки и разделение их на массив @@ -596,8 +596,8 @@ $( function() { }); function showOverviewHapWI() { removeData(); - getChartDataHapWiCpu('1'); - getChartDataHapWiRam('1'); + getChartDataHapWiCpu('127.0.0.1'); + getChartDataHapWiRam('127.0.0.1'); NProgress.configure({showSpinner: false}); } function updatingCpuRamCharts() { diff --git a/app/static/js/overview.js b/app/static/js/overview.js index 42c913e7..ead90474 100644 --- a/app/static/js/overview.js +++ b/app/static/js/overview.js @@ -116,8 +116,8 @@ function showOverviewServer(name, ip, id, service) { $("#div-pannel-" + id).insertBefore('#up-pannel') $("#ajax-server-" + id).html(data); $.getScript(awesome) - getChartDataHapWiRam() - getChartDataHapWiCpu() + getChartDataHapWiRam(ip) + getChartDataHapWiCpu(ip) } } } ); diff --git a/app/templates/include/add/backend.html b/app/templates/include/add/backend.html index bb1f186e..5e0b4f69 100644 --- a/app/templates/include/add/backend.html +++ b/app/templates/include/add/backend.html @@ -21,11 +21,11 @@ {{ input('new_backend', name='name', title=lang.words.name|title() + ' ' +lang.words.backend, placeholder="web_80", required='required') }} - + {{lang.words.mode|title()}}: {% set values = dict() %} - {% set values = {'http':'http','tcp':'tcp'} %} + {% set values = {'http':'http','tcp':'tcp', 'log': 'log'} %} {{ select('backend-mode-select', name='mode', values=values, selected='http', required='required', class='force_close') }} diff --git a/app/templates/include/add/frontend.html b/app/templates/include/add/frontend.html index bb203d4e..407c4077 100644 --- a/app/templates/include/add/frontend.html +++ b/app/templates/include/add/frontend.html @@ -36,7 +36,7 @@ - + {{lang.words.mode|title()}}: {% set values = dict() %} diff --git a/app/templates/include/add/listen.html b/app/templates/include/add/listen.html index 7d74c206..6208309c 100644 --- a/app/templates/include/add/listen.html +++ b/app/templates/include/add/listen.html @@ -36,11 +36,11 @@ - + {{lang.words.mode|title()}}: {% set values = dict() %} - {% set values = {'http':'http','tcp':'tcp'} %} + {% set values = {'http':'http','tcp':'tcp', 'log': 'log'} %} {{ select('listen-mode-select', name='mode', values=values, selected='http', required='required', class='force_close') }} diff --git a/app/templates/install.html b/app/templates/install.html index 320668fb..d4abae21 100644 --- a/app/templates/install.html +++ b/app/templates/install.html @@ -274,7 +274,7 @@ {% set values = dict() %} - {% set values = {'1.3.0':'1.3.0', '1.3.1':'1.3.1', '1.5.0':'1.5.0', '1.6.1':'1.6.1', '1.7.0':'1.7.0', '1.8.0':'1.8.0', '1.8.2':'1.8.2'} %} + {% set values = {'1.5.0':'1.5.0', '1.6.1':'1.6.1', '1.7.0':'1.7.0', '1.8.0':'1.8.0', '1.8.2':'1.8.2', '1.9.1':'1.9.1'} %} {{ select('nodeexpver', values=values, selected='1.8.2') }} diff --git a/app/views/service/views.py b/app/views/service/views.py index 71f08ec1..4667ee2b 100644 --- a/app/views/service/views.py +++ b/app/views/service/views.py @@ -475,12 +475,6 @@ class ServiceConfigView(MethodView): except Exception as e: return f'error: {e}', 200 - if body.action != 'test': - try: - config_mod.diff_config(body.config_local_path, cfg) - except Exception as e: - return roxywi_common.handler_exceptions_for_json_data(e, 'Cannot compare configs') - return DataStrResponse(data=stderr).model_dump(mode='json'), 201 @@ -654,7 +648,7 @@ class ServiceConfigVersionsView(MethodView): try: file.add(get + "\n") roxywi_common.logging( - server_ip, f"Version of config has been deleted: {get}", login=1, keep_history=1, + server_ip, f"Version of config has been deleted: {get}", keep_history=1, service=service ) except Exception: