v8.1.7: Add "log" mode, improve metrics, and refactor logging

Extended "mode" options to include "log" for frontend/backend configurations. Enhanced RAM/CPU metrics to better handle remote servers and removed redundant logic. Streamlined logging with structured formatting, improved error handling, and removed unnecessary parameters.
pull/418/head
Aidaho 2025-04-05 12:33:22 +03:00
parent aedba82e7c
commit 53d319f5e0
23 changed files with 150 additions and 249 deletions

View File

@ -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')

View File

@ -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:

View File

@ -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}<br />'
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}<br />'
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}<br />'
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}<br />'
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:

View File

@ -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'
)

View File

@ -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

View File

@ -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)

View File

@ -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]

View File

@ -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')

View File

@ -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

View File

@ -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

View File

@ -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}'

View File

@ -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:

View File

@ -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('/<service>/table-metrics')

View File

@ -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()

View File

@ -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:

View File

@ -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"

View File

@ -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('<img class="loading_hapwi_overview" src="/static/images/loading.gif" alt="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() {

View File

@ -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)
}
}
} );

View File

@ -21,11 +21,11 @@
{{ input('new_backend', name='name', title=lang.words.name|title() + ' ' +lang.words.backend, placeholder="web_80", required='required') }}
</td>
</tr>
<tr class="advance">
<tr>
<td class="addName">{{lang.words.mode|title()}}: </td>
<td class="addOption">
{% 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') }}
<span id="https-backend-span">
<label for="https-backend" style="margin-top: 5px;">Is SSL enabled on frontend?</label>

View File

@ -36,7 +36,7 @@
</div>
</td>
</tr>
<tr class="advance">
<tr>
<td class="addName">{{lang.words.mode|title()}}: </td>
<td class="addOption">
{% set values = dict() %}

View File

@ -36,11 +36,11 @@
</div>
</td>
</tr>
<tr class="advance">
<tr>
<td class="addName">{{lang.words.mode|title()}}: </td>
<td class="addOption">
{% 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') }}
<span id="https-listen-span">
<label for="https-listen" style="margin-top: 5px;" title="{{lang.words.enable|title()}} SSL Offloading" data-help="{{lang.add_page.desc.ssl_offloading}}">SSL Offloading</label>

View File

@ -274,7 +274,7 @@
<td id="cur_node_exp_ver" class="padding10 first-collumn"></td>
<td class="padding10 first-collumn" style="width: 20%;">
{% 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') }}
</td>
<td class="padding10 first-collumn">

View File

@ -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: