Aidaho 2024-08-02 12:50:02 +03:00
parent 9e6405aaa5
commit 8f50e1b8bf
183 changed files with 6670 additions and 5603 deletions

View File

@ -1,305 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import os
from bottle import route, run, hook, response, request, error
import api_funct
import app.modules.db.user as user_sql
import app.modules.roxywi.common as roxywi_common
_error_auth = '403 Auth before'
_allow_origin = '*'
_allow_methods = 'PUT, GET, POST, DELETE, OPTIONS'
_allow_headers = 'Authorization, Origin, Accept, Content-Type, X-Requested-With'
@hook('before_request')
def check_login(required_service=0):
return api_funct.check_login(required_service=required_service)
@hook('after_request')
def enable_cors():
response.headers['Access-Control-Allow-Origin'] = _allow_origin
response.headers['Access-Control-Allow-Methods'] = _allow_methods
response.headers['Access-Control-Allow-Headers'] = _allow_headers
@error(500)
def error_handler_500(error):
return json.dumps({"status": "error", "message": str(error.exception)})
@route('/', method=['GET', 'POST'])
@route('/help', method=['GET', 'POST'])
def index():
if not check_login(required_service=1):
return dict(error=_error_auth)
data = {
'help': 'show all available endpoints',
'login': 'get temporarily token. Must be JSON body: login, password and group for which getting token. METHOD: POST',
'user': 'show info about all users inside a group. METHOD: GET',
'user': 'create a new user inside a group. Must be JSON body: username, email, password, role. METHOD: POST',
'server': 'show info about all servers. METHOD: GET',
'server': 'create a new server inside a group. Must be JSON body: hostname, ip, port, virt: enter 0 if is not Virtual IP, group_id, master_id: enter 0 if is not slave, cred_id, description. METHOD: POST',
'server/ssh': 'show info about all SSH credentials inside a group. METHOD: GET',
'server/ssh': 'create a new SSH credentials inside a group. Must be JSON body: name, key_enabled, username, password. METHOD: POST',
'server/ssh/key': 'upload a new SSH key inside a group. Must be JSON body: name, key, passphrase (could be empty). Name it is credentials name, in key new lines must be replaced with "\n" METHOD: POST',
'servers/status': 'show status all HAProxyes. METHOD: GET',
'haproxy/<id,hostname,ip>': 'show info about the HAProxy by id or hostname or ip. METHOD: GET',
'haproxy/<id,hostname,ip>/status': 'show HAProxy status by id or hostname or ip. METHOD: GET',
'haproxy/<id,hostname,ip>/runtime': 'exec HAProxy runtime commands by id or hostname or ip. Must be JSON body: "command". METHOD: POST',
'haproxy/<id,hostname,ip>/backends': 'show backends by id or hostname or ip. METHOD: GET',
'haproxy/<id,hostname,ip>/action/start': 'start HAProxy service by id or hostname or ip. METHOD: GET',
'haproxy/<id,hostname,ip>/action/stop': 'stop HAProxy service by id or hostname or ip. METHOD: GET',
'haproxy/<id,hostname,ip>/action/restart': 'restart HAProxy service by id or hostname or ip. METHOD: GET',
'haproxy/<id,hostname,ip>/config': 'get HAProxy config from a server by id or hostname or ip. METHOD: GET',
'haproxy/<id,hostname,ip>/config': 'upload HAProxy config to a server by id or hostname or ip. Headers: action: save/reload/restart. Body must consist a whole HAProxy config. METHOD: POST',
'haproxy/<id,hostname,ip>/log': 'show HAProxy logs by id or hostname or ip. May to have config next Headers: rows(format INT) default: 10 grep, waf(if needs WAF log) default: 0, start_hour(format: 24) default: 00, start_minute, end_hour(format: 24) default: 24, end_minute. METHOD: GET',
'haproxy/<id,hostname,ip>/section': 'show a certain section, headers: section-name. METHOD: GET',
'haproxy/<id,hostname,ip>/section/add': 'add a section to the HAProxy config by id or hostname or ip. Has to have config header with section and action header for action after upload. Section header must consist type: listen, frontend, etc. Action header accepts next value: save, test, reload and restart. Can be empty for just save. METHOD: POST',
'haproxy/<id,hostname,ip>/section/edit': 'edit a section in the HAProxy config by id or hostname or ip. Has to have config header section-name, action header for action after upload and body of a new section configuration. Section header must consist type: listen, frontend, etc. Action header accepts next value: save, test, reload and restart. Can be empty for just save. METHOD: POST',
'haproxy/<id,hostname,ip>/section/delete': 'delete a section in the HAProxy config by id or hostname or ip. Has to have config header section-name, action header for action after upload and body of a new section configuration. Section header must consist type: listen, frontend, etc. Action header accepts next value: save, test, reload and restart. Can be empty for just save. METHOD: POST',
'haproxy/<id,hostname,ip>/acl': 'add an acl to certain section. Must be JSON body: "section-name", "if", "then", "if_value", "then_value" and "action" for action after upload. Action accepts next value: "save", "test", "reload" and "restart". METHOD: POST',
'haproxy/<id,hostname,ip>/acl': 'delete an acl to certain section. Must be JSON body: "section-name", "if", "then", "if_value", "then_value" and "action" for action after upload. Action accepts next value: "save", "test", "reload" and "restart". METHOD: DELETE',
'nginx/<id,hostname,ip>': 'show info about the NGINX by id or hostname or ip. METHOD: GET',
'nginx/<id,hostname,ip>/status': 'show NGINX status by id or hostname or ip. METHOD: GET',
'nginx/<id,hostname,ip>/action/start': 'start NGINX service by id or hostname or ip. METHOD: GET',
'nginx/<id,hostname,ip>/action/stop': 'stop NGINX service by id or hostname or ip. METHOD: GET',
'nginx/<id,hostname,ip>/action/restart': 'restart NGINX service by id or hostname or ip. METHOD: GET',
'nginx/<id,hostname,ip>/config': 'get NGINX config from a server by id or hostname or ip. Headers: The full path to a config file, like: /etc/nginx/conf.d/default.conf. METHOD: GET',
'nginx/<id,hostname,ip>/config': 'upload NGINX config to a server by id or hostname or ip. Headers: action: save/reload/restart, config-file: the full path to the config, like /etc/nginx/conf.d/example.com.conf. Body must consist a whole NGINX config. METHOD: POST',
'apache/<id,hostname,ip>': 'show info about the Apache by id or hostname or ip. METHOD: GET',
'apache/<id,hostname,ip>/status': 'show Apache status by id or hostname or ip. METHOD: GET',
'apache/<id,hostname,ip>/action/start': 'start Apache service by id or hostname or ip. METHOD: GET',
'apache/<id,hostname,ip>/action/stop': 'stop Apache service by id or hostname or ip. METHOD: GET',
'apache/<id,hostname,ip>/action/restart': 'restart Apache service by id or hostname or ip. METHOD: GET',
'apache/<id,hostname,ip>/config': 'get Apache config from a server by id or hostname or ip. Headers: The full path to a config file, like: /etc/httpd/conf.d/default.conf. METHOD: GET',
'apache/<id,hostname,ip>/config': 'upload Apache config to a server by id or hostname or ip. Headers: action: save/reload/restart, config-file: the full path to the config, like /etc/httpd/conf.d/example.com.conf. Body must consist a whole Apache config. METHOD: POST',
'keepalived/<id,hostname,ip>': 'show info about the Keepalived by id or hostname or ip. METHOD: GET',
'keepalived/<id,hostname,ip>/status': 'show Keepalived status by id or hostname or ip. METHOD: GET',
'keepalived/<id,hostname,ip>/action/start': 'start Keepalived service by id or hostname or ip. METHOD: GET',
'keepalived/<id,hostname,ip>/action/stop': 'stop Keepalived service by id or hostname or ip. METHOD: GET',
'keepalived/<id,hostname,ip>/action/restart': 'restart Keepalived service by id or hostname or ip. METHOD: GET',
'keepalived/<id,hostname,ip>/config': 'get Keepalived config from a server by id or hostname or ip. METHOD: GET',
'keepalived/<id,hostname,ip>/config': 'upload Keepalived config to a server by id or hostname or ip. Headers: action: save/reload/restart. Body must consist a whole Keepalived config. METHOD: POST',
'ha': 'HA clusters list. METHOD: GET',
'ha': 'Create HA cluster. Body must be JSON: name: str, desc: str, cluster_id: 0, router_id: "", vip: str, servers: {server_id: dict:{eth: str, ip: str, name: str, master: int}}, service: dict: {{haproxy: int, docker: int}, {nginx: int, docker: int}}, virt_server: int, syn_flood: int, return_to_master: int, use_src: int. METHOD: POST',
'ha': 'Edit HA cluster. Body must be JSON: name: str, desc: str, cluster_id: int, router_id: "", vip: str, servers: {server_id: dict:{eth: str, ip: str, name: str, master: int}}, service: dict: {{haproxy: int, docker: int}, {nginx: int, docker: int}}, virt_server: int, syn_flood: int, return_to_master: int, use_src: int. METHOD: PUT',
'ha': 'Delete HA cluster. Body must be JSON: cluster_id: int. METHOD: DELETE',
}
return dict(help=data)
@route('/login', method=['POST'])
def get_token():
token = api_funct.get_token()
return dict(token=token)
@route('/server', method=['GET'])
def get_servers():
if not check_login():
return dict(error=_error_auth)
data = {}
try:
token = request.headers.get('token')
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
servers = roxywi_common.get_dick_permit(username=login, group_id=group_id, token=token)
for s in servers:
data[s[0]] = {
'server_id': s[0],
'hostname': s[1],
'ip': s[2],
'group': s[3],
'virt': s[4],
'enable': s[5],
'is_master': s[6],
'creds': s[7],
'alert': s[8],
'metrics': s[9]
}
except Exception as e:
data = {'error': e}
return dict(servers=data)
@route('/server', method=['POST'])
def show_servers():
if not check_login():
return dict(error=_error_auth)
return api_funct.create_server()
@route('/user', method=['GET'])
def show_users():
if not check_login():
return dict(error=_error_auth)
return api_funct.user_list()
@route('/user', method=['POST'])
def create_user():
if not check_login():
return dict(error=_error_auth)
return api_funct.create_user()
@route('/server/ssh', method=['GET'])
def show_ssh():
if not check_login():
return dict(error=_error_auth)
return api_funct.ssh_list()
@route('/server/ssh', method=['POST'])
def create_ssh():
if not check_login():
return dict(error=_error_auth)
return api_funct.create_ssh()
@route('/server/ssh/key', method=['POST'])
def upload_ssh_key():
if not check_login():
return dict(error=_error_auth)
return api_funct.upload_ssh_key()
@route('/servers/status', method=['GET'])
def servers_status():
if not check_login():
return dict(error=_error_auth)
return api_funct.get_all_statuses()
@route('/haproxy/<haproxy_id>/runtime', method=['POST'])
@route('/haproxy/<haproxy_id:int>/runtime', method=['POST'])
def haproxy_runtime(haproxy_id):
if not check_login(required_service=1):
return dict(error=_error_auth)
return api_funct.runtime(haproxy_id)
@route('/haproxy/<haproxy_id>/backends', method=['GET'])
@route('/haproxy/<haproxy_id:int>/backends', method=['GET'])
def haproxy_backends(haproxy_id):
if not check_login(required_service=1):
return dict(error=_error_auth)
return api_funct.show_backends(haproxy_id)
@route('/haproxy/<haproxy_id>/log', method=['GET'])
@route('/haproxy/<haproxy_id:int>/log', method=['GET'])
def haproxy_log(haproxy_id):
if not check_login(required_service=1):
return dict(error=_error_auth)
return api_funct.show_log(haproxy_id)
@route('/haproxy/<haproxy_id>/section', method=['GET'])
def get_section(haproxy_id):
if not check_login(required_service=1):
return dict(error=_error_auth)
return api_funct.get_section(haproxy_id)
@route('/haproxy/<haproxy_id>/section/add', method=['POST'])
@route('/haproxy/<haproxy_id:int>/section/add', method=['POST'])
def haproxy_section_add(haproxy_id):
if not check_login(required_service=1):
return dict(error=_error_auth)
return api_funct.add_to_config(haproxy_id)
@route('/haproxy/<haproxy_id>/section/delete', method=['POST'])
@route('/haproxy/<haproxy_id:int>/section/delete', method=['POST'])
def haproxy_section_delete(haproxy_id):
if not check_login(required_service=1):
return dict(error=_error_auth)
return api_funct.edit_section(haproxy_id, delete=1)
@route('/haproxy/<haproxy_id>/section/edit', method=['POST'])
@route('/haproxy/<haproxy_id:int>/section/edit', method=['POST'])
def haproxy_sectiond_edit(haproxy_id):
if not check_login(required_service=1):
return dict(error=_error_auth)
return api_funct.edit_section(haproxy_id)
@route('/haproxy/<haproxy_id>/acl', method=['POST'])
def add_acl(haproxy_id):
if not check_login(required_service=1):
return dict(error=_error_auth)
return api_funct.add_acl(haproxy_id)
@route('/ha', method=['GET', 'POST', 'PUT', 'DELETE'])
def create_ha():
if not check_login(required_service=5):
return dict(error=_error_auth)
if request.method == 'POST':
return api_funct.create_ha_cluster()
elif request.method == 'PUT':
return api_funct.update_cluster()
elif request.method == 'DELETE':
return api_funct.delete_ha_cluster()
elif request.method == 'GET':
return api_funct.cluster_list()
@route('/<service>/<server_id>', method=['GET'])
@route('/<service>/<server_id:int>', method=['GET'])
def callback(server_id, service):
required_service = api_funct.return_requred_serivce(service)
if not check_login(required_service=required_service):
return dict(error=_error_auth)
return api_funct.get_server(server_id, service)
@route('/<service>/<server_id>/status', method=['GET'])
@route('/<service>/<server_id:int>/status', method=['GET'])
def service_status(server_id, service):
required_service = api_funct.return_requred_serivce(service)
if not check_login(required_service=required_service):
return dict(error=_error_auth)
return api_funct.get_status(server_id, service)
@route('/<service>/<server_id>/action/<action:re:[a-z]+>', method=['GET'])
@route('/<service>/<server_id:int>/action/<action:re:[a-z]+>', method=['GET'])
def service_action(server_id, action, service):
required_service = api_funct.return_requred_serivce(service)
if not check_login(required_service=required_service):
return dict(error=_error_auth)
return api_funct.actions(server_id, action, service)
@route('/<service>/<server_id>/config', method=['GET'])
@route('/<service>/<server_id:int>/config', method=['GET'])
def service_config_show(server_id, service):
required_service = api_funct.return_requred_serivce(service)
if not check_login(required_service=required_service):
return dict(error=_error_auth)
config_path = request.headers.get('config-file')
return api_funct.get_config(server_id, service=service, config_path=config_path)
@route('/<service>/<server_id>/config', method=['POST'])
@route('/<service>/<server_id:int>/config', method=['POST'])
def service_config_edit(server_id, service):
required_service = api_funct.return_requred_serivce(service)
if not check_login(required_service=required_service):
return dict(error=_error_auth)
config_path = request.headers.get('config-file')
return api_funct.upload_config(server_id, service=service, config_path=config_path)
if __name__ == '__main__':
port = int(os.environ.get('PORT', 8080))
run(host='0.0.0.0', port=port, debug=True)

View File

@ -1,933 +0,0 @@
import os
import sys
import json
from bottle import request
sys.path.append(os.path.join(sys.path[0], '/var/www/haproxy-wi/'))
import app.modules.db.sql as sql
import app.modules.db.cred as cred_sql
import app.modules.db.user as user_sql
import app.modules.db.group as group_sql
import app.modules.db.server as server_sql
import app.modules.db.ha_cluster as ha_sql
import app.modules.server.ssh as ssh_mod
import app.modules.server.server as server_mod
import app.modules.config.section as section_mod
import app.modules.config.config as config_mod
import app.modules.config.runtime as runtime_mod
import app.modules.roxy_wi_tools as roxy_wi_tools
import app.modules.roxywi.logs as roxywi_logs
import app.modules.roxywi.user as roxywi_user
import app.modules.roxywi.common as roxywi_common
import app.modules.service.common as service_common
import app.modules.service.installation as service_mod
import app.modules.service.ha_cluster as ha_cluster
get_config_var = roxy_wi_tools.GetConfigVar()
def get_token():
try:
user_subscription = roxywi_common.return_user_status()
except Exception as e:
user_subscription = roxywi_common.return_unsubscribed_user_status()
roxywi_common.logging('Roxy-WI server', f'Cannot get a user plan: {e}', roxywi=1)
if user_subscription['user_status'] == 0:
roxywi_common.logging('API', 'You are not subscribed. Please subscribe to have access to this feature.', roxywi=1)
return False
elif user_subscription['user_plan'] == 'user':
roxywi_common.logging('API', 'This feature is not available for your plan.', roxywi=1)
return False
try:
body = request.body.getvalue().decode('utf-8')
login_pass = json.loads(body)
login = login_pass['login']
password_from_user = login_pass['password']
except Exception as e:
return f'error getting credentials: {e}'
try:
group_name = login_pass['group']
group_id = group_sql.get_group_id_by_name(group_name)
except Exception as e:
return f'error getting group: {e}'
try:
user = user_sql.get_user_id_by_username(login)
password = roxy_wi_tools.Tools.get_hash(password_from_user)
except Exception as e:
return f'error one more: {e}'
if user.activeuser == 0:
return False
if login in user.username and password == user.password:
import uuid
user_token = str(uuid.uuid4())
role_id = user_sql.get_role_id(user.user_id, group_id)
user_sql.write_api_token(user_token, group_id, role_id, user.username)
return user_token
else:
return False
def check_login(required_service=0) -> bool:
try:
user_subscription = roxywi_common.return_user_status()
except Exception as e:
user_subscription = roxywi_common.return_unsubscribed_user_status()
roxywi_common.logging('Roxy-WI server', f'Cannot get a user plan: {e}', roxywi=1)
if user_subscription['user_status'] == 0:
roxywi_common.logging('API', 'You are not subscribed. Please subscribe to have access to this feature.', roxywi=1)
return False
elif user_subscription['user_plan'] == 'user':
roxywi_common.logging('API', 'This feature is not available for your plan.', roxywi=1)
return False
token = request.headers.get('token')
if user_sql.get_api_token(token):
if required_service != 0:
user_id = user_sql.get_user_id_by_api_token(token)
try:
user_services = user_sql.select_user_services(user_id)
except Exception:
return False
if str(required_service) in user_services:
return True
else:
return False
else:
return True
else:
return False
def return_dict_from_out(server_id, out):
data = {server_id: {}}
for k in out:
if "Ncat:" not in k:
k = k.split(':')
data[server_id][k[0]] = k[1].strip()
else:
data[server_id] = {"error": "Cannot connect to HAProxy"}
return data
def check_permit_to_server(server_id, service='haproxy'):
servers = server_sql.select_servers(id_hostname=server_id)
token = request.headers.get('token')
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
try:
for s in servers:
server = roxywi_common.get_dick_permit(username=login, group_id=group_id, ip=s[2], token=token, service=service)
except Exception as e:
raise Exception(f'error: {e}')
return server
def return_requred_serivce(service):
if service == 'haproxy':
required_service = 1
elif service == 'nginx':
required_service = 2
elif service == 'apache':
required_service = 4
elif service == 'keepalived':
required_service = 3
else:
required_service = 0
return required_service
def get_server(server_id, service):
if service != 'apache' and service != 'nginx' and service != 'haproxy' and service != 'keepalived':
return dict(status='wrong service')
data = {}
try:
servers = check_permit_to_server(server_id, service=service)
for s in servers:
data = {
'server_id': s[0],
'hostname': s[1],
'ip': s[2],
'group': s[3],
'virt': s[4],
'enable': s[5],
'master': s[6],
'creds': s[7]
}
except Exception as e:
data = {server_id: {"error": f"{e}"}}
return dict(error=data)
return dict(server=data)
def get_status(server_id, service):
if service not in ('apache', 'nginx', 'haproxy', 'keepalived'):
return dict(status='wrong service')
try:
servers = check_permit_to_server(server_id, service=service)
for s in servers:
if service == 'haproxy':
cmd = 'echo "show info" |nc %s %s -w 1|grep -e "Ver\|CurrConns\|Maxco\|MB\|Uptime:"' % (s[2], sql.get_setting('haproxy_sock_port'))
out = server_mod.subprocess_execute(cmd)
data = return_dict_from_out(server_id, out[0])
elif service == 'nginx':
cmd = "/usr/sbin/nginx -v 2>&1|awk '{print $3}' && systemctl status nginx |grep -e 'Active'|awk '{print $2, $9$10$11$12$13}' && ps ax |grep nginx:|grep -v grep |wc -l"
try:
out = server_mod.ssh_command(s[2], cmd)
out1 = out.split()
json_for_sending = {server_id: {"Version": out1[0].split('/')[1], "Uptime": out1[2], "Process": out1[3]}}
data = json_for_sending
except Exception as e:
data = {server_id: {"error": "Cannot get status: " + str(e)}}
elif service == 'apache':
apache_stats_user = sql.get_setting('apache_stats_user')
apache_stats_password = sql.get_setting('apache_stats_password')
apache_stats_port = sql.get_setting('apache_stats_port')
apache_stats_page = sql.get_setting('apache_stats_page')
cmd = "curl -s -u %s:%s http://%s:%s/%s?auto |grep 'ServerVersion\|Processes\|ServerUptime:'" % \
(apache_stats_user, apache_stats_password, s[2], apache_stats_port, apache_stats_page)
servers_with_status = list()
try:
out = server_mod.subprocess_execute(cmd)
if out != '':
for k in out:
servers_with_status.append(k)
json_for_sending = {
server_id: {
"Version": servers_with_status[0][0].split('/')[1],
"Uptime": servers_with_status[0][1].split(':')[1].strip(),
"Process": servers_with_status[0][2].split(' ')[1]
}
}
data = json_for_sending
except Exception as e:
data = {server_id: {"error": "Cannot get status: " + str(e)}}
except Exception:
data = {server_id: {"error": "Cannot find the server"}}
return dict(error=data)
return dict(status=data)
def get_all_statuses():
data = {}
try:
token = request.headers.get('token')
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
sock_port = sql.get_setting('haproxy_sock_port')
except Exception as e:
data = {"error": f"Cannot parameters: {e}"}
return dict(error=data)
try:
servers = roxywi_common.get_dick_permit(username=login, group_id=group_id, token=token)
except Exception as e:
data = {"error": f"Cannot get the server: {e}"}
return dict(error=data)
try:
for s in servers:
cmd = 'echo "show info" |nc %s %s -w 1|grep -e "Ver\|CurrConns\|Maxco\|MB\|Uptime:"' % (s[2], sock_port)
data[s[2]] = {}
out = server_mod.subprocess_execute(cmd)
data[s[2]] = return_dict_from_out(s[1], out[0])
except Exception as e:
data = {"error": f"Cannot find the server: {e}"}
return dict(error=data)
return dict(status=data)
def actions(server_id, action, service):
if action not in ('start', 'stop', 'restart', 'reload'):
return dict(status='wrong action')
if service not in ('apache', 'nginx', 'haproxy', 'keepalived'):
return dict(status='wrong service')
try:
servers = check_permit_to_server(server_id, service=service)
for s in servers:
if service == 'apache':
service = service_common.get_correct_apache_service_name(server_ip=s[2])
cmd = "sudo systemctl %s %s" % (action, service)
error = server_mod.ssh_command(s[2], cmd)
done = error if error else 'done'
data = {'server_id': s[0], 'ip': s[2], 'action': action, 'hostname': s[1], 'status': done}
return dict(status=data)
except Exception as e:
return dict(status=str(e))
def runtime(server_id):
try:
body = request.body.getvalue().decode('utf-8')
json_loads = json.loads(body)
action = json_loads['command']
haproxy_sock = sql.get_setting('haproxy_sock')
servers = check_permit_to_server(server_id)
cmd = 'echo "%s" |sudo socat stdio %s' % (action, haproxy_sock)
for s in servers:
out = server_mod.ssh_command(s[2], cmd)
sep_data = out.split('\r\n')
data = {server_id: sep_data}
return dict(status=data)
except Exception:
return dict(status='error')
def show_backends(server_id):
try:
servers = check_permit_to_server(server_id)
for s in servers:
out = runtime_mod.show_backends(s[2], ret=1)
data = {server_id: out}
except Exception:
data = {server_id: {"error": "Cannot find the server"}}
return dict(error=data)
return dict(backends=data)
def get_config(server_id, **kwargs):
service = kwargs.get('service')
if service not in ('apache', 'nginx', 'haproxy', 'keepalived'):
return dict(status='wrong service')
try:
servers = check_permit_to_server(server_id, service=service)
except Exception as e:
data = {server_id: {"error": f"Cannot find the server {e}"}}
return dict(error=data)
for s in servers:
server_ip = s[2]
try:
cfg = f'/tmp/{server_ip}.cfg'
except Exception as e:
data = {server_id: {"error": f"Cannot find the server with the service {service}: {e}"}}
return dict(error=data)
try:
config_mod.get_config(server_ip, cfg, service=service, config_file_name=kwargs.get('config_path'))
except Exception as e:
data = {server_id: {"error": f"Cannot get config {e}"}}
return dict(error=data)
try:
os.system("sed -i 's/\\n/\n/g' " + cfg)
except Exception as e:
data = {server_id: {"error": f"Cannot edit config {e}"}}
return dict(error=data)
try:
conf = open(cfg, "r")
config_read = conf.read()
conf.close()
except IOError as e:
data = {server_id: {"error": f"Cannot read config {e}"}}
return dict(error=data)
data = {server_id: config_read}
return dict(config=data)
def get_section(server_id):
section_name = request.headers.get('section-name')
servers = check_permit_to_server(server_id)
for s in servers:
cfg = '/tmp/' + s[2] + '.cfg'
config_mod.get_config(s[2], cfg)
start_line, end_line, config_read = section_mod.get_section_from_config(cfg, section_name)
data = {server_id: {section_name: {'start_line': start_line, 'end_line': end_line, 'config_read': config_read}}}
return dict(section=data)
def edit_section(server_id, delete=0):
body = request.body.getvalue().decode('utf-8')
section_name = request.headers.get('section-name')
save = request.headers.get('action')
token = request.headers.get('token')
servers = check_permit_to_server(server_id)
hap_configs_dir = get_config_var.get_config_var('configs', 'haproxy_save_configs_dir')
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
if save == '':
save = 'save'
elif save == 'restart':
save = ''
elif save == 'reload':
save = 'reload'
if delete == 1:
body = ''
action = 'deleted'
else:
action = 'edited'
for s in servers:
ip = s[2]
cfg = f'/tmp/{ip}.cfg'
out = config_mod.get_config(ip, cfg)
start_line, end_line, config_read = section_mod.get_section_from_config(cfg, section_name)
returned_config = section_mod.rewrite_section(start_line, end_line, cfg, body)
time_zone = sql.get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
cur_date = get_date.return_date('config')
try:
cfg_for_save = f'{hap_configs_dir}{ip}-{cur_date}.cfg'
try:
with open(cfg, "w") as conf:
conf.write(returned_config)
return_mess = 'section has been updated'
os.system(f"/bin/cp {cfg} {cfg_for_save}")
out = config_mod.master_slave_upload_and_restart(ip, cfg, save, login=login)
roxywi_common.logging('localhost', f" section {section_name} has been {action} via API", login=login)
roxywi_common.logging(
ip, f'Section {section_name} has been {action} via API', roxywi=1,
login=login, keep_history=1, service='haproxy'
)
if out:
return_mess = out
except IOError:
return_mess = "cannot upload config"
data = {server_id: return_mess}
except Exception as e:
data = {server_id: {"error": str(e)}}
return dict(error=data)
return dict(config=data)
def upload_config(server_id, **kwargs):
service = kwargs.get('service')
if service not in ('apache', 'nginx', 'haproxy', 'keepalived'):
return dict(status='wrong service')
body = request.body.getvalue().decode('utf-8')
save = request.headers.get('action')
token = request.headers.get('token')
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
nginx = ''
apache = ''
if service == 'nginx':
configs_dir = get_config_var.get_config_var('configs', 'nginx_save_configs_dir')
service_name = 'Apache'
nginx = 1
elif service == 'apache':
configs_dir = get_config_var.get_config_var('configs', 'apache_save_configs_dir')
service_name = 'NGINX'
apache = 1
else:
configs_dir = get_config_var.get_config_var('configs', 'haproxy_save_configs_dir')
service_name = 'HAProxy'
if save == '':
save = 'save'
elif save == 'restart':
save = ''
elif save == 'reload':
save = 'reload'
try:
servers = check_permit_to_server(server_id)
for s in servers:
ip = s[2]
cfg = f'/tmp/{ip}.cfg'
time_zone = sql.get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
cur_date = get_date.return_date('config')
cfg_for_save = f'{configs_dir}{ip}-{cur_date}.cfg'
try:
with open(cfg, "w") as conf:
conf.write(body)
return_mess = 'config has been uploaded'
os.system("/bin/cp %s %s" % (cfg, cfg_for_save))
if kwargs.get('service') == 'nginx':
out = config_mod.master_slave_upload_and_restart(ip, cfg, save, login=login, nginx=nginx, config_file_name=kwargs.get('config_path'))
elif kwargs.get('service') == 'apache':
out = config_mod.master_slave_upload_and_restart(ip, cfg, save, login=login, apache=apache, config_file_name=kwargs.get('config_path'))
else:
out = config_mod.master_slave_upload_and_restart(ip, cfg, save, login=login)
roxywi_common.logging('localhost', " config has been uploaded via API", login=login)
roxywi_common.logging(
ip, 'Config has been uploaded via API', roxywi=1, login=login, keep_history=1, service=service_name
)
if out:
return_mess = out
except IOError as e:
return_mess = f"cannot upload config {e}"
data = {server_id: return_mess}
except Exception as e:
data = {server_id: {"error": str(e)}}
return dict(error=data)
return dict(config=data)
def add_to_config(server_id):
data = {}
body = request.body.getvalue().decode('utf-8')
save = request.headers.get('action')
hap_configs_dir = get_config_var.get_config_var('configs', 'haproxy_save_configs_dir')
token = request.headers.get('token')
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
time_zone = sql.get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
if save == '':
save = 'save'
elif save == 'restart':
save = ''
try:
servers = check_permit_to_server(server_id)
for s in servers:
ip = s[2]
cfg = f'/tmp/{ip}.cfg'
cur_date = get_date.return_date('config')
cfg_for_save = f'{hap_configs_dir}{ip}-{cur_date}.cfg'
out = config_mod.get_config(ip, cfg)
try:
with open(cfg, "a") as conf:
conf.write('\n' + body + '\n')
return_mess = 'section has been added to the config'
os.system(f"/bin/cp {cfg} {cfg_for_save}")
roxywi_common.logging('localhost', " section has been added via REST API", login=login)
out = config_mod.upload_and_restart(ip, cfg, just_save=save)
if out:
return_mess = out
except IOError:
return_mess = "cannot upload config"
data = {server_id: return_mess}
except Exception:
data[server_id] = {"error": "cannot find the server"}
return dict(error=data)
return dict(config=data)
def show_log(server_id):
data = {}
rows = request.headers.get('rows')
waf = request.headers.get('waf')
grep = request.headers.get('grep')
hour = request.headers.get('start_hour')
minute = request.headers.get('start_minute')
hour1 = request.headers.get('end_hour')
minute1 = request.headers.get('end_minute')
if rows is None:
rows = '10'
if waf is None:
waf = '0'
if hour is None:
hour = '00'
if minute is None:
minute = '00'
if hour1 is None:
hour1 = '24'
if minute1 is None:
minute1 = '00'
try:
servers = check_permit_to_server(server_id)
for s in servers:
ip = s[2]
except Exception:
data[server_id] = {"error": "Cannot find the server"}
return dict(error=data)
out = roxywi_logs.show_roxy_log(ip, rows=rows, waf=str(waf), grep=grep, hour=str(hour), minut=str(minute), hour1=str(hour1), minut1=str(minute1), html=0)
data = {server_id: out}
return dict(log=data)
def add_acl(server_id):
body = request.body.getvalue().decode('utf-8')
json_loads = json.loads(body)
save = json_loads['action']
section_name = json_loads['section-name']
acl = generate_acl(with_newline=1)
servers = check_permit_to_server(server_id)
status = ''
for s in servers:
cfg = '/tmp/' + s[2] + '.cfg'
server_ip = s[2]
try:
out = config_mod.get_config(server_ip, cfg)
start_line, end_line, config_read = section_mod.get_section_from_config(cfg, section_name)
except Exception as e:
data = {server_id: {"error": f"Cannot read section: {e}"}}
return dict(error=data)
try:
config_read += acl
config = section_mod.rewrite_section(start_line, end_line, cfg, config_read)
try:
with open(cfg, "w") as conf:
conf.write(config)
except IOError as e:
data = {server_id: {"error": f"Cannot read import config file: {e}"}}
return dict(error=data)
except Exception as e:
data = {server_id: {"error": f"{e}"}}
return dict(error=data)
try:
out = config_mod.master_slave_upload_and_restart(server_ip, cfg, just_save=save)
if out != '':
status = out
else:
status = 'ACL has been added'
except Exception as e:
data = {server_id: {"error": f"{e}"}}
return dict(error=data)
data = {'acl': status}
return dict(data)
def del_acl(server_id):
body = request.body.getvalue().decode('utf-8')
json_loads = json.loads(body)
save = json_loads['action']
section_name = json_loads['section-name']
acl = generate_acl()
servers = check_permit_to_server(server_id)
for s in servers:
server_ip = s[2]
cfg = f'/tmp/{server_ip}.cfg'
try:
out = config_mod.get_config(server_ip, cfg)
start_line, end_line, config_read = section_mod.get_section_from_config(cfg, section_name)
except Exception as e:
data = {server_id: {"error": f"{e}"}}
return dict(error=data)
try:
config_new_read = ''
for line in config_read.split('\n'):
if not line.startswith(acl):
if line != '':
config_new_read += line + '\n'
except Exception as e:
data = {server_id: {"error": f"Cannot delete ACL: {e}"}}
return dict(error=data)
try:
config = config_mod.master_slave_upload_and_restart(start_line, end_line, cfg, config_new_read)
try:
with open(cfg, "w") as conf:
conf.write(config)
except IOError as e:
data = {server_id: {"error": f"Cannot read import config file: {e}"}}
return dict(error=data)
except Exception as e:
data = {server_id: {"error": f"Cannot delete ACL: {e}"}}
return dict(error=data)
try:
out = config_mod.master_slave_upload_and_restart(server_ip, cfg, just_save=save)
if out != '':
status = out
else:
status = 'ACL has been deleted'
except Exception as e:
data = {server_id: {"error": f"{e}"}}
return dict(error=data)
return dict(acl=status)
def generate_acl(**kwargs):
body = request.body.getvalue().decode('utf-8')
json_loads = json.loads(body)
if_value = json_loads['if_value']
then_value = json_loads['then_value']
if_acl = json_loads['if']
then_acl = json_loads['then']
acl = ''
if if_acl == 'host_starts':
acl_if_word = 'hdr_beg(host) -i '
elif if_acl == 'host_ends':
acl_if_word = 'hdr_end(host) -i '
elif if_acl == 'path_starts':
acl_if_word = 'path_beg -i '
elif if_acl == 'path_ends':
acl_if_word = 'path_end -i '
elif if_acl == 'src_ip':
acl_if_word = 'src ip '
else:
acl_if_word = ''
if then_acl == 'use_backend':
acl += ' use_backend '
elif then_acl == 'redirect':
acl += ' http-request redirect location '
elif then_acl == 'allow':
acl += ' http-request allow'
elif then_acl == 'deny':
acl += ' http-request deny'
elif then_acl == 'return':
acl += ' return '
elif then_acl == 'set-header':
acl += ' set-header '
newline = '\n' if kwargs.get('with_newline') else ''
acl += then_value + ' if { ' + acl_if_word + if_value + ' } ' + newline
return acl
def user_list():
data = {}
token = request.headers.get('token')
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
users = user_sql.select_users(by_group_id=group_id)
for user in users:
data[user.user_id] = {
'login': user.username,
'email': user.email,
'role': user.role,
'ldap': user.ldap_user,
'enabled': user.activeuser,
'last_login_ip': user.last_login_ip,
}
data = {'users': data}
return dict(data)
def create_user():
body = request.body.getvalue().decode('utf-8')
json_loads = json.loads(body)
name = json_loads['name']
email = json_loads['email']
password = json_loads['password']
role = json_loads['role']
token = request.headers.get('token')
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
if roxywi_user.create_user(name, email, password, role, 1, group_id, role_id=role_id, token=token):
data = {'status': 'done'}
return dict(data)
else:
data = {'status': 'something went wrong'}
return dict(data)
def ssh_list():
data = {}
token = request.headers.get('token')
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
sshs = cred_sql.select_ssh(group=group_id)
for ssh in sshs:
data[ssh.id] = {
'name': ssh.name,
'username': ssh.username,
'key_enabled': ssh.enable,
}
data = {'creds': data}
return dict(data)
def create_ssh():
body = request.body.getvalue().decode('utf-8')
json_loads = json.loads(body)
name = json_loads['name']
enable = json_loads['key_enabled']
username = json_loads['username']
password = json_loads['password']
token = request.headers.get('token')
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
try:
ssh_mod.create_ssh_cred_api(name, enable, group_id, username, password)
data = {'status': 'done'}
except Exception as e:
data = {'status': f'error: {e}'}
return dict(data)
def upload_ssh_key():
body = request.body.getvalue().decode('utf-8')
json_loads = json.loads(body)
name = json_loads['name']
key = json_loads['key']
passphrase = json_loads['passphrase']
token = request.headers.get('token')
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
groups = group_sql.select_groups(id=group_id)
for group in groups:
user_group = group.name
try:
ssh_mod.upload_ssh_key(f'{name}_{user_group}', user_group, key, passphrase)
data = {'status': 'done'}
return dict(data)
except Exception as e:
data = {'status': f'{e}'}
return dict(data)
def create_server():
body = request.body.getvalue().decode('utf-8')
json_loads = json.loads(body)
hostname = json_loads['hostname']
ip = json_loads['ip']
port = json_loads['port']
virt = json_loads['virt']
master_id = json_loads['master_id']
cred_id = json_loads['cred_id']
desc = json_loads['description']
token = request.headers.get('token')
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
try:
if server_mod.create_server(hostname, ip, group_id, virt, 1, master_id, cred_id, port, desc, 0, 0, 0, 0, role_id=role_id, token=token):
data = {'status': 'done'}
roxywi_common.logging(ip, f'A new server {hostname} has been created', roxywi=1, keep_history=1, service='server')
return dict(data)
except Exception as e:
data = {'status': f'error: {e}'}
return dict(data)
def cluster_list():
token = request.headers.get('token')
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
clusters = ha_sql.select_clusters(group_id)
data = {}
for cluster in clusters:
data.setdefault(cluster.id, cluster.name)
return dict(data)
def create_ha_cluster():
token = request.headers.get('token')
body = request.body.getvalue().decode('utf-8')
json_loads = json.loads(body)
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
data = {'status': dict()}
try:
cluster_id = ha_cluster.create_cluster(json_loads, group_id)
except Exception as e:
data['status'] = f'error: Cannot create HA cluster: {e}'
return data['status']
else:
data['status'].setdefault('cluster', 'done')
try:
json_loads['cluster_id'] = cluster_id
json_dump = json.dumps(json_loads)
service_mod.install_service('keepalived', json.loads(json_dump))
except Exception as e:
data['status'].setdefault('keepalived', f'{e}')
else:
data['status'].setdefault('keepalived', 'done')
if json_loads['services']['haproxy']['enabled']:
try:
service_mod.install_service('haproxy', json.loads(body))
except Exception as e:
data['status'].setdefault('haproxy', f'{e}')
else:
data['status'].setdefault('haproxy', 'done')
if json_loads['services']['nginx']['enabled']:
try:
service_mod.install_service('nginx', json.loads(body))
except Exception as e:
data['status'].setdefault('nginx', f'{e}')
else:
data['status'].setdefault('nginx', 'done')
return dict(data)
def update_cluster():
token = request.headers.get('token')
body = request.body.getvalue().decode('utf-8')
json_loads = json.loads(body)
login, group_id, role_id = user_sql.get_username_group_id_from_api_token(token)
data = {'status': dict()}
try:
ha_cluster.update_cluster(json_loads, group_id)
except Exception as e:
data['status'] = f'error: Cannot create HA cluster: {e}'
return data['status']
if json_loads['services']['haproxy']['enabled']:
try:
service_mod.install_service('haproxy', body)
except Exception as e:
data['status'].setdefault('haproxy', f'error: {e}')
else:
data['status'].setdefault('haproxy', 'done')
if json_loads['services']['nginx']['enabled']:
try:
service_mod.install_service('nginx', body)
except Exception as e:
data['status'].setdefault('nginx', f'error: {e}')
else:
data['status'].setdefault('nginx', 'done')
return dict(data)
def delete_ha_cluster():
body = request.body.getvalue().decode('utf-8')
json_loads = json.loads(body)
cluster_id = json_loads['cluster_id']
data = {'status': dict()}
try:
ha_cluster.delete_cluster(cluster_id)
except Exception as e:
data['status'] = f'error: {e}'
else:
data['status'] = 'done'
return dict(data)

View File

@ -1,8 +0,0 @@
import sys
import os
import bottle
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
os.chdir(os.path.dirname(os.path.abspath(__file__)))
import api
application = bottle.default_app()

View File

@ -1,6 +1,6 @@
from flask import Flask
from flask_caching import Cache
from flask_login import LoginManager
from flask_jwt_extended import JWTManager
from flask_apscheduler import APScheduler
app = Flask(__name__)
@ -15,8 +15,11 @@ scheduler = APScheduler()
scheduler.init_app(app)
scheduler.start()
login_manager = LoginManager(app)
login_manager.login_view = 'login_page'
jwt = JWTManager(app)
from app.api.routes import bp as api_bp
app.register_blueprint(api_bp, url_prefix='/api')
from app.routes.main import bp as main_bp
from app.routes.overview import bp as overview_bp

View File

@ -0,0 +1,5 @@
from flask import Blueprint
bp = Blueprint('api', __name__)
from app.api.routes import routes

178
app/api/routes/routes.py Normal file
View File

@ -0,0 +1,178 @@
from flask_swagger import swagger
from flask import jsonify, render_template, abort
from flask_pydantic import validate
from app import app, jwt
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.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
from app.views.udp.views import UDPListener, UDPListeners, UDPListenerActionView
from app.views.channel.views import ChannelView, ChannelsView
from app.views.tools.views import CheckerView
from app.views.admin.views import SettingsView
from app.modules.roxywi.class_models import LoginRequest
import app.modules.roxywi.auth as roxywi_auth
import app.modules.roxywi.common as roxywi_common
@bp.before_request
def before_request():
""" Protect all the API endpoints. """
user_subscription = roxywi_common.return_user_subscription()
if user_subscription['user_status'] == 0 or user_subscription['user_plan'] == 'user':
abort(403, 'Your subscription is not active or you are on a Home plan.')
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'])
def register_api_id_ip(view, endpoint, url: str = '', methods: list = ['GET', 'POST']):
for point in ('_id', '_ip'):
view_func = view.as_view(f'{endpoint}_{point}')
pk = 'int:' if point == '_id' else ''
bp.add_url_rule(f'/service/<any(haproxy, nginx, apache, keepalived):service>/<{pk}server_id>{url}', view_func=view_func, methods=methods)
register_api(HAView, 'ha_cluster', '/ha/<service>', 'cluster_id')
register_api(UDPListener, 'udp_listener', '/<service>/listener', 'listener_id')
bp.add_url_rule('/<service>/listener/<int:listener_id>/<any(start, stop, reload, restart):action>', view_func=UDPListenerActionView.as_view('listener_action'), methods=['GET'])
bp.add_url_rule('/<service>/listeners', view_func=UDPListeners.as_view('listeners'), methods=['GET'])
bp.add_url_rule('/ha/<service>/<int:cluster_id>/vip/<int:router_id>', view_func=HAVIPView.as_view('ha_vip_g'), methods=['GET'])
bp.add_url_rule('/ha/<service>/<int:cluster_id>/vip', view_func=HAVIPView.as_view('ha_vip'), methods=['POST', 'PUT'])
bp.add_url_rule('/ha/<service>/<int:router_id>/vip', view_func=HAVIPView.as_view('ha_vip_d'), methods=['DELETE'])
bp.add_url_rule('/ha/<service>/<int:cluster_id>/vips', view_func=HAVIPsView.as_view('ha_vips'), methods=['GET'])
register_api_id_ip(ServiceView, 'service', '/status', ['GET'])
register_api_id_ip(ServiceBackendView, 'service_backend', '/backend', ['GET'])
register_api_id_ip(ServiceConfigView, 'config_view')
register_api_id_ip(ServiceConfigVersionsView, 'config_version', '/versions', methods=['GET'])
register_api_id_ip(CheckerView, 'checker', '/tools')
register_api_id_ip(InstallView, 'install', '/install', methods=['POST'])
register_api_id_ip(ServiceActionView, 'service_action', '/<any(start, stop, reload, restart):action>', methods=['GET'])
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')
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')
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'])
register_api(ServerGroupView, 'group', '/group', 'group_id')
bp.add_url_rule('/groups', view_func=ServerGroupsView.as_view('groups'), methods=['GET'])
def register_api_with_group(view, endpoint, url_beg, url_end, pk='user_id', pk_type='int', pk_end='group_id', pk_type_end='int'):
view_func = view.as_view(endpoint)
bp.add_url_rule(f'/{url_beg}/<{pk_type}:{pk}>/{url_end}', view_func=view_func, methods=['GET'])
bp.add_url_rule(f'/{url_beg}/<{pk_type}:{pk}>/{url_end}/<{pk_type_end}:{pk_end}>', view_func=view_func, methods=['PUT', 'DELETE', 'POST', 'PATCH'])
register_api(UserView, 'user', '/user', 'user_id')
register_api_with_group(UserGroupView, 'user_group', '/user', 'groups')
bp.add_url_rule('/user/roles', view_func=UserRoles.as_view('roles'))
def register_api_channel(view, endpoint, url_beg, pk='receiver', pk_type='int', pk_end='channel_id', pk_type_end='int'):
view_func = view.as_view(endpoint, True)
bp.add_url_rule(f'/{url_beg}/<any(telegram, slack, pd, mm):{pk}>', view_func=view_func, methods=['POST'])
bp.add_url_rule(f'/{url_beg}/<any(telegram, slack, pd, mm):{pk}>/<{pk_type_end}:{pk_end}>', view_func=view_func, methods=['PUT', 'DELETE', 'GET', 'PATCH'])
register_api_channel(ChannelView, 'channel', '/channel')
bp.add_url_rule('/channels/<any(telegram, slack, pd, mm):receiver>', view_func=ChannelsView.as_view('channels'), methods=['GET'])
bp.add_url_rule(
'/settings',
view_func=SettingsView.as_view('settings'),
methods=['GET'],
defaults={'section': None}
)
bp.add_url_rule(
'/settings/<any(smon, main, haproxy, nginx, apache, keepalived, rabbitmq, ldap, monitoring, mail, logs):section>',
view_func=SettingsView.as_view('settings_section'),
methods=['GET', 'POST']
)
@bp.route("/spec")
def spec():
swag = swagger(app)
swag['info']['version'] = "1.0"
swag['info']['title'] = "Roxy-WI API"
return jsonify(swag)
@bp.route("/swagger")
def swagger_ui():
return render_template('swagger.html')
@bp.post('/login')
@validate(body=LoginRequest)
def do_login(body: LoginRequest):
"""
Do log in
---
tags:
- Authentication
description: This route is used to log into the system
parameters:
- name: body
in: body
schema:
type: object
properties:
login:
type: string
required: true
description: The user's login name
password:
type: string
required: true
description: The user's password
responses:
200:
description: Login successfully, return a JWT token
schema:
type: object
properties:
access_token:
type: string
description: JWT token for user authentication
401:
description: Authentication Error
"""
try:
login = body.login
password = body.password
except Exception as e:
return roxywi_common.handler_exceptions_for_json_data(e, 'There is no login or password')
try:
user_params = roxywi_auth.check_user_password(login, password)
except Exception as e:
return roxywi_common.handle_json_exceptions(e, ''), 401
access_token = roxywi_auth.create_jwt_token(user_params)
return jsonify(access_token=access_token)

View File

@ -1,7 +1,16 @@
from datetime import timedelta
class Configuration(object):
SECRET_KEY = 'very secret salt to protect your Roxy-WI sessions'
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = 'strict'
CACHE_TYPE = 'SimpleCache'
CACHE_DEFAULT_TIMEOUT = 3000
SCHEDULER_API_ENABLED = True
JWT_ACCESS_TOKEN_EXPIRES = timedelta(days=1)
JWT_ALGORITHM = 'RS256'
JWT_PRIVATE_KEY = open('/var/lib/roxy-wi/keys/roxy-wi-key').read()
JWT_PUBLIC_KEY = open('/var/lib/roxy-wi/keys/roxy-wi-key.pub').read()
JWT_TOKEN_LOCATION = ["headers", "cookies"]
JWT_IDENTITY_CLAIM = 'user_id'
JWT_ERROR_MESSAGE_KEY = 'error'
FLASK_PYDANTIC_VALIDATION_ERROR_RAISE = True

View File

@ -1,7 +1,10 @@
#!/usr/bin/env python3
#!/usr/bin/env python3.11
import os
import sys
import distro
from modules.db.db_model import *
sys.path.append(os.path.join(sys.path[0], '/var/www/haproxy-wi/'))
from app.modules.db.db_model import *
conn = connect()
@ -101,9 +104,9 @@ def default_values():
print(str(e))
data_source = [
{'username': 'admin', 'email': 'admin@localhost', 'password': '21232f297a57a5a743894a0e4a801fc3', 'role': '1', 'groups': '1'},
{'username': 'editor', 'email': 'editor@localhost', 'password': '5aee9dbd2a188839105073571bee1b1f', 'role': '2', 'groups': '1'},
{'username': 'guest', 'email': 'guest@localhost', 'password': '084e0343a0486ff05530df6c705c8bb4', 'role': '4', 'groups': '1'}
{'username': 'admin', 'email': 'admin@localhost', 'password': '21232f297a57a5a743894a0e4a801fc3', 'role': '1', 'group_id': '1'},
{'username': 'editor', 'email': 'editor@localhost', 'password': '5aee9dbd2a188839105073571bee1b1f', 'role': '2', 'group_id': '1'},
{'username': 'guest', 'email': 'guest@localhost', 'password': '084e0343a0486ff05530df6c705c8bb4', 'role': '4', 'group_id': '1'}
]
try:
@ -458,7 +461,7 @@ def update_db_v_3_4_5_22():
def update_db_v_4_3_0():
try:
UserGroups.insert_from(
User.select(User.user_id, User.groups), fields=[UserGroups.user_id, UserGroups.user_group_id]
User.select(User.user_id, User.group_id), fields=[UserGroups.user_id, UserGroups.user_group_id]
).on_conflict_ignore().execute()
except Exception as e:
if e.args[0] == 'duplicate column name: haproxy' or str(e) == '(1060, "Duplicate column name \'haproxy\'")':
@ -659,6 +662,37 @@ def update_db_v_7_3_1():
else:
print("An error occurred:", e)
def update_db_v_7_4():
try:
migrate(
migrator.rename_column('backups', 'cred', 'cred_id'),
migrator.rename_column('backups', 'backup_type', 'type'),
migrator.rename_column('servers', 'active', 'haproxy_active'),
migrator.rename_column('servers', 'metrics', 'haproxy_metrics'),
migrator.rename_column('servers', 'alert', 'haproxy_alert'),
migrator.rename_column('udp_balancers', 'desc', 'description'),
migrator.rename_column('ha_clusters', 'desc', 'description'),
migrator.rename_column('servers', 'desc', 'description'),
migrator.rename_column('telegram', 'groups', 'group_id'),
migrator.rename_column('slack', 'groups', 'group_id'),
migrator.rename_column('mattermost', 'groups', 'group_id'),
migrator.rename_column('pd', 'groups', 'group_id'),
migrator.rename_column('servers', 'groups', 'group_id'),
migrator.rename_column('servers', 'cred', 'cred_id'),
migrator.rename_column('servers', 'enable', 'enabled'),
migrator.rename_column('user', 'activeuser', 'enabled'),
migrator.rename_column('user', 'groups', 'group_id'),
migrator.rename_column('cred', 'enable', 'key_enabled'),
migrator.rename_column('cred', 'groups', 'group_id'),
)
except Exception as e:
if e.args[0] == 'no such column: "cred"' or str(e) == '(1060, no such column: "cred")':
print("Updating... DB has been updated to version 7.4")
elif e.args[0] == "'bool' object has no attribute 'sql'":
print("Updating... DB has been updated to version 7.4")
else:
print("An error occurred:", e)
def update_ver():
try:
@ -693,6 +727,7 @@ def update_all():
update_db_v_7_2_0_1()
update_db_v_7_2_3()
update_db_v_7_3_1()
update_db_v_7_4()
update_ver()

View File

@ -39,13 +39,6 @@ def update_cur_tool_versions():
tools_common.update_cur_tool_versions()
@scheduler.task('interval', id='delete_old_uuid', minutes=60, misfire_grace_time=None)
def delete_old_uuid():
app = scheduler.app
with app.app_context():
user_sql.delete_old_uuid()
@scheduler.task('interval', id='delete_action_history_for_period', minutes=70, misfire_grace_time=None)
def delete_action_history_for_period():
app = scheduler.app

View File

@ -1,103 +1,67 @@
from flask import render_template, request, redirect, url_for, make_response
from flask_login import login_required, logout_user, current_user, login_url
from flask import render_template, request, redirect, make_response, abort
from flask_jwt_extended import unset_jwt_cookies, jwt_required
from app import app, login_manager, cache
from app import app
import app.modules.db.user as user_sql
import app.modules.roxywi.common as roxywi_common
import app.modules.roxywi.auth as roxywi_auth
import app.modules.roxywi.roxy as roxy
import app.modules.roxy_wi_tools as roxy_wi_tools
import app.modules.roxywi.auth as roxywi_auth
import app.modules.roxywi.common as roxywi_common
@app.before_request
def check_login():
if request.endpoint not in (
'login_page', 'static', 'main.show_roxywi_version', 'service.check_service', 'smon.show_smon_status_page',
'smon.smon_history_statuses', 'smon.agent_get_checks', 'smon.get_check_status'
):
allowed_endpoints = (
'login_page', 'static', 'main.show_roxywi_version', 'service.check_service', 'smon.show_smon_status_page',
'smon.smon_history_statuses', 'smon.agent_get_checks', 'smon.get_check_status' 'api', 'favicon'
)
if 'api' not in request.url and request.endpoint not in allowed_endpoints:
try:
user_params = roxywi_common.get_users_params()
except Exception:
return redirect(login_url('login_page', next_url=request.url))
except Exception as e:
print(f'{e}')
abort(401)
if not user_sql.is_user_active(user_params['user_id']):
return redirect(login_url('login_page', next_url=request.url))
abort(401)
try:
roxywi_auth.check_login(user_params['user_uuid'])
roxywi_auth.check_login(user_params['user_id'])
except Exception:
return redirect(login_url('login_page', next_url=request.url))
@login_manager.user_loader
def load_user(user_id):
user = f'user_{user_id}'
user_obj = cache.get(user)
if user_obj is None:
query = user_sql.get_user_id(user_id)
cache.set(user, query, timeout=360)
return query
return user_obj
abort(401)
@app.after_request
def redirect_to_login(response):
if response.status_code == 401:
return redirect(login_url('login_page', next_url=request.url))
return response
@app.route('/login', methods=['GET', 'POST'])
def login_page():
try:
roxy.update_plan()
except Exception:
pass
next_url = request.args.get('next') or request.form.get('next')
login = request.form.get('login')
password = request.form.get('pass')
if login and password:
users = user_sql.select_users(user=login)
for user in users:
if user.activeuser == 0:
return 'Your login is disabled', 200
if user.ldap_user == 1:
if login in user.username:
if roxywi_auth.check_in_ldap(login, password):
user_uuid = roxywi_auth.create_uuid_and_token(login)
return roxywi_auth.do_login(user_uuid, str(user.groups), user, next_url)
else:
hashed_password = roxy_wi_tools.Tools.get_hash(password)
if login in user.username and hashed_password == user.password:
user_uuid = roxywi_auth.create_uuid_and_token(login)
return roxywi_auth.do_login(user_uuid, str(user.groups), user, next_url)
else:
return 'ban', 200
else:
return 'ban', 200
try:
if request.method == 'GET':
lang = roxywi_common.get_user_lang_for_flask()
except Exception:
lang = 'en'
return render_template('login.html', lang=lang)
return render_template('login.html', lang=lang)
elif request.method == 'POST':
next_url = request.args.get('next') or request.form.get('next')
login = request.json.get('login')
password = request.json.get('pass')
try:
roxy.update_plan()
except Exception:
pass
try:
user_params = roxywi_auth.check_user_password(login, password)
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Cannot check login password'), 401
try:
return roxywi_auth.do_login(user_params, next_url)
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Cannot do login'), 401
@app.route('/logout', methods=['GET', 'POST'])
@login_required
@jwt_required()
def logout():
user = f'user_{current_user.id}'
cache.delete(user)
logout_user()
resp = make_response(redirect(url_for('login_page')))
resp.delete_cookie('uuid')
resp.delete_cookie('group')
resp = make_response(redirect('/', 302))
unset_jwt_cookies(resp)
return resp

View File

@ -2,8 +2,8 @@ from functools import wraps
from flask import redirect, url_for, abort, g
import modules.roxywi.auth as roxywi_auth
import modules.roxywi.common as roxywi_common
import app.modules.roxywi.auth as roxywi_auth
import app.modules.roxywi.common as roxywi_common
def check_services(fn):
@ -26,7 +26,30 @@ def get_user_params(virt=0, disable=0):
user_params = roxywi_common.get_users_params(virt=virt, disable=disable, service=kwargs.get('service'))
g.user_params = user_params
except Exception:
return redirect(url_for('login_page'))
return abort(401)
return fn(*args, **kwargs)
return decorated_views
return inner_decorator
def page_for_admin(level=1):
def inner_decorator(fn):
@wraps(fn)
def decorated_views(*args, **kwargs):
if not roxywi_auth.is_admin(level=level):
return abort(403, 'bad permission')
else:
return fn(*args, **kwargs)
return decorated_views
return inner_decorator
def check_group():
def inner_decorator(fn):
@wraps(fn)
def decorated_views(*args, **kwargs):
if not roxywi_common.check_user_group_for_flask():
return roxywi_common.handle_json_exceptions('Wrong group', 'Cannot create user')
return fn(*args, **kwargs)
return decorated_views
return inner_decorator

View File

@ -0,0 +1,50 @@
from typing import Union
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
class SupportClass:
def __init__(self, is_id=True):
self.is_id = is_id
@get_user_params()
def return_server_ip_or_id(self, server_id: Union[int, str]) -> Union[int, str]:
if isinstance(server_id, str):
try:
server = server_sql.get_server_by_ip(server_id)
except Exception as e:
raise e
else:
try:
server = server_sql.get_server_by_id(server_id)
except Exception as e:
raise e
try:
roxywi_common.is_user_has_access_to_group(g.user_params['user_id'], server.group_id)
except Exception as e:
roxywi_common.handler_exceptions_for_json_data(e, '')
if self.is_id:
return server.server_id
else:
return server.ip
@staticmethod
@get_user_params()
def return_group_id(body: Union[ServerRequest, CredRequest, GroupQuery, ChannelRequest]):
if body.group_id:
if g.user_params['role'] == 1:
return body.group_id
else:
try:
roxywi_common.is_user_has_access_to_group(g.user_params['user_id'], body.group_id)
return body.group_id
except Exception:
return int(g.user_params['group_id'])
else:
return int(g.user_params['group_id'])

View File

@ -1,5 +1,5 @@
import app.modules.db.sql as sql
import modules.roxy_wi_tools as roxy_wi_tools
import app.modules.roxy_wi_tools as roxy_wi_tools
get_config_var = roxy_wi_tools.GetConfigVar()
time_zone = sql.get_setting('time_zone')

View File

@ -2,7 +2,9 @@ import os
from pathlib import Path
from typing import Any
from flask import render_template, request, g
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
@ -243,7 +245,7 @@ def upload_and_restart(server_ip: str, cfg: str, just_save: str, service: str, *
try:
commands = _generate_command(service, server_id, just_save, config_path, tmp_file, cfg, server_ip)
except Exception as e:
return f'error: {e}'
roxywi_common.handle_exceptions(e, 'Roxy-WI server', f'Cannot generate command for service {service}')
try:
error = server_mod.ssh_command(server_ip, commands)
@ -383,19 +385,20 @@ def diff_config(old_cfg, cfg, **kwargs):
return diff
try:
user_uuid = request.cookies.get('uuid')
login = user_sql.get_user_name_by_uuid(user_uuid)
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}, group: {user_group} {line}\n"
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, roxywi=1)
roxywi_common.logging('Roxy-WI server', f'error: Cannot write a diff config to the log file: {e}, {stderr}', login=login.username, roxywi=1)
def _classify_line(line: str) -> str:
@ -409,7 +412,7 @@ def show_finding_in_config(stdout: str, **kwargs) -> str:
"""
:param stdout: The stdout of a command execution.
:param kwargs: Additional keyword arguments.
:keyword grep: The word to find and highlight in the output. (Optional)
:keyword grep: The word to find and highlight in the output. (Optional)
:return: The output with highlighted lines and formatted dividers.
This method takes the stdout of a command execution and additional keyword arguments. It searches for a word specified by the `grep` keyword argument in each line of the stdout and highlights
@ -467,10 +470,11 @@ def compare_config(service: str, left: str, right: str) -> str:
return render_template('ajax/compare.html', stdout=output, lang=lang)
def show_config(server_ip: str, service: str, config_file_name: str, configver: str) -> str:
def show_config(server_ip: str, service: str, config_file_name: str, configver: str, claims: dict) -> str:
"""
Get and display the configuration file for a given server.
:param claims:
:param server_ip: The IP address of the server.
:param service: The name of the service.
:param config_file_name: The name of the configuration file.
@ -478,8 +482,8 @@ def show_config(server_ip: str, service: str, config_file_name: str, configver:
:return: The rendered template for displaying the configuration.
"""
user_uuid = request.cookies.get('uuid')
group_id = int(request.cookies.get('group'))
user_id = claims['user_id']
group_id = claims['group']
configs_dir = config_common.get_config_dir(service)
server_id = server_sql.select_server_id_by_ip(server_ip)
@ -513,7 +517,7 @@ def show_config(server_ip: str, service: str, config_file_name: str, configver:
'conf': conf,
'serv': server_ip,
'configver': configver,
'role': user_sql.get_user_role_by_uuid(user_uuid, group_id),
'role': user_sql.get_user_role_in_group(user_id, group_id),
'service': service,
'config_file_name': config_file_name,
'is_serv_protected': server_sql.is_serv_protected(server_ip),

View File

@ -1,62 +1,46 @@
from app.modules.db.db_model import Backup, S3Backup, GitSetting
from app.modules.db.common import out_error
from app.modules.roxywi.exception import RoxywiResourceNotFound
def insert_backup_job(server, rserver, rpath, backup_type, time, cred, description):
try:
Backup.insert(
server=server, rhost=rserver, rpath=rpath, backup_type=backup_type, time=time,
cred=cred, description=description
return Backup.insert(
server=server, rhost=rserver, rpath=rpath, type=backup_type, time=time,
cred_id=cred, description=description
).execute()
except Exception as e:
out_error(e)
return False
else:
return True
def insert_s3_backup_job(server, s3_server, bucket, secret_key, access_key, time, description):
def insert_s3_backup_job(**kwargs):
try:
S3Backup.insert(
server=server, s3_server=s3_server, bucket=bucket, secret_key=secret_key, access_key=access_key, time=time,
description=description
).execute()
return S3Backup.insert(**kwargs).execute()
except Exception as e:
out_error(e)
return False
else:
return True
def update_backup(server, rserver, rpath, backup_type, time, cred, description, backup_id):
backup_update = Backup.update(
server=server, rhost=rserver, rpath=rpath, backup_type=backup_type, time=time,
cred=cred, description=description
server=server, rhost=rserver, rpath=rpath, type=backup_type, time=time,
cred_id=cred, description=description
).where(Backup.id == backup_id)
try:
backup_update.execute()
except Exception as e:
out_error(e)
return False
else:
return True
def delete_backups(backup_id: int) -> bool:
query = Backup.delete().where(Backup.id == backup_id)
def delete_backups(backup_id: int) -> None:
try:
query.execute()
Backup.delete().where(Backup.id == backup_id).execute()
except Exception as e:
out_error(e)
return False
else:
return True
def delete_s3_backups(backup_id: int) -> bool:
query = S3Backup.delete().where(S3Backup.id == backup_id)
try:
query.execute()
S3Backup.delete().where(S3Backup.id == backup_id).execute()
except Exception as e:
out_error(e)
return False
@ -106,11 +90,9 @@ def select_backups(**kwargs):
query = Backup.select().order_by(Backup.id)
try:
query_res = query.execute()
return query.execute()
except Exception as e:
out_error(e)
else:
return query_res
def select_s3_backups(**kwargs):
@ -153,3 +135,18 @@ def check_exists_s3_backup(server: str) -> bool:
return True
else:
return False
def get_backup(backup_id: int, model: str) -> Backup:
models = {
'fs': Backup,
's3': S3Backup,
'git': GitSetting,
}
model = models[model]
try:
return model.get(model.id == backup_id)
except model.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)

View File

@ -1,272 +1,82 @@
from app.modules.db.db_model import Telegram, Slack, PD, Server, MM
from app.modules.db.common import out_error
from app.modules.roxywi.exception import RoxywiResourceNotFound
models = {
'telegram': Telegram,
'slack': Slack,
'pd': PD,
'mm': MM
}
def get_user_telegram_by_group(group):
def get_user_receiver_by_group(receiver: str, group: int):
model = models[receiver]
try:
return Telegram.select().where(Telegram.groups == group).execute()
return model.select().where(model.group_id == group).execute()
except Exception as e:
out_error(e)
def get_telegram_by_ip(ip):
def get_receiver_by_ip(receiver:str, ip: str):
model = models[receiver]
try:
return Telegram.select().join(Server, on=(Server.groups == Telegram.groups)).where(Server.ip == ip).execute()
return model.select().join(Server, on=(Server.group_id == model.group_id)).where(Server.ip == ip).execute()
except Exception as e:
out_error(e)
def get_telegram_by_id(telegram_id):
def get_receiver_by_id(receiver: str, channel_id: str):
model = models[receiver]
try:
return Telegram.select().where(Telegram.id == telegram_id).execute()
return model.select().where(model.id == channel_id).execute()
except Exception as e:
out_error(e)
def get_user_slack_by_group(group):
def select_receiver(receiver: str, channel_id: str):
model = models[receiver]
try:
return Slack.select().where(Slack.groups == group).execute()
return model.get(model.id == channel_id)
except model.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)
def get_slack_by_ip(ip):
def insert_new_receiver(receiver: str, token: str, channel: str, group: str):
model = models[receiver]
try:
return Slack.select().join(Server, on=(Server.groups == Slack.groups)).where(Server.ip == ip).execute()
return model.insert(token=token, chanel_name=channel, group_id=group).execute()
except Exception as e:
out_error(e)
def get_slack_by_id(slack_id):
def update_receiver(receiver: str, token: str, channel: str, group: str, channel_id: int) -> None:
model = models[receiver]
try:
return Slack.select().where(Slack.id == slack_id).execute()
model.update(token=token, chanel_name=channel, group_id=group).where(model.id == channel_id).execute()
except model.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)
def get_user_pd_by_group(group):
def delete_receiver(receiver: str, channel_id: int) -> None:
model = models[receiver]
try:
return PD.select().where(PD.groups == group).execute()
model.delete().where(model.id == channel_id).execute()
except model.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)
def get_user_mm_by_group(group):
def get_receiver_with_group(receiver: str, channel_id: int, group_id: int):
try:
return MM.select().where(MM.groups == group).execute()
except Exception as e:
out_error(e)
def get_pd_by_ip(ip):
query = PD.select().join(Server, on=(Server.groups == PD.groups)).where(Server.ip == ip)
try:
query_res = query.execute()
except Exception as e:
out_error(e)
else:
return query_res
def get_pd_by_id(pd_id):
try:
return PD.select().where(PD.id == pd_id).execute()
except Exception as e:
out_error(e)
def delete_telegram(telegram_id):
query = Telegram.delete().where(Telegram.id == telegram_id)
try:
query.execute()
except Exception as e:
out_error(e)
return False
else:
return True
def select_telegram(**kwargs):
if kwargs.get('token'):
query = Telegram.select().where(Telegram.token == kwargs.get('token'))
elif kwargs.get('id'):
query = Telegram.select().where(Telegram.id == kwargs.get('id'))
else:
query = Telegram.select()
try:
query_res = query.execute()
except Exception as e:
out_error(e)
else:
return query_res
def insert_new_telegram(token, channel, group):
try:
Telegram.insert(token=token, chanel_name=channel, groups=group).execute()
except Exception as e:
out_error(e)
return False
else:
return True
def update_telegram(token, channel, group, telegram_id):
telegram_update = Telegram.update(token=token, chanel_name=channel, groups=group).where(Telegram.id == telegram_id)
try:
telegram_update.execute()
except Exception as e:
out_error(e)
return False
else:
return True
def delete_slack(slack_id):
query = Slack.delete().where(Slack.id == slack_id)
try:
query.execute()
except Exception as e:
out_error(e)
return False
else:
return True
def select_slack(**kwargs):
if kwargs.get('token'):
query = Slack.select().where(Slack.token == kwargs.get('token'))
elif kwargs.get('id'):
query = Slack.select().where(Slack.id == kwargs.get('id'))
else:
query = Slack.select()
try:
query_res = query.execute()
except Exception as e:
out_error(e)
else:
return query_res
def insert_new_slack(token, chanel, group):
try:
Slack.insert(token=token, chanel_name=chanel, groups=group).execute()
except Exception as e:
out_error(e)
return False
else:
return True
def update_slack(token, chanel, group, slack_id):
try:
return Slack.update(token=token, chanel_name=chanel, groups=group).where(Slack.id == slack_id).execute()
except Exception as e:
out_error(e)
def delete_pd(pd_id):
try:
PD.delete().where(PD.id == pd_id).execute()
except Exception as e:
out_error(e)
return False
else:
return True
def select_pd(**kwargs):
if kwargs.get('token'):
query = PD.select().where(PD.token == kwargs.get('token'))
elif kwargs.get('id'):
query = PD.select().where(PD.id == kwargs.get('id'))
else:
query = PD.select()
try:
query_res = query.execute()
except Exception as e:
out_error(e)
else:
return query_res
def insert_new_pd(token, chanel, group):
try:
PD.insert(token=token, chanel_name=chanel, groups=group).execute()
except Exception as e:
out_error(e)
return False
else:
return True
def update_pd(token, chanel, group, pd_id):
try:
PD.update(token=token, chanel_name=chanel, groups=group).where(PD.id == pd_id).execute()
except Exception as e:
out_error(e)
return False
else:
return True
def insert_new_mm(token, chanel, group):
try:
MM.insert(token=token, chanel_name=chanel, groups=group).execute()
except Exception as e:
out_error(e)
return False
else:
return True
def update_mm(token, chanel, group, mm_id):
try:
MM.update(token=token, chanel_name=chanel, groups=group).where(MM.id == mm_id).execute()
except Exception as e:
out_error(e)
return False
else:
return True
def delete_mm(pd_id):
try:
MM.delete().where(MM.id == pd_id).execute()
except Exception as e:
out_error(e)
return False
else:
return True
def select_mm(**kwargs):
if kwargs.get('token'):
query = MM.select().where(MM.token == kwargs.get('token'))
elif kwargs.get('id'):
query = MM.select().where(MM.id == kwargs.get('id'))
else:
query = MM.select()
try:
query_res = query.execute()
except Exception as e:
out_error(e)
else:
return query_res
def get_mm_by_ip(ip):
query = MM.select().join(Server, on=(Server.groups == MM.groups)).where(Server.ip == ip)
try:
query_res = query.execute()
except Exception as e:
out_error(e)
else:
return query_res
def get_mm_by_id(pd_id):
try:
return MM.select().where(MM.id == pd_id).execute()
model = models[receiver]
return model.get((model.id == channel_id) & (model.group_id == group_id))
except model.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)

View File

@ -19,12 +19,9 @@ def select_checker_settings_for_server(service_id: int, server_id: int):
& (CheckerSetting.server_id == server_id)
)
try:
query_res = query.execute()
return query.execute()
except Exception as e:
out_error(e)
return
else:
return query_res
def insert_new_checker_setting_for_server(server_ip: str) -> None:
@ -121,10 +118,10 @@ def inset_or_update_service_status(server_id: int, service_id: int, service_chec
def select_alert(**kwargs):
if kwargs.get("group") is not None:
query = Server.select(Server.ip).where(
(Server.alert == 1) & (Server.enable == 1) & (Server.groups == kwargs.get('group'))
(Server.haproxy_alert == 1) & (Server.enabled == 1) & (Server.group_id == kwargs.get('group'))
)
else:
query = Server.select(Server.ip).where((Server.alert == 1) & (Server.enable == 1))
query = Server.select(Server.ip).where((Server.haproxy_alert == 1) & (Server.enabled == 1))
try:
query_res = query.execute()
except Exception as e:
@ -136,10 +133,10 @@ def select_alert(**kwargs):
def select_all_alerts(**kwargs):
if kwargs.get("group") is not None:
query = Server.select(Server.ip).where(
((Server.alert == 1) | (Server.nginx_alert == 1)) & (Server.enable == 1) & (Server.groups == kwargs.get('group'))
((Server.haproxy_alert == 1) | (Server.nginx_alert == 1)) & (Server.enabled == 1) & (Server.group_id == kwargs.get('group'))
)
else:
query = Server.select(Server.ip).where(((Server.alert == 1) | (Server.nginx_alert == 1)) & (Server.enable == 1))
query = Server.select(Server.ip).where(((Server.haproxy_alert == 1) | (Server.nginx_alert == 1)) & (Server.enabled == 1))
try:
query_res = query.execute()
except Exception as e:
@ -152,14 +149,14 @@ def select_nginx_alert(**kwargs):
if kwargs.get("group") is not None:
query = Server.select(Server.ip).where(
(Server.nginx_alert == 1)
& (Server.enable == 1)
& (Server.groups == kwargs.get('group'))
& (Server.enabled == 1)
& (Server.group_id == kwargs.get('group'))
& (Server.nginx == 1)
)
else:
query = Server.select(Server.ip).where(
(Server.nginx_alert == 1)
& (Server.enable == 1)
& (Server.enabled == 1)
& (Server.nginx == 1)
)
try:
@ -174,12 +171,12 @@ def select_apache_alert(**kwargs):
if kwargs.get("group") is not None:
query = Server.select(Server.ip).where(
(Server.apache_alert == 1)
& (Server.enable == 1)
& (Server.groups == kwargs.get('group'))
& (Server.enabled == 1)
& (Server.group_id == kwargs.get('group'))
& (Server.apache == 1)
)
else:
query = Server.select(Server.ip).where((Server.apache_alert == 1) & (Server.enable == 1) & (Server.apache == 1))
query = Server.select(Server.ip).where((Server.apache_alert == 1) & (Server.enabled == 1) & (Server.apache == 1))
try:
query_res = query.execute()
except Exception as e:
@ -192,14 +189,14 @@ def select_keepalived_alert(**kwargs):
if kwargs.get("group") is not None:
query = Server.select(Server.ip).where(
(Server.keepalived_alert == 1)
& (Server.enable == 1)
& (Server.groups == kwargs.get('group'))
& (Server.enabled == 1)
& (Server.group_id == kwargs.get('group'))
& (Server.keepalived == 1)
)
else:
query = Server.select(Server.ip).where(
(Server.keepalived_alert == 1)
& (Server.enable == 1)
& (Server.enabled == 1)
& (Server.keepalived == 1)
)
try:

View File

@ -1,5 +1,6 @@
from app.modules.db.db_model import Cred, Server
from app.modules.db.common import out_error
from app.modules.roxywi.exception import RoxywiResourceNotFound
def select_ssh(**kwargs):
@ -8,9 +9,9 @@ def select_ssh(**kwargs):
elif kwargs.get("id") is not None:
query = Cred.select().where(Cred.id == kwargs.get('id'))
elif kwargs.get("serv") is not None:
query = Cred.select().join(Server, on=(Cred.id == Server.cred)).where(Server.ip == kwargs.get('serv'))
query = Cred.select().join(Server, on=(Cred.id == Server.cred_id)).where(Server.ip == kwargs.get('serv'))
elif kwargs.get("group") is not None:
query = Cred.select().where(Cred.groups == kwargs.get("group"))
query = Cred.select().where(Cred.group_id == kwargs.get("group"))
else:
query = Cred.select()
try:
@ -25,7 +26,7 @@ def insert_new_ssh(name, enable, group, username, password):
if password is None:
password = 'None'
try:
return Cred.insert(name=name, enable=enable, groups=group, username=username, password=password).execute()
return Cred.insert(name=name, key_enabled=enable, group_id=group, username=username, password=password).execute()
except Exception as e:
out_error(e)
@ -44,7 +45,7 @@ def update_ssh(cred_id, name, enable, group, username, password):
if password is None:
password = 'None'
cred_update = Cred.update(name=name, enable=enable, groups=group, username=username, password=password).where(
cred_update = Cred.update(name=name, key_enabled=enable, group_id=group, username=username, password=password).where(
Cred.id == cred_id)
try:
cred_update.execute()
@ -57,3 +58,21 @@ def update_ssh_passphrase(name: str, passphrase: str):
Cred.update(passphrase=passphrase).where(Cred.name == name).execute()
except Exception as e:
out_error(e)
def get_ssh_by_id_and_group(creds_id: int, group_id: int) -> Cred:
try:
return Cred.select().where((Cred.group_id == group_id) & (Cred.id == creds_id)).execute()
except Cred.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)
def get_ssh(ssh_id: int) -> Cred:
try:
return Cred.get(Cred.id == ssh_id)
except Cred.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)

View File

@ -1,11 +1,10 @@
from datetime import datetime
from playhouse.migrate import *
from flask_login import UserMixin
from playhouse.shortcuts import ReconnectMixin
from playhouse.sqlite_ext import SqliteExtDatabase
import modules.roxy_wi_tools as roxy_wi_tools
import app.modules.roxy_wi_tools as roxy_wi_tools
get_config = roxy_wi_tools.GetConfigVar()
mysql_enable = get_config.get_config_var('mysql', 'enable')
@ -43,15 +42,15 @@ class BaseModel(Model):
database = connect()
class User(BaseModel, UserMixin):
class User(BaseModel):
user_id = AutoField(column_name='id')
username = CharField(constraints=[SQL('UNIQUE')])
email = CharField(constraints=[SQL('UNIQUE')])
password = CharField(null=True)
role = CharField()
groups = CharField()
group_id = CharField()
ldap_user = IntegerField(constraints=[SQL('DEFAULT "0"')])
activeuser = IntegerField(constraints=[SQL('DEFAULT "1"')])
enabled = IntegerField(constraints=[SQL('DEFAULT "1"')])
user_services = CharField(constraints=[SQL('DEFAULT "1 2 3 4 5 6"')])
last_login_date = DateTimeField(constraints=[SQL('DEFAULT "0000-00-00 00:00:00"')])
last_login_ip = CharField(null=True)
@ -64,16 +63,16 @@ class Server(BaseModel):
server_id = AutoField(column_name='id')
hostname = CharField()
ip = CharField(constraints=[SQL('UNIQUE')])
groups = CharField()
group_id = CharField()
type_ip = IntegerField(constraints=[SQL('DEFAULT 0')])
enable = IntegerField(constraints=[SQL('DEFAULT 1')])
enabled = IntegerField(constraints=[SQL('DEFAULT 1')])
master = IntegerField(constraints=[SQL('DEFAULT 0')])
cred = IntegerField(constraints=[SQL('DEFAULT 1')])
alert = IntegerField(constraints=[SQL('DEFAULT 0')])
metrics = IntegerField(constraints=[SQL('DEFAULT 0')])
cred_id = IntegerField(constraints=[SQL('DEFAULT 1')])
haproxy_alert = IntegerField(constraints=[SQL('DEFAULT 0')])
haproxy_metrics = IntegerField(constraints=[SQL('DEFAULT 0')])
port = IntegerField(constraints=[SQL('DEFAULT 22')])
desc = CharField(null=True)
active = IntegerField(constraints=[SQL('DEFAULT 0')])
description = CharField(null=True)
haproxy_active = IntegerField(constraints=[SQL('DEFAULT 0')])
keepalived = IntegerField(constraints=[SQL('DEFAULT 0')])
nginx = IntegerField(constraints=[SQL('DEFAULT 0')])
haproxy = IntegerField(constraints=[SQL('DEFAULT 0')])
@ -107,7 +106,7 @@ class Telegram(BaseModel):
id = AutoField()
token = CharField()
chanel_name = CharField()
groups = IntegerField()
group_id = IntegerField()
class Meta:
table_name = 'telegram'
@ -117,7 +116,7 @@ class Slack(BaseModel):
id = AutoField()
token = CharField()
chanel_name = CharField()
groups = IntegerField()
group_id = IntegerField()
class Meta:
table_name = 'slack'
@ -127,7 +126,7 @@ class MM(BaseModel):
id = AutoField()
token = CharField()
chanel_name = CharField()
groups = IntegerField()
group_id = IntegerField()
class Meta:
table_name = 'mattermost'
@ -137,22 +136,12 @@ class PD(BaseModel):
id = AutoField()
token = CharField()
chanel_name = CharField()
groups = IntegerField()
group_id = IntegerField()
class Meta:
table_name = 'pd'
class UUID(BaseModel):
user_id = IntegerField()
uuid = CharField()
exp = DateTimeField(default=datetime.now)
class Meta:
table_name = 'uuid'
primary_key = False
class ApiToken(BaseModel):
token = CharField()
user_name = CharField()
@ -202,10 +191,10 @@ class UserGroups(BaseModel):
class Cred(BaseModel):
id = AutoField()
name = CharField()
enable = IntegerField(constraints=[SQL('DEFAULT 1')])
key_enabled = IntegerField(constraints=[SQL('DEFAULT 1')])
username = CharField()
password = CharField(null=True)
groups = IntegerField(constraints=[SQL('DEFAULT 1')])
group_id = IntegerField(constraints=[SQL('DEFAULT 1')])
passphrase = CharField(null=True)
class Meta:
@ -218,9 +207,9 @@ class Backup(BaseModel):
server = CharField()
rhost = CharField()
rpath = CharField()
backup_type = CharField(column_name='type')
type = CharField(column_name='type')
time = CharField()
cred = IntegerField()
cred_id = IntegerField()
description = CharField(null=True)
class Meta:
@ -693,7 +682,7 @@ class HaCluster(BaseModel):
name = CharField()
syn_flood = IntegerField(constraints=[SQL('DEFAULT "0"')])
group_id = IntegerField()
desc = CharField()
description = CharField()
pos = IntegerField(constraints=[SQL('DEFAULT "0"')])
class Meta:
@ -765,7 +754,7 @@ class UDPBalancer(BaseModel):
port = IntegerField()
group_id = ForeignKeyField(Groups)
config = CharField()
desc = CharField()
description = CharField()
lb_algo = CharField(constraints=[SQL('DEFAULT "rr"')])
check_enabled = IntegerField(constraints=[SQL('DEFAULT "1"')])
delay_loop = IntegerField(constraints=[SQL('DEFAULT "10"')])
@ -781,7 +770,7 @@ def create_tables():
conn = connect()
with conn:
conn.create_tables(
[User, Server, Role, Telegram, Slack, UUID, ApiToken, Groups, UserGroups, ConfigVersion, Setting,
[User, Server, Role, Telegram, Slack, ApiToken, Groups, UserGroups, ConfigVersion, Setting,
Cred, Backup, Metrics, WafMetrics, Version, Option, SavedServer, Waf, ActionHistory, PortScannerSettings,
PortScannerPorts, PortScannerHistory, ServiceSetting, MetricsHttpStatus, SMON, WafRules, Alerts, GeoipCodes,
NginxMetrics, SystemInfo, Services, UserName, GitSetting, CheckerSetting, ApacheMetrics, WafNginx, ServiceStatus,

View File

@ -1,5 +1,6 @@
from app.modules.db.db_model import Groups, Setting, UserGroups
from app.modules.db.common import out_error
from app.modules.roxywi.exception import RoxywiResourceNotFound
def select_groups(**kwargs):
@ -123,11 +124,11 @@ def update_group(name, descript, group_id):
def get_group_name_by_id(group_id):
try:
group_name = Groups.get(Groups.group_id == group_id)
return Groups.get(Groups.group_id == group_id).name
except Groups.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)
else:
return group_name.name
def get_group_id_by_name(group_name):

View File

@ -12,7 +12,7 @@ def select_clusters(group_id: int):
def create_cluster(name: str, syn_flood: int, group_id: int, desc: str) -> int:
try:
last_id = HaCluster.insert(
name=name, syn_flood=syn_flood, group_id=group_id, desc=desc
name=name, syn_flood=syn_flood, group_id=group_id, description=desc
).execute()
return last_id
except Exception as e:
@ -79,7 +79,7 @@ def select_cluster_master_slaves(cluster_id: int, group_id: int, router_id: int)
conn = connect()
cursor = conn.cursor()
sql = f"select * from servers left join ha_cluster_slaves on (servers.id = ha_cluster_slaves.server_id) " \
f"where servers.groups = {group_id} and ha_cluster_slaves.cluster_id = {cluster_id} and ha_cluster_slaves.router_id = {router_id};"
f"where servers.group_id = {group_id} and ha_cluster_slaves.cluster_id = {cluster_id} and ha_cluster_slaves.router_id = {router_id};"
try:
cursor.execute(sql)
except Exception as e:
@ -133,7 +133,7 @@ def select_ha_cluster_not_masters_not_slaves(group_id: int):
query = Server.select().where(
(Server.type_ip == 0) &
(Server.server_id.not_in(HaClusterSlave.select(HaClusterSlave.server_id))) &
(Server.groups == group_id)
(Server.group_id == group_id)
)
return query.execute()
except Exception as e:
@ -206,7 +206,7 @@ def update_slave(cluster_id: int, server_id: int, eth: str, master: int, router_
def update_cluster(cluster_id: int, name: str, desc: str, syn_flood: int) -> None:
try:
HaCluster.update(name=name, desc=desc, syn_flood=syn_flood).where(HaCluster.id == cluster_id).execute()
HaCluster.update(name=name, description=desc, syn_flood=syn_flood).where(HaCluster.id == cluster_id).execute()
except Exception as e:
out_error(e)
@ -276,4 +276,4 @@ def get_cred_id_by_server_ip(server_ip):
except Exception as e:
return out_error(e)
else:
return cred.cred
return cred.cred_id

View File

@ -3,7 +3,7 @@ from app.modules.db.common import out_error
def select_keep_alive():
query = Server.select(Server.ip, Server.groups, Server.server_id).where(Server.active == 1)
query = Server.select(Server.ip, Server.group_id, Server.server_id).where(Server.haproxy_active == 1)
try:
query_res = query.execute()
except Exception as e:
@ -13,7 +13,7 @@ def select_keep_alive():
def select_nginx_keep_alive():
query = Server.select(Server.ip, Server.groups, Server.server_id).where(Server.nginx_active == 1)
query = Server.select(Server.ip, Server.group_id, Server.server_id).where(Server.nginx_active == 1)
try:
query_res = query.execute()
except Exception as e:
@ -23,7 +23,7 @@ def select_nginx_keep_alive():
def select_apache_keep_alive():
query = Server.select(Server.ip, Server.groups, Server.server_id).where(Server.apache_active == 1)
query = Server.select(Server.ip, Server.group_id, Server.server_id).where(Server.apache_active == 1)
try:
query_res = query.execute()
except Exception as e:
@ -33,7 +33,7 @@ def select_apache_keep_alive():
def select_keepalived_keep_alive():
query = Server.select(Server.ip, Server.port, Server.groups, Server.server_id).where(Server.keepalived_active == 1)
query = Server.select(Server.ip, Server.port, Server.group_id, Server.server_id).where(Server.keepalived_active == 1)
try:
query_res = query.execute()
except Exception as e:

View File

@ -209,12 +209,12 @@ def select_metrics(serv, service, **kwargs):
def select_servers_metrics_for_master(**kwargs):
if kwargs.get('group') != 1:
query = Server.select(Server.ip).where(
((Server.metrics == 1) | (Server.nginx_metrics == 1) | (Server.apache_metrics == 1))
& (Server.groups == kwargs.get('group'))
((Server.haproxy_metrics == 1) | (Server.nginx_metrics == 1) | (Server.apache_metrics == 1))
& (Server.group_id == kwargs.get('group'))
)
else:
query = Server.select(Server.ip).where(
(Server.metrics == 1)
(Server.haproxy_metrics == 1)
| (Server.nginx_metrics == 1)
| (Server.apache_metrics == 1)
)
@ -228,7 +228,7 @@ def select_servers_metrics_for_master(**kwargs):
def select_haproxy_servers_metrics_for_master():
query = Server.select(Server.ip).where(Server.metrics == 1)
query = Server.select(Server.ip).where(Server.haproxy_metrics == 1)
try:
query_res = query.execute()
except Exception as e:
@ -262,10 +262,10 @@ def select_apache_servers_metrics_for_master():
def select_servers_metrics(group_id):
if group_id == 1:
query = Server.select(Server.ip).where((Server.enable == 1) & (Server.metrics == 1))
query = Server.select(Server.ip).where((Server.enabled == 1) & (Server.haproxy_metrics == 1))
else:
query = Server.select(Server.ip).where(
(Server.enable == 1) & (Server.groups == group_id) & (Server.metrics == 1))
(Server.enabled == 1) & (Server.group_id == group_id) & (Server.haproxy_metrics == 1))
try:
query_res = query.execute()
except Exception as e:
@ -281,84 +281,84 @@ def select_table_metrics(group_id):
if group_id == 1:
groups = ""
else:
groups = "and servers.groups = '{group}' ".format(group=group_id)
groups = "and servers.group_id = '{group}' ".format(group=group_id)
if mysql_enable == '1':
sql = """
select ip.ip, hostname, avg_sess_1h, avg_sess_24h, avg_sess_3d, max_sess_1h, max_sess_24h, max_sess_3d,
avg_cur_1h, avg_cur_24h, avg_cur_3d, max_con_1h, max_con_24h, max_con_3d from
(select servers.ip from servers where metrics = 1 ) as ip,
(select servers.ip from servers where haproxy_metrics = 1 ) as ip,
(select servers.ip, servers.hostname as hostname from servers left join metrics as metr on servers.ip = metr.serv where servers.metrics = 1 %s) as hostname,
(select servers.ip,round(avg(metr.sess_rate), 1) as avg_sess_1h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= now() and metr.date >= DATE_ADD(NOW(), INTERVAL -1 HOUR)
group by servers.ip) as avg_sess_1h,
(select servers.ip,round(avg(metr.sess_rate), 1) as avg_sess_24h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= now() and metr.date >= DATE_ADD(NOW(),INTERVAL -24 HOUR)
group by servers.ip) as avg_sess_24h,
(select servers.ip,round(avg(metr.sess_rate), 1) as avg_sess_3d from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= now() and metr.date >= DATE_ADD(NOW(), INTERVAL -3 DAY)
group by servers.ip ) as avg_sess_3d,
(select servers.ip,max(metr.sess_rate) as max_sess_1h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= now() and metr.date >= DATE_ADD(NOW(),INTERVAL -1 HOUR)
group by servers.ip) as max_sess_1h,
(select servers.ip,max(metr.sess_rate) as max_sess_24h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= now() and metr.date >= DATE_ADD(NOW(),INTERVAL -24 HOUR)
group by servers.ip) as max_sess_24h,
(select servers.ip,max(metr.sess_rate) as max_sess_3d from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= now() and metr.date >= DATE_ADD(NOW(),INTERVAL -3 DAY)
group by servers.ip ) as max_sess_3d,
(select servers.ip,round(avg(metr.curr_con+metr.cur_ssl_con), 1) as avg_cur_1h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= now() and metr.date >= DATE_ADD(NOW(),INTERVAL -1 HOUR)
group by servers.ip) as avg_cur_1h,
(select servers.ip,round(avg(metr.curr_con+metr.cur_ssl_con), 1) as avg_cur_24h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= now() and metr.date >= DATE_ADD(NOW(),INTERVAL -24 HOUR)
group by servers.ip) as avg_cur_24h,
(select servers.ip,round(avg(metr.curr_con+metr.cur_ssl_con), 1) as avg_cur_3d from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= now() and metr.date >= DATE_ADD(NOW(),INTERVAL -3 DAY)
group by servers.ip ) as avg_cur_3d,
(select servers.ip,max(metr.curr_con) as max_con_1h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= now() and metr.date >= DATE_ADD(NOW(),INTERVAL -1 HOUR)
group by servers.ip) as max_con_1h,
(select servers.ip,max(metr.curr_con) as max_con_24h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= now() and metr.date >= DATE_ADD(NOW(),INTERVAL -24 HOUR)
group by servers.ip) as max_con_24h,
(select servers.ip,max(metr.curr_con) as max_con_3d from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= now() and metr.date >= DATE_ADD(NOW(),INTERVAL -3 DAY)
group by servers.ip ) as max_con_3d
@ -381,79 +381,79 @@ def select_table_metrics(group_id):
sql = """
select ip.ip, hostname, avg_sess_1h, avg_sess_24h, avg_sess_3d, max_sess_1h, max_sess_24h, max_sess_3d, avg_cur_1h,
avg_cur_24h, avg_cur_3d, max_con_1h, max_con_24h, max_con_3d from
(select servers.ip from servers where metrics = 1 ) as ip,
(select servers.ip from servers where haproxy_metrics = 1 ) as ip,
(select servers.ip, servers.hostname as hostname from servers left join metrics as metr on servers.ip = metr.serv where servers.metrics = 1 %s) as hostname,
(select servers.ip,round(avg(metr.sess_rate), 1) as avg_sess_1h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= datetime('now', 'localtime') and metr.date >= datetime('now', '-1 hours', 'localtime')
group by servers.ip) as avg_sess_1h,
(select servers.ip,round(avg(metr.sess_rate), 1) as avg_sess_24h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= datetime('now', 'localtime') and metr.date >= datetime('now', '-24 hours', 'localtime')
group by servers.ip) as avg_sess_24h,
(select servers.ip,round(avg(metr.sess_rate), 1) as avg_sess_3d from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= datetime('now', 'localtime') and metr.date >= datetime('now', '-3 days', 'localtime')
group by servers.ip ) as avg_sess_3d,
(select servers.ip,max(metr.sess_rate) as max_sess_1h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= datetime('now', 'localtime') and metr.date >= datetime('now', '-1 hours', 'localtime')
group by servers.ip) as max_sess_1h,
(select servers.ip,max(metr.sess_rate) as max_sess_24h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= datetime('now', 'localtime') and metr.date >= datetime('now', '-24 hours', 'localtime')
group by servers.ip) as max_sess_24h,
(select servers.ip,max(metr.sess_rate) as max_sess_3d from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= datetime('now', 'localtime') and metr.date >= datetime('now', '-3 days', 'localtime')
group by servers.ip ) as max_sess_3d,
(select servers.ip,round(avg(metr.curr_con+metr.cur_ssl_con), 1) as avg_cur_1h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= datetime('now', 'localtime') and metr.date >= datetime('now', '-1 hours', 'localtime')
group by servers.ip) as avg_cur_1h,
(select servers.ip,round(avg(metr.curr_con+metr.cur_ssl_con), 1) as avg_cur_24h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= datetime('now', 'localtime') and metr.date >= datetime('now', '-24 hours', 'localtime')
group by servers.ip) as avg_cur_24h,
(select servers.ip,round(avg(metr.curr_con+metr.cur_ssl_con), 1) as avg_cur_3d from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= datetime('now', 'localtime') and metr.date >= datetime('now', '-3 days', 'localtime')
group by servers.ip ) as avg_cur_3d,
(select servers.ip,max(metr.curr_con) as max_con_1h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= datetime('now', 'localtime') and metr.date >= datetime('now', '-1 hours', 'localtime')
group by servers.ip) as max_con_1h,
(select servers.ip,max(metr.curr_con) as max_con_24h from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= datetime('now', 'localtime') and metr.date >= datetime('now', '-24 hours', 'localtime')
group by servers.ip) as max_con_24h,
(select servers.ip,max(metr.curr_con) as max_con_3d from servers
left join metrics as metr on metr.serv = servers.ip
where servers.metrics = 1 and
where servers.haproxy_metrics = 1 and
metr.date <= datetime('now', 'localtime') and metr.date >= datetime('now', '-3 days', 'localtime')
group by servers.ip ) as max_con_3d
@ -491,7 +491,7 @@ def select_service_table_metrics(service: str, group_id: int):
if group_id == 1:
groups = ""
else:
groups = f"and servers.groups = '{group_id}' "
groups = f"and servers.group_id = '{group_id}' "
if mysql_enable == '1':
sql = """

View File

@ -1,12 +1,13 @@
from app.modules.db.db_model import mysql_enable, connect, Server, SystemInfo
from app.modules.db.common import out_error
from app.modules.roxywi.exception import RoxywiResourceNotFound
def add_server(hostname, ip, group, typeip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall):
def add_server(hostname, ip, group, type_ip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall):
try:
server_id = Server.insert(
hostname=hostname, ip=ip, groups=group, type_ip=typeip, enable=enable, master=master, cred=cred,
port=port, desc=desc, haproxy=haproxy, nginx=nginx, apache=apache, firewall_enable=firewall
hostname=hostname, ip=ip, group_id=group, type_ip=type_ip, enabled=enable, master=master, cred_id=cred,
port=port, description=desc, haproxy=haproxy, nginx=nginx, apache=apache, firewall_enable=firewall
).execute()
return server_id
except Exception as e:
@ -24,11 +25,11 @@ def delete_server(server_id):
return True
def update_server(hostname, group, typeip, enable, master, server_id, cred, port, desc, firewall, protected):
def update_server(hostname, group, type_ip, enable, master, server_id, cred, port, desc, firewall, protected):
try:
server_update = Server.update(
hostname=hostname, groups=group, type_ip=typeip, enable=enable, master=master, cred=cred,
port=port, desc=desc, firewall_enable=firewall, protected=protected
hostname=hostname, 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()
except Exception as e:
@ -44,9 +45,20 @@ def get_hostname_by_server_ip(server_ip):
return hostname.hostname
def get_server_by_id(server_id):
def get_server_by_id(server_id: int) -> Server:
try:
return Server.get(Server.server_id == server_id)
except Server.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
return out_error(e)
def get_server_by_ip(server_ip: str) -> Server:
try:
return Server.get(Server.ip == server_ip)
except Server.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
return out_error(e)
@ -167,20 +179,19 @@ def select_servers(**kwargs):
cursor = conn.cursor()
if mysql_enable == '1':
sql = """select * from `servers` where `enable` = 1 ORDER BY servers.groups """
sql = """select * from `servers` where `enabled` = 1 ORDER BY servers.group_id """
if kwargs.get("server") is not None:
sql = """select * from `servers` where `ip` = '{}' """.format(kwargs.get("server"))
if kwargs.get("full") is not None:
sql = """select * from `servers` ORDER BY hostname """
if kwargs.get("get_master_servers") is not None:
sql = """select id,hostname from `servers` where `master` = 0 and type_ip = 0 and enable = 1 ORDER BY servers.groups """
if kwargs.get("get_master_servers") is not None and kwargs.get('uuid') is not None:
sql = """select id,hostname from `servers` where `master` = 0 and type_ip = 0 and enabled = 1 ORDER BY servers.group_id """
if kwargs.get("get_master_servers") is not None and kwargs.get('user_id') is not None:
sql = """ select servers.id, servers.hostname from `servers`
left join user as user on servers.groups = user.groups
left join uuid as uuid on user.id = uuid.user_id
where uuid.uuid = '{}' and servers.master = 0 and servers.type_ip = 0 and servers.enable = 1 ORDER BY servers.groups
""".format(kwargs.get('uuid'))
left join user as user on servers.group_id = user.group_id
where user.user_id = '{}' and servers.master = 0 and servers.type_ip = 0 and servers.enabled = 1 ORDER BY servers.group_id
""".format(kwargs.get('user_id'))
if kwargs.get("id"):
sql = """select * from `servers` where `id` = '{}' """.format(kwargs.get("id"))
if kwargs.get("hostname"):
@ -189,22 +200,21 @@ def select_servers(**kwargs):
sql = """select * from `servers` where `hostname` ='{}' or id = '{}' or ip = '{}'""".format(
kwargs.get("id_hostname"), kwargs.get("id_hostname"), kwargs.get("id_hostname"))
if kwargs.get("server") and kwargs.get("keep_alive"):
sql = """select active from `servers` where `ip` = '{}' """.format(kwargs.get("server"))
sql = """select haproxy_active from `servers` where `ip` = '{}' """.format(kwargs.get("server"))
else:
sql = """select * from servers where enable = '1' ORDER BY servers.groups """
sql = """select * from servers where enabled = '1' ORDER BY servers.group_id """
if kwargs.get("server") is not None:
sql = """select * from servers where ip = '{}' """.format(kwargs.get("server"))
if kwargs.get("full") is not None:
sql = """select * from servers ORDER BY hostname """
if kwargs.get("get_master_servers") is not None:
sql = """select id,hostname from servers where master = 0 and type_ip = 0 and enable = 1 ORDER BY servers.groups """
if kwargs.get("get_master_servers") is not None and kwargs.get('uuid') is not None:
sql = """select id,hostname from servers where master = 0 and type_ip = 0 and enabled = 1 ORDER BY servers.group_id """
if kwargs.get("get_master_servers") is not None and kwargs.get('user_id') is not None:
sql = """ select servers.id, servers.hostname from servers
left join user as user on servers.groups = user.groups
left join uuid as uuid on user.id = uuid.user_id
where uuid.uuid = '{}' and servers.master = 0 and servers.type_ip = 0 and servers.enable = 1 ORDER BY servers.groups
""".format(kwargs.get('uuid'))
left join user as user on servers.group_id = user.group_id
where user.user_id = '{}' and servers.master = 0 and servers.type_ip = 0 and servers.enabled = 1 ORDER BY servers.group_id
""".format(kwargs.get('user_id'))
if kwargs.get("id"):
sql = """select * from servers where id = '{}' """.format(kwargs.get("id"))
if kwargs.get("hostname"):
@ -213,7 +223,7 @@ def select_servers(**kwargs):
sql = """select * from servers where hostname = '{}' or id = '{}' or ip = '{}'""".format(
kwargs.get("id_hostname"), kwargs.get("id_hostname"), kwargs.get("id_hostname"))
if kwargs.get("server") and kwargs.get("keep_alive"):
sql = """select active from servers where ip = '{}' """.format(kwargs.get("server"))
sql = """select haproxy_active from servers where ip = '{}' """.format(kwargs.get("server"))
try:
cursor.execute(sql)
@ -225,7 +235,7 @@ def select_servers(**kwargs):
def get_dick_permit(group_id, **kwargs):
only_group = kwargs.get('only_group')
disable = 'enable = 1'
disable = 'enabled = 1'
haproxy = ''
nginx = ''
keepalived = ''
@ -237,7 +247,7 @@ def get_dick_permit(group_id, **kwargs):
else:
type_ip = "and type_ip = 0"
if kwargs.get('disable') == 0:
disable = '(enable = 1 or enable = 0)'
disable = '(enabled = 1 or enabled = 0)'
if kwargs.get('ip'):
ip = "and ip = '%s'" % kwargs.get('ip')
if kwargs.get('haproxy') or kwargs.get('service') == 'haproxy':
@ -255,12 +265,12 @@ def get_dick_permit(group_id, **kwargs):
if group_id == '1' and not only_group:
sql = f" select * from `servers` where {disable} {type_ip} {nginx} {haproxy} {keepalived} {apache} {ip} order by `pos` asc"
else:
sql = f" select * from `servers` where `groups` = {group_id} and ({disable}) {type_ip} {ip} {haproxy} {nginx} {keepalived} {apache} order by `pos` asc"
sql = f" select * from `servers` where `group_id` = {group_id} and ({disable}) {type_ip} {ip} {haproxy} {nginx} {keepalived} {apache} order by `pos` asc"
else:
if group_id == '1' and not only_group:
sql = f" select * from servers where {disable} {type_ip} {nginx} {haproxy} {keepalived} {apache} {ip} order by pos"
else:
sql = f" select * from servers where groups = '{group_id}' and ({disable}) {type_ip} {ip} {haproxy} {nginx} {keepalived} {apache} order by pos"
sql = f" select * from servers where group_id = '{group_id}' and ({disable}) {type_ip} {ip} {haproxy} {nginx} {keepalived} {apache} order by pos"
except Exception as e:
raise Exception(f'error: {e}')
@ -293,8 +303,19 @@ def is_master(ip, **kwargs):
return cursor.fetchall()
def get_server(server_id: int) -> Server:
def get_server_with_group(server_id: int, group_id: int) -> Server:
try:
return Server.get(Server.server_id == server_id)
return Server.get((Server.server_id == server_id) & (Server.group_id == group_id))
except Server.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)
def select_servers_with_group(group_id: int) -> Server:
try:
return Server.select().where(Server.group_id == group_id)
except Server.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)

View File

@ -15,7 +15,7 @@ def update_hapwi_server(server_id, alert, metrics, active, service_name):
update_hapwi = Server.update(apache_alert=alert, apache_active=active, apache_metrics=metrics).where(
Server.server_id == server_id)
else:
update_hapwi = Server.update(alert=alert, metrics=metrics, active=active).where(
update_hapwi = Server.update(haproxy_alert=alert, haproxy_metrics=metrics, haproxy_active=active).where(
Server.server_id == server_id)
update_hapwi.execute()
except Exception as e:

View File

@ -9,7 +9,7 @@ import app.modules.roxy_wi_tools as roxy_wi_tools
def get_agents(group_id: int):
try:
return SmonAgent.select(SmonAgent, Server).join(Server).where(Server.groups == group_id).objects().execute()
return SmonAgent.select(SmonAgent, Server).join(Server).where(Server.group_id == group_id).objects().execute()
except Exception as e:
out_error(e)
@ -19,7 +19,7 @@ def get_free_servers_for_agent(group_id: int):
query = Server.select().where(
(Server.type_ip == 0) &
(Server.server_id.not_in(SmonAgent.select(SmonAgent.server_id))) &
(Server.groups == group_id)
(Server.group_id == group_id)
)
return query.execute()
except Exception as e:

View File

@ -1,20 +1,17 @@
from flask import request
from app.modules.db.db_model import GeoipCodes, Setting, Role
from app.modules.db.common import out_error
def get_setting(param, **kwargs):
user_group_id = ''
try:
user_group_id = request.cookies.get('group')
except Exception:
pass
if user_group_id == '' or user_group_id is None or param == 'proxy':
if kwargs.get('group_id'):
user_group_id = kwargs.get('group_id')
else:
user_group_id = 1
if kwargs.get('all'):
if kwargs.get('all') and not kwargs.get('section'):
query = Setting.select().where(Setting.group == user_group_id).order_by(Setting.section.desc())
elif kwargs.get('section'):
query = Setting.select().where((Setting.group == user_group_id) & (Setting.section == kwargs.get('section')))
else:
query = Setting.select().where((Setting.param == param) & (Setting.group == user_group_id))
@ -23,7 +20,7 @@ def get_setting(param, **kwargs):
except Exception as e:
out_error(e)
else:
if kwargs.get('all'):
if kwargs.get('all') or kwargs.get('section'):
return query_res
else:
for setting in query_res:
@ -38,14 +35,12 @@ def get_setting(param, **kwargs):
return setting.value
def update_setting(param: str, val: str, user_group: int) -> bool:
def update_setting(param: str, val: str, user_group: int) -> None:
query = Setting.update(value=val).where((Setting.param == param) & (Setting.group == user_group))
try:
query.execute()
return True
except Exception as e:
out_error(e)
return False
def select_roles():

View File

@ -1,10 +1,13 @@
from app.modules.db.db_model import UDPBalancer
from app.modules.db.common import out_error
from app.modules.roxywi.exception import RoxywiResourceNotFound, RoxywiGroupNotFound
def select_listeners(group_id: int) -> UDPBalancer:
try:
return UDPBalancer.select().where(UDPBalancer.group_id == group_id).execute()
except UDPBalancer.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)
@ -12,13 +15,19 @@ def select_listeners(group_id: int) -> UDPBalancer:
def insert_listener(**kwargs) -> int:
try:
return UDPBalancer.insert(**kwargs).execute()
except UDPBalancer.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
if e.args[0] == 1215 or str(e) == 'FOREIGN KEY constraint failed':
raise RoxywiGroupNotFound
out_error(e)
def update_listener(listener_id: int, **kwargs) -> int:
try:
return UDPBalancer.update(**kwargs).where(UDPBalancer.id == listener_id).execute()
except UDPBalancer.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)
@ -26,6 +35,8 @@ def update_listener(listener_id: int, **kwargs) -> int:
def get_listener(listener_id: int) -> UDPBalancer:
try:
return UDPBalancer.get(UDPBalancer.id == listener_id)
except UDPBalancer.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)
@ -33,5 +44,7 @@ def get_listener(listener_id: int) -> UDPBalancer:
def delete_listener(listener_id: int) -> None:
try:
UDPBalancer.delete().where(UDPBalancer.id == listener_id).execute()
except UDPBalancer.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)

View File

@ -1,9 +1,10 @@
from peewee import Case, JOIN
from app.modules.db.db_model import User, UserGroups, Groups, UUID, ApiToken
from app.modules.db.db_model import User, UserGroups, Groups, ApiToken
from app.modules.db.sql import get_setting
from app.modules.db.common import out_error
import app.modules.roxy_wi_tools as roxy_wi_tools
from app.modules.roxywi.exception import RoxywiResourceNotFound
def add_user(user, email, password, role, enabled, group):
@ -11,7 +12,7 @@ def add_user(user, email, password, role, enabled, group):
try:
hashed_pass = roxy_wi_tools.Tools.get_hash(password)
last_id = User.insert(
username=user, email=email, password=hashed_pass, role=role, activeuser=enabled, groups=group
username=user, email=email, password=hashed_pass, role=role, enabled=enabled, group_id=group
).execute()
except Exception as e:
out_error(e)
@ -20,7 +21,7 @@ def add_user(user, email, password, role, enabled, group):
else:
try:
last_id = User.insert(
username=user, email=email, role=role, ldap_user=1, activeuser=enabled, groups=group
username=user, email=email, role=role, ldap_user=1, enabled=enabled, group_id=group
).execute()
except Exception as e:
out_error(e)
@ -28,16 +29,16 @@ def add_user(user, email, password, role, enabled, group):
return last_id
def update_user(user, email, role, user_id, active_user):
def update_user(user, email, role, user_id, enabled):
try:
User.update(username=user, email=email, role=role, activeuser=active_user).where(User.user_id == user_id).execute()
User.update(username=user, email=email, role=role, enabled=enabled).where(User.user_id == user_id).execute()
except Exception as e:
out_error(e)
def update_user_from_admin_area(user, email, user_id, active_user):
def update_user_from_admin_area(user_id, **kwargs):
try:
User.update(username=user, email=email, activeuser=active_user).where(User.user_id == user_id).execute()
User.update(**kwargs).where(User.user_id == user_id).execute()
except Exception as e:
out_error(e)
@ -53,17 +54,16 @@ def delete_user_groups(user_id):
return True
def update_user_current_groups(groups, user_uuid):
user_id = get_user_id_by_uuid(user_uuid)
def update_user_current_groups(group_id: int, user_id: int) -> None:
try:
User.update(groups=groups).where(User.user_id == user_id).execute()
User.update(group_id=group_id).where(User.user_id == user_id).execute()
except Exception as e:
out_error(e)
def update_user_current_groups_by_id(groups, user_id):
try:
user_update = User.update(groups=groups).where(User.user_id == user_id)
user_update = User.update(group_id=groups).where(User.user_id == user_id)
user_update.execute()
except Exception as e:
out_error(e)
@ -111,7 +111,7 @@ def select_users(**kwargs):
UserGroups.user_group_id == kwargs.get("group")
))
elif kwargs.get('by_group_id'):
query = User.select().where(User.groups == kwargs.get("by_group_id"))
query = User.select().where(User.group_id == kwargs.get("by_group_id"))
else:
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
cur_date = get_date.return_date('regular', timedelta_minutes_minus=15)
@ -127,7 +127,7 @@ def select_users(**kwargs):
def is_user_active(user_id: int) -> int:
try:
query = User.get(User.user_id == user_id).activeuser
query = User.get(User.user_id == user_id).enabled
except Exception as e:
out_error(e)
else:
@ -137,6 +137,8 @@ def is_user_active(user_id: int) -> int:
def check_user_group(user_id, group_id):
try:
query_res = UserGroups.get((UserGroups.user_id == user_id) & (UserGroups.user_group_id == group_id))
except UserGroups.DoesNotExist:
return False
except Exception:
return False
else:
@ -188,55 +190,26 @@ def select_users_roles():
return query_res
def update_last_act_user(uuid: str,ip: str) -> None:
def update_last_act_user(user_id: int, ip: str) -> None:
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
session_ttl = get_setting('session_ttl')
cur_date_session = get_date.return_date('regular', timedelta=session_ttl)
cur_date = get_date.return_date('regular')
user_id = get_user_id_by_uuid(uuid)
try:
UUID.update(exp=cur_date_session).where(UUID.uuid == uuid).execute()
User.update(last_login_date=cur_date, last_login_ip=ip).where(User.user_id == user_id).execute()
except Exception as e:
out_error(e)
def get_user_name_by_uuid(uuid):
try:
query = User.select(User.username).join(UUID, on=(User.user_id == UUID.user_id)).where(UUID.uuid == uuid)
query_res = query.execute()
except Exception as e:
out_error(e)
else:
for user in query_res:
return user.username
def get_user_id_by_uuid(uuid):
try:
query = User.select(User.user_id).join(UUID, on=(User.user_id == UUID.user_id)).where(UUID.uuid == uuid)
query_res = query.execute()
except Exception as e:
out_error(e)
else:
for user in query_res:
return user.user_id
def get_user_id_by_username(username: str) -> User:
def get_user_by_username(username: str) -> User:
try:
return User.get(User.username == username)
except Exception as e:
out_error(e)
def get_user_role_by_uuid(uuid, group_id):
def get_user_role_in_group(user_id, group_id):
try:
query_res = UserGroups.select(UserGroups.user_role_id).join(
UUID, on=(UserGroups.user_id == UUID.user_id)
).where(
(UUID.uuid == uuid) &
(UserGroups.user_group_id == group_id)
query_res = UserGroups.select().where(
(UserGroups.user_id == user_id) & (UserGroups.user_group_id == group_id)
).execute()
except Exception as e:
out_error(e)
@ -245,28 +218,9 @@ def get_user_role_by_uuid(uuid, group_id):
return int(user_id.user_role_id)
def get_user_current_group_by_uuid(uuid):
def get_user_id_by_username(username: str) -> User:
try:
query_res = User.select(User.groups).join(
UUID, on=(User.user_id == UUID.user_id)
).where(
(UUID.uuid == uuid)
).execute()
except Exception as e:
out_error(e)
else:
for user_id in query_res:
return int(user_id.groups)
def write_user_uuid(login, user_uuid):
session_ttl = get_setting('session_ttl')
user_id = get_user_id_by_username(login)
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta=session_ttl)
try:
UUID.insert(user_id=user_id.user_id, uuid=user_uuid, exp=cur_date).execute()
return User.get(User.username == username)
except Exception as e:
out_error(e)
@ -304,7 +258,7 @@ def get_super_admin_count() -> int:
def select_users_emails_by_group_id(group_id: int):
query = User.select(User.email).where((User.groups == group_id) & (User.role != 'guest'))
query = User.select(User.email).where((User.group_id == group_id) & (User.role != 'guest'))
try:
query_res = query.execute()
except Exception as e:
@ -314,17 +268,6 @@ def select_users_emails_by_group_id(group_id: int):
return query_res
def select_user_email_by_uuid(uuid: str) -> str:
user_id = get_user_id_by_uuid(uuid)
try:
query_res = User.get(User.user_id == user_id).email
except Exception as e:
out_error(e)
return ""
else:
return query_res
def is_user_super_admin(user_id: int) -> bool:
query = UserGroups.select().where(UserGroups.user_id == user_id)
try:
@ -383,15 +326,6 @@ def get_username_group_id_from_api_token(token):
return user_name.user_name, user_name.user_group_id, user_name.user_role
def delete_old_uuid():
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
UUID.delete().where((UUID.exp < cur_date) | (UUID.exp.is_null(True))).execute()
except Exception as e:
out_error(e)
def get_role_id(user_id: int, group_id: int) -> int:
try:
role_id = UserGroups.get((UserGroups.user_id == user_id) & (UserGroups.user_group_id == group_id))
@ -404,5 +338,16 @@ def get_role_id(user_id: int, group_id: int) -> int:
def get_user_id(user_id: int) -> User:
try:
return User.get(User.user_id == user_id)
except User.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)
def delete_user_from_group(group_id: int, user_id):
try:
UserGroups.delete().where((UserGroups.user_id == user_id) & (UserGroups.user_group_id == group_id)).execute()
except UserGroups.DoesNotExist:
raise RoxywiResourceNotFound
except Exception as e:
out_error(e)

View File

@ -46,7 +46,7 @@ def insert_waf_nginx_server(server_ip):
def select_waf_servers_metrics_for_master():
query = Server.select(Server.ip).join(
Waf, on=(Waf.server_id == Server.server_id)
).where((Server.enable == 1) & Waf.metrics == 1)
).where((Server.enabled == 1) & Waf.metrics == 1)
try:
query_res = query.execute()
except Exception as e:
@ -58,11 +58,11 @@ def select_waf_servers_metrics_for_master():
def select_waf_servers_metrics(group_id):
if group_id == '1':
query = Waf.select(Server.ip).join(Server, on=(Waf.server_id == Server.server_id)).where(
(Server.enable == 1) & (Waf.metrics == 1)
(Server.enabled == 1) & (Waf.metrics == 1)
)
else:
query = Waf.select(Server.ip).join(Server, on=(Waf.server_id == Server.server_id)).where(
(Server.enable == 1) & (Waf.metrics == 1) & (Server.groups == group_id)
(Server.enabled == 1) & (Waf.metrics == 1) & (Server.group_id == group_id)
)
try:
query_res = query.execute()

View File

@ -1,40 +1,38 @@
import uuid
from flask import request, abort, make_response, url_for
from flask_login import login_user
from datetime import datetime, timedelta
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
from flask_jwt_extended import verify_jwt_in_request
import app.modules.db.sql as sql
import app.modules.db.user as user_sql
import app.modules.db.group as group_sql
import app.modules.db.service as service_sql
import app.modules.roxywi.common as roxywi_common
import app.modules.roxy_wi_tools as roxy_wi_tools
def check_login(user_uuid) -> str:
if user_uuid is None:
def check_login(user_id: int) -> str:
if user_id is None:
return 'login_page'
if user_uuid is not None:
if user_sql.get_user_name_by_uuid(user_uuid) is None:
return 'login_page'
else:
try:
ip = request.remote_addr
except Exception:
ip = ''
if user_sql.get_user_id(user_id) is None:
return 'login_page'
else:
try:
ip = request.remote_addr
except Exception:
ip = ''
user_sql.update_last_act_user(user_uuid, ip)
user_sql.update_last_act_user(user_id, ip)
return 'ok'
return 'login_page'
return 'ok'
def is_access_permit_to_service(service: str) -> bool:
service_id = service_sql.select_service_id_by_slug(service)
user_uuid = request.cookies.get('uuid')
user_id = user_sql.get_user_id_by_uuid(user_uuid)
user_services = user_sql.select_user_services(user_id)
verify_jwt_in_request()
claims = get_jwt()
user_services = user_sql.select_user_services(claims['user_id'])
if str(service_id) in user_services:
return True
else:
@ -45,11 +43,13 @@ def is_admin(level=1, **kwargs):
if kwargs.get('role_id'):
role = kwargs.get('role_id')
else:
user_id = request.cookies.get('uuid')
group_id = request.cookies.get('group')
verify_jwt_in_request()
claims = get_jwt()
user_id = claims['user_id']
group_id = claims['group']
try:
role = user_sql.get_user_role_by_uuid(user_id, group_id)
role = user_sql.get_user_role_in_group(user_id, group_id)
except Exception:
role = 4
try:
@ -60,7 +60,7 @@ def is_admin(level=1, **kwargs):
def page_for_admin(level=1) -> None:
if not is_admin(level=level):
return abort(404, 'Not found')
return abort(400, 'bad permission')
def check_in_ldap(user, password):
@ -103,42 +103,51 @@ def check_in_ldap(user, password):
return True
def create_uuid_and_token(login: str):
user_uuid = str(uuid.uuid4())
user_sql.write_user_uuid(login, user_uuid)
return user_uuid
def do_login(user_uuid: str, user_group: str, user: str, next_url: str):
try:
session_ttl = sql.get_setting('session_ttl')
except Exception:
session_ttl = 5
if session_ttl is None:
session_ttl = 5
def do_login(user_params: dict, next_url: str):
if next_url:
redirect_to = f'https://{request.host}{next_url}'
else:
redirect_to = f"https://{request.host}{url_for('overview.index')}"
expires = datetime.utcnow() + timedelta(days=session_ttl)
login_user(user)
resp = make_response(redirect_to)
resp.set_cookie('uuid', user_uuid, secure=True, expires=expires.strftime("%a, %d %b %Y %H:%M:%S GMT"), samesite='Strict')
resp.set_cookie('group', str(user_group), expires=expires.strftime("%a, %d %b %Y %H:%M:%S GMT"), samesite='Strict')
response = jsonify({"status": "done", "next_url": redirect_to})
access_token = create_jwt_token(user_params)
set_access_cookies(response, access_token)
try:
user_group_name = group_sql.get_group_name_by_id(user_group)
user_group_name = group_sql.get_group_name_by_id(user_params['group'])
except Exception:
user_group_name = ''
try:
user_name = user_sql.get_user_name_by_uuid(user_uuid)
roxywi_common.logging('Roxy-WI server', f' user: {user_name}, group: {user_group_name} login', roxywi=1)
roxywi_common.logging('RMON server', f' user: {user_params["name"]}, group: {user_group_name} login', roxywi=1)
except Exception as e:
print(f'error: {e}')
return resp
return response
def create_jwt_token(user_params: dict) -> str:
additional_claims = {'group': str(user_params['group'])}
return create_access_token(str(user_params['user']), additional_claims=additional_claims)
def check_user_password(login: str, password: str) -> dict:
if not login and not password:
raise Exception('There is no login or password')
try:
user = user_sql.get_user_by_username(login)
except Exception:
raise Exception('ban')
if user.enabled == 0:
raise Exception('Your login is disabled')
if user.ldap_user == 1:
if login in user.username and check_in_ldap(login, password):
return {'group': str(user.group_id), 'user': user.user_id, 'name': user.username}
else:
raise Exception('ban')
else:
hashed_password = roxy_wi_tools.Tools.get_hash(password)
if login in user.username and hashed_password == user.password:
return {'group': str(user.group_id), 'user': user.user_id, 'name': user.username}
else:
raise Exception('ban')

View File

@ -2,7 +2,9 @@ import os
import glob
from typing import Any, Union
from flask import request
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
@ -13,6 +15,8 @@ import app.modules.db.server as server_sql
import app.modules.db.history as history_sql
import app.modules.db.ha_cluster as ha_sql
import app.modules.roxy_wi_tools as roxy_wi_tools
from app.modules.roxywi.class_models import ErrorResponse
from app.modules.roxywi.exception import RoxywiResourceNotFound, RoxywiGroupMismatch, RoxywiGroupNotFound
get_config_var = roxy_wi_tools.GetConfigVar()
@ -25,37 +29,45 @@ def get_user_group(**kwargs) -> int:
user_group = ''
try:
user_group_id = request.cookies.get('group')
verify_jwt_in_request()
claims = get_jwt()
user_group_id = claims['group']
groups = group_sql.select_groups(id=user_group_id)
for g in groups:
if g.group_id == int(user_group_id):
for group in groups:
if group.group_id == int(user_group_id):
if kwargs.get('id'):
user_group = g.group_id
user_group = group.group_id
else:
user_group = g.name
user_group = group.name
except Exception as e:
raise Exception(f'error: {e}')
return user_group
def check_user_group_for_flask(**kwargs) -> bool:
if kwargs.get('api_token') is not None:
def check_user_group_for_flask(api_token: bool = False):
if api_token:
return True
if kwargs.get('user_uuid'):
group_id = kwargs.get('user_group_id')
user_uuid = kwargs.get('user_uuid')
else:
user_uuid = request.cookies.get('uuid')
group_id = request.cookies.get('group')
verify_jwt_in_request()
claims = get_jwt()
user_id = claims['user_id']
group_id = claims['group']
user_id = user_sql.get_user_id_by_uuid(user_uuid)
if user_sql.check_user_group(user_id, group_id):
return True
else:
logging('Roxy-WI server', ' has tried to actions in not his group ', roxywi=1, login=1)
logging('RMON server', 'has tried to actions in not his group', login=1)
return False
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)
return False
def check_is_server_in_group(server_ip: str) -> bool:
group_id = get_user_group(id=1)
servers = server_sql.select_servers(server=server_ip)
@ -63,7 +75,7 @@ def check_is_server_in_group(server_ip: str) -> bool:
if (s[2] == server_ip and int(s[3]) == 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', 'has tried to actions in not his group server', roxywi=1, login=1)
return False
@ -98,6 +110,10 @@ 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')
log_path = get_config_var.get_config_var('main', 'log_path')
verify_jwt_in_request()
claims = get_jwt()
user_id = claims['user_id']
login = user_sql.get_user_id(user_id=user_id)
if not os.path.exists(log_path):
os.makedirs(log_path)
@ -112,25 +128,19 @@ def logging(server_ip: Union[str, int], action: str, **kwargs) -> None:
except Exception:
ip = ''
try:
user_uuid = request.cookies.get('uuid')
login = user_sql.get_user_name_by_uuid(user_uuid)
except Exception:
login = ''
if kwargs.get('roxywi') == 1:
if kwargs.get('login'):
mess = f"{cur_date_in_log} from {ip} user: {login}, group: {user_group}, {action} on: {server_ip}\n"
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"
else:
mess = f"{cur_date_in_log} from {ip} user: {login}, group: {user_group}, {action} on: {server_ip} {kwargs.get('service')}\n"
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"
if kwargs.get('keep_history'):
try:
keep_action_history(kwargs.get('service'), action, server_ip, login, ip)
keep_action_history(kwargs.get('service'), action, server_ip, login.username, ip)
except Exception as e:
print(f'error: Cannot save history: {e}')
@ -198,34 +208,22 @@ def get_dick_permit(**kwargs):
def get_users_params(**kwargs):
verify_jwt_in_request()
user_data = get_jwt()
try:
user_uuid = request.cookies.get('uuid')
user = user_sql.get_user_name_by_uuid(user_uuid)
user_id = user_data['user_id']
user = user_sql.get_user_id(user_id)
except Exception:
raise Exception('error: Cannot get user UUID')
raise Exception('error: Cannot get user id')
if int(user_data['group']) != int(user.group_id):
raise Exception('error: Wrong active group')
try:
group_id = user_sql.get_user_current_group_by_uuid(user_uuid)
role = user_sql.get_role_id(user_id, user.group_id)
except Exception as e:
raise Exception(f'error: Cannot get user group: {e}')
try:
group_id_from_cookies = int(request.cookies.get('group'))
except Exception as e:
raise Exception(f'error: Cannot get group id from cookies: {e}')
if group_id_from_cookies != group_id:
raise Exception('error: Wrong current group')
try:
role = user_sql.get_user_role_by_uuid(user_uuid, group_id)
except Exception:
raise Exception('error: Cannot get user role')
try:
user_id = user_sql.get_user_id_by_uuid(user_uuid)
except Exception as e:
raise Exception(f'error: Cannot get user id {e}')
raise Exception(f'error: Cannot get user role {e}')
try:
user_services = user_sql.select_user_services(user_id)
@ -246,14 +244,13 @@ def get_users_params(**kwargs):
user_lang = get_user_lang_for_flask()
user_params = {
'user': user,
'user_uuid': user_uuid,
'user': user.username,
'role': role,
'servers': servers,
'user_services': user_services,
'lang': user_lang,
'user_id': user_id,
'group_id': group_id
'group_id': user.group_id
}
return user_params
@ -305,9 +302,33 @@ def handle_exceptions(ex: Exception, server_ip: str, message: str, **kwargs: Any
"""
logging(server_ip, f'error: {message}: {ex}', **kwargs)
raise Exception(f'error: {message}: {ex}')
raise Exception(f'{message}: {ex}')
def is_user_has_access_to_its_group(user_id: int) -> None:
if not user_sql.check_user_group(user_id, g.user_params['group_id']) and g.user_params['role'] != 1:
raise RoxywiGroupMismatch
def is_user_has_access_to_group(user_id: int, group_id: int) -> None:
if not user_sql.check_user_group(user_id, group_id) and g.user_params['role'] != 1:
raise RoxywiGroupMismatch
def handle_json_exceptions(ex: Exception, message: str, server_ip='Roxy-WI server') -> dict:
logging(server_ip, f'error: {message}: {ex}', roxywi=1, login=1)
return {'status': 'failed', 'error': f'{message}: {ex}'}
logging(server_ip, f'{message}: {ex}', login=1, roxywi=1)
return ErrorResponse(error=f'{message}: {ex}').model_dump(mode='json')
def handler_exceptions_for_json_data(ex: Exception, main_ex_mes: str) -> tuple[dict, int]:
if isinstance(ex, KeyError):
return handle_json_exceptions(ex, 'Missing key in JSON data'), 500
elif isinstance(ex, ValueError):
return handle_json_exceptions(ex, 'Wrong type or missing value in JSON data'), 500
elif isinstance(ex, RoxywiResourceNotFound):
return handle_json_exceptions(ex, 'Resource not found'), 404
elif isinstance(ex, RoxywiGroupNotFound):
return handle_json_exceptions(ex, 'Group not found'), 404
elif isinstance(ex, RoxywiGroupMismatch):
return handle_json_exceptions(ex, 'Resource not found in group'), 404
else:
return handle_json_exceptions(ex, main_ex_mes), 500

View File

@ -1,6 +1,8 @@
import psutil
import requests
from flask import render_template, request
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.waf as waf_sql
@ -40,13 +42,12 @@ def show_sub_ovw() -> str:
def show_overview(serv) -> str:
servers = []
user_uuid = request.cookies.get('uuid')
group_id = request.cookies.get('group')
verify_jwt_in_request()
claims = get_jwt()
lang = roxywi_common.get_user_lang_for_flask()
role = user_sql.get_user_role_by_uuid(user_uuid, group_id)
role = user_sql.get_user_role_in_group(claims['user_id'], claims['group'])
server = [server for server in server_sql.select_servers(server=serv)]
user_id = user_sql.get_user_id_by_uuid(user_uuid)
user_services = user_sql.select_user_services(user_id)
user_services = user_sql.select_user_services(claims['user_id'])
haproxy = service_sql.select_haproxy(serv) if '1' in user_services else 0
nginx = service_sql.select_nginx(serv) if '2' in user_services else 0

View File

@ -45,18 +45,7 @@ def delete_user(user_id: int):
roxywi_common.logging(user.username, 'has been deleted user', roxywi=1, login=1)
def update_user(email, new_user, user_id, enabled, group_id, role_id):
try:
user_sql.update_user(new_user, email, role_id, user_id, enabled)
except Exception as e:
roxywi_common.handle_exceptions(e, 'Roxy-WI server', f'Cannot update user {new_user}', roxywi=1, login=1)
user_sql.update_user_role(user_id, group_id, role_id)
roxywi_common.logging(new_user, ' has been updated user ', roxywi=1, login=1)
def update_user_password(password: str, uuid: str, user_id: int):
if uuid:
user_id = user_sql.get_user_id_by_uuid(uuid)
def update_user_password(password, user_id):
user = user_sql.get_user_id(user_id)
user_sql.update_user_password(password, user_id)
roxywi_common.logging(f'user {user.username}', 'has changed password', roxywi=1, login=1)
@ -85,36 +74,36 @@ def change_user_services(user: str, user_id: int, user_services: dict):
roxywi_common.logging('Roxy-WI server', f'Access to the services has been updated for user: {user}', roxywi=1, login=1)
def change_user_active_group(group_id: int, user_uuid: str) -> str:
def change_user_active_group(group_id: int, user_id: int) -> str:
try:
user_sql.update_user_current_groups(group_id, user_uuid)
user_sql.update_user_current_groups(group_id, user_id)
return 'Ok'
except Exception as e:
roxywi_common.handle_exceptions(e, 'Roxy-WI server', 'Cannot change the group', roxywi=1, login=1)
def get_user_active_group(uuid: str, group: str) -> str:
group_id = user_sql.get_user_id_by_uuid(uuid)
groups = user_sql.select_user_groups_with_names(group_id)
def get_user_active_group(group_id: int, user_id: int) -> str:
# group_id = user_sql.get_user_id_by_uuid(uuid)
groups = user_sql.select_user_groups_with_names(user_id)
lang = roxywi_common.get_user_lang_for_flask()
return render_template('ajax/user_current_group.html', groups=groups, group=group, id=group_id, lang=lang)
return render_template('ajax/user_current_group.html', groups=groups, group=group_id, lang=lang)
def show_user_groups_and_roles(user_id: int, lang: str) -> str:
groups = user_sql.select_user_groups_with_names(user_id, user_not_in_group=1)
roles = sql.select_roles()
user_groups = user_sql.select_user_groups_with_names(user_id)
return render_template('ajax/user_groups_and_roles.html', groups=groups, user_groups=user_groups, roles=roles, lang=lang)
# def show_user_groups_and_roles(user_id: int, lang: str) -> str:
# groups = user_sql.select_user_groups_with_names(user_id, user_not_in_group=1)
# roles = sql.select_roles()
# user_groups = user_sql.select_user_groups_with_names(user_id)
# return render_template('ajax/user_groups_and_roles.html', groups=groups, user_groups=user_groups, roles=roles, lang=lang)
def is_current_user(user_id: int, user_uuid: str) -> bool:
current_user_id = user_sql.get_user_id_by_uuid(user_uuid)
if current_user_id == user_id:
return True
return False
# def is_current_user(user_id: int, user_uuid: str) -> bool:
# current_user_id = user_sql.get_user_id_by_uuid(user_uuid)
# if current_user_id == user_id:
# return True
# return False
def save_user_group_and_role(user: str, groups_and_roles: dict, user_uuid: str):
def save_user_group_and_role(user: str, groups_and_roles: dict):
resp = make_response('ok')
for k, v in groups_and_roles.items():
user_id = int(k)
@ -125,8 +114,7 @@ def save_user_group_and_role(user: str, groups_and_roles: dict, user_uuid: str):
role_id = int(v2['role_id'])
if len(v) == 1:
user_sql.update_user_current_groups_by_id(group_id, user_id)
if is_current_user(user_id, user_uuid):
resp.set_cookie('group', str(group_id), secure=True)
resp.set_cookie('group', str(group_id), secure=True)
try:
user_sql.update_user_role(user_id, group_id, role_id)
except Exception as e:

View File

@ -1,4 +1,4 @@
from flask import render_template, request
from flask import render_template
import app.modules.db.sql as sql
import app.modules.db.waf as waf_sql
@ -10,11 +10,9 @@ import app.modules.server.server as server_mod
import app.modules.roxywi.common as roxywi_common
def waf_overview(serv, waf_service) -> str:
def waf_overview(serv: str, waf_service: str, claims: dict) -> str:
servers = server_sql.select_servers(server=serv)
user_id = request.cookies.get('uuid')
group_id = int(request.cookies.get('group'))
role = user_sql.get_user_role_by_uuid(user_id, group_id)
role = user_sql.get_user_role_in_group(claims['user_id'], claims['group'])
returned_servers = []
waf = ''
metrics_en = 0

View File

@ -414,11 +414,11 @@ def show_firewalld_rules(server_ip) -> str:
return render_template('ajax/firewall_rules.html', input_chain=input_chain2, IN_public_allow=in_public_allow, output_chain=output_chain, lang=lang)
def create_server(hostname, ip, group, typeip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall, **kwargs) -> int:
def create_server(hostname, ip, group, type_ip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall, **kwargs) -> int:
if not roxywi_auth.is_admin(level=2, role_id=kwargs.get('role_id')):
raise Exception('error: not enough permission')
last_id = server_sql.add_server(hostname, ip, group, typeip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall)
last_id = server_sql.add_server(hostname, ip, group, type_ip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall)
return last_id

View File

@ -2,7 +2,7 @@ import os
from cryptography.fernet import Fernet
import paramiko
from flask import render_template, request
from flask import render_template
import app.modules.db.cred as cred_sql
import app.modules.db.group as group_sql
@ -11,6 +11,7 @@ import app.modules.common.common as common
from app.modules.server import ssh_connection
import app.modules.roxywi.common as roxywi_common
import app.modules.roxy_wi_tools as roxy_wi_tools
from app.modules.roxywi.class_models import IdResponse, IdDataResponse
error_mess = common.error_mess
get_config = roxy_wi_tools.GetConfigVar()
@ -40,10 +41,10 @@ def return_ssh_keys_path(server_ip: str, **kwargs) -> dict:
else:
passphrase = ssh.passphrase
ssh_settings.setdefault('enabled', ssh.enable)
ssh_settings.setdefault('enabled', ssh.key_enabled)
ssh_settings.setdefault('user', ssh.username)
ssh_settings.setdefault('password', password)
ssh_key = f'{lib_path}/keys/{ssh.name}.pem' if ssh.enable == 1 else ''
ssh_key = f'{lib_path}/keys/{ssh.name}.pem' if ssh.key_enabled == 1 else ''
ssh_settings.setdefault('key', ssh_key)
ssh_settings.setdefault('passphrase', passphrase)
@ -63,32 +64,29 @@ def ssh_connect(server_ip):
return ssh
def create_ssh_cred(json_data: dict) -> dict:
name = common.checkAjaxInput(json_data['ssh'])
enable = int(json_data['enabled'])
group = common.checkAjaxInput(json_data['group'])
def create_ssh_cred(name: str, password: str, group: int, username: str, enable: int, is_api: int) -> dict:
group_name = group_sql.get_group_name_by_id(group)
username = common.checkAjaxInput(json_data['user'])
password = common.checkAjaxInput(json_data['pass'])
lang = roxywi_common.get_user_lang_for_flask()
name = f'{name}_{group_name}'
if password != '':
if password and password != "''":
try:
password = crypt_password(password)
except Exception as e:
raise Exception(e)
if username is None or name is None:
return error_mess
else:
password = ''
try:
last_id = cred_sql.insert_new_ssh(name, enable, group, username, password)
except Exception as e:
roxywi_common.handle_exceptions(e, 'Roxy-WI server', 'Cannot create new SSH credentials', roxywi=1, login=1)
roxywi_common.logging('Roxy-WI server', f'New SSH credentials {name} has been created', roxywi=1, login=1)
rendered_template = render_template('ajax/new_ssh.html', groups=group_sql.select_groups(), sshs=cred_sql.select_ssh(name=name), lang=lang)
return {'id': last_id, 'template': rendered_template}
return roxywi_common.handle_json_exceptions(e, 'Cannot create new SSH credentials')
roxywi_common.logging('RMON server', f'New SSH credentials {name} has been created', roxywi=1, login=1)
if is_api:
return IdResponse(id=last_id).model_dump(mode='json')
else:
data = render_template('ajax/new_ssh.html', groups=group_sql.select_groups(), sshs=cred_sql.select_ssh(name=name), lang=lang)
return IdDataResponse(id=last_id, data=data).model_dump(mode='json')
def create_ssh_cred_api(name: str, enable: str, group: str, username: str, password: str) -> bool:
@ -116,30 +114,28 @@ def create_ssh_cred_api(name: str, enable: str, group: str, username: str, passw
roxywi_common.handle_exceptions(e, 'Roxy-WI server', f'Cannot create SSH credentials {name}', roxywi=1)
def upload_ssh_key(name: str, user_group: int, key: str, passphrase: str) -> str:
if '..' in name:
raise Exception('error: nice try')
if name == '':
raise Exception('error: please select credentials first')
def upload_ssh_key(ssh_id: int, key: str, passphrase: str) -> None:
key = key.replace("'", "")
ssh = cred_sql.get_ssh(ssh_id)
group_name = group_sql.get_group_name_by_id(ssh.group_id)
lib_path = get_config.get_config_var('main', 'lib_path')
full_dir = f'{lib_path}/keys/'
name = ssh.name
ssh_keys = f'{name}.pem'
try:
key = paramiko.pkey.load_private_key(key, password=passphrase)
except Exception as e:
raise Exception(f'error: Cannot save SSH key file: {e}')
lib_path = get_config.get_config_var('main', 'lib_path')
full_dir = f'{lib_path}/keys/'
ssh_keys = f'{name}.pem'
raise Exception(e)
try:
_check_split = name.split('_')[1]
_ = name.split('_')[1]
split_name = True
except Exception:
split_name = False
if not os.path.isfile(ssh_keys) and not split_name:
name = f'{name}_{user_group}'
name = f'{ssh.name}_{group_name}'
if not os.path.exists(full_dir):
os.makedirs(full_dir)
@ -149,38 +145,35 @@ def upload_ssh_key(name: str, user_group: int, key: str, passphrase: str) -> str
try:
key.write_private_key_file(ssh_keys)
except Exception as e:
raise Exception(f'error: Cannot save SSH key file: {e}')
raise Exception(e)
try:
os.chmod(ssh_keys, 0o600)
except IOError as e:
roxywi_common.logging('Roxy-WI server', e.args[0], roxywi=1)
raise Exception(f'error: something went wrong: {e}')
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:
raise Exception(e)
else:
passphrase = ''
try:
cred_sql.update_ssh_passphrase(name, passphrase)
cred_sql.update_ssh_passphrase(ssh_id, passphrase)
except Exception as e:
raise Exception(e)
roxywi_common.logging("Roxy-WI server", f"A new SSH cert has been uploaded {ssh_keys}", roxywi=1, login=1)
return f'success: SSH key has been saved into: {ssh_keys}'
roxywi_common.logging("RMON server", f"A new SSH cert has been uploaded {ssh_keys}", roxywi=1, login=1)
def update_ssh_key(json_data: dict):
ssh_id = int(json_data['id'])
name = common.checkAjaxInput(json_data['name'])
enable = common.checkAjaxInput(json_data['ssh_enable'])
group = int(json_data['group'])
username = common.checkAjaxInput(json_data['ssh_user'])
password = common.checkAjaxInput(json_data['ssh_pass'])
new_ssh_key_name = ''
ssh_key_name = ''
ssh_enable = 0
def update_ssh_key(ssh_id: int, name: str, password: str, enable: int, username: str, group: int) -> None:
lib_path = get_config.get_config_var('main', 'lib_path')
ssh = cred_sql.get_ssh(ssh_id)
ssh_key_name = f'{lib_path}/keys/{ssh.name}.pem'
new_ssh_key_name = f'{lib_path}/keys/{name}.pem'
if password != '':
try:
@ -188,22 +181,15 @@ def update_ssh_key(json_data: dict):
except Exception as e:
raise Exception(e)
if username is None:
return error_mess
lib_path = get_config.get_config_var('main', 'lib_path')
for sshs in cred_sql.select_ssh(id=ssh_id):
ssh_enable = sshs.enable
ssh_key_name = f'{lib_path}/keys/{sshs.name}.pem'
new_ssh_key_name = f'{lib_path}/keys/{name}.pem'
if ssh_enable == 1:
if ssh.key_enabled == 1 and os.path.isfile(ssh_key_name):
os.rename(ssh_key_name, new_ssh_key_name)
os.chmod(new_ssh_key_name, 0o600)
cred_sql.update_ssh(ssh_id, name, enable, group, username, password)
roxywi_common.logging('Roxy-WI server', f'The SSH credentials {name} has been updated ', roxywi=1, login=1)
try:
cred_sql.update_ssh(ssh_id, name, enable, group, username, password)
roxywi_common.logging('RMON server', f'The SSH credentials {name} has been updated ', roxywi=1, login=1)
except Exception as e:
raise Exception(e)
def delete_ssh_key(ssh_id) -> str:
@ -213,7 +199,7 @@ def delete_ssh_key(ssh_id) -> str:
ssh_key_name = ''
for sshs in cred_sql.select_ssh(id=ssh_id):
ssh_enable = sshs.enable
ssh_enable = sshs.key_enabled
name = sshs.name
ssh_key_name = f'{lib_path}/keys/{sshs.name}.pem'

View File

@ -1,8 +1,4 @@
import socket
from contextlib import closing
import app.modules.db.sql as sql
import app.modules.db.user as user_sql
import app.modules.db.server as server_sql
import app.modules.db.service as service_sql
import app.modules.common.common as common
@ -11,7 +7,7 @@ import app.modules.roxywi.common as roxywi_common
import app.modules.service.common as service_common
def common_action(server_ip: str, action: str, service: str) -> str:
def common_action(server_ip: str, action: str, service: str) -> None:
action_functions = {
'haproxy': service_action,
'nginx': service_action,
@ -21,11 +17,13 @@ def common_action(server_ip: str, action: str, service: str) -> str:
'waf_nginx': action_nginx_waf
}
return action_functions[service](server_ip, action, service)
try:
action_functions[service](server_ip, action, service)
except Exception as e:
raise e
def service_action(server_ip: str, action: str, service: str) -> str:
def service_action(server_ip: str, action: str, service: str) -> None:
"""
:param server_ip: The IP address of the server on which the action will be performed.
:param action: The action to be performed on the service (e.g., "start", "stop").
@ -35,25 +33,21 @@ def service_action(server_ip: str, action: str, service: str) -> str:
try:
service_common.is_protected(server_ip, action)
except Exception as e:
return str(e)
raise e
server_id = server_sql.select_server_id_by_ip(server_ip=server_ip)
if service_common.is_not_allowed_to_restart(server_id, service, action):
return 'error: This server is not allowed to be restarted'
raise Exception('This server is not allowed to be restarted')
try:
if service != 'keepalived':
service_common.check_service_config(server_ip, server_id, service)
except Exception as e:
return f'error: Cannot check config: {e}'
raise Exception(f'Cannot check config: {e}')
command = get_action_command(service, action, server_id)
try:
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)
return f"success: {service.title()} has been {action}"
except Exception as e:
return f"error: Cannot {action} {service.title()}: {e}"
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)
def get_action_command(service: str, action: str, server_id: int) -> str:
@ -77,29 +71,26 @@ def get_action_command(service: str, action: str, server_id: int) -> str:
return commands
def action_haproxy_waf(server_ip: str, action: str, service: str) -> str:
def action_haproxy_waf(server_ip: str, action: str, service: str) -> None:
try:
service_common.is_protected(server_ip, action)
except Exception as e:
return str(e)
raise e
roxywi_common.logging(
server_ip, f'HAProxy WAF service has been {action}ed', roxywi=1, login=1, keep_history=1, service='haproxy'
)
command = f"sudo systemctl {action} waf"
try:
server_mod.ssh_command(server_ip, command)
return f"success: WAF has been {action}"
except Exception as e:
return f"error: Cannot {action} WAF service: {e}"
server_mod.ssh_command(server_ip, command)
def action_nginx_waf(server_ip: str, action: str, service: str) -> str:
def action_nginx_waf(server_ip: str, action: str, service: str) -> None:
config_dir = common.return_nice_path(sql.get_setting('nginx_dir'))
try:
service_common.is_protected(server_ip, action)
except Exception as e:
return str(e)
raise e
waf_new_state = 'on' if action == 'start' else 'off'
waf_old_state = 'off' if action == 'start' else 'on'
@ -108,37 +99,32 @@ def action_nginx_waf(server_ip: str, action: str, service: str) -> str:
command = (f"sudo sed -i 's/modsecurity {waf_old_state}/modsecurity {waf_new_state}/g' {config_dir}nginx.conf "
f"&& sudo systemctl reload nginx")
try:
server_mod.ssh_command(server_ip, command)
return f"success: WAF has been {action}"
except Exception as e:
return f"error: Cannot {action} WAF service: {e}"
server_mod.ssh_command(server_ip, command)
def check_service(server_ip: str, user_uuid: str, service: str) -> str:
user_id = user_sql.get_user_id_by_uuid(user_uuid)
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}'
# 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

@ -1,5 +1,3 @@
import os
from flask import render_template
import app.modules.db.sql as sql
@ -8,102 +6,42 @@ import app.modules.db.backup as backup_sql
import app.modules.db.server as server_sql
import app.modules.db.service as service_sql
import app.modules.server.ssh as ssh_mod
import app.modules.server.server as server_mod
import app.modules.common.common as common
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
def delete_backup(serv: str, backup_id: int) -> None:
if backup_sql.check_exists_backup(serv):
raise Exception(f'Backup job for {serv} already exists')
backup_sql.delete_backups(backup_id)
roxywi_common.logging('backup ', f' a backup job for server {serv} has been deleted', roxywi=1, login=1)
def backup(json_data) -> str:
cred = int(json_data['cred'])
server = common.is_ip_or_dns(json_data['server'])
rserver = common.is_ip_or_dns(json_data['rserver'])
ssh_settings = ssh_mod.return_ssh_keys_path(rserver, id=cred)
update_id = ''
description = ''
if 'del_id' in json_data:
time = ''
rpath = ''
backup_type = ''
del_id = int(json_data['del_id'])
else:
del_id = ''
rpath = common.checkAjaxInput(json_data['rpath'])
backup_type = common.checkAjaxInput(json_data['type'])
time = common.checkAjaxInput(json_data['time'])
description = common.checkAjaxInput(json_data['description'])
if backup_sql.check_exists_backup(server):
return f'warning: Backup job for {server} already exists'
if 'update_id' in json_data:
update_id = int(json_data['update_id'])
def create_backup_inv(json_data: BackupRequest, del_id: int = 0) -> None:
ssh_settings = ssh_mod.return_ssh_keys_path(str(json_data.server), id=json_data.cred_id)
inv = {"server": {"hosts": {}}}
server_ips = []
inv['server']['hosts'][server] = {
'HOST': rserver,
"SERVER": server,
"TYPE": backup_type,
"TIME": time,
"RPATH": rpath,
inv['server']['hosts'][str(json_data.server)] = {
'HOST': str(json_data.rserver),
"SERVER": str(json_data.server),
"TYPE": json_data.type,
"TIME": json_data.time,
"RPATH": json_data.rpath,
"DELJOB": del_id,
"USER": ssh_settings['user'],
"KEY": ssh_settings['key']
}
server_ips.append(server)
server_ips.append(str(json_data.server))
try:
installation_mod.run_ansible(inv, server_ips, 'backup')
except Exception as e:
raise Exception(f'error: {e}')
if not del_id and not update_id:
if backup_sql.insert_backup_job(server, rserver, rpath, backup_type, time, cred, description):
roxywi_common.logging('backup ', f' a new backup job for server {server} has been created', roxywi=1,
login=1)
return render_template(
'ajax/new_backup.html', backups=backup_sql.select_backups(server=server, rserver=rserver), sshs=cred_sql.select_ssh()
)
else:
raise Exception('Cannot add the job into DB')
elif del_id:
backup_sql.delete_backups(del_id)
roxywi_common.logging('backup ', f' a backup job for server {server} has been deleted', roxywi=1, login=1)
return 'ok'
elif update_id:
backup_sql.update_backup(server, rserver, rpath, backup_type, time, cred, description, update_id)
roxywi_common.logging('backup ', f' a backup job for server {server} has been updated', roxywi=1, login=1)
return 'ok'
def s3_backup(server, s3_server, bucket, secret_key, access_key, time, deljob, description) -> str:
if deljob:
time = ''
secret_key = ''
access_key = ''
tag = 'delete'
else:
tag = 'add'
if backup_sql.check_exists_s3_backup(server):
raise Exception(f'error: Backup job for {server} already exists')
def create_s3_backup_inv(data: S3BackupRequest, tag: str) -> None:
inv = {"server": {"hosts": {}}}
inv["server"]["hosts"]["localhost"] = {
"SERVER": server,
"S3_SERVER": s3_server,
"BUCKET": bucket,
"SECRET_KEY": secret_key,
"ACCESS_KEY": access_key,
"TIME": time,
"SERVER": str(data.server),
"S3_SERVER": str(data.s3_server),
"BUCKET": data.bucket,
"SECRET_KEY": data.secret_key,
"ACCESS_KEY": data.access_key,
"TIME": data.time,
"action": tag
}
@ -112,17 +50,85 @@ def s3_backup(server, s3_server, bucket, secret_key, access_key, time, deljob, d
except Exception as e:
raise Exception(f'error: {e}')
if not deljob:
try:
backup_sql.insert_s3_backup_job(server, s3_server, bucket, secret_key, access_key, time, description)
except Exception as e:
raise Exception(e)
roxywi_common.logging('backup ', f' a new S3 backup job for server {server} has been created', roxywi=1, login=1)
return render_template('ajax/new_s3_backup.html', backups=backup_sql.select_s3_backups(server=server, s3_server=s3_server, bucket=bucket))
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 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')
create_backup_inv(json_data)
last_id = backup_sql.insert_backup_job(json_data.server, json_data.rserver, json_data.rpath, json_data.type,
json_data.time, json_data.cred_id, json_data.description)
roxywi_common.logging('backup ', f' a new backup job for server {json_data.server} has been created', roxywi=1, login=1)
if is_api:
return IdResponse(id=last_id).model_dump(mode='json'), 201
else:
data = render_template(
'ajax/new_backup.html',
backups=backup_sql.select_backups(server=json_data.server, rserver=json_data.rserver),
sshs=cred_sql.select_ssh()
)
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)
roxywi_common.logging('backup ', f' a backup job for server {json_data.server} has been deleted', roxywi=1, login=1)
return BaseResponse().model_dump(mode='json'), 204
def update_backup(json_data: BackupRequest, backup_id: int) -> tuple:
create_backup_inv(json_data)
backup_sql.update_backup(json_data.server, json_data.rserver, json_data.rpath, json_data.type,
json_data.time, json_data.cred_id, json_data.description, backup_id)
roxywi_common.logging('backup ', f' a backup job for server {json_data.server} has been updated', roxywi=1, login=1)
return BaseResponse().model_dump(mode='json'), 201
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')
try:
create_s3_backup_inv(data, 'add')
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)
except Exception as e:
raise Exception(e)
if is_api:
return IdResponse(id=last_id).model_dump(mode='json'), 201
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:
try:
create_s3_backup_inv(data, 'delete')
backup_sql.delete_s3_backups(backup_id)
roxywi_common.logging('backup ', f'a S3 backup job for server {data.server} has been deleted', roxywi=1, login=1)
except Exception as e:
raise e
def git_backup(server_id, service_id, git_init, repo, branch, period, cred, del_job, description, backup_id) -> str:

View File

@ -1,5 +1,7 @@
import requests
from flask import render_template, request
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
@ -32,15 +34,15 @@ def get_correct_service_name(service: str, server_id: int) -> str:
return service
def check_haproxy_version(server_ip):
hap_sock_p = sql.get_setting('haproxy_sock_port')
ver = ""
cmd = f"echo 'show info' |nc {server_ip} {hap_sock_p} |grep Version |awk '{{print $2}}'"
output, stderr = server_mod.subprocess_execute(cmd)
for line in output:
ver = line
return ver
# def check_haproxy_version(server_ip):
# hap_sock_p = sql.get_setting('haproxy_sock_port')
# ver = ""
# cmd = f"echo 'show info' |nc {server_ip} {hap_sock_p} |grep Version |awk '{{print $2}}'"
# output, stderr = server_mod.subprocess_execute(cmd)
# for line in output:
# ver = line
#
# return ver
def is_protected(server_ip: str, action: str) -> None:
@ -52,9 +54,9 @@ def is_protected(server_ip: str, action: str) -> None:
:return: None
:raises: Exception if the server is protected and the user role is not high enough.
"""
user_uuid = request.cookies.get('uuid')
group_id = int(request.cookies.get('group'))
user_role = user_sql.get_user_role_by_uuid(user_uuid, group_id)
verify_jwt_in_request()
claims = get_jwt()
user_role = user_sql.get_user_role_in_group(claims['user_id'], claims['group'])
if server_sql.is_serv_protected(server_ip) and int(user_role) > 2:
raise Exception(f'error: This server is protected. You cannot {action} it')
@ -187,11 +189,9 @@ def check_service_config(server_ip: str, server_id: int, service: str) -> None:
def overview_backends(server_ip: str, service: str) -> str:
import modules.config.config as config_mod
import app.modules.config.config as config_mod
lang = roxywi_common.get_user_lang_for_flask()
if service != 'nginx' and service != 'apache':
if service not in ('nginx', 'apache'):
format_file = config_common.get_file_format(service)
config_dir = config_common.get_config_dir(service)
cfg = config_common.generate_config_path(service, server_ip)
@ -204,16 +204,24 @@ def overview_backends(server_ip: str, service: str) -> str:
try:
config_mod.get_config(server_ip, cfg, service=service)
except Exception as e:
roxywi_common.logging('Roxy-WI server', f' Cannot download a config {e}', roxywi=1)
raise e
try:
sections = section_mod.get_sections(cfg, service=service)
except Exception as e:
roxywi_common.logging('Roxy-WI server', f' Cannot get sections from config file {e}', roxywi=1)
sections = f'error: Cannot get backends {e}'
raise e
else:
sections = section_mod.get_remote_sections(server_ip, service)
sections = {}
sections_not_formated = section_mod.get_remote_sections(server_ip, service)
for section in sections_not_formated.split('\r'):
if section == '\n':
continue
back_path = section.split(":")[0]
back_name = section.split(":")[1]
back_name = back_name.strip().replace('\n', '').replace('\r', '').replace(';', '')
back_path = back_path.strip().replace('/', '92').replace(':', '')
sections[back_path] = back_name
return render_template('ajax/haproxyservers_backends.html', backends=sections, serv=server_ip, service=service, lang=lang)
return sections
def get_overview_last_edit(server_ip: str, service: str) -> str:
@ -261,24 +269,24 @@ def get_stat_page(server_ip: str, service: str) -> str:
return data.decode('utf-8')
def show_service_version(server_ip: str, service: str) -> str:
if service == 'haproxy':
return check_haproxy_version(server_ip)
server_id = server_sql.select_server_id_by_ip(server_ip)
service_name = get_correct_service_name(service, server_id)
is_dockerized = service_sql.select_service_setting(server_id, service, 'dockerized')
if is_dockerized == '1':
container_name = sql.get_setting(f'{service}_container_name')
if service == 'apache':
cmd = f'docker exec -it {container_name} /usr/local/apache2/bin/httpd -v 2>&1|head -1|awk -F":" \'{{print $2}}\''
else:
cmd = f'docker exec -it {container_name} /usr/sbin/{service_name} -v 2>&1|head -1|awk -F":" \'{{print $2}}\''
else:
cmd = [f'sudo /usr/sbin/{service_name} -v|head -1|awk -F":" \'{{print $2}}\'']
try:
return server_mod.ssh_command(server_ip, cmd, timeout=5)
except Exception as e:
return f'{e}'
# def show_service_version(server_ip: str, service: str) -> str:
# if service == 'haproxy':
# return check_haproxy_version(server_ip)
#
# server_id = server_sql.select_server_id_by_ip(server_ip)
# service_name = get_correct_service_name(service, server_id)
# is_dockerized = service_sql.select_service_setting(server_id, service, 'dockerized')
#
# if is_dockerized == '1':
# container_name = sql.get_setting(f'{service}_container_name')
# if service == 'apache':
# cmd = f'docker exec -it {container_name} /usr/local/apache2/bin/httpd -v 2>&1|head -1|awk -F":" \'{{print $2}}\''
# else:
# cmd = f'docker exec -it {container_name} /usr/sbin/{service_name} -v 2>&1|head -1|awk -F":" \'{{print $2}}\''
# else:
# cmd = [f'sudo /usr/sbin/{service_name} -v|head -1|awk -F":" \'{{print $2}}\'']
#
# try:
# return server_mod.ssh_command(server_ip, cmd, timeout=5)
# except Exception as e:
# return f'{e}'

View File

@ -1,45 +1,57 @@
import json
from typing import Union
import app.modules.db.server as server_sql
import app.modules.db.ha_cluster as ha_sql
import app.modules.db.service as service_sql
from app.modules.db.db_model import HaCluster, HaClusterRouter, HaClusterVip, HaClusterVirt
import app.modules.common.common as common
import app.modules.server.server as server_mod
import app.modules.roxywi.common as roxywi_common
from app.modules.server.ssh import return_ssh_keys_path
from app.modules.roxywi.class_models import HAClusterRequest, HAClusterVIP
def create_cluster(cluster: json, group_id: int) -> str:
def _get_servers_dict(cluster: Union[HAClusterRequest, HAClusterVIP]) -> dict:
for i, k in cluster.model_dump(mode='json').items():
if i == 'servers':
servers = k
return servers
def _get_services_dict(cluster: HAClusterRequest) -> dict:
for i, k in cluster.model_dump(mode='json').items():
if i == 'services':
services = k
return services
def create_cluster(cluster: HAClusterRequest, group_id: int) -> int:
master_ip = None
vip = common.is_ip_or_dns(cluster['vip'])
syn_flood = int(cluster['syn_flood'])
return_master = int(cluster['return_to_master'])
cluster_name = common.checkAjaxInput(cluster['name'])
desc = common.checkAjaxInput(cluster['desc'])
servers = _get_servers_dict(cluster)
services = _get_services_dict(cluster)
try:
cluster_id = ha_sql.create_cluster(cluster_name, syn_flood, group_id, desc)
cluster_id = ha_sql.create_cluster(cluster.name, cluster.syn_flood, group_id, cluster.description)
roxywi_common.logging(cluster_id, 'New cluster has been created', keep_history=1, roxywi=1, service='HA cluster')
except Exception as e:
return f'error: Cannot create new HA cluster: {e}'
raise Exception(f'error: Cannot create new HA cluster: {e}')
try:
router_id = HaClusterRouter.insert(cluster_id=cluster_id, default=1).on_conflict_ignore().execute()
except Exception as e:
return f'error: Cannon create router: {e}'
raise Exception(f'error: Cannon create router: {e}')
try:
vip_id = HaClusterVip.insert(cluster_id=cluster_id, router_id=router_id, vip=vip, return_master=return_master).execute()
roxywi_common.logging(cluster_id, f'New vip {vip} has been created and added to the cluster', keep_history=1, roxywi=1, service='HA cluster')
vip_id = HaClusterVip.insert(cluster_id=cluster_id, router_id=router_id, vip=cluster.vip, return_master=cluster.return_master).execute()
roxywi_common.logging(cluster_id, f'New vip {cluster.vip} has been created and added to the cluster', keep_history=1, roxywi=1, service='HA cluster')
except Exception as e:
return f'error: Cannon add VIP: {e}'
raise Exception(f'error: Cannon add VIP: {e}')
for _slave_id, value in cluster['servers'].items():
for value in cluster.servers:
if value['master']:
master_ip = value['ip']
for _slave_id, value in cluster['servers'].items():
for value in cluster.servers:
if value['master']:
continue
try:
@ -47,7 +59,8 @@ def create_cluster(cluster: json, group_id: int) -> str:
except Exception as e:
raise Exception(f'error: Cannot update master on slave {value["ip"]: {e}}')
for slave_id, value in cluster['servers'].items():
for value in servers:
slave_id = servers['ip']
if value['master']:
slave_id = server_sql.select_server_id_by_ip(master_ip)
try:
@ -56,7 +69,7 @@ def create_cluster(cluster: json, group_id: int) -> str:
except Exception as e:
raise Exception(f'error: Cannot update slave server {value["ip"]}: {e}')
for service, value in cluster['services'].items():
for service, value in services.items():
if not value['enabled']:
continue
try:
@ -66,17 +79,15 @@ def create_cluster(cluster: json, group_id: int) -> str:
except Exception as e:
raise Exception(f'error: Cannot add service {service}: {e}')
if cluster['virt_server']:
add_or_update_virt(cluster, cluster_id, vip_id, group_id)
if cluster.virt_server:
add_or_update_virt(cluster, servers, cluster_id, vip_id, group_id)
return str(cluster_id)
return int(cluster_id)
def update_cluster(cluster: json, group_id: int) -> None:
cluster_id = int(cluster['cluster_id'])
syn_flood = int(cluster['syn_flood'])
cluster_name = common.checkAjaxInput(cluster['name'])
desc = common.checkAjaxInput(cluster['desc'])
def update_cluster(cluster: HAClusterRequest, cluster_id: int, group_id: int) -> None:
servers = _get_servers_dict(cluster)
services = _get_services_dict(cluster)
try:
router_id = ha_sql.get_router_id(cluster_id, default_router=1)
@ -84,12 +95,12 @@ def update_cluster(cluster: json, group_id: int) -> None:
raise Exception(f'error: Cannot get router: {e}')
try:
ha_sql.update_cluster(cluster_id, cluster_name, desc, syn_flood)
ha_sql.update_cluster(cluster_id, cluster.name, cluster.description, cluster.syn_flood)
except Exception as e:
raise Exception(f'error: Cannot update HA cluster: {e}')
try:
update_slaves(cluster, router_id)
update_slaves(servers, cluster_id, router_id)
except Exception as e:
raise Exception(e)
@ -103,7 +114,7 @@ def update_cluster(cluster: json, group_id: int) -> None:
except Exception as e:
raise Exception(f'error: Cannot delete old services: {e}')
for service, value in cluster['services'].items():
for service, value in services.items():
if not value['enabled']:
continue
try:
@ -112,7 +123,7 @@ def update_cluster(cluster: json, group_id: int) -> None:
except Exception as e:
raise Exception(f'error: Cannot add service {service}: {e}')
roxywi_common.logging(cluster_id, f'Cluster {cluster_name} has been updated', keep_history=1, roxywi=1, service='HA cluster')
roxywi_common.logging(cluster_id, f'Cluster {cluster.name} has been updated', keep_history=1, roxywi=1, service='HA cluster')
def delete_cluster(cluster_id: int) -> str:
@ -132,39 +143,37 @@ def delete_cluster(cluster_id: int) -> str:
return 'ok'
def update_vip(cluster_id: int, router_id: int, json_data: json, group_id: int) -> None:
return_master = int(json_data['return_to_master'])
use_src = int(json_data['use_src'])
vip = common.is_ip_or_dns(json_data['vip'])
def update_vip(cluster_id: int, router_id: int, cluster: Union[HAClusterRequest, HAClusterVIP], group_id: int) -> None:
vip_id = ha_sql.select_clusters_vip_id(cluster_id, router_id)
servers = _get_servers_dict(cluster)
try:
ha_sql.update_ha_cluster_vip(cluster_id, router_id, vip, return_master, use_src)
ha_sql.update_ha_cluster_vip(cluster_id, router_id, cluster.vip, cluster.return_master, cluster.use_src)
except Exception as e:
raise Exception(f'error: Cannot update VIP: {e}')
for slave_id, value in json_data['servers'].items():
for value in servers:
try:
ha_sql.update_slave(cluster_id, slave_id, value['eth'], value['master'], router_id)
ha_sql.update_slave(cluster_id, value['id'], value['eth'], value['master'], router_id)
except Exception as e:
raise Exception(f'error: Cannot add server {value["ip"]}: {e}')
if json_data['virt_server']:
add_or_update_virt(json_data, cluster_id, vip_id, group_id)
if cluster.virt_server:
add_or_update_virt(cluster, servers, cluster_id, vip_id, group_id)
else:
try:
if ha_sql.check_ha_virt(vip_id):
ha_sql.delete_ha_virt(vip_id)
roxywi_common.logging(cluster_id, f'Cluster virtual server for VIP: {vip} has been deleted', keep_history=1, roxywi=1, service='HA cluster')
roxywi_common.logging(cluster_id, f'Cluster virtual server for VIP: {cluster.vip} has been deleted', keep_history=1, roxywi=1, service='HA cluster')
except Exception as e:
roxywi_common.logging(cluster_id, f'Cannot delete cluster virtual server for VIP {vip}: {e}', keep_history=1, roxywi=1, service='HA cluster')
roxywi_common.logging(cluster_id, f'Cannot delete cluster virtual server for VIP {cluster.vip}: {e}', keep_history=1, roxywi=1, service='HA cluster')
roxywi_common.logging(cluster_id, f'Cluster VIP {vip} has been updated', keep_history=1, roxywi=1, service='HA cluster')
roxywi_common.logging(cluster_id, f'Cluster VIP {cluster.vip} has been updated', keep_history=1, roxywi=1, service='HA cluster')
def insert_vip(cluster_id: int, json_data: json, group_id: int) -> None:
vip = common.is_ip_or_dns(json_data['vip'])
return_master = int(json_data['return_to_master'])
def insert_vip(cluster_id: int, cluster: HAClusterVIP, group_id: int) -> None:
vip = cluster.vip
servers = _get_servers_dict(cluster)
try:
router_id = ha_sql.create_ha_router(cluster_id)
@ -172,39 +181,38 @@ def insert_vip(cluster_id: int, json_data: json, group_id: int) -> None:
raise Exception(f'error: Cannot create new router: {e}')
try:
vip_id = HaClusterVip.insert(cluster_id=cluster_id, router_id=router_id, vip=vip, return_master=return_master).execute()
vip_id = HaClusterVip.insert(cluster_id=cluster_id, router_id=router_id, vip=vip, return_master=cluster.return_master).execute()
except Exception as e:
raise Exception(f'error: Cannot save VIP {vip}: {e}')
for slave_id, value in json_data['servers'].items():
for value in servers:
try:
ha_sql.insert_or_update_slave(cluster_id, slave_id, value['eth'], value['master'], router_id)
ha_sql.insert_or_update_slave(cluster_id, value['id'], value['eth'], value['master'], router_id)
except Exception as e:
raise Exception(f'error: Cannot add server {value["ip"]}: {e}')
if json_data['virt_server']:
add_or_update_virt(json_data, cluster_id, vip_id, group_id)
if cluster.virt_server:
add_or_update_virt(cluster, servers, cluster_id, vip_id, group_id)
roxywi_common.logging(cluster_id, f'New cluster VIP: {vip} has been created', keep_history=1, roxywi=1, service='HA cluster')
def update_slaves(json_data: json, router_id: int) -> None:
def update_slaves(servers: dict, cluster_id: int, router_id: int) -> None:
master_ip = None
cluster = json_data
cluster_id = int(json_data['cluster_id'])
all_routers_in_cluster = HaClusterRouter.select(HaClusterRouter.id).where(HaClusterRouter.cluster_id == cluster_id).execute()
server_ids_from_db = ha_sql.select_cluster_slaves(cluster_id, router_id)
server_ids = []
server_ids_from_json = []
for _slave_id, value in cluster['servers'].items():
for value in servers:
if value['master']:
master_ip = common.is_ip_or_dns(value['ip'])
master_ip = value['ip']
for server in server_ids_from_db:
server_ids.append(server[0])
for slave_id, value in cluster['servers'].items():
for value in servers:
slave_id = value['id']
if value['master']:
slave_id = server_sql.select_server_id_by_ip(master_ip)
server_ids_from_json.append(int(slave_id))
@ -213,7 +221,8 @@ def update_slaves(json_data: json, router_id: int) -> None:
server_ids_for_adding = set(server_ids_from_json) - set(server_ids)
for router in all_routers_in_cluster:
for slave_id, value in cluster['servers'].items():
for value in servers:
slave_id = value['id']
for server_id_add in server_ids_for_adding:
if int(slave_id) == int(server_id_add):
try:
@ -229,15 +238,16 @@ def update_slaves(json_data: json, router_id: int) -> None:
except Exception as e:
raise Exception(f'error: Cannot recreate slaves server: {e}')
for _slave_id, value in cluster['servers'].items():
for value in servers:
if value['master']:
continue
try:
ha_sql.update_server_master(master_ip, common.is_ip_or_dns((value['ip'])))
ha_sql.update_server_master(master_ip, value['ip'])
except Exception as e:
raise Exception(f'error: Cannot update master on slave {value["ip"]}: {e}')
for slave_id, value in cluster['servers'].items():
for value in servers:
slave_id = value['id']
if value['master']:
slave_id = server_sql.select_server_id_by_ip(master_ip)
try:
@ -246,17 +256,16 @@ def update_slaves(json_data: json, router_id: int) -> None:
raise Exception(f'error: Cannot update server {value["ip"]}: {e}')
def add_or_update_virt(cluster: json, cluster_id: int, vip_id: int, group_id: int) -> None:
def add_or_update_virt(cluster: Union[HAClusterRequest, HAClusterVIP], servers: dict, cluster_id: int, vip_id: int, group_id: int) -> None:
haproxy = 0
nginx = 0
apache = 0
master_ip = None
vip = common.is_ip_or_dns(cluster['vip'])
cluster_name = common.checkAjaxInput(cluster['name'])
vip = cluster.vip
for _slave_id, value in cluster['servers'].items():
for value in servers:
if value['master']:
master_ip = common.is_ip_or_dns(value['ip'])
master_ip = value['ip']
if ha_sql.check_ha_virt(vip_id):
try:
@ -276,7 +285,7 @@ def add_or_update_virt(cluster: json, cluster_id: int, vip_id: int, group_id: in
ssh_settings = return_ssh_keys_path(master_ip)
virt_id = server_sql.add_server(
f'{vip}-VIP', vip, group_id, '1', '1', '0', cred_id, ssh_settings['port'],
f'VRRP IP for {cluster_name} cluster', haproxy, nginx, apache, firewall
f'VRRP IP for {cluster.name} cluster', haproxy, nginx, apache, firewall
)
HaClusterVirt.insert(cluster_id=cluster_id, virt_id=virt_id, vip_id=vip_id).execute()
roxywi_common.logging(cluster_id, f'New cluster virtual server for VIP: {vip} has been created', keep_history=1, roxywi=1,

View File

@ -234,12 +234,12 @@ def show_map(serv: str) -> str:
nx.draw_networkx_edge_labels(G, pos, alpha=0.4, label_pos=0.5, font_color="#5d9ceb", edge_labels=edge_labels,
font_size=8)
plt.savefig("/var/www/haproxy-wi/map.png")
plt.savefig("/var/www/haproxy-wi/app/static/map.png")
plt.show()
except Exception as e:
return f'error: Cannot create a map: {e}'
output += '<img src="/map.png" alt="map"></center>'
output += '<img src="/static/map.png" alt="map"></center>'
return output

View File

@ -1,5 +1,7 @@
import os
import json
from typing import Union
from packaging import version
import ansible
@ -15,6 +17,7 @@ import app.modules.common.common as common
import app.modules.server.server as server_mod
import app.modules.roxywi.common as roxywi_common
from app.modules.server.ssh import return_ssh_keys_path
from app.modules.roxywi.class_models import ServiceInstall
def generate_udp_inv(listener_id: int, action: str) -> object:
@ -26,7 +29,6 @@ def generate_udp_inv(listener_id: int, action: str) -> object:
elif listener['server_id']:
server = server_sql.get_server_by_id(listener['server_id'])
server_ips.append(server.ip)
for server_ip in server_ips:
inv['server']['hosts'][server_ip] = {
'action': action,
@ -66,6 +68,7 @@ def generate_grafana_inv() -> object:
def generate_kp_inv(json_data: json, installed_service) -> object:
inv = {"server": {"hosts": {}}}
server_ips = []
print(json_data)
cluster_id = int(json_data['cluster_id'])
haproxy = json_data['services']['haproxy']['enabled']
nginx = json_data['services']['nginx']['enabled']
@ -88,7 +91,7 @@ def generate_kp_inv(json_data: json, installed_service) -> object:
routers[router_id][slave_ip].setdefault('master', slave.master)
routers[router_id][slave_ip].setdefault('eth', slave.eth)
for k, v in json_data['servers'].items():
for v in json_data['servers']:
server_ip = v['ip']
inv['server']['hosts'][server_ip] = {
"HAPROXY": haproxy,
@ -116,7 +119,7 @@ def generate_waf_inv(server_ip: str, installed_service: str) -> object:
return inv, server_ips
def generate_haproxy_inv(json_data: json, installed_service: str) -> object:
def generate_haproxy_inv(json_data: ServiceInstall, installed_service: str) -> object:
inv = {"server": {"hosts": {}}}
slaves = []
server_ips = []
@ -130,13 +133,13 @@ def generate_haproxy_inv(json_data: json, installed_service: str) -> object:
container_name = sql.get_setting('haproxy_container_name')
haproxy_ver = '2.9.6-1'
is_docker = json_data['services']['haproxy']['docker']
for k, v in json_data['servers'].items():
for v in json_data['servers']:
if not v['master']:
slaves.append(v['ip'])
else:
master_ip = v['ip']
for k, v in json_data['servers'].items():
for v in json_data['servers']:
server_ip = v['ip']
is_master = v['master']
@ -163,7 +166,7 @@ def generate_haproxy_inv(json_data: json, installed_service: str) -> object:
return inv, server_ips
def generate_service_inv(json_data: json, installed_service: str) -> object:
def generate_service_inv(json_data: ServiceInstall, installed_service: str) -> object:
inv = {"server": {"hosts": {}}}
server_ips = []
stats_user = sql.get_setting(f'{installed_service}_stats_user')
@ -204,7 +207,7 @@ def generate_service_inv(json_data: json, installed_service: str) -> object:
return inv, server_ips
def run_ansible(inv: dict, server_ips: list, ansible_role: str) -> object:
def run_ansible(inv: dict, server_ips: list, ansible_role: str) -> dict:
inventory_path = '/var/www/haproxy-wi/app/scripts/ansible/inventory'
inventory = f'{inventory_path}/{ansible_role}.json'
proxy = sql.get_setting('proxy')
@ -325,7 +328,7 @@ def service_actions_after_install(server_ips: str, service: str, json_data) -> N
service_sql.insert_or_update_service_setting(server_id, service, 'restart', '1')
def install_service(service: str, json_data: str) -> object:
def install_service(service: str, json_data: Union[str, ServiceInstall]) -> dict:
generate_functions = {
'haproxy': generate_haproxy_inv,
'nginx': generate_service_inv,
@ -333,13 +336,14 @@ def install_service(service: str, json_data: str) -> object:
'keepalived': generate_kp_inv,
}
json_data = json_data.model_dump(mode='json')
try:
inv, server_ips = generate_functions[service](json_data, service)
except Exception as e:
roxywi_common.handle_exceptions(e, 'Roxy-WI server', f'Cannot generate inv {service}', roxywi=1)
try:
service_actions_after_install(server_ips, service, json_data)
return run_ansible(inv, server_ips, service), 201
return run_ansible(inv, server_ips, service)
except Exception as e:
roxywi_common.handle_exceptions(e, 'Roxy-WI server', f'Cannot install {service}', roxywi=1)

View File

@ -1,94 +1,15 @@
import json
from playhouse.shortcuts import model_to_dict
import app.modules.db.udp as udp_sql
import app.modules.db.server as server_sql
import app.modules.db.ha_cluster as ha_sql
import app.modules.common.common as common
import app.modules.server.server as server_mod
import app.modules.roxywi.common as roxywi_common
def create_listener(json_data: json) -> int:
listener = _validate_form(json_data)
listener_id = udp_sql.insert_listener(**listener)
roxywi_common.logging(listener_id, f'UDP listener {listener["name"]} has been created', keep_history=1, roxywi=1, service='UDP Listener')
return listener_id
def update_listener(json_data: json) -> str:
listener = _validate_form(json_data)
listener_id = json_data['listener_id']
udp_sql.update_listener(listener_id, **listener)
roxywi_common.logging(listener_id, f'UDP listener {listener["name"]} has been updated', keep_history=1, roxywi=1, service='UDP Listener')
return 'ok'
def _validate_form(json_data: json) -> dict:
returned_data = {}
if not isinstance(json_data, dict):
raise ValueError("error: Invalid form data")
returned_data['name'] = common.checkAjaxInput(json_data['new-listener-name'])
returned_data['desc'] = common.checkAjaxInput(json_data['new-listener-desc'])
returned_data['lb_algo'] = common.checkAjaxInput(json_data['new-udp-balancer-type'])
try:
returned_data['port'] = int(json_data['new-listener-port'])
except Exception:
raise ValueError("error: Invalid port number")
returned_data['group_id'] = int(json_data['group_id'])
returned_data['config'] = {}
for k, v in json_data.items():
if k == 'servers':
_validate_backend_servers(v)
for server, value in v.items():
server_ip = common.is_ip_or_dns(server)
returned_data['config'][server_ip] = {}
returned_data['config'][server_ip]['port'] = int(value['port'])
returned_data['config'][server_ip]['weight'] = int(value['weight'])
if json_data['new-listener-type'] == 'server':
returned_data['server_id'] = int(json_data['serv'])
try:
returned_data['vip'] = common.is_ip_or_dns(json_data['new-udp-ip'])
except ValueError:
raise ValueError("error: Cannot parse Server and IP")
else:
try:
cluster_id = int(json_data['ha-cluster'])
returned_data['cluster_id'] = cluster_id
except ValueError:
raise ValueError("error: Cannot parse Cluster ID")
returned_data['vip'] = common.is_ip_or_dns(json_data['new-udp-vip'])
return returned_data
def _validate_backend_servers(serves: dict):
if not isinstance(serves, dict):
raise ValueError("error: Invalid backend servers data")
if len(serves) == 0:
raise ValueError("error: Empty backend servers")
for server, value in serves.items():
server = common.is_ip_or_dns(server)
if server == '':
raise ValueError("error: Cannot parse backend server IP")
try:
port = int(value['port'])
except ValueError:
raise ValueError(f"error: Invalid port for backend server {server}")
if port > 65535 or port < 1:
raise Exception(f'error: Port must be 1-65535 for backend server {server}')
try:
weight = int(value['weight'])
except ValueError:
raise ValueError(f"error: Invalid weight for backend server {server}")
if weight > 65535 or weight < 1:
raise Exception(f'error: Weight must be 1-65535 for backend server {server}')
def get_listener_config(listener_id: int) -> dict:
listener = udp_sql.get_listener(listener_id)
listener_json = model_to_dict(listener)
listener_json = model_to_dict(listener, recurse=False)
listener_json['config'] = eval(listener_json['config'])
return listener_json
@ -111,7 +32,7 @@ def get_slaves_for_udp_listener(cluster_id: int, vip: str) -> list:
def _return_listener_servers(listener_id: int, group_id=None):
servers = []
listener = udp_sql.get_listener(listener_id)
if group_id is not None and int(listener.group_id.group_id) != group_id:
if group_id is not None and int(listener.group_id.group_id) != int(group_id):
raise ValueError("error: Invalid group")
if listener.cluster_id:
servers = get_slaves_for_udp_listener(listener.cluster_id, listener.vip)
@ -125,10 +46,7 @@ def _return_listener_servers(listener_id: int, group_id=None):
def listener_actions(listener_id: int, action: str, group_id: int) -> str:
if action not in ('start', 'stop', 'restart'):
raise ValueError("error: Invalid action")
def listener_actions(listener_id: int, action: str, group_id: int) -> None:
cmd = f'sudo systemctl {action} keepalived-udp-{listener_id}.service'
try:
servers, listener = _return_listener_servers(listener_id, group_id)
@ -141,7 +59,6 @@ def listener_actions(listener_id: int, action: str, group_id: int) -> str:
roxywi_common.logging(listener.id, f'UDP listener {listener.name} has been {action} on {server_ip}', keep_history=1, roxywi=1, service='UDP Listener')
except Exception as e:
roxywi_common.handle_exceptions(e, 'Roxy-WI server', f'Cannot {action} for UDP balancer {listener.name}', roxywi=1)
return 'ok'
def check_is_listener_active(listener_id: int) -> str:

View File

@ -5,7 +5,7 @@ import pdpyras
import requests
import telebot
from telebot import apihelper
from flask import render_template, request, abort
from flask import render_template, request, abort, g
import app.modules.db.sql as sql
import app.modules.db.user as user_sql
@ -176,9 +176,9 @@ def telegram_send_mess(mess, level, **kwargs):
return
if kwargs.get('channel_id'):
telegrams = channel_sql.get_telegram_by_id(kwargs.get('channel_id'))
telegrams = channel_sql.get_receiver_by_id('telegram', kwargs.get('channel_id'))
else:
telegrams = channel_sql.get_telegram_by_ip(kwargs.get('ip'))
telegrams = channel_sql.get_receiver_by_ip('telegram', kwargs.get('ip'))
proxy = sql.get_setting('proxy')
@ -210,9 +210,9 @@ def slack_send_mess(mess, level, **kwargs):
return
if kwargs.get('channel_id'):
slacks = channel_sql.get_slack_by_id(kwargs.get('channel_id'))
slacks = channel_sql.get_receiver_by_id('slack', kwargs.get('channel_id'))
else:
slacks = channel_sql.get_slack_by_ip(kwargs.get('ip'))
slacks = channel_sql.get_receiver_by_ip('slack', kwargs.get('ip'))
proxy = sql.get_setting('proxy')
@ -241,12 +241,12 @@ def pd_send_mess(mess, level, server_ip=None, service_id=None, alert_type=None,
if kwargs.get('channel_id'):
try:
pds = channel_sql.get_pd_by_id(kwargs.get('channel_id'))
pds = channel_sql.get_receiver_by_id('pd', kwargs.get('channel_id'))
except Exception as e:
print(e)
else:
try:
pds = channel_sql.get_pd_by_ip(kwargs.get('ip'))
pds = channel_sql.get_receiver_by_ip('pd', kwargs.get('ip'))
except Exception as e:
print(e)
@ -283,12 +283,12 @@ def mm_send_mess(mess, level, server_ip=None, service_id=None, alert_type=None,
if kwargs.get('channel_id'):
try:
mms = channel_sql.get_mm_by_id(kwargs.get('channel_id'))
mms = channel_sql.get_receiver_by_id('mm', kwargs.get('channel_id'))
except Exception as e:
print(e)
else:
try:
mms = channel_sql.get_mm_by_ip(kwargs.get('ip'))
mms = channel_sql.get_receiver_by_ip('mm', kwargs.get('ip'))
except Exception as e:
print(e)
@ -343,164 +343,48 @@ def check_rabbit_alert() -> None:
raise Exception(f'Cannot send message {e}')
def check_email_alert() -> None:
def check_email_alert() -> str:
subject = 'test message'
message = 'Test message from Roxy-WI'
try:
user_uuid = request.cookies.get('uuid')
user = user_sql.get_user_id(g.user_params['user_id'])
except Exception as e:
raise Exception(f'Cannot send a message {e}')
return f'error: Cannot get a user email: {e}'
try:
user_email = user_sql.select_user_email_by_uuid(user_uuid)
send_email(user.email, subject, message)
except Exception as e:
raise Exception(f'Cannot get a user email: {e}')
return f'error: Cannot send a message {e}'
try:
send_email(user_email, subject, message)
except Exception as e:
raise Exception('Cannot send a message {e}')
return 'ok'
def add_telegram_channel(token: str, channel: str, group: str) -> str:
if token is None or channel is None or group is None:
return error_mess
def add_receiver(receiver: str, token: str, channel: str, group: str, is_api=False) -> str:
last_id = channel_sql.insert_new_receiver(receiver, token, channel, group)
if is_api:
return last_id
else:
if channel_sql.insert_new_telegram(token, channel, group):
lang = roxywi_common.get_user_lang_for_flask()
channels = channel_sql.select_telegram(token=token)
groups = group_sql.select_groups()
roxywi_common.logging('Roxy-WI server', f'A new Telegram channel {channel} has been created ', roxywi=1, login=1)
return render_template('ajax/new_receiver.html', groups=groups, lang=lang, channels=channels, receiver='telegram')
def add_slack_channel(token: str, channel: str, group: str) -> str:
if token is None or channel is None or group is None:
return error_mess
else:
if channel_sql.insert_new_slack(token, channel, group):
lang = roxywi_common.get_user_lang_for_flask()
channels = channel_sql.select_slack(token=token)
groups = group_sql.select_groups()
roxywi_common.logging('Roxy-WI server', f'A new Slack channel {channel} has been created ', roxywi=1, login=1)
return render_template('ajax/new_receiver.html', groups=groups, lang=lang, channels=channels, receiver='slack')
def add_pd_channel(token: str, channel: str, group: str) -> str:
if token is None or channel is None or group is None:
return error_mess
else:
if channel_sql.insert_new_pd(token, channel, group):
lang = roxywi_common.get_user_lang_for_flask()
channels = channel_sql.select_pd(token=token)
groups = group_sql.select_groups()
roxywi_common.logging('Roxy-WI server', f'A new PagerDuty channel {channel} has been created ', roxywi=1, login=1)
return render_template('ajax/new_receiver.html', groups=groups, lang=lang, channels=channels, receiver='pd')
def add_mm_channel(token: str, channel: str, group: str) -> str:
if token is None or channel is None or group is None:
return error_mess
else:
if channel_sql.insert_new_mm(token, channel, group):
lang = roxywi_common.get_user_lang_for_flask()
channels = channel_sql.select_mm(token=token)
groups = group_sql.select_groups()
roxywi_common.logging('Roxy-WI server', f'A new Mattermost channel {channel} has been created ', roxywi=1, login=1)
return render_template('ajax/new_receiver.html', groups=groups, lang=lang, channels=channels, receiver='mm')
def delete_telegram_channel(channel_id) -> str:
telegram = channel_sql.select_telegram(id=channel_id)
channel_name = ''
for t in telegram:
channel_name = t.token
if channel_sql.delete_telegram(channel_id):
roxywi_common.logging('Roxy-WI server', f'The Telegram channel {channel_name} has been deleted ', roxywi=1, login=1)
return 'ok'
def delete_slack_channel(channel_id) -> None:
slack = channel_sql.select_slack(id=channel_id)
channel_name = ''
for t in slack:
channel_name = t.chanel_name
if channel_sql.delete_slack(channel_id):
roxywi_common.logging('Roxy-WI server', f'The Slack channel {channel_name} has been deleted ', roxywi=1, login=1)
def delete_pd_channel(channel_id) -> None:
pd = channel_sql.select_pd(id=channel_id)
channel_name = ''
for t in pd:
channel_name = t.chanel_name
if channel_sql.delete_pd(channel_id):
roxywi_common.logging('Roxy-WI server', f'The PageDuty channel {channel_name} has been deleted ', roxywi=1, login=1)
def delete_mm_channel(channel_id) -> None:
pd = channel_sql.select_mm(id=channel_id)
channel_name = ''
for t in pd:
channel_name = t.chanel_name
if channel_sql.delete_mm(channel_id):
roxywi_common.logging('Roxy-WI server', f'The Mattermost channel {channel_name} has been deleted ', roxywi=1, login=1)
def update_telegram(token: str, channel: str, group: int, user_id: int) -> None:
channel_sql.update_telegram(token, channel, group, user_id)
roxywi_common.logging(f'group {group}', f'The Telegram token has been updated for channel: {channel}', roxywi=1, login=1)
def update_slack(token: str, channel: str, group: int, user_id: int) -> None:
channel_sql.update_slack(token, channel, group, user_id)
roxywi_common.logging(f'group {group}', f'The Slack token has been updated for channel: {channel}', roxywi=1, login=1)
def update_pd(token: str, channel: str, group: int, user_id: int) -> None:
channel_sql.update_pd(token, channel, group, user_id)
roxywi_common.logging(f'group {group}', f'The PagerDuty token has been updated for channel: {channel}', roxywi=1, login=1)
def update_mm(token: str, channel: str, group: int, user_id: int) -> None:
channel_sql.update_mm(token, channel, group, user_id)
roxywi_common.logging(f'group {group}', f'The Mattermost token has been updated for channel: {channel}', roxywi=1, login=1)
lang = roxywi_common.get_user_lang_for_flask()
new_channel = channel_sql.select_receiver(receiver, last_id)
groups = group_sql.select_groups()
roxywi_common.logging('Roxy-WI server', f'A new {receiver.title()} channel {channel} has been created ', roxywi=1, login=1)
return render_template('ajax/new_receiver.html', groups=groups, lang=lang, channel=new_channel, receiver=receiver)
def delete_receiver_channel(channel_id: int, receiver_name: str) -> None:
delete_functions = {
"telegram": delete_telegram_channel,
"slack": delete_slack_channel,
"pd": delete_pd_channel,
"mm": delete_mm_channel,
}
return delete_functions[receiver_name](channel_id)
def add_receiver_channel(receiver_name: str, token: str, channel: str, group: id) -> str:
add_functions = {
"telegram": add_telegram_channel,
"slack": add_slack_channel,
"pd": add_pd_channel,
"mm": add_mm_channel,
}
try:
return add_functions[receiver_name](token, channel, group)
channel_sql.delete_receiver(receiver_name, channel_id)
except Exception as e:
raise Exception(e)
raise e
def update_receiver_channel(receiver_name: str, token: str, channel: str, group: id, user_id: int) -> None:
update_functions = {
"telegram": update_telegram,
"slack": update_slack,
"pd": update_pd,
"mm": update_mm,
}
return update_functions[receiver_name](token, channel, group, user_id)
def update_receiver_channel(receiver_name: str, token: str, channel: str, group: id, channel_id: int) -> None:
try:
channel_sql.update_receiver(receiver_name, token, channel, group, channel_id)
except Exception as e:
raise e
def check_receiver(channel_id: int, receiver_name: str) -> None:
@ -543,11 +427,11 @@ def load_channels():
if user_subscription['user_status']:
user_group = roxywi_common.get_user_group(id=1)
kwargs.setdefault('telegrams', channel_sql.get_user_telegram_by_group(user_group))
kwargs.setdefault('pds', channel_sql.get_user_pd_by_group(user_group))
kwargs.setdefault('mms', channel_sql.get_user_mm_by_group(user_group))
kwargs.setdefault('telegrams', channel_sql.get_user_receiver_by_group('telegram', user_group))
kwargs.setdefault('pds', channel_sql.get_user_receiver_by_group('pd', user_group))
kwargs.setdefault('mms', channel_sql.get_user_receiver_by_group('mm', user_group))
kwargs.setdefault('groups', group_sql.select_groups())
kwargs.setdefault('slacks', channel_sql.get_user_slack_by_group(user_group))
kwargs.setdefault('slacks', channel_sql.get_user_receiver_by_group('slack', user_group))
kwargs.setdefault('user_subscription', user_subscription)
kwargs.setdefault('user_params', user_params)
kwargs.setdefault('lang', user_params['lang'])

View File

@ -28,11 +28,11 @@ def load_checker() -> str:
if user_subscription['user_status']:
user_group = roxywi_common.get_user_group(id=1)
kwargs.setdefault('services', tools_common.get_services_status())
kwargs.setdefault('telegrams', channel_sql.get_user_telegram_by_group(user_group))
kwargs.setdefault('pds', channel_sql.get_user_pd_by_group(user_group))
kwargs.setdefault('mms', channel_sql.get_user_mm_by_group(user_group))
kwargs.setdefault('telegrams', channel_sql.get_user_receiver_by_group('telegram', user_group))
kwargs.setdefault('pds', channel_sql.get_user_receiver_by_group('pd', user_group))
kwargs.setdefault('mms', channel_sql.get_user_receiver_by_group('mm', user_group))
kwargs.setdefault('groups', group_sql.select_groups())
kwargs.setdefault('slacks', channel_sql.get_user_slack_by_group(user_group))
kwargs.setdefault('slacks', channel_sql.get_user_receiver_by_group('slack', user_group))
kwargs.setdefault('haproxy_servers', roxywi_common.get_dick_permit(haproxy=1, only_group=1))
kwargs.setdefault('nginx_servers', roxywi_common.get_dick_permit(nginx=1, only_group=1))
kwargs.setdefault('apache_servers', roxywi_common.get_dick_permit(apache=1, only_group=1))

View File

@ -1,7 +1,7 @@
import os
from flask import render_template, request, jsonify, redirect, url_for, g
from flask_login import login_required
from flask_jwt_extended import jwt_required, get_jwt
from app.routes.add import bp
import app.modules.db.sql as sql
@ -17,7 +17,7 @@ get_config = roxy_wi_tools.GetConfigVar()
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass
@ -41,7 +41,8 @@ def add(service):
}
if service == 'haproxy':
user_group = request.cookies.get('group')
claims = get_jwt()
user_group = claims['group']
lib_path = get_config.get_config_var('main', 'lib_path')
list_dir = lib_path + "/lists"
white_dir = lib_path + "/lists/" + user_group + "/white"

View File

@ -1,6 +1,6 @@
import pytz
from flask import render_template, request, g
from flask_login import login_required
from flask_jwt_extended import jwt_required
from app import scheduler
from app.routes.admin import bp
@ -16,10 +16,17 @@ 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
from app.views.admin.views import SettingsView
bp.add_url_rule(
'/settings/<any(smon, main, haproxy, nginx, apache, keepalived, rabbitmq, ldap, monitoring, mail, logs):section>',
view_func=SettingsView.as_view('settings'),
methods=['GET', 'POST']
)
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass
@ -38,7 +45,7 @@ def admin():
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_uuid'])
masters = server_sql.select_servers(get_master_servers=1, uuid=g.user_params['user_id'])
sshs = cred_sql.select_ssh(group=user_group)
kwargs = {
@ -115,7 +122,7 @@ def check_update():
@get_user_params()
def get_settings():
kwargs = {
'settings': sql.get_setting('', all=1),
'settings': sql.get_setting('', all=1, group_id=g.user_params['group_id']),
'timezones': pytz.all_timezones,
}
return render_template('include/admin_settings.html', **kwargs)
@ -126,13 +133,16 @@ def update_settings(param):
roxywi_auth.page_for_admin(level=2)
val = request.form.get('val').replace('92', '/')
user_group = roxywi_common.get_user_group(id=1)
if sql.update_setting(param, val, user_group):
roxywi_common.logging('Roxy-WI server', f'The {param} setting has been changed to: {val}', roxywi=1, login=1)
try:
sql.update_setting(param, val, user_group)
except Exception as e:
roxywi_common.handle_json_exceptions(e, 'Cannot update settings')
roxywi_common.logging('Roxy-WI server', f'The {param} setting has been changed to: {val}', roxywi=1, login=1)
if param == 'master_port':
try:
smon_mod.change_smon_port(val)
except Exception as e:
return f'{e}'
if param == 'master_port':
try:
smon_mod.change_smon_port(int(val))
except Exception as e:
return f'{e}'
return 'Ok'

View File

@ -1,15 +1,24 @@
from flask import request, render_template, g, jsonify
from flask_login import login_required
from flask_jwt_extended import jwt_required
from app.routes.channel import bp
from app.middleware import get_user_params
import app.modules.common.common as common
import app.modules.tools.alerting as alerting
import app.modules.roxywi.common as roxywi_common
from app.views.channel.views import ChannelView
def register_api_channel(view, endpoint, url_beg, pk='receiver', pk_type='int', pk_end='channel_id', pk_type_end='int'):
view_func = view.as_view(endpoint, False)
bp.add_url_rule(f'/{url_beg}/<any(telegram, slack, pd, mm):{pk}>', view_func=view_func, methods=['POST'])
bp.add_url_rule(f'/{url_beg}/<any(telegram, slack, pd, mm):{pk}>/<{pk_type_end}:{pk_end}>', view_func=view_func, methods=['PUT', 'DELETE', 'GET', 'PATCH'])
register_api_channel(ChannelView, 'channel', '')
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass
@ -33,15 +42,15 @@ def load_channels():
return f'{e}'
@bp.route('/check/<int:channel_id>/<receiver_name>')
def check_receiver(channel_id, receiver_name):
receiver_name = common.checkAjaxInput(receiver_name)
try:
alerting.check_receiver(channel_id, receiver_name)
return jsonify({'status': 'success'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, f'Cannot send message via {receiver_name}')
# @bp.route('/check/<int:channel_id>/<receiver_name>')
# def check_receiver(channel_id, receiver_name):
# receiver_name = common.checkAjaxInput(receiver_name)
#
# try:
# alerting.check_receiver(channel_id, receiver_name)
# return jsonify({'status': 'success'})
# except Exception as e:
# return roxywi_common.handle_json_exceptions(e, f'Cannot send message via {receiver_name}')
@bp.post('/check')
@ -57,37 +66,3 @@ def check_sender():
return jsonify({'status': 'success'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, f'Cannot send message via {sender.title()}')
@bp.route('/receiver/<receiver_name>', methods=['PUT', 'POST', 'DELETE'])
@get_user_params()
def receiver(receiver_name):
json_data = request.get_json()
if request.method == 'POST':
token = common.checkAjaxInput(json_data['receiver'])
channel = common.checkAjaxInput(json_data['channel'])
group = int(json_data['group'])
try:
data = alerting.add_receiver_channel(receiver_name, token, channel, group)
return jsonify({'status': 'updated', 'data': data})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, f'Cannot create {receiver_name} channel')
elif request.method == 'PUT':
token = common.checkAjaxInput(json_data['receiver_token'])
channel = common.checkAjaxInput(json_data['channel'])
group = int(json_data['group'])
user_id = int(json_data['id'])
try:
alerting.update_receiver_channel(receiver_name, token, channel, group, user_id)
return jsonify({'status': 'updated'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, f'Cannot update {receiver_name} channel')
elif request.method == 'DELETE':
channel_id = int(json_data['channel_id'])
try:
alerting.delete_receiver_channel(channel_id, receiver_name)
return jsonify({'status': 'deleted'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, f'Cannot delete {receiver_name} channel')

View File

@ -1,5 +1,5 @@
from flask import render_template, request, g
from flask_login import login_required
from flask_jwt_extended import jwt_required
from app.routes.checker import bp
from app.middleware import get_user_params
@ -9,7 +9,7 @@ import app.modules.tools.checker as checker_mod
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass

View File

@ -1,11 +1,10 @@
import os
from flask import render_template, request, g
from flask_login import login_required
from flask_jwt_extended import jwt_required, get_jwt
from app.routes.config import bp
import app.modules.db.sql as sql
import app.modules.db.user as user_sql
import app.modules.db.config as config_sql
import app.modules.db.server as server_sql
import app.modules.db.service as service_sql
@ -18,10 +17,14 @@ import app.modules.config.common as config_common
import app.modules.config.section as section_mod
import app.modules.service.haproxy as service_haproxy
import app.modules.server.server as server_mod
from app.views.service.views import ServiceConfigView
bp.add_url_rule('/<service>/<server_id>', view_func=ServiceConfigView.as_view('config_view_ip'), methods=['POST'])
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass
@ -33,8 +36,9 @@ def show_config(service):
config_file_name = request.form.get('config_file_name')
configver = request.form.get('configver')
server_ip = request.form.get('serv')
claims = get_jwt()
return config_mod.show_config(server_ip, service, config_file_name, configver)
return config_mod.show_config(server_ip, service, config_file_name, configver, claims)
@bp.route('/<service>/show-files', methods=['POST'])
@ -132,43 +136,43 @@ def config(service, serv, edit, config_file_name, new):
return render_template('config.html', **kwargs)
@bp.route('/<service>/<server_ip>/save', methods=['POST'])
@check_services
@get_user_params()
def save_config(service, server_ip):
roxywi_common.check_is_server_in_group(server_ip)
config_file = request.form.get('config')
oldcfg = request.form.get('oldconfig')
save = request.form.get('save')
config_file_name = request.form.get('config_file_name')
try:
cfg = config_mod.return_cfg(service, server_ip, config_file_name)
except Exception as e:
return f'error: Cannot get config {e}'
try:
with open(cfg, "a") as conf:
conf.write(config_file)
except IOError as e:
return f"error: Cannot read imported config file: {e}", 200
try:
if service == 'keepalived':
stderr = config_mod.upload_and_restart(server_ip, cfg, save, service, oldcfg=oldcfg)
else:
stderr = config_mod.master_slave_upload_and_restart(server_ip, cfg, save, service, oldcfg=oldcfg,
config_file_name=config_file_name)
except Exception as e:
return f'error: {e}', 200
if save != 'test':
config_mod.diff_config(oldcfg, cfg)
if stderr:
return stderr, 200
return
# @bp.route('/<service>/<server_ip>/save', methods=['POST'])
# @check_services
# @get_user_params()
# def save_config(service, server_ip):
# roxywi_common.check_is_server_in_group(server_ip)
# config_file = request.form.get('config')
# oldcfg = request.form.get('oldconfig')
# save = request.form.get('save')
# config_file_name = request.form.get('config_file_name')
#
# try:
# cfg = config_mod.return_cfg(service, server_ip, config_file_name)
# except Exception as e:
# return f'error: Cannot get config {e}'
#
# try:
# with open(cfg, "a") as conf:
# conf.write(config_file)
# except IOError as e:
# return f"error: Cannot read imported config file: {e}", 200
#
# try:
# if service == 'keepalived':
# stderr = config_mod.upload_and_restart(server_ip, cfg, save, service, oldcfg=oldcfg)
# else:
# stderr = config_mod.master_slave_upload_and_restart(server_ip, cfg, save, service, oldcfg=oldcfg,
# config_file_name=config_file_name)
# except Exception as e:
# return f'error: {e}', 200
#
# if save != 'test':
# config_mod.diff_config(oldcfg, cfg)
#
# if stderr:
# return stderr, 200
#
# return
@bp.route('/versions/<service>', defaults={'server_ip': None}, methods=['GET', 'POST'])
@ -177,15 +181,15 @@ def save_config(service, server_ip):
@get_user_params(disable=1)
def versions(service, server_ip):
roxywi_auth.page_for_admin(level=3)
aftersave = ''
after_save = ''
file = set()
stderr = ''
file_fortmat = config_common.get_file_format(service)
file_format = config_common.get_file_format(service)
if request.form.get('del'):
aftersave = 1
after_save = 1
for get in request.form.getlist('do_delete'):
if file_fortmat in get and server_ip in get:
if file_format in get and server_ip in get:
try:
if config_sql.delete_config_version(service, get):
try:
@ -209,7 +213,7 @@ def versions(service, server_ip):
kwargs = {
'serv': server_ip,
'aftersave': aftersave,
'aftersave': after_save,
'file': file,
'service': service,
'stderr': stderr,
@ -222,10 +226,10 @@ def versions(service, server_ip):
@check_services
def list_of_version(service):
server_ip = common.is_ip_or_dns(request.form.get('serv'))
configver = common.checkAjaxInput(request.form.get('configver'))
config_ver = common.checkAjaxInput(request.form.get('configver'))
for_delver = common.checkAjaxInput(request.form.get('for_delver'))
return config_mod.list_of_versions(server_ip, service, configver, for_delver)
return config_mod.list_of_versions(server_ip, service, config_ver, for_delver)
@bp.route('/versions/<service>/<server_ip>/<configver>', defaults={'save': None}, methods=['GET', 'POST'])

View File

@ -1,64 +1,37 @@
from flask import render_template, g, request, jsonify
from flask_login import login_required
from playhouse.shortcuts import model_to_dict
from flask import render_template, g, request
from flask_jwt_extended import jwt_required
from app.routes.ha import bp
from app.middleware import get_user_params, check_services
import app.modules.db.ha_cluster as ha_sql
import app.modules.db.server as server_sql
import app.modules.db.service as service_sql
import app.modules.common.common as common
import app.modules.server.server as server_mod
import app.modules.roxywi.common as roxywi_common
import app.modules.service.keepalived as keepalived
import app.modules.service.ha_cluster as ha_cluster
from app.views.ha.views import HAView, HAVIPView, HAVIPsView
# 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=['GET'], defaults={pk: None})
# 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'])
# register_api(HAView, 'ha_cluster', '/<service>', 'cluster_id')
# bp.add_url_rule('/<service>/<int:cluster_id>/vip/<int:router_id>', view_func=HAVIPView.as_view('ha_vip_g'), methods=['GET'])
bp.add_url_rule('/<service>', view_func=HAView.as_view('ha_cluster'), methods=['GET'], defaults={'cluster_id': None})
# bp.add_url_rule('/<service>/<int:router_id>/vip', view_func=HAVIPView.as_view('ha_vip_d'), methods=['DELETE'])
# bp.add_url_rule('/<service>/<int:cluster_id>/vips', view_func=HAVIPsView.as_view('ha_vips'), methods=['GET'])
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass
@bp.route('/<service>', methods=['GET', 'POST', 'PUT', 'DELETE'])
@check_services
@get_user_params()
def cluster_function(service):
group_id = g.user_params['group_id']
if request.method == 'GET':
kwargs = {
'clusters': ha_sql.select_clusters(group_id),
'is_needed_tool': common.is_tool('ansible'),
'user_subscription': roxywi_common.return_user_subscription(),
'lang': g.user_params['lang'],
}
return render_template('ha_cluster.html', **kwargs)
elif request.method == 'PUT':
cluster = request.get_json()
try:
ha_cluster.update_cluster(cluster, group_id)
return jsonify({'status': 'updated'})
except Exception as e:
return jsonify({'status': 'failed', 'error': f'Cannot update the cluster: {e}'})
elif request.method == 'POST':
cluster = request.get_json()
try:
cluster_id = ha_cluster.create_cluster(cluster, group_id)
return jsonify({'status': 'created', 'cluster_id': cluster_id})
except Exception as e:
return jsonify({'status': 'failed', 'error': f'Cannot create a cluster: {e}'})
elif request.method == 'DELETE':
cluster_id = int(request.form.get('cluster_id'))
try:
return ha_cluster.delete_cluster(cluster_id)
except Exception as e:
return jsonify({'status': 'failed', 'error': f'Cannot delete the cluster: {e}'})
@bp.route('/<service>/get/<int:cluster_id>')
@check_services
@get_user_params()
@ -80,41 +53,6 @@ def get_ha_cluster(service, cluster_id):
return render_template('ajax/ha/clusters.html', **kwargs)
@bp.route('/<service>/settings/<int:cluster_id>')
@check_services
@get_user_params()
def get_cluster_settings(service, cluster_id):
settings = {}
clusters = ha_sql.select_cluster(cluster_id)
router_id = ha_sql.get_router_id(cluster_id, default_router=1)
slaves = ha_sql.select_cluster_slaves(cluster_id, router_id)
cluster_services = ha_sql.select_cluster_services(cluster_id)
vip = ha_sql.select_cluster_vip(cluster_id, router_id)
is_virt = ha_sql.check_ha_virt(vip.id)
for cluster in clusters:
settings.setdefault('name', cluster.name)
settings.setdefault('desc', cluster.desc)
settings.setdefault('return_to_master', vip.return_master)
settings.setdefault('syn_flood', cluster.syn_flood)
settings.setdefault('vip', vip.vip)
settings.setdefault('virt_server', is_virt)
settings.setdefault('use_src', vip.use_src)
for slave in slaves:
if slave[31]:
settings.setdefault('eth', slave[32])
for c_s in cluster_services:
if int(c_s.service_id) == 1:
settings.setdefault('haproxy', 1)
elif int(c_s.service_id) == 2:
settings.setdefault('nginx', 1)
elif int(c_s.service_id) == 4:
settings.setdefault('apache', 1)
return jsonify(settings)
@bp.route('/<service>/<int:cluster_id>')
@check_services
@get_user_params()
@ -214,58 +152,3 @@ def get_masters(service):
free_servers = ha_sql.select_ha_cluster_not_masters_not_slaves(group_id)
return render_template('ajax/ha/masters.html', free_servers=free_servers)
@bp.route('/<service>/settings/<int:cluster_id>/vip/<int:router_id>')
@check_services
def get_vip_settings(service, cluster_id, router_id):
settings = {}
vip = ha_sql.select_cluster_vip(cluster_id, router_id)
is_virt = ha_sql.check_ha_virt(vip.id)
settings.setdefault('return_to_master', vip.return_master)
settings.setdefault('use_src', vip.use_src)
settings.setdefault('virt_server', is_virt)
return jsonify(settings)
@bp.route('/<service>/<int:cluster_id>/vip', methods=['POST', 'PUT', 'DELETE'])
@check_services
@get_user_params()
def ha_vip(service, cluster_id):
user_params = g.user_params
group_id = user_params['group_id']
json_data = request.get_json()
if request.method == 'PUT':
router_id = int(json_data['router_id'])
try:
ha_cluster.update_vip(cluster_id, router_id, json_data, group_id)
except Exception as e:
return jsonify({'status': 'failed', 'error': f'Cannot update VIP: {e}'})
return jsonify({'status': 'updated'})
elif request.method == 'POST':
try:
ha_cluster.insert_vip(cluster_id, json_data, group_id)
except Exception as e:
return jsonify({'status': 'failed', 'error': f'Cannot create VIP: {e}'})
return jsonify({'status': 'created'})
elif request.method == 'DELETE':
router_id = int(json_data['router_id'])
router = ha_sql.get_router(router_id)
if router.default:
return jsonify({'status': 'failed', 'error': 'You cannot delete default VIP'})
try:
ha_sql.delete_ha_router(router_id)
return jsonify({'status': 'deleted'})
except Exception as e:
return jsonify({'status': 'failed', 'error': f'Cannot delete VIP: {e}'})
@bp.route('/<service>/<int:cluster_id>/vips', methods=['GET'])
@check_services
@get_user_params()
def get_vips(service, cluster_id):
if request.method == 'GET':
vips = ha_sql.select_cluster_vips(cluster_id)
vips = [model_to_dict(vip) for vip in vips]
return jsonify(vips)

View File

@ -1,8 +1,8 @@
from flask import render_template, request, g, jsonify
from flask_login import login_required
from flask_jwt_extended import jwt_required
from app.routes.install import bp
from app.middleware import get_user_params, check_services
from app.middleware import get_user_params
import app.modules.db.sql as sql
import app.modules.db.waf as waf_sql
import app.modules.common.common as common
@ -11,10 +11,23 @@ import app.modules.server.server as server_mod
import app.modules.service.common as service_common
import app.modules.service.installation as service_mod
import app.modules.service.exporter_installation as exp_installation
from app.views.install.views import InstallView
bp.add_url_rule(
'/<any(haproxy, nginx, apache, keepalived):service>',
view_func=InstallView.as_view('install'),
methods=['POST'],
defaults={'server_id': None}
)
bp.add_url_rule(
'/<any(haproxy, nginx, apache, keepalived):service>/<server_id>',
view_func=InstallView.as_view('install_ip'),
methods=['POST'],
)
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass
@ -32,25 +45,14 @@ def install_monitoring():
return render_template('install.html', **kwargs)
@bp.post('/<service>')
@check_services
def install_service(service):
json_data = request.get_json()
try:
return service_mod.install_service(service, json_data)
except Exception as e:
return jsonify({'status': 'failed', 'error': f'{e}'})
@bp.route('/<service>/version/<server_ip>')
def get_service_version(service, server_ip):
if service in ('haproxy', 'nginx', 'apache'):
return service_common.show_service_version(server_ip, service)
elif service == 'keepalived':
cmd = "sudo /usr/sbin/keepalived -v 2>&1|head -1|awk '{print $2}'"
return server_mod.ssh_command(server_ip, cmd)
else:
return 'error: Wrong service'
# @bp.post('/<service>')
# @check_services
# def install_service(service):
# json_data = request.get_json()
# try:
# return service_mod.install_service(service, json_data)
# except Exception as e:
# return jsonify({'status': 'failed', 'error': f'{e}'})
@bp.post('/exporter/<exporter>')
@ -140,13 +142,13 @@ def check_geoip(service, server_ip):
cmd = f"ls {service_dir}geoip/"
return server_mod.ssh_command(server_ip, cmd)
@bp.post('/udp')
def install_udp():
json_data = request.get_json()
listener_id = int(json_data['listener_id'])
try:
inv, server_ips = service_mod.generate_udp_inv(listener_id, 'install')
return service_mod.run_ansible(inv, server_ips, 'udp'), 201
except Exception as e:
return jsonify({'status': 'failed', 'error': f'Cannot create listener: {e}'})
#
# @bp.post('/udp')
# def install_udp():
# json_data = request.get_json()
# listener_id = int(json_data['listener_id'])
# try:
# inv, server_ips = service_mod.generate_udp_inv(listener_id, 'install')
# return service_mod.run_ansible(inv, server_ips, 'udp'), 201
# except Exception as e:
# return jsonify({'status': 'failed', 'error': f'Cannot create listener: {e}'})

View File

@ -1,5 +1,5 @@
from flask import render_template, request, redirect, url_for, g
from flask_login import login_required
from flask_jwt_extended import jwt_required
from app.routes.logs import bp
from app.middleware import check_services, get_user_params
@ -16,7 +16,7 @@ get_config = roxy_wi_tools.GetConfigVar()
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass

View File

@ -1,10 +1,8 @@
import os
import sys
from flask import render_template, request, session, g, abort, jsonify
from flask_login import login_required
sys.path.append(os.path.join(sys.path[0], '/var/www/haproxy-wi/app'))
from flask import render_template, request, g, abort, jsonify, redirect, url_for, send_from_directory
from flask_jwt_extended import jwt_required
from flask_pydantic.exceptions import ValidationError
from app import app, cache
from app.routes.main import bp
@ -20,6 +18,7 @@ import app.modules.roxywi.nettools as nettools_mod
import app.modules.roxywi.common as roxywi_common
import app.modules.service.common as service_common
import app.modules.service.haproxy as service_haproxy
from app.modules.roxywi.class_models import ErrorResponse
@app.template_filter('strftime')
@ -27,9 +26,37 @@ def _jinja2_filter_datetime(date, fmt=None):
return common.get_time_zoned_date(date, fmt)
@app.errorhandler(ValidationError)
def handle_pydantic_validation_errors1(e):
errors = []
if e.body_params:
req_type = e.body_params
elif e.form_params:
req_type = e.form_params
elif e.path_params:
req_type = e.path_params
else:
req_type = e.query_params
for er in req_type:
if len(er["loc"]) > 0:
errors.append(f'{er["loc"][0]}: {er["msg"]}')
else:
errors.append(er["msg"])
return ErrorResponse(error=errors).model_dump(mode='json'), 400
@app.errorhandler(401)
def no_auth(e):
if 'api' in request.url:
return jsonify({'error': str(e)}), 401
return redirect(url_for('login_page'))
@app.errorhandler(403)
@get_user_params()
def page_is_forbidden(e):
if 'api' in request.url:
return jsonify({'error': str(e)}), 403
kwargs = {
'user_params': g.user_params,
'title': e,
@ -41,6 +68,8 @@ def page_is_forbidden(e):
@app.errorhandler(404)
@get_user_params()
def page_not_found(e):
if 'api' in request.url:
return jsonify({'error': str(e)}), 404
kwargs = {
'user_params': g.user_params,
'title': e,
@ -52,6 +81,8 @@ 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,
@ -63,6 +94,8 @@ def method_not_allowed(e):
@app.errorhandler(500)
@get_user_params()
def internal_error(e):
if 'api' in request.url:
return jsonify({'error': str(e)}), 500
kwargs = {
'user_params': g.user_params,
'title': e,
@ -71,19 +104,19 @@ def internal_error(e):
return render_template('error.html', **kwargs), 500
@app.before_request
def make_session_permanent():
session.permanent = True
@app.route('/favicon.ico')
def favicon():
return send_from_directory(os.path.join(app.root_path, 'static'),
'images/favicon/favicon.ico', mimetype='image/vnd.microsoft.icon')
@bp.route('/stats/<service>/', defaults={'serv': None})
@bp.route('/stats/<service>/<serv>')
@login_required
@jwt_required()
@check_services
@get_user_params()
def stats(service, serv):
kwargs = {
'autorefresh': 1,
'serv': serv,
'service': service,
'service_desc': service_sql.select_service(service),
@ -93,7 +126,7 @@ def stats(service, serv):
@bp.route('/stats/view/<service>/<server_ip>')
@login_required
@jwt_required()
@check_services
def show_stats(service, server_ip):
server_ip = common.is_ip_or_dns(server_ip)
@ -111,14 +144,14 @@ def show_stats(service, server_ip):
@bp.route('/nettools')
@login_required
@jwt_required()
@get_user_params(1)
def nettools():
return render_template('nettools.html', lang=g.user_params['lang'])
@bp.post('/nettools/<check>')
@login_required
@jwt_required()
def nettools_check(check):
server_from = common.checkAjaxInput(request.form.get('server_from'))
server_to = common.is_ip_or_dns(request.form.get('server_to'))
@ -154,7 +187,7 @@ def nettools_check(check):
@bp.route('/history/<service>/<server_ip>')
@login_required
@jwt_required()
@get_user_params()
def service_history(service, server_ip):
history = ''

View File

@ -3,7 +3,7 @@ import time
import distro
from flask import render_template, request, jsonify, g, Response, stream_with_context
from flask_login import login_required
from flask_jwt_extended import jwt_required
from app.routes.metric import bp
import app.modules.db.server as server_sql
@ -17,7 +17,7 @@ import app.modules.roxywi.common as roxywi_common
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass

View File

@ -1,5 +1,5 @@
from flask import render_template, g
from flask_login import login_required
from flask_jwt_extended import jwt_required
from app.routes.overview import bp
from app.middleware import get_user_params
@ -10,7 +10,7 @@ import app.modules.roxywi.overview as roxy_overview
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass

View File

@ -1,5 +1,5 @@
from flask import render_template, request, g, jsonify
from flask_login import login_required
from flask_jwt_extended import jwt_required
from app.routes.portscanner import bp
from app.middleware import get_user_params
@ -12,7 +12,7 @@ import app.modules.tools.common as tools_common
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass

View File

@ -1,5 +1,5 @@
from flask import render_template, request, g
from flask_login import login_required
from flask_jwt_extended import jwt_required
from app.routes.runtime import bp
from app.middleware import get_user_params
@ -9,7 +9,7 @@ import app.modules.service.haproxy as service_haproxy
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass

View File

@ -1,29 +1,45 @@
import json
import time
from flask import render_template, request, g, jsonify, Response, stream_with_context
from flask_login import login_required
from flask import render_template, request, g, jsonify, Response
from flask_jwt_extended import jwt_required
from app.routes.server import bp
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.db.backup as backup_sql
import app.modules.common.common as common
import app.modules.roxywi.group as group_mod
import app.modules.roxywi.auth as roxywi_auth
import app.modules.roxywi.common as roxywi_common
import app.modules.server.ssh as ssh_mod
import app.modules.server.server as server_mod
import app.modules.tools.smon as smon_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
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'])
register_api(ServerView, 'server', '', 'server_id')
register_api(ServerGroupView, 'group', '/group', 'group_id')
register_api(CredView, 'cred', '/cred', 'creds_id')
bp.add_url_rule('/groups', view_func=ServerGroupsView.as_view('groups'), methods=['GET'])
bp.add_url_rule('/creds', view_func=CredsView.as_view('creds'), methods=['GET'])
bp.add_url_rule('/<server_id>/ip', view_func=ServerIPView.as_view('server_ip_ip'), methods=['GET'])
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'])
error_mess = roxywi_common.return_error_message()
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass
@ -45,7 +61,7 @@ def check_server(server_id):
def get_check():
while True:
try:
server = server_sql.get_server(server_id)
server = server_sql.get_server_by_id(server_id)
except Exception as e:
raise e
result = server_mod.server_is_up(server.ip)
@ -54,19 +70,19 @@ def check_server(server_id):
'name': server.hostname,
'ip': server.ip,
'port': server.port,
'enabled': server.enable,
'creds_id': server.cred,
'group_id': server.groups,
'enabled': server.enabled,
'creds_id': server.cred_id,
'group_id': server.group_id,
'firewall': server.firewall_enable,
'slave': server.master,
'type_ip': server.type_ip,
'desc': server.desc,
'description': server.description,
'protected': server.protected,
}
yield f'data:{json.dumps(status)}\n\n'
time.sleep(60)
time.sleep(10)
response = Response(stream_with_context(get_check()), mimetype="text/event-stream")
response = Response(get_check(), mimetype="text/event-stream")
response.headers["Cache-Control"] = "no-cache"
response.headers["X-Accel-Buffering"] = "no"
return response
@ -81,205 +97,6 @@ def show_if(server_ip):
return server_mod.ssh_command(server_ip, command)
@bp.route('/show/ip/<server_ip>')
def show_ip_by_id(server_ip):
server_ip = common.is_ip_or_dns(server_ip)
if server_ip == '':
raise Exception('error: Cannot find server ip')
commands = 'sudo hostname -I | tr " " "\\n"|sed "/^$/d"'
return server_mod.ssh_command(server_ip, commands, ip="1")
@bp.route('/show/ip/<int:server_id>')
def show_ip(server_id):
server_ip = server_sql.get_server_by_id(server_id)
commands = 'sudo hostname -I | tr " " "\\n"|sed "/^$/d"'
return server_mod.ssh_command(server_ip.ip, commands, ip="1")
@bp.route('', methods=['POST', 'PUT', 'DELETE', 'PATCH'])
@get_user_params()
def create_server():
roxywi_auth.page_for_admin(level=2)
json_data = request.get_json()
lang = roxywi_common.get_user_lang_for_flask()
if request.method in ('POST', 'PUT'):
hostname = common.checkAjaxInput(json_data['name'])
group = int(json_data['group'])
type_ip = int(json_data['type_ip'])
firewall = int(json_data['firewall'])
enable = int(json_data['enable'])
cred = int(json_data['cred'])
port = int(json_data['port'])
desc = common.checkAjaxInput(json_data['desc'])
master = int(json_data['slave'])
protected = int(json_data['protected'])
if request.method == 'POST':
ip = common.is_ip_or_dns(json_data['ip'])
haproxy = int(json_data['haproxy'])
nginx = int(json_data['nginx'])
apache = int(json_data['apache'])
add_to_smon = int(json_data['add_to_smon'])
if ip == '':
return jsonify({'status': 'failed','error': 'IP or DNS name is not valid'})
try:
last_id = server_mod.create_server(hostname, ip, group, type_ip, enable, master, cred, port, desc, haproxy, nginx, apache, firewall)
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Cannot create server')
try:
user_subscription = roxywi_common.return_user_status()
except Exception as e:
user_subscription = roxywi_common.return_unsubscribed_user_status()
roxywi_common.logging('Roxy-WI server', f'Cannot get a user plan: {e}', roxywi=1)
if add_to_smon:
try:
user_group = roxywi_common.get_user_group(id=1)
json_data = {
"name": hostname,
"ip": ip,
"port": "0",
"enabled": "1",
"url": "",
"body": "",
"group": hostname,
"desc": f"Ping {hostname}",
"tg": "0",
"slack": "0",
"pd": "0",
"resolver": "",
"record_type": "",
"packet_size": "56",
"http_method": "",
"check_type": "ping",
"agent_id": "1",
"interval": "120",
}
smon_mod.create_smon(json_data, user_group)
except Exception as e:
roxywi_common.logging(ip, f'error: Cannot add server {hostname} to SMON: {e}', roxywi=1)
roxywi_common.logging(ip, f'A new server {hostname} has been created', roxywi=1, login=1, keep_history=1, service='server')
kwargs = {
'groups': group_sql.select_groups(),
'servers': server_sql.select_servers(server=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
}
return jsonify({'status': 'created', 'id': last_id, 'data': render_template('ajax/new_server.html', **kwargs)})
elif request.method == 'PUT':
serv_id = int(json_data['id'])
if hostname is None or port is None:
return jsonify({'status': 'failed', 'error': 'Cannot find server ip or port'})
else:
try:
server_sql.update_server(hostname, group, type_ip, enable, master, serv_id, cred, port, desc, firewall, protected)
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Cannot update server')
server_ip = server_sql.select_server_ip_by_id(serv_id)
roxywi_common.logging(server_ip, f'The server {hostname} has been update', roxywi=1, login=1,
keep_history=1, service='server')
return jsonify({'status': 'updated'})
elif request.method == 'DELETE':
server_id = int(json_data['id'])
try:
server_mod.delete_server(server_id)
return jsonify({'status': 'deleted'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Cannot delete the server')
elif request.method == 'PATCH':
hostname = common.checkAjaxInput(json_data['name'])
ip = common.is_ip_or_dns(json_data['ip'])
scan_server = int(json_data['scan_server'])
try:
server_mod.update_server_after_creating(hostname, ip, scan_server)
return jsonify({'status': 'updated'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Cannot scan the server')
@bp.route('/group', methods=['POST', 'PUT', 'DELETE'])
def create_group():
roxywi_auth.page_for_admin()
json_data = request.get_json()
if request.method == 'POST':
name = json_data.get('name')
desc = json_data.get('desc')
if name == '':
return error_mess
try:
last_id = group_sql.add_group(name, desc)
roxywi_common.logging('Roxy-WI server', f'A new group {name} has been created', roxywi=1, login=1)
return jsonify({
'status': 'created',
'id': last_id,
'data': render_template('ajax/new_group.html', groups=group_sql.select_groups(group=name))}
)
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Cannot create a new group')
elif request.method == 'PUT':
name = json_data.get('name')
desc = json_data.get('desc')
group_id = json_data.get('group_id')
try:
group_mod.update_group(group_id, name, desc)
return jsonify({'status': 'updated'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, f'Cannot update group {name}')
elif request.method == 'DELETE':
group_id = json_data.get('group_id')
try:
group_mod.delete_group(group_id)
return jsonify({'status': 'deleted'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, f'Cannot delete {group_id}')
@bp.route('/ssh', methods=['POST', 'PUT', 'DELETE', 'PATCH'])
@get_user_params()
def create_ssh():
roxywi_auth.page_for_admin(level=2)
json_data = request.get_json()
if request.method == 'POST':
try:
data = ssh_mod.create_ssh_cred(json_data)
return jsonify({'status': 'created', 'id': data['id'], 'data': data['template']})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Cannot create SSH')
elif request.method == 'PUT':
try:
ssh_mod.update_ssh_key(json_data)
return jsonify({'status': 'updated'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Cannot update SSH')
elif request.method == 'DELETE':
ssh_id = int(json_data.get('id'))
try:
ssh_mod.delete_ssh_key(ssh_id)
return jsonify({'status': 'deleted'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Cannot delete SSH')
elif request.method == 'PATCH':
user_group = roxywi_common.get_user_group()
name = common.checkAjaxInput(json_data['name'])
passphrase = common.checkAjaxInput(json_data['pass'])
key = json_data['ssh_cert']
try:
saved_path = ssh_mod.upload_ssh_key(name, user_group, key, passphrase)
return jsonify({'status': 'uploaded', 'message': saved_path})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Cannot upload ssh')
@bp.app_template_filter('string_to_dict')
def string_to_dict(dict_string) -> dict:
from ast import literal_eval
@ -322,47 +139,39 @@ def show_firewall(server_ip):
return server_mod.show_firewalld_rules(server_ip)
@bp.route('/backup', methods=['GET', 'POST', 'PUT', 'DELETE'])
@bp.route('/backup', methods=['GET'])
@get_user_params()
def load_backup():
if request.method == 'GET':
user_group = g.user_params['group_id']
kwargs = {
'sshs': cred_sql.select_ssh(group=user_group),
'servers': roxywi_common.get_dick_permit(virt=1, disable=0, only_group=1),
'backups': backup_sql.select_backups(),
's3_backups': backup_sql.select_s3_backups(),
'gits': backup_sql.select_gits(),
'lang': g.user_params['lang'],
'is_needed_tool': common.is_tool('ansible'),
'user_subscription': roxywi_common.return_user_subscription(),
}
return render_template('include/admin_backup.html', **kwargs)
elif request.method in ('POST', 'PUT', 'DELETE'):
json_data = request.get_json()
try:
data = backup_mod.backup(json_data)
return jsonify({'status': 'ok', 'data': data})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, f'Cannot {request.method} backup')
user_group = g.user_params['group_id']
kwargs = {
'sshs': cred_sql.select_ssh(group=user_group),
'servers': roxywi_common.get_dick_permit(virt=1, disable=0, only_group=1),
'backups': backup_sql.select_backups(),
's3_backups': backup_sql.select_s3_backups(),
'gits': backup_sql.select_gits(),
'lang': g.user_params['lang'],
'is_needed_tool': common.is_tool('ansible'),
'user_subscription': roxywi_common.return_user_subscription(),
}
return render_template('include/admin_backup.html', **kwargs)
@bp.post('/s3backup/create')
@bp.post('/s3backup/delete')
def create_s3_backup():
server = common.is_ip_or_dns(request.form.get('s3_backup_server'))
s3_server = common.checkAjaxInput(request.form.get('s3_server'))
bucket = common.checkAjaxInput(request.form.get('s3_bucket'))
secret_key = common.checkAjaxInput(request.form.get('s3_secret_key'))
access_key = common.checkAjaxInput(request.form.get('s3_access_key'))
time = common.checkAjaxInput(request.form.get('time'))
deljob = common.checkAjaxInput(request.form.get('dels3job'))
description = common.checkAjaxInput(request.form.get('description'))
try:
return backup_mod.s3_backup(server, s3_server, bucket, secret_key, access_key, time, deljob, description)
except Exception as e:
return str(e)
# @bp.post('/s3backup/create')
# @bp.post('/s3backup/delete')
# def create_s3_backup():
# server = common.is_ip_or_dns(request.form.get('s3_backup_server'))
# s3_server = common.checkAjaxInput(request.form.get('s3_server'))
# bucket = common.checkAjaxInput(request.form.get('s3_bucket'))
# secret_key = common.checkAjaxInput(request.form.get('s3_secret_key'))
# access_key = common.checkAjaxInput(request.form.get('s3_access_key'))
# time = common.checkAjaxInput(request.form.get('time'))
# deljob = common.checkAjaxInput(request.form.get('dels3job'))
# description = common.checkAjaxInput(request.form.get('description'))
#
# try:
# return backup_mod.s3_backup(server, s3_server, bucket, secret_key, access_key, time, deljob, description)
# except Exception as e:
# return str(e)
@bp.route('/git', methods=['DELETE', 'POST'])

View File

@ -1,6 +1,6 @@
import distro
from flask import render_template, request, g
from flask_login import login_required
from flask_jwt_extended import jwt_required, get_jwt
from app import cache
from app.routes.service import bp
@ -13,15 +13,22 @@ import app.modules.db.service as service_sql
from app.middleware import check_services, get_user_params
import app.modules.common.common as common
import app.modules.server.server as server_mod
import app.modules.service.action as service_action
import app.modules.service.common as service_common
import app.modules.service.keepalived as keepalived
import app.modules.roxywi.common as roxywi_common
import app.modules.roxywi.overview as roxy_overview
from app.views.service.views import ServiceActionView, ServiceBackendView, ServiceView
bp.add_url_rule('/<service>/<server_id>/<any(start, stop, reload, restart):action>', view_func=ServiceActionView.as_view('service_action_ip'), methods=['GET'])
bp.add_url_rule('/<service>/<int:server_id>/<any(start, stop, reload, restart):action>', view_func=ServiceActionView.as_view('service_action'), methods=['GET'])
bp.add_url_rule('/<service>/<server_id>/backend', view_func=ServiceBackendView.as_view('service_backend_ip'), methods=['GET'])
bp.add_url_rule('/<service>/<int:server_id>/backend', view_func=ServiceBackendView.as_view('service_backend'), methods=['GET'])
bp.add_url_rule('/<service>/<server_id>/status', view_func=ServiceView.as_view('service_ip'), methods=['GET'])
bp.add_url_rule('/<service>/<int:server_id>/status', view_func=ServiceView.as_view('service'), methods=['GET'])
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass
@ -178,22 +185,22 @@ def services(service, serv):
return render_template('service.html', **kwargs)
@bp.post('/action/<service>/check-service')
def check_service(service):
user_uuid = request.cookies.get('uuid')
server_ip = common.checkAjaxInput(request.form.get('server_ip'))
try:
return service_action.check_service(server_ip, user_uuid, service)
except Exception:
return 'logout'
@bp.route('/action/<service>/<server_ip>/<action>', methods=['GET'])
def action_service(service, server_ip, action):
server_ip = common.is_ip_or_dns(server_ip)
return service_action.common_action(server_ip, action, service)
# @bp.post('/action/<service>/check-service')
# def check_service(service):
# claims = get_jwt()
# server_ip = common.checkAjaxInput(request.form.get('server_ip'))
#
# try:
# return service_action.check_service(server_ip, claims['user_id'], service)
# except Exception:
# return 'logout'
#
#
# @bp.route('/action/<service>/<server_ip>/<action>', methods=['GET'])
# def action_service(service, server_ip, action):
# server_ip = common.is_ip_or_dns(server_ip)
#
# return service_action.common_action(server_ip, action, service)
@bp.route('/<service>/<server_ip>/last-edit')
@ -222,11 +229,10 @@ def cpu_ram_metrics(server_ip, server_id, name, service):
return_out = ''
servers = [[name, server_ip, return_out]]
user_id = request.cookies.get('uuid')
group_id = int(request.cookies.get('group'))
claims = get_jwt()
kwargs = {
'service_status': sorted(servers, key=common.get_key),
'role': user_sql.get_user_role_by_uuid(user_id, group_id),
'role': user_sql.get_user_role_in_group(claims['user_id'], claims['group']),
'id': server_id,
'service_page': service,
'lang': g.user_params['lang']
@ -271,26 +277,26 @@ def show_keepalived_become_master():
server_ip = common.is_ip_or_dns(request.form.get('keepalivedBecameMaster'))
return roxy_overview.keepalived_became_master(server_ip)
@bp.route('/<service>/backends/<server_ip>')
@cache.cached()
def show_service_backends(service, server_ip):
server_ip = common.is_ip_or_dns(server_ip)
return service_common.overview_backends(server_ip, service)
#
#
# @bp.route('/<service>/backends/<server_ip>')
# @cache.cached()
# def show_service_backends(service, server_ip):
# server_ip = common.is_ip_or_dns(server_ip)
#
# return service_common.overview_backends(server_ip, service)
@bp.route('/position/<int:server_id>/<int:pos>')
def change_pos(server_id, pos):
return server_sql.update_server_pos(pos, server_id)
@bp.route('/haproxy/version/<server_ip>')
def get_haproxy_v(server_ip):
server_ip = common.is_ip_or_dns(server_ip)
return service_common.check_haproxy_version(server_ip)
#
# @bp.route('/haproxy/version/<server_ip>')
# def get_haproxy_v(server_ip):
# server_ip = common.is_ip_or_dns(server_ip)
#
# return service_common.check_haproxy_version(server_ip)
@bp.route('/settings/<service>/<int:server_id>')

View File

@ -1,8 +1,8 @@
from flask import render_template, request, jsonify, g
from flask_login import login_required
from flask_jwt_extended import jwt_required
from app.routes.smon import bp
from middleware import get_user_params
from app.middleware import get_user_params
import app.modules.db.smon as smon_sql
import app.modules.common.common as common
import app.modules.tools.smon_agent as smon_agent
@ -12,7 +12,7 @@ import app.modules.server.server as server_mod
@bp.route('/agent', methods=['GET', 'POST', 'PUT', 'DELETE'])
@login_required
@jwt_required()
@get_user_params()
def agent():
if request.method == 'GET':
@ -61,7 +61,7 @@ def agent_get_checks():
@bp.get('/agent/free')
@login_required
@jwt_required()
@get_user_params()
def get_free_agents():
group_id = g.user_params['group_id']
@ -74,7 +74,7 @@ def get_free_agents():
@bp.get('/agent/count')
@login_required
@jwt_required()
def get_agent_count():
try:
smon_agent.check_agent_limit()
@ -85,7 +85,7 @@ def get_agent_count():
@bp.get('/agent/<int:agent_id>')
@login_required
@jwt_required()
@get_user_params()
def get_agent(agent_id):
try:
@ -97,7 +97,7 @@ def get_agent(agent_id):
@bp.get('/agent/settings/<int:agent_id>')
@login_required
@jwt_required()
def get_agent_settings(agent_id):
settings = {}
try:
@ -116,7 +116,7 @@ def get_agent_settings(agent_id):
@bp.get('/agent/version/<server_ip>')
@login_required
@jwt_required()
def get_agent_version(server_ip):
agent_id = int(request.args.get('agent_id'))
@ -128,7 +128,7 @@ def get_agent_version(server_ip):
@bp.get('/agent/uptime/<server_ip>')
@login_required
@jwt_required()
def get_agent_uptime(server_ip):
agent_id = int(request.args.get('agent_id'))
@ -140,7 +140,7 @@ def get_agent_uptime(server_ip):
@bp.get('/agent/status/<server_ip>')
@login_required
@jwt_required()
def get_agent_status(server_ip):
agent_id = int(request.args.get('agent_id'))
@ -152,7 +152,7 @@ def get_agent_status(server_ip):
@bp.get('/agent/checks/<server_ip>')
@login_required
@jwt_required()
def get_agent_checks(server_ip):
agent_id = int(request.args.get('agent_id'))
@ -164,7 +164,7 @@ def get_agent_checks(server_ip):
@bp.post('/agent/action/<action>')
@login_required
@jwt_required()
def agent_action(action):
server_ip = common.is_ip_or_dns(request.form.get('server_ip'))

View File

@ -1,7 +1,7 @@
import json
from flask import render_template, request, jsonify, g
from flask_login import login_required
from flask_jwt_extended import jwt_required
from datetime import datetime
from app.routes.smon import bp
@ -16,7 +16,7 @@ import app.modules.tools.common as tools_common
@bp.route('/dashboard')
@login_required
@jwt_required()
@get_user_params()
def smon_main_dashboard():
"""
@ -36,10 +36,10 @@ def smon_main_dashboard():
'group': group_id,
'smon_status': tools_common.is_tool_active('roxy-wi-smon'),
'user_subscription': roxywi_common.return_user_subscription(),
'telegrams': channel_sql.get_user_telegram_by_group(group_id),
'slacks': channel_sql.get_user_slack_by_group(group_id),
'pds': channel_sql.get_user_pd_by_group(group_id),
'mms': channel_sql.get_user_mm_by_group(group_id),
'telegrams': channel_sql.get_user_receiver_by_group('telegram', group_id),
'slacks': channel_sql.get_user_receiver_by_group('slack', group_id),
'pds': channel_sql.get_user_receiver_by_group('pd', group_id),
'mms': channel_sql.get_user_receiver_by_group('mm', group_id),
'sort': request.args.get('sort', None)
}
@ -47,7 +47,7 @@ def smon_main_dashboard():
@bp.route('/dashboard/<int:smon_id>/<int:check_id>')
@login_required
@jwt_required()
@get_user_params()
def smon_dashboard(smon_id, check_id):
"""
@ -115,7 +115,7 @@ def smon_dashboard(smon_id, check_id):
@bp.route('/check', methods=['POST', 'PUT', 'DELETE'])
@login_required
@jwt_required()
def smon_add():
json_data = request.get_json()
if request.method == "POST":
@ -150,7 +150,7 @@ def smon_add():
@bp.route('/check/settings/<int:smon_id>/<int:check_type_id>')
@login_required
@jwt_required()
def check(smon_id, check_type_id):
smon = smon_sql.select_one_smon(smon_id, check_type_id)
settings = {}
@ -190,7 +190,7 @@ def check(smon_id, check_type_id):
@bp.route('/check/<int:smon_id>/<int:check_type_id>')
@login_required
@jwt_required()
@get_user_params()
def get_check(smon_id, check_type_id):
"""
@ -210,7 +210,7 @@ def get_check(smon_id, check_type_id):
@bp.route('/status-page', methods=['GET', 'POST', 'DELETE', 'PUT'])
@login_required
@jwt_required()
@get_user_params()
def status_page():
"""
@ -295,7 +295,7 @@ def status_page():
@bp.route('/status/checks/<int:page_id>')
@login_required
@jwt_required()
def get_checks(page_id):
"""
:param page_id: The ID of the page for which to fetch the checks.
@ -327,7 +327,7 @@ def smon_history_statuses_avg(page_id):
@bp.route('/history')
@login_required
@jwt_required()
@get_user_params()
def smon_history():
roxywi_common.check_user_group_for_flask()
@ -344,7 +344,7 @@ def smon_history():
@bp.route('/history/host/<server_ip>')
@login_required
@jwt_required()
@get_user_params()
def smon_host_history(server_ip):
roxywi_common.check_user_group_for_flask()
@ -367,7 +367,7 @@ def smon_host_history(server_ip):
@bp.route('/history/metric/<int:dashboard_id>')
@login_required
@jwt_required()
def smon_history_metric(dashboard_id):
return jsonify(smon_mod.history_metrics(dashboard_id))
@ -378,13 +378,13 @@ def smon_history_statuses(dashboard_id):
@bp.route('/history/cur_status/<int:dashboard_id>/<int:check_id>')
@login_required
@jwt_required()
def smon_history_cur_status(dashboard_id, check_id):
return smon_mod.history_cur_status(dashboard_id, check_id)
@bp.post('/refresh')
@login_required
@jwt_required()
def smon_show():
sort = common.checkAjaxInput(request.form.get('sort'))
return smon_mod.show_smon(sort)

View File

@ -1,122 +1,14 @@
from flask import render_template, request, g, jsonify
from flask_login import login_required
from flask_jwt_extended import jwt_required
from app.routes.udp import bp
import app.modules.db.udp as udp_sql
import app.modules.db.server as server_sql
import app.modules.db.ha_cluster as ha_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.service.udp as udp_mod
import app.modules.service.installation as service_mod
from app.middleware import get_user_params, check_services
from app.views.udp.views import UDPListener
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass
@bp.route('/<service>/listener', methods=['GET', 'POST', 'PUT', 'DELETE'])
@check_services
@get_user_params()
def listener_funct(service):
if request.method != 'GET':
roxywi_auth.page_for_admin(level=2)
if request.method == 'GET':
kwargs = {
'listeners': udp_sql.select_listeners(g.user_params['group_id']),
'lang': g.user_params['lang'],
'clusters': ha_sql.select_clusters(g.user_params['group_id']),
'is_needed_tool': common.is_tool('ansible'),
'user_subscription': roxywi_common.return_user_subscription()
}
return render_template('udp/listeners.html', **kwargs)
elif request.method == 'POST':
json_data = request.get_json()
json_data['group_id'] = g.user_params['group_id']
listener_name = json_data['new-listener-name']
try:
listener_id = udp_mod.create_listener(json_data)
roxywi_common.logging(listener_id, f'UDP listener {listener_name} has been created', roxywi=1, keep_history=1, login=1, service='UDP listener')
return jsonify({'status': 'created', 'listener_id': listener_id})
except Exception as e:
return roxywi_common.handle_json_exceptions(e,'Cannot create UDP listener')
elif request.method == 'PUT':
json_data = request.get_json()
json_data['group_id'] = g.user_params['group_id']
listener_name = json_data['new-listener-name']
listener_id = json_data['listener_id']
try:
udp_mod.update_listener(json_data)
roxywi_common.logging(listener_id, f'UDP listener {listener_name} has been updated', roxywi=1, keep_history=1, login=1, service='UDP listener')
return jsonify({'status': 'updated'}), 201
except Exception as e:
return jsonify({'status': 'failed', 'error': str(e)})
elif request.method == 'DELETE':
kwargs = request.get_json()
listener_id = int(kwargs['listener_id'])
try:
inv, server_ips = service_mod.generate_udp_inv(listener_id, 'uninstall')
service_mod.run_ansible(inv, server_ips, 'udp'), 201
roxywi_common.logging(listener_id, f'UDP listener has been deleted {listener_id}', roxywi=1, keep_history=1, login=1, service='UDP listener')
except Exception as e:
return roxywi_common.handle_json_exceptions(e,f'Cannot create inventory for UDP listener deleting {listener_id}')
try:
udp_sql.delete_listener(listener_id)
return jsonify({'status': 'deleted'}), 201
except Exception as e:
return roxywi_common.handle_json_exceptions(e,f'Cannot delete UDP listener {listener_id}')
@bp.get('/<service>/listener/<int:listener_id>')
@check_services
@get_user_params()
def get_listener(service, listener_id):
listener = udp_sql.get_listener(listener_id)
cluster = dict()
server = dict()
if listener.cluster_id:
cluster = ha_sql.select_cluster(listener.cluster_id)
elif listener.server_id:
server = server_sql.get_server_by_id(listener.server_id)
kwargs = {
'clusters': cluster,
'listener': listener,
'server': server,
'lang': g.user_params['lang'],
}
return render_template('udp/listener.html', **kwargs)
@bp.get('/<service>/listener/<int:listener_id>/settings')
@check_services
@get_user_params()
def get_listener_settings(service, listener_id):
listener_config = udp_mod.get_listener_config(listener_id)
return jsonify(listener_config)
@bp.get('/<service>/listener/<int:listener_id>/<action>')
@check_services
@get_user_params()
def action_with_listener(service, listener_id, action):
try:
udp_mod.listener_actions(listener_id, action, g.user_params['group_id'])
roxywi_common.logging(listener_id, f'UDP listener {listener_id} has been {action}ed', roxywi=1, keep_history=1, login=1, service='UDP listener')
return jsonify({'status': 'done'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e,f'Cannot {action} listener')
@bp.get('/<service>/listener/<int:listener_id>/check')
@check_services
def check_listener(service, listener_id):
try:
status = udp_mod.check_is_listener_active(listener_id)
return jsonify({'status': status})
except Exception as e:
return roxywi_common.handle_json_exceptions(e,f'Cannot get status')
bp.add_url_rule('/<service>/listener', view_func=UDPListener.as_view('udp_listener', False), methods=['GET'], defaults={'listener_id': None})
bp.add_url_rule('/<service>/listener/<int:listener_id>', view_func=UDPListener.as_view('udp_listener_id', False), methods=['GET'])

View File

@ -1,74 +1,87 @@
import json
from flask import render_template, request, jsonify, g, abort
from flask_login import login_required
from flask import request, jsonify, g
from flask_jwt_extended import jwt_required, get_jwt
from app.routes.user import bp
import app.modules.db.sql as sql
import app.modules.db.user as user_sql
import app.modules.db.group as group_sql
import app.modules.common.common as common
import app.modules.roxywi.user as roxywi_user
import app.modules.roxywi.auth as roxywi_auth
import app.modules.roxywi.common as roxywi_common
from app.middleware import get_user_params
from app.modules.roxywi.class_models import BaseResponse, ErrorResponse
from app.views.user.views import UserView, UserGroupView
def register_api_with_group(view, endpoint, url_beg, url_end, pk='user_id', pk_type='int', pk_end='group_id', pk_type_end='int'):
view_func = view.as_view(endpoint)
bp.add_url_rule(f'/<{pk_type}:{pk}>/{url_end}', view_func=view_func, methods=['GET'])
bp.add_url_rule(f'/<{pk_type}:{pk}>/{url_end}/<{pk_type_end}:{pk_end}>', view_func=view_func, methods=['PUT', 'DELETE', 'POST', 'PATCH'])
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'])
register_api(UserView, 'user', '', 'user_id')
register_api_with_group(UserGroupView, 'user_group', '', 'groups')
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass
@bp.route('', methods=['POST', 'PUT', 'DELETE'])
@get_user_params()
def create_user():
roxywi_auth.page_for_admin(level=2)
json_data = request.get_json()
if request.method == 'POST':
email = common.checkAjaxInput(json_data['email'])
password = common.checkAjaxInput(json_data['password'])
role = int(json_data['role'])
new_user = common.checkAjaxInput(json_data['username'])
enabled = int(json_data['enabled'])
group_id = int(json_data['user_group'])
lang = roxywi_common.get_user_lang_for_flask()
current_user_role_id = g.user_params['role']
if not roxywi_common.check_user_group_for_flask():
return roxywi_common.handle_json_exceptions('Wrong group', 'Roxy-WI server', '')
if current_user_role_id > role:
return roxywi_common.handle_json_exceptions('Wrong role', 'Roxy-WI server', '')
try:
user_id = roxywi_user.create_user(new_user, email, password, role, enabled, group_id)
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Cannot create a new user')
else:
return jsonify({'status': 'created', 'id': user_id, 'data': render_template(
'ajax/new_user.html', users=user_sql.select_users(user=new_user), groups=group_sql.select_groups(),
roles=sql.select_roles(), adding=1, lang=lang
)})
elif request.method == 'PUT':
user_id = int(json_data['user_id'])
user_name = common.checkAjaxInput(json_data['username'])
email = common.checkAjaxInput(json_data['email'])
enabled = int(json_data['enabled'])
if roxywi_common.check_user_group_for_flask():
try:
user_sql.update_user_from_admin_area(user_name, email, user_id, enabled)
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Cannot update user')
roxywi_common.logging(user_name, ' has been updated user ', roxywi=1, login=1)
return jsonify({'status': 'updated'})
elif request.method == 'DELETE':
roxywi_auth.page_for_admin(level=2)
user_id = int(json_data['user_id'])
try:
roxywi_user.delete_user(user_id)
return jsonify({'status': 'deleted'})
except Exception as e:
return roxywi_common.handle_json_exceptions(e, f'Cannot delete the user {user_id}')
# @bp.route('', methods=['POST', 'PUT', 'DELETE'])
# @get_user_params()
# def create_user():
# roxywi_auth.page_for_admin(level=2)
# json_data = request.get_json()
#
# if request.method == 'POST':
# email = common.checkAjaxInput(json_data['email'])
# password = common.checkAjaxInput(json_data['password'])
# role = int(json_data['role'])
# new_user = common.checkAjaxInput(json_data['username'])
# enabled = int(json_data['enabled'])
# group_id = int(json_data['user_group'])
# lang = roxywi_common.get_user_lang_for_flask()
# current_user_role_id = g.user_params['role']
# if not roxywi_common.check_user_group_for_flask():
# return roxywi_common.handle_json_exceptions('Wrong group', 'Roxy-WI server', '')
# if current_user_role_id > role:
# return roxywi_common.handle_json_exceptions('Wrong role', 'Roxy-WI server', '')
# try:
# user_id = roxywi_user.create_user(new_user, email, password, role, enabled, group_id)
# except Exception as e:
# return roxywi_common.handle_json_exceptions(e, 'Cannot create a new user')
# else:
# return jsonify({'status': 'created', 'id': user_id, 'data': render_template(
# 'ajax/new_user.html', users=user_sql.select_users(user=new_user), groups=group_sql.select_groups(),
# roles=sql.select_roles(), adding=1, lang=lang
# )})
# elif request.method == 'PUT':
# user_id = int(json_data['user_id'])
# user_name = common.checkAjaxInput(json_data['username'])
# email = common.checkAjaxInput(json_data['email'])
# enabled = int(json_data['enabled'])
# if roxywi_common.check_user_group_for_flask():
# try:
# user_sql.update_user_from_admin_area(user_name, email, user_id, enabled)
# except Exception as e:
# return roxywi_common.handle_json_exceptions(e, 'Cannot update user')
# roxywi_common.logging(user_name, ' has been updated user ', roxywi=1, login=1)
# return jsonify({'status': 'updated'})
# elif request.method == 'DELETE':
# roxywi_auth.page_for_admin(level=2)
# user_id = int(json_data['user_id'])
# try:
# roxywi_user.delete_user(user_id)
# return jsonify({'status': 'deleted'})
# except Exception as e:
# return roxywi_common.handle_json_exceptions(e, f'Cannot delete the user {user_id}')
@bp.route('/ldap/<username>')
@ -83,21 +96,27 @@ def get_ldap_email(username):
@bp.post('/password')
def update_password():
json_data = request.get_json()
password = json_data['password']
uuid = ''
user_id = ''
if 'uuid' in json_data:
uuid = common.checkAjaxInput(json_data['uuid'])
else:
user_id = int(json_data['id'])
@get_user_params()
def update_user_its_password():
password = request.json.get('pass')
try:
roxywi_user.update_user_password(password, uuid, user_id)
return jsonify({'status': 'updated'})
roxywi_user.update_user_password(password, g.user_params['user_id'])
return BaseResponse().model_dump(mode='json')
except Exception as e:
return roxywi_common.handle_json_exceptions(e, 'Cannot update password')
return ErrorResponse(error=str(e)).model_dump(mode='json'), 501
@bp.post('/password/<int:user_id>')
def update_user_password(user_id):
password = request.json.get('pass')
try:
roxywi_user.update_user_password(password, user_id)
return BaseResponse().model_dump(mode='json')
except Exception as e:
return ErrorResponse(error=str(e)).model_dump(mode='json'), 501
@bp.route('/services/<int:user_id>', methods=['GET', 'POST'])
@ -117,33 +136,35 @@ def show_user_services(user_id):
@bp.route('/group', methods=['GET', 'PUT'])
def get_current_group():
claims = get_jwt()
group_id = claims['group']
user_id = claims['user_id']
if request.method == 'GET':
uuid = common.checkAjaxInput(request.cookies.get('uuid'))
group = common.checkAjaxInput(request.cookies.get('group'))
return roxywi_user.get_user_active_group(uuid, group)
# uuid = common.checkAjaxInput(request.cookies.get('uuid'))
# group = common.checkAjaxInput(request.cookies.get('group'))
return roxywi_user.get_user_active_group(group_id, user_id)
elif request.method == 'PUT':
group_id = common.checkAjaxInput(request.form.get('group'))
user_uuid = common.checkAjaxInput(request.form.get('uuid'))
# group_id = common.checkAjaxInput(request.form.get('group'))
# user_uuid = common.checkAjaxInput(request.form.get('uuid'))
return roxywi_user.change_user_active_group(group_id, user_uuid)
return roxywi_user.change_user_active_group(group_id, user_id)
@bp.route('/groups/<int:user_id>')
def show_user_groups_and_roles(user_id):
lang = roxywi_common.get_user_lang_for_flask()
return roxywi_user.show_user_groups_and_roles(user_id, lang)
# @bp.route('/groups/<int:user_id>')
# def show_user_groups_and_roles(user_id):
# lang = roxywi_common.get_user_lang_for_flask()
#
# return roxywi_user.show_user_groups_and_roles(user_id, lang)
@bp.post('/groups/save')
def change_user_groups_and_roles():
user = common.checkAjaxInput(request.form.get('changeUserGroupsUser'))
groups_and_roles = json.loads(request.form.get('jsonDatas'))
user_uuid = request.cookies.get('uuid')
return roxywi_user.save_user_group_and_role(user, groups_and_roles, user_uuid)
return roxywi_user.save_user_group_and_role(user, groups_and_roles)
@bp.route('/group/name/<int:group_id>')
def get_group_name_by_id(group_id):
return group_sql.get_group_name_by_id(group_id)
# @bp.route('/group/name/<int:group_id>')
# def get_group_name_by_id(group_id):
# return group_sql.get_group_name_by_id(group_id)

View File

@ -1,7 +1,7 @@
import os
from flask import render_template, request, g, abort, jsonify
from flask_login import login_required
from flask_jwt_extended import jwt_required, get_jwt
from app.routes.waf import bp
import app.modules.db.sql as sql
@ -18,7 +18,7 @@ get_config = roxy_wi_tools.GetConfigVar()
@bp.before_request
@login_required
@jwt_required()
def before_request():
""" Protect all the admin endpoints. """
pass
@ -218,7 +218,9 @@ def overview_waf(service, server_ip):
if service not in ('haproxy', 'nginx'):
return 'error: Wrong service'
return roxy_waf.waf_overview(server_ip, service)
claims = get_jwt()
return roxy_waf.waf_overview(server_ip, service, claims)
@bp.route('/metric/enable/<int:enable>/<server_name>')

View File

@ -7,11 +7,11 @@ virtual_server {{ vip }} {{ port }} {
retry 3
{% for server, value in config.items() %}
real_server {{ server }} {{ value.port }} {
weight {{ value.weight }}
{% for server in config %}
real_server {{ server.backend_ip }} {{ server.port }} {
weight {{ server.weight }}
MISC_CHECK {
misc_path "{{ service_dir }}/checks/udp_check.sh {{ server }} {{ value.port }}"
misc_path "{{ service_dir }}/checks/udp_check.sh {{ server.backend_ip }} {{ server.port }}"
misc_timeout 5
}
}

View File

@ -35,11 +35,11 @@
font-family: "Font Awesome 5 Regular";
content: "\f080";
}
.logs::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f02d";
}
/*.logs::before {*/
/* display: none;*/
/* font-family: "Font Awesome 5 Solid";*/
/* content: "\f02d";*/
/*}*/
.map::before {
display: none;
font-family: "Font Awesome 5 Solid";
@ -50,16 +50,16 @@
font-family: "Font Awesome 5 Solid";
content: "\f233";
}
.metrics::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f1fe";
}
.config-show::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f6ff";
}
/*.metrics::before {*/
/* display: none;*/
/* font-family: "Font Awesome 5 Solid";*/
/* content: "\f1fe";*/
/*}*/
/*.config-show::before {*/
/* display: none;*/
/* font-family: "Font Awesome 5 Solid";*/
/* content: "\f6ff";*/
/*}*/
.compare::before {
display: none;
font-family: "Font Awesome 5 Regular";
@ -76,16 +76,16 @@
.plus-after > .fa-plus, .minus-after > .fa-minus, .minus > .fa-minus, .plus > .fa-plus {
color: var(--blue-color);
}
.add-proxy::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f067";
}
.cert::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f0a3";
}
/*.add-proxy::before {*/
/* display: none;*/
/* font-family: "Font Awesome 5 Solid";*/
/* content: "\f067";*/
/*}*/
/*.cert::before {*/
/* display: none;*/
/* font-family: "Font Awesome 5 Solid";*/
/* content: "\f0a3";*/
/*}*/
.option::before {
display: none;
font-family: "Font Awesome 5 Regular";
@ -101,11 +101,11 @@
font-family: "Font Awesome 5 Solid";
content: "\f0cb";
}
.waf-menu::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f06d";
}
/*.waf-menu::before {*/
/* display: none;*/
/* font-family: "Font Awesome 5 Solid";*/
/* content: "\f06d";*/
/*}*/
.hap-menu::before {
display: none;
font-family: "Font Awesome 5 Solid";
@ -116,11 +116,11 @@
font-family: "Font Awesome 5 Regular";
content: "\f074";
}
.backup::before {
display: none;
font-family: "Font Awesome 5 Regular";
content: "\f24d";
}
/*.backup::before {*/
/* display: none;*/
/* font-family: "Font Awesome 5 Regular";*/
/* content: "\f24d";*/
/*}*/
.ha::before {
display: none;
font-family: "Font Awesome 5 Solid";
@ -131,11 +131,11 @@
font-family: "Font Awesome 5 Solid";
content: "\f126";
}
.nginx-menu::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f0e8";
}
/*.nginx-menu::before {*/
/* display: none;*/
/* font-family: "Font Awesome 5 Solid";*/
/* content: "\f0e8";*/
/*}*/
.apache-menu::before {
display: none;
font-family: "Font Awesome 5 Solid";
@ -146,7 +146,7 @@
font-family: "Font Awesome 5 Solid";
content: "\f1da";
}
.tools::before,
/*.tools::before,*/
.services::before {
display: none;
font-family: "Font Awesome 5 Regular";
@ -185,11 +185,11 @@
font-family: "Font Awesome 5 Solid";
content: "\f21b";
}
.users::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f234";
}
/*.users::before {*/
/* display: none;*/
/* font-family: "Font Awesome 5 Solid";*/
/* content: "\f234";*/
/*}*/
.group::before {
display: none;
font-family: "Font Awesome 5 Solid";
@ -200,11 +200,11 @@
font-family: "Font Awesome 5 Regular";
content: "\f2b9";
}
.settings::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f0ad";
}
/*.settings::before {*/
/* display: none;*/
/* font-family: "Font Awesome 5 Solid";*/
/* content: "\f0ad";*/
/*}*/
.add-admin::before {
display: none;
font-family: "Font Awesome 5 Solid";
@ -362,16 +362,16 @@
.note-symbol .question-circle {
padding-left: 5px;
}
.port-scanner::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f796";
}
.net-tools::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f7d9";
}
/*.port-scanner::before {*/
/* display: none;*/
/* font-family: "Font Awesome 5 Solid";*/
/* content: "\f796";*/
/*}*/
/*.net-tools::before {*/
/* display: none;*/
/* font-family: "Font Awesome 5 Solid";*/
/* content: "\f7d9";*/
/*}*/
.shield::before {
display: none;
font-family: "Font Awesome 5 Solid";

View File

@ -37,8 +37,10 @@
height: 40px;
box-sizing: border-box;
border: solid 5px transparent;
border-top-color: #5d9ceb;
border-left-color: #5d9ceb;
/*border-top-color: #5d9ceb;*/
/*border-left-color: #5d9ceb;*/
border-top-color: var(--color-wanring);
border-left-color: var(--color-wanring);
border-radius: 50%;
-webkit-animation: nprogress-spinner 400ms linear infinite;
animation: nprogress-spinner 400ms linear infinite;

File diff suppressed because one or more lines are too long

View File

@ -8,32 +8,43 @@
--right-menu-blue-rolor: #5D9CEB;
--yellow-color: #ffcc00;
--unknown-color: #fff3cd;
--border-radius: 3px;
--indent: 15px;
--container--width: 1434px;
--background: #f0f0f0;
--background-dark: #e9e9e9;
--color-black: #000000;
--color-white: #ffffff;
--color-wanring: #ff9501;
--color-secondary: #8d8d8d;
--color-blue: #027f9f;
--color-gray: #D9D9D9;
--color-gray-light: #e7e7e7;
--color-gray-alpha: rgba(217, 217, 217, 0.5);
--color-gray-light-alpha: rgba(217, 217, 217, 0.3);
--color-gray-dark-alpha: rgba(192, 192, 192, 0.3);
--border-radius: 10px;
}
html {
font-size: 10px;
}
body {
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
font-size: 1.2em;
line-height: 1.42857143;
color: #000;
background-color: #fff;
margin: 0;
padding: 0;
overflow: auto;
height:100%
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
font-size: 1.2em;
line-height: 1.42857143;
color: #000;
margin: 0;
padding: 0;
overflow: auto;
height: 100%;
background-color: var(--background);
}
h2 {
font-size: 1.5em;
background: var(--blue-color);
border: 1px solid var(--blue-color);
padding: 2px 3px 3px 15px;
color: #fff;
margin-top: 0;
margin-bottom: 0;
height: 27px;
font-size: 3em;
background-color: transparent;
border: none;
color: var(--color-black);
margin-bottom: 20px;
margin-left: var(--indent);
}
h3 {
margin-top: -0;
@ -49,7 +60,7 @@ ul#browse_history {
margin-top: 3px;
margin-bottom: -1px;
list-style: none;
border-bottom: 1px solid #D9D9D9;
border: none;
padding-bottom: 5px;
clear: both;
}
@ -94,7 +105,7 @@ pre {
.icon-hapservs {
margin-bottom: 0;
}
.top-menu {
.top-menu {
position: absolute;
min-height: calc(99vh - 50px);
height: 120%;
@ -105,14 +116,15 @@ pre {
right: 0;
left: 0;
display: block;
background-color: var(--menu-color);
background-color: var(--color-gray-light) !important;
font-size: 12px;
z-index: 99;
}
.menu-active {
padding-left: 30px;
background-color: var(--right-menu-blue-rolor) !important;
border-left: 4px solid var(--right-menu-blue-rolor);
padding-left: 30px;
background-color: var(--color-gray-dark-alpha) !important;
border-left: none;
border-left: 4px solid var(--color-wanring) !important;
}
.logoText {
color: #EBF1F1;
@ -120,25 +132,34 @@ pre {
font-style: italic;
font-weight: bold;
height: 32px;
border-bottom: 1px solid aliceblue;
border-bottom: none;
padding-left: 20px;
padding-top: 2px;
padding-bottom: 5px;
}
#logo_text {
display: block;
margin-top: -4px;
}
.top-menu img {
.menu-logo {
max-width: 200px;
margin-left: 23px;
margin-top: 3px;
}
.menu-vendor-logo {
width: 20px;
margin: -20px 5px -6px 0;
padding: 0;
}
.menu-vendor-a {
padding-bottom: 5px;
padding-top: 5px;
}
.container {
min-height: calc(99vh - 50px);
height: auto;
max-width: 100%;
min-width: 40%;
background-color: #fff;
background-color: var(--background);
margin-left: 207px;
padding-bottom: 10px;
}
@ -148,10 +169,10 @@ pre {
left: 0;
max-width: 91%;
min-width: 40%;
background-color: #fff;
background-color: var(--background);
margin-left: 207px;
margin-right: 20px;
border-top: 1px solid #ddd;
border-top: none;
clear: both;
}
#version {
@ -160,25 +181,17 @@ pre {
font-size: 14.5px;
font-weight: bold;
}
#logo_footer {
float: left;
margin-left: 43%;
}
#logo_footer_img {
width: 35px;
margin-top: 8px;
}
.footer-div {
display: block;
display: block;
padding-top: 11px;
text-align: right;
margin-right: 20px;
width: 380px;
width: 450px;
float: left;
margin-left: 16%;
margin-left: 71%;
margin-top: -50px;
}
.footer-link, .footer-copyright {
color: var(--blue-color);
font-size: 0.9em;
padding: 12px 5px 20px 15px;
}
@ -187,79 +200,60 @@ pre {
float: left;
margin-left: 10px;
}
#main_div {
margin-top: 10%;
margin-left: 35%;
@media (max-width: 1900px) {
margin-top: 7%;
margin-left: 26%;
}
@media (max-width: 1500px) {
margin-left: 25%;
}
@media (max-width: 1024px) {
margin-left: 16%;
}
@media (max-width: 430px) {
margin-left: 12%;
margin-top: 20%;
}
}
#logo_span {
height: 270px;
float: left;
@media (max-width: 1900px) {
margin-left: 12%;
}
}
#logo_span img {
margin: auto 40px auto 100px;
width: 330px;
}
.login {
float: right;
margin-top: 3px;
margin-left: 14px;
margin-right: 50px;
color: #fff !important;
color: var(--color-wanring) !important;
font-size: 15px;
cursor: pointer;
@media (width <= 1500px) {
margin-left: -260px;
}
}
.auto-refresh {
margin-left: auto;
float: right;
margin-top: 3.7px;
margin-right: 5px;
.logs_link, .accordion-link, .link, .alert a {
color: var(--color-wanring) !important;
}
.auto-refresh-span, .auto-refresh a {
color: #fff !important;
cursor: pointer;
font-size: 15px;
}
.auto-refresh-div {
display: none;
position: relative;
padding: 10px;
background-color: #F5F5F5;
border-top: solid 1px #D9D9D9;
margin-bottom: 10px;
line-height: 20px;
}
.auto-refresh-div span, .auto-refresh-div a {
color: #000;
cursor: pointer;
}
.auto-refresh-head {
font-size: 16px;
color: #2d2d2d;
font-weight: bold;
margin-left: 83%;
}
.auto-refresh-interval {
float: right;
padding: 0 15px;
margin-top: 5px;
margin-bottom: 10px;
margin-left: 60%;
}
.auto-refresh-ul{
#auth {
margin-top: 260px;
margin-left: -310px;
float: left;
padding-left: 0;
list-style: none;
margin-top: 10px;
}
.auto-refresh-ul ul li {
margin: 0;
padding: 0 0 0 15px;
border: 0;
font-family: inherit;
vertical-align: baseline;
list-style: none;
}
.auto-refresh-pause, .auto-refresh-resume {
margin-top: 10px;
margin-left: -100px;
position: fixed;
color: #000;
font-size: 12px;
height: 15px;
}
.auto-refresh-reload-icon {
margin-top: 3px;
display: block;
float: left;
margin-right: 5px;
@media (max-width: 1900px) {
margin-left: -260px;
}
@media (width <= 1900px) {
margin-left: -310px;
}
}
.configShow, .diff {
overflow: auto;
@ -302,29 +296,26 @@ pre {
font-weight: bold;
}
.line {
background-color: #f3f8fb;
background-color: var(--background-dark);
border: 1px solid #ddd;
}
.line, .line3 {
padding: 5px 10px;
}
.line:hover {
background-color: #f6f8fa;
}
.line3:hover {
background-color: #f6f8ff;
.line:hover, .line3:hover {
background-color: var(--color-gray-light);
}
.accordion-link {
float: right;
margin-right: 1em;
}
.time-range {
border: 0;
background-color: #f5faf4;
font-weight: bold;
width: 18px;
padding-left: 0;
padding-right: 0;
border: 0;
background-color: var(--color-gray-light);
font-weight: bold;
width: 18px;
padding-left: 0;
padding-right: 0;
}
.comment {
color: #aaa;
@ -374,27 +365,27 @@ pre {
display: block;
}
.overview-wi {
width: 47%;
min-width: 566px;
width: 47%;
min-width: 566px;
max-width: 50%;
min-height: 160px;
float: left;
margin: 0 20px 20px 7px;
border-bottom: 1px solid #D9D9D9;
border-top: 1px solid #D9D9D9;
min-height: 160px;
float: left;
margin: 0 20px 20px 7px;
border: none;
}
.overviewHead {
border-radius: 5px;
background-color: #fbfbfb;
font-weight: bold;
border-radius: var(--border-radius);
background-color: var(--color-gray-light);
font-weight: bold;
}
.overview-wi .overviewHead {
border-bottom: 1px solid #A4C7F5;
height: 25px;
height: 25px;
border-radius: var(--border-radius);
background-color: var(--color-gray-alpha);
border: none;
}
.overview tr{
border-bottom: 1px solid #ddd;
border-radius: 5px;
.overview tr {
border: none;
}
.checkbox {
min-width: 30px;
@ -435,7 +426,7 @@ pre {
background-color: #ddd;
}
.add-button {
background-color: var(--blue-color);
background-color: var(--right-menu-blue-rolor);
border-radius: 5px;
color: #fff;
padding: 5px 10px;
@ -515,19 +506,18 @@ ul{
font-size: 1.1em;
}
.menu a {
background: var(--menu-color);
color: #fff;
background-color: var(--color-gray-light);
color: var(--color-black) !important;
padding: 10px;
display: block;
border-bottom: 1px solid #666;
border-bottom: none;
transition: 0.5s all;
cursor: pointer;
}
.menu a:hover {
background: #48505A;
padding: 10px 0 10px 20px;
color: #fff;
border-left: 4px solid var(--blue-color);
background: var(--color-gray-light) !important;
color: var(--color-wanring) !important;
border-left: none;
}
.menu li:first-child a, .menu li .v_menu li:first-child a{
border-radius: 3px 3px 0 0;
@ -549,7 +539,7 @@ ul{
transition: 0.5s opacity;
}
.v_menu a {
background-color: #48505A;
background-color: var(--color-gray-light) !important;
}
.p_menu:hover .v_menu{
opacity: 1;
@ -559,7 +549,7 @@ ul{
content: "";
position: absolute;
border:5px solid;
border-color: transparent transparent transparent #eee;
border-color: transparent var(--color-gray) transparent transparent;
top:1em;
right: 0.7em;
transition: 0.5s;
@ -570,35 +560,23 @@ ul{
.head-submenu {
margin-left: 20px;
}
@keyframes shadow {
from {box-shadow: 0 0 0 red inset;}
50% {text-shadow: 0 0 30px black;}
to {box-shadow: 0 -5px 5px -5px rgb(38, 137, 60) inset}
}
@keyframes shadow-red {
from {box-shadow: 0 0 0 red inset;}
50% {text-shadow: 0 0 30px black;}
to {box-shadow: 0 -5px 5px -5px var(--blue-color) inset}
}
.form-control:hover {
animation: shadow-red 0.3s forwards;
}
.form-control:invalid, .form-control:valid {
background-image: linear-gradient(0deg,#d50000 2px,rgba(213,0,0,0) 0),linear-gradient(0deg,rgba(0,0,0,.26) 1px,transparent 0);
}
.form-control {
background: no-repeat bottom,50% calc(100% - 1px);
background-size: 0 100%,100% 100%;
border: 0;
background: no-repeat bottom, 50% calc(100% - 1px);
background-size: 0 100%, 100% 100%;
transition: background 1s ease-out;
font-size: 0.9em;
font-size: 0.9em;
border-top: none;
border-left: none;
border-right: none;
border-bottom: 1px solid var(--color-secondary);
}
.form-login {
background-color: #fff;
background-color: var(--color-gray) !important;
padding: 10px 10px 10px 30px;
width: 220px;
background-size: 0 !important;
border: 0 !important;
width: 220px;
background-size: 0 !important;
border: none;
border-radius: var(--border-radius);
}
.ui-selectmenu-open, .ui-selectmenu-menu {
z-index: 1010 !important;
@ -650,7 +628,7 @@ ul{
}
.ui-state-active {
background-color: #376fb6 !important;
border: none var(--link-dark-blue) !important;
border: none;
}
.ui-tabs-nav {
border-radius: 0 !important;
@ -658,9 +636,10 @@ ul{
padding-top: 0.28em !important;
}
.ui-tabs .ui-tabs-panel {
background-color: var(--background) !important;
padding: 0 !important;
padding-bottom: 10px !important;
}
}
.ui-tabs {
padding-left: 0 !important;
margin-left: -2px;
@ -678,6 +657,50 @@ ul{
.ui-state-focus {
border: none !important;
}
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited, a.ui-button, a:link.ui-button, a:visited.ui-button, .ui-button {
background-color: var(--color-gray-dark-alpha) !important;
border-radius: 7px !important;
border: none !important;
}
.ui-state-active, .ui-widget-content .ui-state-active {
background-color: var(--color-blue) !important;
color: #fff !important;
}
.ui-widget-header .ui-state-active, a.ui-button:active, .ui-button:active {
color: #D6D6D6 !important;
background-color: var(--color-gray-dark-alpha) !important;
border: none !important;
}
.ui-button.ui-state-active:hover {
background-color: var(--color-blue) !important;
}
.ui-icon-blank.ui-icon-blank.ui-icon-blank {
background-color: var(--background) !important;
}
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited {
color: var(--color-black) !important;
}
.ui-widget.ui-widget-content, .ui-widget-content {
border: none !important;
}
.ui-widget-header {
background-color: var(--color-gray-light) !important;
}
.ui-dialog {
padding: 0 !important;
}
.ui-dialog .ui-dialog-content {
background-color: var(--background) !important;
}
.ui-widget-content {
background-color: var(--background) !important;
}
.ui-dialog .ui-dialog-title {
color: var(--color-black) !important;
}
.ui-tabs-active, .ui-state-active, .ui-state-focus, .ui-tabs-focus {
border: none !important;
}
.need-field {
color: var(--red-color);
}
@ -688,7 +711,7 @@ a, a:visited {
text-decoration: underline;
}
a {
color: var(--link-dark-blue);
color: var(--color-wanring);
text-decoration: none;
background-color: transparent;
}
@ -700,18 +723,14 @@ a:focus {
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
.logs_link, .accordion-link, .link {
color: var(--blue-color) !important;
.accordion-link, .link {
color: var(--color-wanring) !important;
cursor: pointer;
}
.logs_link {
color: var(--link-dark-blue) !important;
}
table {
border-spacing: 0;
border-collapse: collapse;
background-color: transparent;
border-top: 1px solid #ddd;
border-radius: var(--border-radius);
width: 100%;
font-size: 1.1em;
@ -728,8 +747,17 @@ td,th {
text-align: left;
min-width: 25px;
}
textarea {
background-color: var(--background);
}
.odd {
background-color: var(--background) !important;
}
.even {
background-color: var(--color-gray-light-alpha) !important;
}
.odd:hover, .even:hover {
background-color: var(--light-blue-color);
background-color: var(--color-gray-alpha);
}
.row {
margin-right: -15px;
@ -751,6 +779,7 @@ td,th {
}
.alert-danger, .alert-info, .alert-success, .alert-warning, .added {
margin-top: var(--indent);
border-radius: var(--border-radius);
}
.alert-danger {
color: #a94442;
@ -759,24 +788,23 @@ td,th {
margin-bottom: -50px;
}
.alert-success, .added{
color: #3c763d;
background-color: #dff0d8;
border-color: #d6e9c6;
color: var(--color-blue);
background-color: rgba(2, 159, 201, 0.15);
}
.alert-info {
color: #0c5460;
background-color: #d1ecf1;
border-color: #bee5eb;
margin-left: var(--indent);
color: #0c5460;
background-color: var(--color-gray-light);
border: none;
margin-left: var(--indent);
border-radius: var(--border-radius);
}
.alert-warning {
color: #856404;
background-color: var(--unknown-color);
border-color: #ffeeba;
color: #000;
background-color: rgba(255, 149, 1, 0.15);
}
.wrong-login {
display: none;
margin-top: 220px;
margin-top: 450px;
margin-right: 50px;
width: 300px;
text-align: center;
@ -804,19 +832,13 @@ label {
font-weight: bold;
padding-right: 10px;
}
.odd {
background-color: white;
}
.even {
background-color: #f3f8fb;
}
#up-pannel {
margin-top: var(--indent);
}
.div-server, .div-server-hapwi, .bin_bout {
background-color: #fbfbfb;
border: 1px solid #A4C7F5;
border-radius: var(--border-radius);
background-color: var(--color-gray-light-alpha);
border: none;
border-radius: var(--border-radius);
height: 165px;
width: 400px;
padding: 10px 15px 20px;
@ -828,19 +850,19 @@ label {
height: 95px;
}
.div-server-head-up {
border-top: 3px solid var(--green-color) !important;
border-top: 7px solid var(--green-color) !important;
}
.div-server-head-down {
border-top: 3px solid var(--red-color) !important;
border-top: 7px solid var(--red-color) !important;
}
.div-server-head-dis {
border-top: 3px solid #aaa !important;
border-top: 7px solid #aaa !important;
}
.div-server-head-pause {
border-top: 3px solid orange !important;
border-top: 7px solid orange !important;
}
.div-server-head-unknown {
border-top: 3px solid #efdb9d !important;
border-top: 7px solid #efdb9d !important;
}
.div-server-head-up, .div-server-head-down, .div-server-head-dis, .div-server-head-pause {
padding-top: 7px;
@ -858,12 +880,17 @@ label {
width: 91.2%;
}
.server-name {
padding-bottom: 3px;
padding-bottom: 3px;
font-size: 1.4em;
color: var(--blue-color);
border-bottom: 1px solid #A4C7F5;
width: 99%;
height: 25px;
color: var(--color-wanring);
width: 99%;
height: 25px;
border: none;
}
.name-span {
width: 260px;
display: inline-block;
margin-top: 3px;
}
.server-status {
border-radius: 50% 50%;
@ -906,12 +933,13 @@ label {
float: left;
}
.ajax-server {
border-radius: var(--border-radius);
margin: 25px 25px 0 787px;
width: 797px;
display: none;
height: 185px;
padding: 10px 0 0 15px;
display: block;
background-color: var(--color-gray-light);
border-radius: var(--border-radius);
margin: 25px 25px 0 787px;
width: 797px;
height: 185px;
padding: 10px 0 0 15px;
}
.haproxy-info {
display: inline-block;
@ -955,16 +983,6 @@ label {
.span-link {
cursor: pointer;
}
#logo_span {
float: left;
margin-left: 8%;
border-right: 3px solid #ddd;
height: 270px;
}
#logo_span img {
margin: auto 40px auto 100px;
width: 330px;
}
.chart-container, .chart-container_overview {
position: relative;
height: 300px;
@ -996,11 +1014,11 @@ label {
width: 300px;
height: 185px;
float: left;
background-color: #fbfbfb;;
background-color: var(--color-gray-light-alpha);
margin: 10px 10px 10px 0;
padding-left: var(--indent);
padding-top: 0;
border: 1px solid #A4C7F5;
border-radius: var(--border-radius);
}
#good_services {
clear: both;
@ -1015,7 +1033,6 @@ label {
padding-top: 5px;
padding-bottom: 3px;
color: var(--blue-color);
border-bottom: 1px solid #A4C7F5;
width: 93%;
margin-bottom: 5px;
}
@ -1046,9 +1063,8 @@ label {
border-color: #ebccd1;
}
.unknown {
color: #856404;
background-color: var(--unknown-color);
border-color: #ffeeba;
color: #e3a556;
background-color: rgba(255, 149, 1, 0.15);
}
.disable {
background-color: grey;
@ -1058,23 +1074,11 @@ label {
cursor: pointer;
}
@media (max-width: 1920px) {
#logo_span {
margin-left: 17%;
}
}
@media (max-width: 1900px) {
#logo_span {
margin-left: 15%;
}
.wrong-login {
margin-left: 44%;
margin-left: -360px;
}
}
@media (max-width: 1600px) {
#logo_span img {
width: 300px;
margin: 25px 50px auto 85px;
}
.ajax-server {
clear: both !important;
margin-left: 20px !important;
@ -1083,10 +1087,6 @@ label {
}
}
@media (max-width: 1450px) {
#logo_span img {
width: 250px;
margin: 35px 30px auto 120px;
}
.ajax-server, .div-backends {
clear: both !important;
margin-left: 20px !important;
@ -1112,10 +1112,6 @@ label {
}
}
@media (max-width: 1280px) {
#logo_span img {
width: 250px;
margin: 30px 60px auto 70px;
}
.div-pannel {
height: 430px !important;
}
@ -1134,13 +1130,6 @@ label {
}
}
@media (max-width: 1024px) {
#logo_span {
margin-left: -5%;
}
#logo_span img {
width: 250px;
margin: 35px 0 auto 120px;
}
.wrong-login {
margin-right: -150px;
}
@ -1159,13 +1148,6 @@ label {
}
}
@media (max-width: 1080px) {
#logo_span {
margin-left: -5%;
}
#logo_span img {
width: 250px;
margin: 35px 60px auto 120px;
}
.chart-container {
position: relative;
height: 410px;
@ -1190,14 +1172,6 @@ label {
}
}
@media (max-width: 768px) {
#logo_span {
margin-left: -12%;
border: none;
}
#logo_span img {
width: 250px;
margin: 35px 0 auto 120px;
}
.wrong-login {
margin-right: -260px;
}
@ -1225,14 +1199,6 @@ label {
}
}
@media (max-width: 667px) {
#logo_span {
margin-left: -12%;
border: none;
}
#logo_span img {
width: 250px;
margin: 35px 0 auto 120px;
}
.wrong-login {
margin-right: -210px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 81 KiB

View File

@ -262,10 +262,10 @@ $( function() {
request.term = 1
}
$.ajax({
url: "/app/server/show/ip/" + $("#serv").val(),
url: `/server/${$("#serv").val()}/ip`,
contentType: "application/json; charset=utf-8",
success: function (data) {
data = data.replace(/\s+/g, ' ');
response(data.split(" "));
response(data);
}
});
},
@ -282,10 +282,10 @@ $( function() {
request.term = 1
}
$.ajax({
url: "/app/server/show/ip/" + $("#serv2").val(),
url: `/server/${$("#serv2").val()}/ip`,
contentType: "application/json; charset=utf-8",
success: function (data) {
data = data.replace(/\s+/g, ' ');
response(data.split(" "));
response(data);
}
});
},
@ -302,7 +302,7 @@ $( function() {
request.term = 1
}
$.ajax({
url: "/app/runtimeapi/backends/" + $("#serv2").val(),
url: "/runtimeapi/backends/" + $("#serv2").val(),
success: function (data) {
response(data.split('<br>'));
}
@ -317,7 +317,7 @@ $( function() {
request.term = 1
}
$.ajax({
url: "/app/add/haproxy/bwlists/black/" + $("#group_id").val(),
url: "/add/haproxy/bwlists/black/" + $("#group_id").val(),
success: function (data) {
data = data.replace(/\s+/g, ' ');
response(data.split(" "));
@ -333,7 +333,7 @@ $( function() {
request.term = 1
}
$.ajax({
url: "/app/add/haproxy/bwlists/black/" + $("#group_id").val(),
url: "/add/haproxy/bwlists/black/" + $("#group_id").val(),
success: function (data) {
data = data.replace(/\s+/g, ' ');
response(data.split(" "));
@ -349,7 +349,7 @@ $( function() {
request.term = 1
}
$.ajax({
url: "/app/add/haproxy/bwlists/white/" + $("#group_id").val(),
url: "/add/haproxy/bwlists/white/" + $("#group_id").val(),
success: function (data) {
data = data.replace(/\s+/g, ' ');
response(data.split(" "));
@ -365,7 +365,7 @@ $( function() {
request.term = 1
}
$.ajax({
url: "/app/add/haproxy/bwlists/white/" + $("#group_id").val(),
url: "/add/haproxy/bwlists/white/" + $("#group_id").val(),
success: function (data) {
data = data.replace(/\s+/g, ' ');
response(data.split(" "));
@ -399,7 +399,7 @@ $( function() {
});
$("#saved-options").autocomplete({
dataType: "json",
source: "/app/add/option/get/" + $('#group_id').val(),
source: "/add/option/get/" + $('#group_id').val(),
autoFocus: true,
minLength: 1,
select: function (event, ui) {
@ -420,7 +420,7 @@ $( function() {
});
$("#saved-options1").autocomplete({
dataType: "json",
source: "/app/add/option/get/" + $('#group_id').val(),
source: "/add/option/get/" + $('#group_id').val(),
autoFocus: true,
minLength: 1,
select: function (event, ui) {
@ -441,7 +441,7 @@ $( function() {
});
$("#saved-options2").autocomplete({
dataType: "json",
source: "/app/add/option/get/" + $('#group_id').val(),
source: "/add/option/get/" + $('#group_id').val(),
autoFocus: true,
minLength: 1,
select: function (event, ui) {
@ -457,7 +457,7 @@ $( function() {
});
$('#add-option-new').click(function () {
$.ajax({
url: "/app/add/option/save",
url: "/add/option/save",
data: {
option: $('#new-option').val()
},
@ -481,7 +481,7 @@ $( function() {
});
$('[name=servers]').autocomplete({
source: "/app/add/server/get/" + $('#group_id').val(),
source: "/add/server/get/" + $('#group_id').val(),
autoFocus: true,
minLength: 1,
select: function (event, ui) {
@ -501,7 +501,7 @@ $( function() {
});
$('#add-saved-server-new').click(function () {
$.ajax({
url: "/app/add/server/save",
url: "/add/server/save",
data: {
server: $('#new-saved-servers').val(),
desc: $('#new-saved-servers-description').val()
@ -722,7 +722,7 @@ $( function() {
$("[name=port_check_text]").show("fast");
}
});
let cur_url = window.location.href.split('/app/').pop();
let cur_url = window.location.href.split('/').pop();
cur_url = cur_url.split('/');
if (cur_url[0] == "add") {
$("#cache").checkboxradio("disable");
@ -838,7 +838,7 @@ $( function() {
source: function (request, response) {
if (!checkIsServerFiled('#serv')) return false;
$.ajax({
url: "/app/add/certs/" + $('#serv').val(),
url: "/add/certs/" + $('#serv').val(),
success: function (data) {
data = data.replace(/\s+/g, ' ');
response(data.split(" "));
@ -852,7 +852,7 @@ $( function() {
source: function (request, response) {
if (!checkIsServerFiled('#serv2')) return false;
$.ajax({
url: "/app/add/certs/" + $('#serv2').val(),
url: "/add/certs/" + $('#serv2').val(),
success: function (data) {
data = data.replace(/\s+/g, ' ');
response(data.split(" "));
@ -867,7 +867,7 @@ $( function() {
if (!checkIsServerFiled('#ssl_name', 'Enter the Certificate name')) return false;
if (!checkIsServerFiled('#ssl_cert', 'Paste the contents of the certificate file')) return false;
$.ajax({
url: "/app/add/cert/add",
url: "/add/cert/add",
data: {
serv: $('#serv4').val(),
ssl_cert: $('#ssl_cert').val(),
@ -893,7 +893,7 @@ $( function() {
$('#ssl_key_view').click(function () {
if (!checkIsServerFiled('#serv5')) return false;
$.ajax({
url: "/app/add/certs/" + $('#serv5').val(),
url: "/add/certs/" + $('#serv5').val(),
success: function (data) {
if (data.indexOf('error:') != '-1') {
toastr.error(data);
@ -931,7 +931,7 @@ $( function() {
} else if (validateEmail(lets_email)) {
$("#ajax-ssl").html(wait_mess);
$.ajax({
url: "/app/add/lets",
url: "/add/lets",
data: {
serv: $('#serv_for_lets').val(),
lets_domain: lets_domain,
@ -1324,7 +1324,7 @@ function confirmDeleteOption(id) {
function removeOption(id) {
$("#option-"+id).css("background-color", "#f2dede");
$.ajax( {
url: "/app/add/option/delete/" + id,
url: "/add/option/delete/" + id,
success: function( data ) {
data = data.replace(/\s+/g,' ');
if (data.indexOf('error:') != '-1') {
@ -1338,7 +1338,7 @@ function removeOption(id) {
function updateOptions(id) {
toastr.clear();
$.ajax({
url: "/app/add/option/update",
url: "/add/option/update",
data: {
option: $('#option-body-' + id).val(),
id: id,
@ -1381,7 +1381,7 @@ function confirmDeleteSavedServer(id) {
function removeSavedServer(id) {
$("#servers-saved-"+id).css("background-color", "#f2dede");
$.ajax( {
url: "/app/add/server/delete/"+id,
url: "/add/server/delete/"+id,
success: function( data ) {
data = data.replace(/\s+/g,' ');
if(data.indexOf('ok') != '-1') {
@ -1393,7 +1393,7 @@ function removeSavedServer(id) {
function updateSavedServer(id) {
toastr.clear();
$.ajax( {
url: "/app/add/server/update",
url: "/add/server/update",
data: {
server: $('#servers-ip-'+id).val(),
desc: $('#servers-desc-'+id).val(),
@ -1417,7 +1417,7 @@ function view_ssl(id) {
let raw_word = translate_div.attr('data-raw');
if(!checkIsServerFiled('#serv5')) return false;
$.ajax( {
url: "/app/add/cert/" + $('#serv5').val() + '/' + id,
url: "/add/cert/" + $('#serv5').val() + '/' + id,
success: function( data ) {
if (data.indexOf('error: ') != '-1') {
toastr.error(data);
@ -1453,7 +1453,7 @@ function view_ssl(id) {
}
function showRawSSL(id) {
$.ajax({
url: "/app/add/cert/get/raw/" + $('#serv5').val() + "/" + id,
url: "/add/cert/get/raw/" + $('#serv5').val() + "/" + id,
success: function (data) {
if (data.indexOf('error: ') != '-1') {
toastr.error(data);
@ -1490,7 +1490,7 @@ function showRawSSL(id) {
function deleteSsl(id) {
if (!checkIsServerFiled('#serv5')) return false;
$.ajax({
url: "/app/add/cert/" + $("#serv5").val() + "/" + id,
url: "/add/cert/" + $("#serv5").val() + "/" + id,
type: "DELETE",
success: function (data) {
if (data.indexOf('error: ') != '-1') {
@ -1505,10 +1505,10 @@ function deleteSsl(id) {
}
function change_select_acceleration(id) {
$.ajax({
url: "/app/service/haproxy/version/" + $('#serv' + id + ' option:selected').val(),
url: "/service/haproxy/" + $('#serv' + id + ' option:selected').val() + "/status",
contentType: "application/json; charset=utf-8",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (parseFloat(data) < parseFloat('1.8') || data == ' ') {
if (parseFloat(data.Version.split('-')[0]) < parseFloat('1.8') || data.Version == ' ') {
$("#cache" + id).checkboxradio("disable");
} else {
$("#cache" + id).checkboxradio("enable");
@ -1518,9 +1518,10 @@ function change_select_acceleration(id) {
}
function change_select_waf(id) {
$.ajax({
url: "/app/service/haproxy/version/" + $('#serv' + id + ' option:selected').val(),
url: "/service/haproxy/" + $('#serv' + id + ' option:selected').val() + "/status",
contentType: "application/json; charset=utf-8",
success: function (data) {
if (parseFloat(data) < parseFloat('1.8')) {
if (parseFloat(data.Version.split('-')[0]) < parseFloat('1.8') || data.Version == ' ') {
$("#waf" + id).checkboxradio("disable");
} else {
$("#waf" + id).checkboxradio("enable");
@ -1536,7 +1537,7 @@ function createList(color) {
}
list = escapeHtml(list);
$.ajax( {
url: "/app/add/haproxy/bwlist/create",
url: "/add/haproxy/bwlist/create",
data: {
bwlists_create: list,
color: color
@ -1560,7 +1561,7 @@ function createList(color) {
}
function editList(list, color) {
$.ajax( {
url: "/app/add/haproxy/bwlist/" + list + "/" + color + "/" + $('#group_id').val(),
url: "/add/haproxy/bwlist/" + list + "/" + color + "/" + $('#group_id').val(),
success: function( data ) {
if (data.indexOf('error:') != '-1') {
toastr.error(data);
@ -1611,7 +1612,7 @@ function saveList(action, list, color) {
let serv = $("#serv-" + color + "-list option:selected").val();
if (!checkIsServerFiled($("#serv-" + color + "-list"))) return false;
$.ajax({
url: "/app/add/haproxy/bwlist/save",
url: "/add/haproxy/bwlist/save",
data: {
bwlists_save: list,
serv: serv,
@ -1640,7 +1641,7 @@ function deleteList(list, color) {
let serv = $( "#serv-"+color+"-list option:selected" ).val();
if(!checkIsServerFiled($("#serv-"+color+"-list"))) return false;
$.ajax({
url: "/app/add/haproxy/bwlist/delete/" + serv + "/" + color + "/" + list + "/" + $('#group_id').val(),
url: "/add/haproxy/bwlist/delete/" + serv + "/" + color + "/" + list + "/" + $('#group_id').val(),
success: function (data) {
if (data.indexOf('error:') != '-1' || data.indexOf('Failed') != '-1' || data.indexOf('Errno') != '-1') {
toastr.error(data);
@ -1659,7 +1660,7 @@ function createMap() {
map_name = $('#new_map_name').val()
map_name = escapeHtml(map_name);
$.ajax( {
url: "/app/add/map",
url: "/add/map",
data: {
map_name: map_name
},
@ -1682,7 +1683,7 @@ function createMap() {
}
function editMap(map) {
$.ajax({
url: "/app/add/map",
url: "/add/map",
data: {
map_name: map,
},
@ -1737,7 +1738,7 @@ function saveMap(action, map) {
let serv = $( "#serv-map option:selected" ).val();
if(!checkIsServerFiled($("#serv-map"))) return false;
$.ajax({
url: "/app/add/map",
url: "/add/map",
data: {
map_name: map,
serv: serv,
@ -1765,7 +1766,7 @@ function deleteMap(map) {
let serv = $( "#serv-map option:selected" ).val();
if(!checkIsServerFiled($("#serv-map"))) return false;
$.ajax({
url: "/app/add/map",
url: "/add/map",
data: {
map_name: map,
serv: serv,
@ -2071,10 +2072,10 @@ function make_actions_for_adding_bind(section_id) {
request.term = 1
}
$.ajax({
url: "/app/server/show/ip/" + $("#" + serv).val(),
url: "/server/" + $("#" + serv).val() + "/ip",
contentType: "application/json; charset=utf-8",
success: function (data) {
data = data.replace(/\s+/g, ' ');
response(data.split(" "));
response(data);
}
});
},
@ -2099,7 +2100,7 @@ function showUserlists() {
let select_id = $("#existing_userlist_serv");
if (!checkIsServerFiled(select_id)) return false;
$.ajax({
url: "/app/add/haproxy/userlist/" + serv,
url: "/add/haproxy/userlist/" + serv,
success: function (data) {
if (data.indexOf('error:') != '-1' || data.indexOf('Failed') != '-1') {
toastr.error(data);
@ -2111,7 +2112,7 @@ function showUserlists() {
let existing_userlist_ajax = $.find("#existing_userlist_ajax");
existing_userlist_ajax = existing_userlist_ajax[0].id;
data[i] = escapeHtml(data[i]);
$('#' + existing_userlist_ajax).append('<a href="/app/config/section/haproxy/' + serv + '/' + data[i] + '" title="Edit/Delete this userlist" target="_blank">' + data[i] + '</a> ');
$('#' + existing_userlist_ajax).append('<a href="/config/section/haproxy/' + serv + '/' + data[i] + '" title="Edit/Delete this userlist" target="_blank">' + data[i] + '</a> ');
}
}
}

View File

@ -36,19 +36,21 @@ $( function() {
var id = $(this).attr('id');
var val = $(this).val();
updateSettings(id, val);
updateSettings(id[1])
let section = $(this).parent().parent().attr('class').split(' ')[1].split('-')[0];
updateSettings(id, section, val);
});
$( "#settings input" ).change(function() {
var id = $(this).attr('id');
var val = $(this).val();
if($('#'+id).is(':checkbox')) {
if ($('#'+id).is(':checked')){
val = 1;
val = '1';
} else {
val = 0;
val = '0';
}
}
updateSettings(id, val);
let section = $(this).parent().parent().attr('class').split(' ')[1].split('-')[0];
updateSettings(id, section, val);
});
});
function hideAndShowSettings(section) {
@ -65,23 +67,27 @@ function hideAndShowSettings(section) {
$.getScript(awesome);
}
}
function updateSettings(param, val) {
function updateSettings(param, section, val) {
try {
val = val.replace(/\//g, "92");
} catch (e) {
val = val;
}
toastr.clear();
let json_data = {
'param': param,
'value': val
}
if (section === 'smon') {
section = 'rmon';
}
$.ajax({
url: "/app/admin/setting/" + param,
data: {
val: val,
token: $('#token').val()
},
url: "/admin/settings/" + section,
data: JSON.stringify(json_data),
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error:') != '-1') {
if (data.status === 'failed') {
toastr.error(data);
} else {
toastr.clear();

View File

@ -3,12 +3,7 @@ $( function() {
let activeTab = $(this).find("a").attr("href");
let activeTabClass = activeTab.replace('#', '');
$('.menu li ul li').each(function () {
$(this).find('a').css('border-left', '0px solid var(--right-menu-blue-rolor)');
$(this).find('a').css('padding-left', '20px')
$(this).find('a').css('background-color', '#48505A');
$(this).children("." + activeTabClass).css('padding-left', '30px');
$(this).children("." + activeTabClass).css('border-left', '4px solid var(--right-menu-blue-rolor)');
$(this).children("." + activeTabClass).css('background-color', 'var(--right-menu-blue-rolor)');
activeSubMenu($(this), activeTabClass)
});
if (activeTab == '#tools') {
loadServices();
@ -24,7 +19,7 @@ $( function() {
window.onload = function() {
$('#tabs').tabs();
let activeTabIdx = $('#tabs').tabs('option','active')
if (cur_url[0].split('#')[0] == 'admin') {
if (cur_url.split('#')[0] == 'admin') {
if (activeTabIdx == 6) {
loadServices();
} else if (activeTabIdx == 3) {
@ -40,7 +35,7 @@ function updateService(service, action='update') {
$("#ajax-update").html('')
$("#ajax-update").html(wait_mess);
$.ajax({
url: "/app/admin/tools/update/" + service,
url: "/admin/tools/update/" + service,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('Complete!') != '-1' || data.indexOf('Unpacking') != '-1') {
@ -90,7 +85,7 @@ function updateService(service, action='update') {
}
function loadSettings() {
$.ajax({
url: "/app/admin/settings",
url: "/admin/settings",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error:') != '-1') {
@ -106,7 +101,7 @@ function loadSettings() {
}
function loadServices() {
$.ajax({
url: "/app/admin/tools",
url: "/admin/tools",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('danger') != '-1' || data.indexOf('unique') != '-1' || data.indexOf('error:') != '-1') {
@ -120,7 +115,7 @@ function loadServices() {
}
function loadupdatehapwi() {
$.ajax({
url: "/app/admin/update",
url: "/admin/update",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('danger') != '-1' || data.indexOf('unique') != '-1' || data.indexOf('error:') != '-1') {
@ -133,7 +128,7 @@ function loadupdatehapwi() {
}
function checkUpdateRoxy() {
$.ajax({
url: "/app/admin/update/check",
url: "/admin/update/check",
success: function (data) {
loadupdatehapwi();
}
@ -163,7 +158,7 @@ function confirmAjaxServiceAction(action, service) {
}
function ajaxActionServices(action, service) {
$.ajax( {
url: "/app/admin/tools/action/" + service + "/" + action,
url: "/admin/tools/action/" + service + "/" + action,
success: function( data ) {
if (data.indexOf('error:') != '-1' || data.indexOf('Failed') != '-1') {
toastr.error(data);
@ -185,7 +180,7 @@ function showApacheLog(serv) {
let minute = $('#time_range_out_minut').val();
let hour1 = $('#time_range_out_hour1').val();
let minute1 = $('#time_range_out_minut1').val();
let url = "/app/logs/apache_internal/" + serv + "/" + rows;
let url = "/logs/apache_internal/" + serv + "/" + rows;
$.ajax( {
url: url,
data: {

View File

@ -39,13 +39,15 @@ function addGroup(dialog_id) {
let allFields = $([]).add($('#new-group-add'));
allFields.removeClass("ui-state-error");
valid = valid && checkLength($('#new-group-add'), "new group name", 1);
let name = $('#new-group-add').val();
let desc = $('#new-desc').val();
if (valid) {
let jsonData = {
'name': $('#new-group-add').val(),
'desc': $('#new-desc').val()
'name': name,
'desc': desc
}
$.ajax({
url: "/app/server/group",
url: "/server/group",
type: 'POST',
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
@ -55,7 +57,19 @@ function addGroup(dialog_id) {
} else {
let id = data.id;
$('select:regex(id, group)').append('<option value=' + id + '>' + $('#new-group-add').val() + '</option>').selectmenu("refresh");
common_ajax_action_after_success(dialog_id, 'newgroup', 'ajax-group', data.data);
let new_group = elem("tr", {"id":"group-"+id,"class":"newgroup"}, [
elem("td", {"class":"padding10","style":"width: 0"}, id),
elem("td", {"class":"padding10 first-collumn"}, [
elem("input", {"type":"text","name":"name-"+id,"value": name,"id":"name-"+id,"class":"form-control","autocomplete":"off"})
]),
elem("td", null, [
elem("input", {"type":"text","name":"descript-"+id,"value":desc,"id":"descript-"+id,"size":"60","class":"form-control","autocomplete":"off"})
]),
elem("td", null, [
elem("a", {"class":"delete","onclick":"confirmDeleteGroup("+id+")","title":"Delete group "+name,"style":"cursor: pointer;"})
])
])
common_ajax_action_after_success(dialog_id, 'newgroup', 'ajax-group', new_group);
}
}
});
@ -66,10 +80,9 @@ function updateGroup(id) {
let jsonData = {
"name": $('#name-' + id).val(),
"desc": $('#descript-' + id).val(),
"group_id": id
}
$.ajax({
url: "/app/server/group",
url: "/server/group/" + id,
type: "PUT",
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
@ -112,31 +125,41 @@ function confirmDeleteGroup(id) {
function removeGroup(id) {
$("#group-" + id).css("background-color", "#f2dede");
$.ajax({
url: "/app/server/group",
url: "/server/group/" + id,
type: 'DELETE',
data: JSON.stringify({'group_id': id}),
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
$("#group-" + id).remove();
statusCode: {
204: function (xhr) {
$("#group-" + id).remove();
$('select:regex(id, group) option[value=' + id + ']').remove();
$('select:regex(id, group)').selectmenu("refresh");
}
}
},
404: function (xhr) {
$("#group-" + id).remove();
$('select:regex(id, group) option[value=' + id + ']').remove();
$('select:regex(id, group)').selectmenu("refresh");
}
},
success: function (data) {
if (data) {
if (data.status === "failed") {
toastr.error(data);
}
}
}
});
}
function getGroupNameById(group_id) {
let group_name = ''
$.ajax({
url: "/app/user/group/name/" + group_id,
url: "/server/group/" + group_id,
async: false,
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.indexOf('error:') != '-1') {
if (data.status === 'failed') {
toastr.error(data);
} else {
group_name = data;
group_name = data.name;
}
}
});

View File

@ -65,7 +65,7 @@ function addServer(dialog_id) {
if ($('#scan_server').is(':checked')) {
scan_server = '1';
}
if ($('#typeip').is(':checked')) {
if ($('#type_ip').is(':checked')) {
type_ip = '1';
}
if ($('#enable').is(':checked')) {
@ -104,24 +104,24 @@ function addServer(dialog_id) {
}
if (valid) {
let json_data = {
"name": servername,
"hostname": servername,
"ip": ip,
"port": $('#new-port').val(),
"group": server_group,
"group_id": server_group,
"type_ip": type_ip,
"haproxy": haproxy,
'nginx': nginx,
"apache": apache,
"firewall": firewall,
"firewall_enable": firewall,
"add_to_smon": add_to_smon,
"enable": enable,
"slave": $('#slavefor').val(),
"cred": cred,
"desc": $('#desc').val(),
"enabled": enable,
"master": $('#slavefor').val(),
"cred_id": cred,
"description": $('#desc').val(),
"protected": 0
}
$.ajax({
url: "/app/server",
url: "/server",
type: "POST",
data: JSON.stringify(json_data),
contentType: "application/json; charset=utf-8",
@ -145,40 +145,18 @@ function addServer(dialog_id) {
$('select:regex(id, haproxyaddserv)').append('<option value=' + ip + '>' + servername + '</option>').selectmenu("refresh");
$('select:regex(id, nginxaddserv)').append('<option value=' + ip + '>' + servername + '</option>').selectmenu("refresh");
$('select:regex(id, apacheaddserv)').append('<option value=' + ip + '>' + servername + '</option>').selectmenu("refresh");
after_server_creating(servername, ip, scan_server);
}
}
});
}
}
function after_server_creating(servername, ip, scan_server) {
let json_data = {
"name": servername,
"ip": ip,
"scan_server": scan_server
}
$.ajax({
url: "/app/server",
data: JSON.stringify(json_data),
contentType: "application/json; charset=utf-8",
type: "PATCH",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('You should install lshw on the server') != '-1') {
toastr.error(data);
} else if (data.indexOf('error:') != '-1') {
toastr.error(data);
}
}
});
}
function updateServer(id) {
toastr.clear();
let type_ip = 0;
let enable = 0;
let firewall = 0;
let protected_serv = 0;
if ($('#typeip-' + id).is(':checked')) {
if ($('#type_ip-' + id).is(':checked')) {
type_ip = '1';
}
if ($('#enable-' + id).is(':checked')) {
@ -195,20 +173,20 @@ function updateServer(id) {
group = $('#new-sshgroup').val();
}
let json_data = {
"name": $('#hostname-' + id).val(),
"hostname": $('#hostname-' + id).val(),
"port": $('#port-' + id).val(),
"group": group,
"ip": $('#ip-' + id).text(),
"group_id": group,
"type_ip": type_ip,
"firewall": firewall,
"enable": enable,
"slave": $('#slavefor-' + id + ' option:selected').val(),
"cred": $('#credentials-' + id + ' option:selected').val(),
"id": id,
"desc": $('#desc-' + id).val(),
"firewall_enable": firewall,
"enabled": enable,
"master": $('#slavefor-' + id + ' option:selected').val(),
"cred_id": $('#credentials-' + id + ' option:selected').val(),
"description": $('#desc-' + id).val(),
"protected": protected_serv
}
$.ajax({
url: "/app/server",
url: "/server/" + id,
type: 'PUT',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(json_data),
@ -253,10 +231,10 @@ function cloneServer(id) {
} else {
$('#enable').prop('checked', false)
}
if ($('#typeip-'+id).is(':checked')) {
$('#typeip').prop('checked', true)
if ($('#type_ip-'+id).is(':checked')) {
$('#type_ip').prop('checked', true)
} else {
$('#typeip').prop('checked', false)
$('#type_ip').prop('checked', false)
}
if ($('#haproxy-'+id).is(':checked')) {
$('#haproxy').prop('checked', true)
@ -269,7 +247,7 @@ function cloneServer(id) {
$('#nginx').prop('checked', false)
}
$('#enable').checkboxradio("refresh");
$('#typeip').checkboxradio("refresh");
$('#type_ip').checkboxradio("refresh");
$('#haproxy').checkboxradio("refresh");
$('#nginx').checkboxradio("refresh");
$('#new-server-add').val($('#hostname-'+id).val())
@ -288,22 +266,29 @@ function cloneServer(id) {
function removeServer(id) {
$("#server-" + id).css("background-color", "#f2dede");
$.ajax({
url: "/app/server",
url: "/server/" + id,
type: "DELETE",
data: JSON.stringify({'id': id}),
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
statusCode: {
204: function (xhr) {
$("#server-" + id).remove();
},
404: function (xhr) {
$("#server-" + id).remove();
}
},
success: function (data) {
if (data) {
if (data.status === "failed") {
toastr.error(data);
}
}
}
});
}
function viewFirewallRules(ip) {
$.ajax({
url: "/app/server/firewall/" + ip,
url: "/server/firewall/" + ip,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('danger') != '-1' || data.indexOf('unique') != '-1' || data.indexOf('error: ') != '-1') {
@ -330,7 +315,7 @@ function viewFirewallRules(ip) {
}
function updateServerInfo(ip, id) {
$.ajax({
url: "/app/server/system_info/update/" + ip + "/" + id,
url: "/server/system_info/update/" + ip + "/" + id,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error:') != '-1' || data.indexOf('error_code') != '-1') {
@ -346,7 +331,7 @@ function updateServerInfo(ip, id) {
function showServerInfo(id, ip) {
let server_info = translate_div.attr('data-server_info');
$.ajax({
url: "/app/server/system_info/get/" + ip + "/" +id,
url: "/server/system_info/get/" + ip + "/" +id,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error:') != '-1' || data.indexOf('error_code') != '-1') {
@ -374,7 +359,7 @@ function showServerInfo(id, ip) {
async function serverIsUp(server_id) {
let random_sleep = getRandomArbitrary(1000, 10000);
await sleep(random_sleep);
const source = new EventSource(`/app/server/check/server/${server_id}`);
const source = new EventSource(`/server/check/server/${server_id}`);
let server_div = $('#server_status-' + server_id);
source.onmessage = function (event) {
let data = JSON.parse(event.data);
@ -397,7 +382,7 @@ async function serverIsUp(server_id) {
$('#hostname-' + server_id).val(data.name);
$('#ip-' + server_id).val(data.ip);
$('#port-' + server_id).val(data.port);
$('#desc-' + server_id).val(data.desc);
$('#desc-' + server_id).val(data.description);
if (data.enabled === 1) {
$('#enable-' + server_id).prop('checked', true);
} else {
@ -409,11 +394,11 @@ async function serverIsUp(server_id) {
$('#protected-' + server_id).prop('checked', false);
}
if (data.type_ip === 1) {
$('#typeip-' + server_id).prop('checked', true);
$('#type_ip-' + server_id).prop('checked', true);
} else {
$('#typeip-' + server_id).prop('checked', false);
$('#type_ip-' + server_id).prop('checked', false);
}
$('#typeip-' + server_id).checkboxradio("refresh");
$('#type_ip-' + server_id).checkboxradio("refresh");
$('#protected-' + server_id).checkboxradio("refresh");
$('#enable-' + server_id).checkboxradio("refresh");
$('#servergroup-' + server_id).val(data.group_id).change();
@ -431,7 +416,7 @@ function openChangeServerServiceDialog(server_id) {
let user_groups_word = translate_div.attr('data-user_groups');
let hostname = $('#hostname-' + server_id).val();
$.ajax({
url: "/app/server/services/" + server_id,
url: "/server/services/" + server_id,
success: function (data) {
$("#groups-roles").html(data);
$("#groups-roles").dialog({
@ -493,7 +478,7 @@ function changeServerServices(server_id) {
jsonData[this_id] = 0
});
$.ajax({
url: "/app/server/services/" + server_id,
url: "/server/services/" + server_id,
data: {
jsonDatas: JSON.stringify(jsonData),
changeServerServicesServer: $('#hostname-' + server_id).val(),

View File

@ -68,14 +68,14 @@ function addCreds(dialog_id) {
valid = valid && checkLength($('#ssh_user'), "Credentials", 1);
if (valid) {
let jsonData = {
"ssh": ssh_add_div.val(),
"group": $('#new-sshgroup').val(),
"user": $('#ssh_user').val(),
"name": ssh_add_div.val(),
"group_id": $('#new-sshgroup').val(),
"username": $('#ssh_user').val(),
"pass": $('#ssh_pass').val(),
"enabled": ssh_enable,
"key_enabled": ssh_enable,
}
$.ajax({
url: "/app/server/ssh",
url: "/server/cred",
type: "POST",
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
@ -123,14 +123,13 @@ function updateSSH(id) {
}
let jsonData = {
"name": ssh_name_val,
"group": group,
"ssh_enable": ssh_enable,
"ssh_user": $('#ssh_user-' + id).val(),
"ssh_pass": $('#ssh_pass-' + id).val(),
"id": id
"group_id": group,
"key_enabled": ssh_enable,
"username": $('#ssh_user-' + id).val(),
"password": $('#ssh_pass-' + id).val(),
}
$.ajax({
url: "/app/server/ssh",
url: "/server/cred/" + id,
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
type: "PUT",
@ -175,52 +174,58 @@ function confirmDeleteSsh(id) {
function removeSsh(id) {
$("#ssh-table-" + id).css("background-color", "#f2dede");
$.ajax({
url: "/app/server/ssh",
url: "/server/cred/" + id,
type: "DELETE",
data: JSON.stringify({"id": id}),
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
statusCode: {
204: function (xhr) {
$("#ssh-table-" + id).remove();
$('select:regex(id, credentials) option[value=' + id + ']').remove();
$('select:regex(id, credentials)').selectmenu("refresh");
},
404: function (xhr) {
$("#ssh-table-" + id).remove();
$('select:regex(id, credentials) option[value=' + id + ']').remove();
$('select:regex(id, credentials)').selectmenu("refresh");
}
},
success: function (data) {
if (data) {
if (data.status === "failed") {
toastr.error(data);
}
}
}
});
}
function uploadSsh() {
toastr.clear();
if ($("#ssh-key-name option:selected").val() == "------" || $('#ssh_cert').val() == '') {
toastr.error('All fields must be completed');
} else {
let jsonData = {
"ssh_cert": $('#ssh_cert').val(),
"name": $('#ssh-key-name').val(),
"pass": $('#ssh-key-pass').val()
}
$.ajax({
url: "/app/server/ssh",
type: "PATCH",
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
} else if (data.status === 'uploaded') {
toastr.clear();
toastr.success(data.message)
} else {
toastr.error('Something wrong, check and try again');
}
}
});
toastr.clear();
if ($("#ssh-key-name option:selected").val() == "------" || $('#ssh_cert').val() == '') {
toastr.error('All fields must be completed');
return false;
}
let jsonData = {
"private_key": $('#ssh_cert').val(),
"passphrase": $('#ssh-key-pass').val(),
}
$.ajax({
url: "/server/cred/" + $('#ssh-key-name').val().split("_")[0],
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
type: "PATCH",
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
toastr.clear();
toastr.success('The SSH key has been loaded')
}
}
});
}
function checkSshConnect(ip) {
$.ajax({
url: "/app/server/check/ssh/" + ip,
url: "/server/check/ssh/" + ip,
success: function (data) {
if (data.indexOf('error:') != '-1') {
toastr.error(data)

View File

@ -1,5 +1,6 @@
var cur_url = window.location.href.split('/app/').pop();
cur_url = cur_url.split('/');
var cur_url = window.location.href.split('/').pop();
// cur_url = cur_url.split('/');
let superAdmin_pass = translate_div.attr('data-superAdmin_pass');
$( function() {
$('#add-user-button').click(function () {
addUserDialog.dialog('open');
@ -35,11 +36,21 @@ $( function() {
});
$("#ajax-users input").change(function () {
let id = $(this).attr('id').split('-');
updateUser(id[1])
if ($('#role-'+id + ' option:selected' ).val() === 'Select a role') {
toastr.warning(superAdmin_pass);
return false;
} else {
updateUser(id[1])
}
});
$("#ajax-users select").on('selectmenuchange', function () {
let id = $(this).attr('id').split('-');
updateUser(id[1])
if ($('#role-'+id + ' option:selected' ).val() === 'Select a role') {
toastr.warning(superAdmin_pass);
return false;
} else {
updateUser(id[1])
}
});
$('#search_ldap_user').click(function () {
toastr.clear();
@ -51,7 +62,7 @@ $( function() {
let user = username_div.val()
if (valid) {
$.ajax({
url: "/app/user/ldap/" + user,
url: "/user/ldap/" + user,
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
@ -103,7 +114,7 @@ function addUser(dialog_id) {
"user_group": user_group,
}
$.ajax({
url: "/app/user",
url: "/user",
type: "POST",
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
@ -142,15 +153,22 @@ function confirmDeleteUser(id) {
function removeUser(id) {
$("#user-" + id).css("background-color", "#f2dede");
$.ajax({
url: "/app/user",
data: JSON.stringify({'user_id': id}),
url: "/user/" + id,
contentType: "application/json; charset=utf-8",
type: "DELETE",
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
statusCode: {
204: function (xhr) {
$("#user-" + id).remove();
},
404: function (xhr) {
$("#user-" + id).remove();
}
},
success: function (data) {
if (data) {
if (data.status === "failed") {
toastr.error(data);
}
}
}
});
@ -165,10 +183,9 @@ function updateUser(id) {
"username": $('#login-' + id).val(),
"email": $('#email-' + id).val(),
"enabled": enabled,
"user_id": id
}
$.ajax({
url: "/app/user",
url: "/user/" + id,
type: "PUT",
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
@ -192,10 +209,9 @@ function openChangeUserServiceDialog(id) {
changeUserServiceDialog(id);
}
function changeUserPasswordDialog(id) {
let superAdmin_pass = translate_div.attr('data-superAdmin_pass');
let change_word = translate_div.attr('data-change2');
let password_word = translate_div.attr('data-password');
if ($('#role-'+id + ' option:selected' ).val() == 'Select a role') {
if ($('#role-'+id + ' option:selected' ).val() === 'Select a role') {
toastr.warning(superAdmin_pass);
return false;
}
@ -229,25 +245,21 @@ function changeUserPasswordDialog(id) {
});
}
function changeUserPassword(id, d) {
let pass = $('#change-password').val();
let pass2 = $('#change2-password').val();
var pass = $('#change-password').val();
var pass2 = $('#change2-password').val();
if (pass != pass2) {
$('#missmatchpass').show();
} else {
$('#missmatchpass').hide();
toastr.clear();
let jsonData = {
"password": pass,
"id": id
}
$.ajax({
url: "/app/user/password",
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
url: "/user/password/" + id,
data: JSON.stringify({'pass': pass,}),
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
toastr.error(data);
} else {
toastr.clear();
$("#user-" + id).addClass("update", 1000);
@ -270,7 +282,7 @@ function changeUserServiceDialog(id) {
return false;
}
$.ajax({
url: "/app/user/services/" + id,
url: "/user/services/" + id,
success: function (data) {
if (data.indexOf('danger') != '-1') {
toastr.error(data);
@ -310,7 +322,7 @@ function changeUserServices(user_id) {
jsonData['services'][user_id][this_id] = {}
});
$.ajax( {
url: "/app/user/services/" + user_id,
url: "/user/services/" + user_id,
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
type: "POST",
@ -355,10 +367,19 @@ function removeServiceFromUser(service_id) {
function confirmChangeGroupsAndRoles(user_id) {
let user_groups_word = translate_div.attr('data-user_groups');
let username = $('#login-' + user_id).val();
let groups = getAllGroups();
$.ajax({
url: "/app/user/groups/" + user_id,
url: "/user/" + user_id + "/groups",
contentType: "application/json; charset=utf-8",
success: function (data) {
$("#groups-roles").html(data);
$("#checked_groups tbody").html('');
$("#all_groups tbody").html('');
for (let group of groups) {
removeGroupFromUser(group.group_id, group.name, group.description)
}
for (let group of data) {
addGroupToUser(group.user_group_id, group.user_role_id);
}
$("#groups-roles").dialog({
resizable: false,
height: "auto",
@ -381,29 +402,40 @@ function confirmChangeGroupsAndRoles(user_id) {
}
});
}
function addGroupToUser(group_id) {
let group_name = $('#add_group-'+group_id).attr('data-group_name');
function addGroupToUser(group_id, user_role_id=0) {
let group_name = $('#add_group-' + group_id).attr('data-group_name');
let group2_word = translate_div.attr('data-group2');
let length_tr = $('#all_groups tbody tr').length;
const roles = {1: 'superAdmin', 2: 'admin', 3: 'user', 4: 'guest'};
let options_roles = '';
for (const [role_id, role_name] of Object.entries(roles)) {
options_roles += '<option value="'+role_id+'">'+role_name+'</option>';
console.log(user_role_id)
if (user_role_id === Number(role_id)) {
options_roles += '<option value="' + role_id + '" selected>' + role_name + '</option>';
} else {
options_roles += '<option value="' + role_id + '">' + role_name + '</option>';
}
}
let tr_class = 'odd';
if (length_tr % 2 != 0) {
tr_class = 'even';
}
let html_tag = '<tr class="'+tr_class+'" id="remove_group-'+group_id+'" data-group_name="'+group_name+'">\n' +
' <td class="padding20" style="width: 50%;">'+group_name+'</td>\n' +
let html_tag = '<tr class="' + tr_class + '" id="remove_group-' + group_id + '" data-group_name="' + group_name + '">\n' +
' <td class="padding20" style="width: 50%;">' + group_name + '</td>\n' +
' <td style="width: 50%;">\n' +
' <select id="add_role-'+group_id+'">'+options_roles+'</select></td>\n' +
' <td><span class="remove_user_group" onclick="removeGroupFromUser('+group_id+')" title="'+delete_word+' '+group2_word+'">-</span></td></tr>'
$('#add_group-'+group_id).remove();
' <select id="add_role-' + group_id + '">' + options_roles + '</select></td>\n' +
' <td><span class="remove_user_group" onclick="removeGroupFromUser(' + group_id + ')" title="' + delete_word + ' ' + group2_word + '">-</span></td></tr>'
$('#add_group-' + group_id).remove();
$("#checked_groups tbody").append(html_tag);
}
function removeGroupFromUser(group_id) {
function removeGroupFromUser(group_id, name=false, desc=false) {
let group_name = $('#remove_group-'+group_id).attr('data-group_name');
let description = '';
if (name) {
group_name = name;
description = desc;
}
let group2_word = translate_div.attr('data-group2');
let length_tr = $('#all_groups tbody tr').length;
let tr_class = 'odd';
@ -412,7 +444,7 @@ function removeGroupFromUser(group_id) {
}
let html_tag = '<tr class="'+tr_class+'" id="add_group-'+group_id+'" data-group_name='+group_name+'>\n' +
' <td class="padding20" style="width: 100%">'+group_name+'</td>\n' +
' <td><span class="add_user_group" title="'+add_word+' '+group2_word+'" onclick="addGroupToUser('+group_id+')">+</span></td></tr>'
' <td><span class="add_user_group" title="'+add_word+' '+group2_word+'" title="'+description+'" onclick="addGroupToUser('+group_id+')">+</span></td></tr>'
$('#remove_group-'+group_id).remove();
$("#all_groups tbody").append(html_tag);
}
@ -432,7 +464,7 @@ function saveGroupsAndRoles(user_id) {
}
}
$.ajax({
url: "/app/user/groups/save",
url: "/user/groups/save",
data: {
changeUserGroupsUser: $('#login-' + user_id).val(),
jsonDatas: JSON.stringify(jsonData)

View File

@ -113,14 +113,14 @@ $( function() {
});
function loadBackup() {
$.ajax({
url: "/app/server/backup",
url: "/server/backup",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('danger') != '-1' || data.indexOf('unique') != '-1' || data.indexOf('error:') != '-1') {
toastr.error(data);
} else {
$('#backup').html(data);
$.getScript('/app/static/js/backup.js');
$.getScript('/static/js/backup.js');
$("select").selectmenu();
$.getScript(awesome);
}
@ -144,13 +144,13 @@ function addBackup(dialog_id) {
"rpath": $('#rpath').val(),
"type": $('#backup-type').val(),
"time": $('#backup-time').val(),
"cred": $('#backup-credentials').val(),
"cred_id": $('#backup-credentials').val(),
"description": $('#backup-description').val()
}
$.ajax({
url: "/app/server/backup",
url: "/server/backup",
data: JSON.stringify(jsonData),
type: "PUT",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
@ -166,7 +166,7 @@ function addBackup(dialog_id) {
function addS3Backup(dialog_id) {
let valid = true;
toastr.clear();
allFields = $([]).add($('#s3-backup-server')).add($('#s3_server')).add($('#s3_bucket')).add($('#s3_secret_key')).add($('#s3_access_key'))
let allFields = $([]).add($('#s3-backup-server')).add($('#s3_server')).add($('#s3_bucket')).add($('#s3_secret_key')).add($('#s3_access_key'))
allFields.removeClass("ui-state-error");
valid = valid && checkLength($('#s3-backup-server'), "backup server ", 1);
valid = valid && checkLength($('#s3_server'), "S3 server", 1);
@ -174,31 +174,25 @@ function addS3Backup(dialog_id) {
valid = valid && checkLength($('#s3_secret_key'), "S3 secret key", 1);
valid = valid && checkLength($('#s3_access_key'), "S3 access key", 1);
if (valid) {
let json_data = {
"s3_server": $('#s3-backup-server').val(),
"server": $('#s3_server').val(),
"bucket": $('#s3_bucket').val(),
"secret_key": $('#s3_secret_key').val(),
"access_key": $('#s3_access_key').val(),
"time": $('#s3-backup-time').val(),
"description": $('#s3-backup-description').val(),
}
$.ajax({
url: "/app/server/s3backup/create",
data: {
s3_backup_server: $('#s3-backup-server').val(),
s3_server: $('#s3_server').val(),
s3_bucket: $('#s3_bucket').val(),
s3_secret_key: $('#s3_secret_key').val(),
s3_access_key: $('#s3_access_key').val(),
time: $('#s3-backup-time').val(),
description: $('#s3-backup-description').val(),
token: $('#token').val()
},
url: "/server/backup/s3",
data: JSON.stringify(json_data),
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error: ') != '-1') {
if (data.status === 'failed') {
toastr.error(data);
} else if (data.indexOf('info: ') != '-1') {
toastr.clear();
toastr.info(data);
} else if (data.indexOf('warning: ') != '-1') {
toastr.clear();
toastr.warning(data);
} else {
common_ajax_action_after_success(dialog_id, 'newbackup', 'ajax-backup-s3-table', data);
common_ajax_action_after_success(dialog_id, 'newbackup', 'ajax-backup-s3-table', data.data);
$("select").selectmenu();
}
}
@ -236,7 +230,7 @@ function addGit(dialog_id) {
"desc": $('#git-description').text(),
}
$.ajax({
url: "/app/server/git",
url: "/server/git",
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
type: "POST",
@ -338,42 +332,55 @@ function cloneS3Backup(id) {
function removeBackup(id) {
$("#backup-table-" + id).css("background-color", "#f2dede");
let jsonData = {
"del_id": id,
"cred": $('#backup-credentials-' + id).val(),
"cred_id": $('#backup-credentials-' + id).val(),
"server": $('#backup-server-' + id).text(),
"rserver": $('#backup-rserver-' + id).val()
}
$.ajax({
url: "/app/server/backup",
url: api_prefix + "/server/backup/fs/" + id,
data: JSON.stringify(jsonData),
type: "DELETE",
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
statusCode: {
204: function (xhr) {
$("#backup-table-" + id).remove();
},
404: function (xhr) {
$("#backup-table-" + id).remove();
}
},
success: function (data) {
if (data) {
if (data.status === "failed") {
toastr.error(data);
}
}
}
});
}
function removeS3Backup(id) {
$("#backup-table-s3-" + id).css("background-color", "#f2dede");
let jsonData = {
"bucket": $('#bucket-' + id).text(),
"server": $('#backup-s3-server-' + id).text(),
}
$.ajax({
url: "/app/server/s3backup/delete",
data: {
dels3job: id,
s3_bucket: $('#bucket-' + id).text(),
s3_backup_server: $('#backup-s3-server-' + id).text(),
token: $('#token').val()
},
type: "POST",
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('ok') != '-1') {
url: api_prefix + "/server/backup/s3/" + id,
data: JSON.stringify(jsonData),
type: "DELETE",
contentType: "application/json; charset=utf-8",
statusCode: {
204: function (xhr) {
$("#s3-backup-table-" + id).remove();
} else if (data.indexOf('error:') != '-1' || data.indexOf('unique') != '-1') {
toastr.error(data);
},
404: function (xhr) {
$("#s3-backup-table-" + id).remove();
}
},
success: function (data) {
if (data) {
if (data.status === "failed") {
toastr.error(data);
}
}
}
});
@ -393,7 +400,7 @@ function removeGit(id) {
"desc": '',
}
$.ajax({
url: "/app/server/git",
url: "/server/git",
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
type: "DELETE",
@ -412,17 +419,16 @@ function updateBackup(id) {
toastr.error('All fields must be completed');
} else {
let jsonData = {
"update_id": id,
"server": $('#backup-server-' + id).text(),
"rserver": $('#backup-rserver-' + id).val(),
"rpath": $('#backup-rpath-' + id).val(),
"type": $('#backup-type-' + id).val(),
"time": $('#backup-time-' + id).val(),
"cred": $('#backup-credentials-' + id).val(),
"cred_id": $('#backup-credentials-' + id).val(),
"description": $('#backup-description-' + id).val()
}
$.ajax({
url: "/app/server/backup",
url: api_prefix + "/server/backup/fs/" + id,
data: JSON.stringify(jsonData),
type: "PUT",
contentType: "application/json; charset=utf-8",

View File

@ -154,7 +154,7 @@ $( function() {
});
function loadChannel() {
$.ajax({
url: "/app/channel/load",
url: "/channel/load",
type: "GET",
success: function (data) {
data = data.replace(/\s+/g, ' ');
@ -165,7 +165,7 @@ function loadChannel() {
$("select").selectmenu();
$("button").button();
$("input[type=checkbox]").checkboxradio();
$.getScript('/app/static/js/channel.js');
$.getScript('/static/js/channel.js');
$.getScript(awesome);
}
}
@ -178,13 +178,12 @@ function updateReceiver(id, receiver_name) {
}
toastr.clear();
let json_data = {
"receiver_token": $('#' + receiver_name + '-token-' + id).val(),
"token": $('#' + receiver_name + '-token-' + id).val(),
"channel": $('#' + receiver_name + '-chanel-' + id).val(),
"group": group,
"id": id
"group_id": group,
}
$.ajax({
url: "/app/channel/receiver/" + receiver_name,
url: "/channel/" + receiver_name + "/" + id,
data: JSON.stringify(json_data),
contentType: "application/json; charset=utf-8",
type: "PUT",
@ -203,8 +202,9 @@ function updateReceiver(id, receiver_name) {
}
function checkReceiver(channel_id, receiver_name) {
$.ajax({
url: "/app/channel/check/" + channel_id + "/" + receiver_name,
url: "/channel/" + receiver_name + "/" + channel_id,
contentType: "application/json; charset=utf-8",
type: "PATCH",
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
@ -229,13 +229,13 @@ function addRecevier(dialog_id, receiver_name) {
}
if (valid) {
let jsonData = {
"receiver": receiver_name_div.val(),
"token": receiver_name_div.val(),
"channel": channel_div.val(),
"group": group,
"group_id": group
}
toastr.clear();
$.ajax({
url: "/app/channel/receiver/" + receiver_name,
url: "/channel/" + receiver_name,
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
type: "POST",
@ -279,22 +279,29 @@ function cloneReceiver(id, receiver_name) {
function removeReceiver(receiver_name, receiver_id) {
$("#" + receiver_name + "-table-" + receiver_id).css("background-color", "#f2dede");
$.ajax({
url: "/app/channel/receiver/" + receiver_name,
data: JSON.stringify({"channel_id": receiver_id}),
url: "/channel/" + receiver_name + "/" + receiver_id,
contentType: "application/json; charset=utf-8",
type: "DELETE",
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
statusCode: {
204: function (xhr) {
$("#" + receiver_name + "-table-" + receiver_id).remove();
},
404: function (xhr) {
$("#" + receiver_name + "-table-" + receiver_id).remove();
}
},
success: function (data) {
if (data) {
if (data.status === "failed") {
toastr.error(data);
}
}
}
});
}
function sendCheckMessage(sender) {
$.ajax({
url: "/app/channel/check",
url: "/channel/check",
data: JSON.stringify({'sender': sender}),
type: "POST",
contentType: "application/json; charset=utf-8",

View File

@ -51,7 +51,7 @@ function updateHaproxyCheckerSettings(id) {
maxconn = '1';
}
$.ajax({
url: "/app/checker/settings/update",
url: "/checker/settings/update",
data: {
service: 'haproxy',
setting_id: id,
@ -95,7 +95,7 @@ function updateKeepalivedCheckerSettings(id) {
backend = '1';
}
$.ajax({
url: "/app/checker/settings/update",
url: "/checker/settings/update",
data: {
service: 'keepavlied',
setting_id: id,
@ -134,7 +134,7 @@ function updateServiceCheckerSettings(id, service_name) {
server = '1';
}
$.ajax({
url: "/app/checker/settings/update",
url: "/checker/settings/update",
data: {
service: service_name,
setting_id: id,
@ -163,7 +163,7 @@ function updateServiceCheckerSettings(id, service_name) {
}
function loadchecker() {
$.ajax({
url: "/app/checker/settings/load",
url: "/checker/settings/load",
type: "GET",
success: function (data) {
data = data.replace(/\s+/g, ' ');
@ -174,7 +174,7 @@ function loadchecker() {
$( "select" ).selectmenu();
$("button").button();
$( "input[type=checkbox]" ).checkboxradio();
$.getScript('/app/static/js/checker.js');
$.getScript('/static/js/checker.js');
$.getScript(awesome);
}
}

View File

@ -1,22 +1,22 @@
$( function() {
$( "input[type=submit], button" ).button();
$( ".configShow" ).accordion({
$("input[type=submit], button").button();
$(".configShow").accordion({
collapsible: true,
heightStyle: "content",
icons: { "header": "ui-icon-plus", "activeHeader": "ui-icon-minus" }
icons: {"header": "ui-icon-plus", "activeHeader": "ui-icon-minus"}
});
$('#raw').click(function() {
$('#raw').click(function () {
$(".configShow").accordion("destroy");
$('#raw').css('display', 'none');
$('.numRow').css('display', 'none');
$('#according').css('display', 'inline-block');
$('.accordion-expand-all').css('display', 'none');
});
$('#according').click(function() {
$( ".configShow" ).accordion({
$('#according').click(function () {
$(".configShow").accordion({
collapsible: true,
heightStyle: "content",
icons: { "header": "ui-icon-plus", "activeHeader": "ui-icon-minus" }
icons: {"header": "ui-icon-plus", "activeHeader": "ui-icon-minus"}
});
$('#raw').css('display', 'inline-block');
$('.numRow').css('display', 'inline-block');
@ -25,9 +25,9 @@ $( function() {
});
let headers = $('.configShow .accordion-header');
let contentAreas = $('.configShow .ui-accordion-content ').hide()
.first().show().end();
.first().show().end();
let expandLink = $('.accordion-expand-all');
headers.click(function() {
headers.click(function () {
// close all panels
contentAreas.slideUp();
// open the appropriate panel
@ -37,39 +37,49 @@ $( function() {
.data('isAllOpen', false);
// stop page scroll
return false;
});
});
// hook up the expand/collapse all
expandLink.click(function(){
expandLink.click(function () {
let isAllOpen = !$(this).data('isAllOpen');
console.log({isAllOpen: isAllOpen, contentAreas: contentAreas})
contentAreas[isAllOpen? 'slideDown': 'slideUp']();
expandLink.text(isAllOpen? 'Collapse All': 'Expand all')
.data('isAllOpen', isAllOpen);
});
$(".accordion-link a").on("click", function(event) {
window.location.href = $(this).attr("href");
event.preventDefault();
});
contentAreas[isAllOpen ? 'slideDown' : 'slideUp']();
$( "#saveconfig" ).on("click", ":submit", function(e){
expandLink.text(isAllOpen ? 'Collapse All' : 'Expand all')
.data('isAllOpen', isAllOpen);
});
$(".accordion-link a").on("click", function (event) {
window.location.href = $(this).attr("href");
event.preventDefault();
});
$("#saveconfig").on("click", ":submit", function (e) {
let frm = $('#saveconfig');
let service = $('#service').val();
myCodeMirror.save();
let unindexed_array = frm.serializeArray();
let indexed_array = {};
$.map(unindexed_array, function (n, i) {
if (n['value'] != 'undefined') {
indexed_array[n['name']] = n['value'];
}
});
indexed_array['action'] = $(this).val();
$.ajax({
url: frm.attr('action'),
data: frm.serialize() + "&save=" + $(this).val(),
dataType: 'json',
data: JSON.stringify(indexed_array),
type: frm.attr('method'),
success: function( data ) {
data = data.replace(/\n/g, "<br>");
contentType: "application/json; charset=UTF-8",
success: function (data) {
toastr.clear();
returnNiceCheckingConfig(data);
data.data = data.data.replace(/\n/g, "<br>");
returnNiceCheckingConfig(data.data);
$(window).unbind('beforeunload');
if (data.indexOf('warning: ') != '-1') {
toastr.warning(data)
if (data.status === 'failed') {
toastr.warning(data.error)
}
}
});
event.preventDefault();
e.preventDefault();
});
})

119
app/static/js/element.js Normal file
View File

@ -0,0 +1,119 @@
"use strict"; // silly safari
if (typeof elem == "undefined") {
function elem(tagName, attributes, children, isHTML) {
let parent;
if (typeof tagName == "string") {
parent = document.createElement(tagName);
} else if (tagName instanceof HTMLElement) {
parent = tagName;
}
// I'm tired of using null as the attributes, e.g.: elem("div", null, ["some", "elements"])
// Wouldn't it be nice if I could just do: elem("div", ["some", "elements"])
// attributes expects a plain object; we can use that to differentiate
if (typeof attributes != "undefined" && ["undefined", "boolean"].includes(typeof children) && typeof isHTML == "undefined") {
let attrType = typeof attributes;
if (["string", "number"].includes(attrType)
|| (attrType == "object" && attributes instanceof Array)
|| (attrType == "object" && attributes instanceof HTMLElement) ) {
isHTML = children;
children = attributes;
attributes = null;
}
}
if (attributes) {
for (let attribute in attributes) {
if (attribute.startsWith("on")) {
let callback = attributes[attribute];
if (typeof callback == "string") {
parent.setAttribute(attribute, callback);
}
else if (typeof callback == "function") {
let eventMatch = attribute.match(/^on([a-zA-Z]+)/);
if (eventMatch) {
let event = eventMatch[1];
// TODO: make sure it's a valid event?
parent.addEventListener(event, callback);
parent.eventListeners = parent.eventListeners || {};
parent.eventListeners[event] = parent.eventListeners[event] || [];
parent.eventListeners[event].push(callback);
}
}
} else {
parent.setAttribute(attribute, attributes[attribute]);
}
}
}
if (typeof children != "undefined" || children === 0) {
elem.append(parent, children, isHTML);
}
return parent;
};
elem.append = function (parent, children, isHTML) {
if (parent instanceof HTMLTextAreaElement || parent instanceof HTMLInputElement) {
if (children instanceof Text || typeof children == "string" || typeof children == "number") {
parent.value = children;
}
else if (children instanceof Array) {
children.forEach(function (child) {
elem.append(parent, child);
});
}
else if (typeof children == "function") {
elem.append(parent, children());
}
} else {
if (children instanceof HTMLElement || children instanceof Text) {
parent.appendChild(children);
}
else if (typeof children == "string" || typeof children == "number") {
if (isHTML) {
parent.innerHTML += children;
} else {
parent.appendChild(document.createTextNode(children));
}
}
else if (children instanceof Array) {
children.forEach(function (child) {
elem.append(parent, child);
});
}
else if (typeof children == "function") {
elem.append(parent, children());
}
}
};
window.elem = elem;
} else {
if (typeof elem == "function" && elem.hasOwnProperty("append")) {
console.warn("elem() is already initialized.");
} else {
console.warn("The name \"elem\" is already in use by some other script.");
}
}

View File

@ -72,16 +72,21 @@ function confirmDeleteCluster(cluster_id) {
}
function deleteCluster(cluster_id) {
$.ajax({
url: "/app/ha/cluster",
url: api_prefix + "/ha/cluster/" + cluster_id,
type: "DELETE",
data: {
cluster_id: cluster_id,
statusCode: {
204: function (xhr) {
$("#cluster-" + cluster_id).remove();
},
404: function (xhr) {
$("#cluster-" + cluster_id).remove();
}
},
success: function (data) {
if (data.indexOf('error:') != '-1') {
toastr.error(data);
} else {
$("#cluster-" + cluster_id).remove();
if (data) {
if (data.status === "failed") {
toastr.error(data);
}
}
}
});
@ -92,7 +97,7 @@ function createHaClusterStep1(edited=false, cluster_id=0, clean=true) {
if (clean) {
clearClusterDialog(edited);
$.ajax({
url: "/app/ha/cluster/masters",
url: "/ha/cluster/masters",
async: false,
type: "GET",
success: function (data) {
@ -118,13 +123,13 @@ function createHaClusterStep1(edited=false, cluster_id=0, clean=true) {
$('#ha-cluster-master').selectmenu("refresh");
get_keepalived_ver($('#cur_master_ver'), master_ip);
$.ajax({
url: "/app/ha/cluster/settings/" + cluster_id,
url: api_prefix + "/ha/cluster/" + cluster_id,
type: "GET",
async: false,
success: function (data) {
let clusterSettings = JSON.parse(JSON.stringify(data));
$('#ha-cluster-name').val(clusterSettings.name);
$('#ha-cluster-desc').val(clusterSettings.desc);
$('#ha-cluster-name').val(clusterSettings.name.replaceAll("'", ""));
$('#ha-cluster-desc').val(clusterSettings.description.replaceAll("'", ""));
$('#ha-cluster-master-interface').val(clusterSettings.eth);
$('#vrrp-ip').val(clusterSettings.vip);
if (clusterSettings.haproxy) {
@ -137,10 +142,10 @@ function createHaClusterStep1(edited=false, cluster_id=0, clean=true) {
} else {
$('#nginx').prop('checked', false);
}
if (clusterSettings.return_to_master) {
$('#return_to_master').prop('checked', true);
if (clusterSettings.return_master) {
$('#return_master').prop('checked', true);
} else {
$('#return_to_master').prop('checked', false);
$('#return_master').prop('checked', false);
}
if (clusterSettings.syn_flood) {
$('#syn_flood').prop('checked', true);
@ -162,7 +167,7 @@ function createHaClusterStep1(edited=false, cluster_id=0, clean=true) {
});
}
$.ajax({
url: "/app/ha/cluster/slaves/servers/" + cluster_id,
url: "/ha/cluster/slaves/servers/" + cluster_id,
async: false,
type: "GET",
success: function (data) {
@ -282,7 +287,7 @@ function createHaClusterStep2(edited=false, cluster_id=0, jsonData='') {
}
function saveCluster(jsonData, cluster_id=0, edited=0, reconfigure=0) {
let virt_server = 0;
let return_to_master = 0;
let return_master = 0;
let syn_flood = 0;
let use_src = 0;
let hap = 0;
@ -291,14 +296,12 @@ function saveCluster(jsonData, cluster_id=0, edited=0, reconfigure=0) {
let nginx_docker = 0;
let apache = 0;
let req_method = 'POST';
if (edited) {
req_method = 'PUT';
}
let url = api_prefix + '/ha/cluster';
if ($('#virt_server').is(':checked')) {
virt_server = '1';
}
if ($('#return_to_master').is(':checked')) {
return_to_master = '1';
if ($('#return_master').is(':checked')) {
return_master = '1';
}
if ($('#syn_flood').is(':checked')) {
syn_flood = '1';
@ -321,12 +324,15 @@ function saveCluster(jsonData, cluster_id=0, edited=0, reconfigure=0) {
if ($('#apache').is(':checked')) {
apache = '1';
}
jsonData['cluster_id'] = cluster_id;
if (edited) {
req_method = 'PUT';
url = api_prefix + '/ha/cluster/' + cluster_id;
}
jsonData['name'] = $('#ha-cluster-name').val();
jsonData['desc'] = $('#ha-cluster-desc').val();
jsonData['description'] = $('#ha-cluster-desc').val();
jsonData['vip'] = $('#vrrp-ip').val();
jsonData['virt_server'] = virt_server;
jsonData['return_to_master'] = return_to_master;
jsonData['return_master'] = return_master;
jsonData['syn_flood'] = syn_flood;
jsonData['use_src'] = use_src;
jsonData['services'] = {'haproxy': {'enabled': hap, 'docker': hap_docker}};
@ -334,7 +340,7 @@ function saveCluster(jsonData, cluster_id=0, edited=0, reconfigure=0) {
jsonData['services']['apache'] = {'enabled': apache, 'docker': 0};
jsonData['router_id'] = $('#router_id-' + cluster_id).val();
$.ajax({
url: "/app/ha/cluster",
url: url,
type: req_method,
async: false,
data: JSON.stringify(jsonData),
@ -344,7 +350,7 @@ function saveCluster(jsonData, cluster_id=0, edited=0, reconfigure=0) {
toastr.error(data.error);
} else {
if (!edited) {
cluster_id = data.cluster_id;
cluster_id = data.id;
getHaCluster(cluster_id, true);
} else {
getHaCluster(cluster_id);
@ -432,7 +438,7 @@ function installServiceCluster(jsonData, service, progress_step, cluster_id) {
let nice_service_name = {'keepalived': 'HA Custer', 'haproxy': 'HAProxy', 'nginx': 'NGINX', 'apache': 'Apache'};
$('#server_creating_list').append('<li id="' + li_id + servers['cluster_id'] + '" class="server-creating proccessing">' + install_mess + ' ' + nice_service_name[service] + '</li>');
return $.ajax({
url: "/app/install/" + service,
url: "/install/" + service,
type: "POST",
data: JSON.stringify(servers),
contentType: "application/json; charset=utf-8",
@ -446,8 +452,7 @@ function installServiceCluster(jsonData, service, progress_step, cluster_id) {
},
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
toastr.error(data);
showErrorStatus(nice_service_name[service], servers["name"], li_id, servers['cluster_id'], progress_step, something_wrong);
} else {
checkInstallResp(data, servers['cluster_id'], progress_step, servers["name"], li_id, nice_service_name[service]);
}
@ -467,7 +472,6 @@ function checkInstallResp(output, server_id, progress_step, name, li_id, service
output = JSON.parse(JSON.stringify(output));
let was_installed = translate_div.attr('data-was_installed');
let something_wrong = translate_div.attr('data-something_wrong');
// let check_apache_log = translate_div.attr('data-check_apache_log');
for (let k in output['ok']) {
$('#' + li_id + server_id).removeClass('proccessing');
$('#' + li_id + server_id).addClass('proccessing_done');
@ -504,15 +508,15 @@ function add_vip_ha_cluster(cluster_id, cluster_name, router_id='', vip='', edit
let req_method = 'GET';
if (edited) {
$.ajax({
url: "/app/ha/cluster/settings/" + cluster_id + "/vip/" + router_id,
url: api_prefix + "/ha/cluster/" + cluster_id + "/vip/" + router_id,
type: "GET",
async: false,
success: function (data) {
let clusterSettings = JSON.parse(JSON.stringify(data));
if (clusterSettings.return_to_master) {
$('#vrrp-ip-add-return_to_master').prop('checked', true);
if (clusterSettings.return_master) {
$('#vrrp-ip-add-return_master').prop('checked', true);
} else {
$('#vrrp-ip-add-return_to_master').prop('checked', false);
$('#vrrp-ip-add-return_master').prop('checked', false);
}
if (clusterSettings.virt_server) {
$('#vrrp-ip-add-virt_server').prop('checked', true);
@ -588,7 +592,7 @@ function add_vip_ha_cluster(cluster_id, cluster_name, router_id='', vip='', edit
}]
}
$.ajax({
url: "/app/ha/cluster/slaves/" + cluster_id,
url: "/ha/cluster/slaves/" + cluster_id,
data: {
router_id: router_id,
},
@ -626,11 +630,11 @@ function add_vip_ha_cluster(cluster_id, cluster_name, router_id='', vip='', edit
}
function saveVip(jsonData, cluster_id, dialog_id, cluster_name, edited, router_id='', vip='', deleted=false) {
let req_type = 'POST'
let return_to_master = 0
let return_master = 0
let virt_server = 0
let use_src = 0
if ($('#vrrp-ip-add-return_to_master').is(':checked')) {
return_to_master = '1';
if ($('#vrrp-ip-add-return_master').is(':checked')) {
return_master = '1';
}
if ($('#vrrp-ip-add-virt_server').is(':checked')) {
virt_server = '1';
@ -639,30 +643,45 @@ function saveVip(jsonData, cluster_id, dialog_id, cluster_name, edited, router_i
use_src = '1';
}
jsonData['vip'] = $('#vrrp-ip-add').val();
jsonData['return_to_master'] = return_to_master;
jsonData['return_master'] = return_master;
jsonData['virt_server'] = virt_server;
jsonData['use_src'] = use_src;
jsonData['name'] = cluster_name;
let url = api_prefix + "/ha/cluster/" + cluster_id + "/vip";
if (edited) {
req_type = 'PUT';
jsonData['router_id'] = router_id;
}
if (deleted) {
req_type = 'DELETE';
jsonData['router_id'] = router_id;
url = api_prefix + "/ha/cluster/" + router_id + "/vip"
}
$.ajax({
url: "/app/ha/cluster/" + cluster_id + "/vip",
url: url,
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
type: req_type,
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
statusCode: {
204: function (xhr) {
getHaCluster(cluster_id);
dialog_id.dialog('destroy');
clearClusterDialog();
},
404: function (xhr) {
getHaCluster(cluster_id);
dialog_id.dialog('destroy');
clearClusterDialog();
}
},
success: function (data) {
if (data) {
if (data.status === "failed") {
toastr.error(data);
} else {
getHaCluster(cluster_id);
dialog_id.dialog('destroy');
clearClusterDialog();
}
}
}
});
@ -671,7 +690,7 @@ function get_interface(input_id, server_ip) {
input_id.autocomplete({
source: function (request, response) {
$.ajax({
url: "/app/server/show/if/" + server_ip,
url: "/server/show/if/" + server_ip,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error:') != '-1' || data.indexOf('Failed') != '-1') {
@ -688,16 +707,16 @@ function get_interface(input_id, server_ip) {
}
function get_keepalived_ver(div_id, server_ip) {
$.ajax({
url: "/app/install/keepalived/version/" + server_ip,
url: api_prefix + "/service/keepalived/" + server_ip + "/status",
contentType: "application/json; charset=utf-8",
success: function (data) {
data = data.replace(/^\s+|\s+$/g, '');
if (data.indexOf('error:') != '-1') {
let p_err = show_pretty_ansible_error(data);
if (data.status === 'failed') {
let p_err = show_pretty_ansible_error(data.error);
toastr.error(p_err);
} else if (data.indexOf('keepalived:') != '-1') {
} else if (!data.Version) {
div_id.text('Keepalived has not installed');
} else {
div_id.text(data);
div_id.text(data.Version);
div_id.css('font-weight', 'bold');
}
}
@ -740,19 +759,20 @@ function removeCheckFromStatus(server_id, server_ip) {
}
function createJsonCluster(div_id) {
let jsonData = {};
jsonData = {'servers': {}};
jsonData['servers'][1] = {
jsonData = {'servers': []};
jsonData['servers'].push({
'id': 1,
'eth': $('#ha-cluster-master-interface').val(),
'ip': $('#ha-cluster-master option:selected').val(),
'name': $('#ha-cluster-master option:selected').text(),
'master': 1
};
});
$(div_id).each(function () {
let this_id = $(this).attr('id').split('-')[1];
let eth = $('#slave_int-' + this_id).val();
let ip = $('#slave_int_div-' + this_id).attr('data-ip');
let name = $('#slave_int_div-' + this_id).parent().text().replace('\n','').replace('\t','').trim();
jsonData['servers'][this_id] = {'eth': eth, 'ip': ip, 'name': name, 'master': 0};
jsonData['servers'].push({'id': this_id, 'eth': eth, 'ip': ip, 'name': name, 'master': 0});
});
return jsonData;
}
@ -801,7 +821,7 @@ function clearClusterDialog(edited=0) {
$('#vrrp-ip-edit').val('');
$('#cur_master_ver').text('');
$('#virt_server').prop('checked', true);
$('#return_to_master').prop('checked', true);
$('#return_master').prop('checked', true);
$('#use_src').prop('checked', false);
$('#hap').prop('checked', false);
$('#hap_docker').prop('checked', false);
@ -818,7 +838,7 @@ function clearClusterDialog(edited=0) {
}
function getHaCluster(cluster_id, new_cluster=false) {
$.ajax({
url: "/app/ha/cluster/get/" + cluster_id,
url: "/ha/cluster/get/" + cluster_id,
success: function (data) {
data = data.replace(/^\s+|\s+$/g, '');
if (data.indexOf('error:') != '-1') {

View File

@ -19,7 +19,7 @@ $( function() {
$("#ajaxmon").html('');
$("#ajaxmon").html(wait_mess);
$.ajax({
url: "/app/install/grafana",
url: "/install/grafana",
success: function (data) {
data = data.replace(/\s+/g, ' ');
$("#ajaxmon").html('');
@ -102,7 +102,7 @@ $( function() {
"update": updating_geoip
}
$.ajax({
url: "/app/install/geoip",
url: "/install/geoip",
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
type: "POST",
@ -120,7 +120,7 @@ $( function() {
});
function checkGeoipInstallation() {
$.ajax({
url: "/app/install/geoip/" + $('#geoip_service option:selected').val() + "/" + $('#geoipserv option:selected').val(),
url: "/install/geoip/" + $('#geoip_service option:selected').val() + "/" + $('#geoipserv option:selected').val(),
success: function (data) {
data = data.replace(/^\s+|\s+$/g, '');
if (data.indexOf('No such file or directory') != '-1' || data.indexOf('cannot access') != '-1') {
@ -144,27 +144,31 @@ function installService(service) {
if ($('#' + service + '_docker').is(':checked')) {
docker = '1';
}
if ($(select_id).val() == '------' || $(select_id).val() === null) {
if ($(select_id).val() === '------' || $(select_id).val() === null) {
let select_server = translate_div.attr('data-select_server');
toastr.warning(select_server);
return false
}
let jsonData = {};
jsonData['servers'] = {'0': {}}
let server = {
"ip": $(select_id).val(),
"master": '0',
"name": $(select_id + ' option:selected').text(),
}
if (service === 'haproxy') {
server['version'] = $('#hapver option:selected').val();
}
jsonData['servers'] = {}
jsonData['services'] = {};
jsonData['services'][service] = {};
jsonData['syn_flood'] = syn_flood;
jsonData['servers']['0']['ip'] = $(select_id).val();
jsonData['servers']['0']['master'] = '0';
jsonData['servers']['0']['name'] = $(select_id + ' option:selected').text();
if (service == 'haproxy') {
jsonData['servers']['0']['version'] = $('#hapver option:selected').val();
}
jsonData['servers'] = [];
jsonData['servers'].push(server);
jsonData['services'][service]['enabled'] = 1;
jsonData['services'][service]['docker'] = docker;
$("#ajax").html(wait_mess);
$.ajax({
url: "/app/install/" + service,
url: "/install/" + service + "/" + $(select_id).val(),
500: function () {
showErrorStatus(nice_names[service], $(select_id + ' option:selected').text());
},
@ -178,8 +182,8 @@ function installService(service) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
parseAnsibleJsonOutput(data, nice_names[service], select_id);
$(select_id).trigger("selectmenuchange");
$("#ajax").empty();
}
}
});
@ -200,7 +204,7 @@ function installExporter(exporter) {
}
$("#ajax").html(wait_mess);
$.ajax({
url: "/app/install/exporter/" + exporter,
url: "/install/exporter/" + exporter,
500: function () {
showErrorStatus(nice_exporter_name, $(exporter_id + ' option:selected').text());
},
@ -214,15 +218,16 @@ function installExporter(exporter) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
parseAnsibleJsonOutput(data, nice_exporter_name, exporter_id);
parseAnsibleJsonOutput(data, nice_names[service], select_id);
$(exporter_id).trigger("selectmenuchange");
$("#ajax").empty();
}
}
});
}
function showExporterVersion(exporter) {
$.ajax({
url: "/app/install/exporter/" + exporter + "/version/" + $('#' + exporter + '_exp_addserv option:selected').val(),
url: "/install/exporter/" + exporter + "/version/" + $('#' + exporter + '_exp_addserv option:selected').val(),
success: function (data) {
data = data.replace(/^\s+|\s+$/g, '');
if (data.indexOf('error:') != '-1') {
@ -237,28 +242,28 @@ function showExporterVersion(exporter) {
});
}
function showServiceVersion(service) {
let install_div = $('#' + service + '_install');
let ver_div = $('#cur_' + service + '_ver');
$.ajax({
url: "/app/install/" + service + "/version/" + $('#' + service + 'addserv option:selected').val(),
url: "/service/" + service + "/" + $('#' + service + 'addserv option:selected').val() + "/status",
statusCode: {
404: function (xhr) {
ver_div.text(service + ' has not installed');
install_div.text('Install');
install_div.attr('title', 'Install');
}
},
success: function (data) {
data = data.replace(/^\s+|\s+$/g, '');
if (data.indexOf('error: ') != '-1') {
toastr.warning(data);
$('#cur_' + service + '_ver').text('');
} else if(data.indexOf('bash') != '-1' || data.indexOf('such') != '-1' || data.indexOf('command not found') != '-1' || data.indexOf('from') != '-1') {
$('#cur_' + service + '_ver').text(service + ' has not installed');
$('#' + service + '_install').text('Install');
$('#' + service + '_install').attr('title', 'Install');
} else if (data.indexOf('warning: ') != '-1') {
toastr.warning(data);
} else if (data == '') {
$('#cur_' + service + '_ver').text(service + ' has not installed');
$('#' + service + '_install').text('Install');
$('#' + service + '_install').attr('title', 'Install');
if (data.status === 'failed') {
ver_div.text(service + ' has not installed');
install_div.text('Install');
install_div.attr('title', 'Install');
toastr.warning('Cannot get version');
} else {
$('#cur_' + service + '_ver').text(data);
$('#cur_' + service + '_ver').css('font-weight', 'bold');
$('#' + service + '_install').text('Update');
$('#' + service + '_install').attr('title', 'Update');
ver_div.text(data.Version);
ver_div.css('font-weight', 'bold');
install_div.text('Update');
install_div.attr('title', 'Update');
}
}
});

View File

@ -64,7 +64,7 @@ function return_service_chart_config() {
function stream_chart(chart_id, service, service_ip, is_http=0) {
let random_sleep = getRandomArbitrary(500, 2000);
sleep(random_sleep);
const source = new EventSource(`/app/metrics/${service}/${service_ip}/${is_http}/chart-stream`);
const source = new EventSource(`/metrics/${service}/${service_ip}/${is_http}/chart-stream`);
source.onmessage = function (event) {
const data = JSON.parse(event.data);
if (chart_id.data.labels.length >= 30) {
@ -89,7 +89,7 @@ function getHttpChartData(server) {
return false;
}
$.ajax({
url: `/app/metrics/haproxy/${server}/http`,
url: `/metrics/haproxy/${server}/http`,
data: {
time_range: $( "#time-range option:selected" ).val(),
},
@ -211,7 +211,7 @@ function renderHttpChart(data, labels, server) {
}
function getChartData(server) {
$.ajax({
url: "/app/metrics/haproxy/" + server,
url: "/metrics/haproxy/" + server,
data: {
time_range: $( "#time-range option:selected" ).val(),
},
@ -315,7 +315,7 @@ function renderChart(data, labels, server) {
}
function getWafChartData(server) {
$.ajax({
url: "/app/metrics/waf/" + server,
url: "/metrics/waf/" + server,
data: {
time_range: $( "#time-range option:selected" ).val(),
},
@ -355,7 +355,7 @@ function renderServiceChart(data, labels, server, service) {
}
function getNginxChartData(server) {
$.ajax({
url: "/app/metrics/nginx/" + server,
url: "/metrics/nginx/" + server,
data: {
time_range: $( "#time-range option:selected" ).val(),
},
@ -371,7 +371,7 @@ function getNginxChartData(server) {
}
function getApacheChartData(server) {
$.ajax({
url: "/app/metrics/apache/" + server,
url: "/metrics/apache/" + server,
data: {
time_range: $( "#time-range option:selected" ).val(),
},
@ -388,9 +388,9 @@ function getApacheChartData(server) {
function loadMetrics() {
let service = $('#service').val();
$.ajax({
url: "/app/metrics/" + service + "/table-metrics",
url: "/metrics/" + service + "/table-metrics",
beforeSend: function () {
$('#table_metrics').html('<img class="loading_full_page" src="/app/static/images/loading.gif" alt="loading..."/>')
$('#table_metrics').html('<img class="loading_full_page" src="/static/images/loading.gif" alt="loading..."/>')
},
type: "GET",
success: function (data) {
@ -404,14 +404,14 @@ function loadMetrics() {
}
function getChartDataHapWiRam(ip) {
$.ajax({
url: "/app/metrics/ram",
url: "/metrics/ram",
data: {
metrics_hapwi_ram: '1',
ip: ip,
token: $('#token').val()
},
beforeSend: function() {
$('#ram').html('<img class="loading_hapwi_overview" src="/app/static/images/loading.gif" alt="loading..." />')
$('#ram').html('<img class="loading_hapwi_overview" src="/static/images/loading.gif" alt="loading..." />')
},
type: "POST",
success: function (result) {
@ -482,7 +482,7 @@ function renderChartHapWiRam(data) {
}
function getChartDataHapWiCpu(ip) {
$.ajax({
url: "/app/metrics/cpu",
url: "/metrics/cpu",
data: {
metrics_hapwi_cpu: '1',
ip: ip,

View File

@ -116,7 +116,7 @@ $( function() {
return false;
}
$.ajax({
url: "/app/portscanner/scan",
url: "/portscanner/scan",
data: JSON.stringify({'ip': port_server}),
type: "POST",
contentType: "application/json; charset=utf-8",

View File

@ -1,4 +1,4 @@
var cur_url = window.location.href.split('/app/').pop();
var cur_url = window.location.href.split('/').pop();
cur_url = cur_url.split('/');
function showHapservers(serv, hostnamea, service) {
let i;
@ -8,9 +8,9 @@ function showHapservers(serv, hostnamea, service) {
}
function showHapserversCallBack(serv, hostnamea, service) {
$.ajax( {
url: "/app/service/" + service + "/" + serv + "/last-edit",
url: "/service/" + service + "/" + serv + "/last-edit",
beforeSend: function() {
$("#edit_date_"+hostnamea).html('<img class="loading_small_haproxyservers" src="/app/static/images/loading.gif" />');
$("#edit_date_"+hostnamea).html('<img class="loading_small_haproxyservers" src="/static/images/loading.gif" />');
},
type: "GET",
success: function( data ) {
@ -28,18 +28,30 @@ function showHapserversCallBack(serv, hostnamea, service) {
}
} );
}
function overviewHapserverBackends(serv, hostnamea, service) {
function overviewHapserverBackends(serv, hostname, service) {
let div = '';
$.ajax( {
url: "/app/service/" + service + "/backends/" + serv[0],
url: `/service/${service}/${serv[0]}/backend`,
beforeSend: function() {
$("#top-"+hostnamea).html('<img class="loading_small" style="padding-left: 45%;" src="/app/static/images/loading.gif" />');
$("#top-"+hostname).html('<img class="loading_small" style="padding-left: 45%;" src="/static/images/loading.gif" />');
},
contentType: "application/json; charset=utf-8",
success: function( data ) {
if (data.indexOf('error:') != '-1') {
if (data.status === 'failed') {
toastr.error(data);
} else {
$("#top-" + hostnamea).empty();
$("#top-" + hostnamea).html(data);
$('.div-backends').css('height', 'auto');
$("#top-" + hostname).empty();
for (let i in data.data) {
if (service === 'haproxy') {
div = `<a href="/config/section/haproxy/${serv}/${data.data[i]}" target="_blank" style="padding-right: 10px;">${data.data[i]}</a> `
} else if (service === 'nginx' || service === 'apache') {
div = `<a href="/config/${service}/${serv}/show/${i}" target="_blank" style="padding-right: 10px;">${data.data[i]}</a>`;
} else {
div = data.data[i];
}
$("#top-" + hostname).append(div);
}
}
}
} );
@ -57,9 +69,9 @@ function showOverview(serv, hostnamea) {
}
function showOverviewCallBack(serv, hostnamea) {
$.ajax( {
url: "/app/overview/server/"+serv,
url: "/overview/server/"+serv,
beforeSend: function() {
$("#"+hostnamea).html('<img class="loading_small" src="/app/static/images/loading.gif" />');
$("#"+hostnamea).html('<img class="loading_small" src="/static/images/loading.gif" />');
},
type: "GET",
success: function( data ) {
@ -75,9 +87,9 @@ function showOverviewCallBack(serv, hostnamea) {
}
function showServicesOverview() {
$.ajax( {
url: "/app/overview/services",
url: "/overview/services",
beforeSend: function() {
$("#services_ovw").html('<img class="loading_small_bin_bout" style="padding-left: 100%;padding-top: 40px;padding-bottom: 40px;" src="/app/static/images/loading.gif" />');
$("#services_ovw").html('<img class="loading_small_bin_bout" style="padding-left: 100%;padding-top: 40px;padding-bottom: 40px;" src="/static/images/loading.gif" />');
},
type: "GET",
@ -93,15 +105,12 @@ function showServicesOverview() {
}
function showOverviewServer(name, ip, id, service) {
$.ajax( {
url: "/app/service/cpu-ram-metrics/" + ip + "/" + id + "/" + name + "/" + service,
url: "/service/cpu-ram-metrics/" + ip + "/" + id + "/" + name + "/" + service,
success: function( data ) {
if (data.indexOf('error:') != '-1') {
toastr.error(data);
} else {
$("#ajax-server-" + id).empty();
$("#ajax-server-" + id).css('display', 'block');
$("#ajax-server-" + id).css('background-color', '#fbfbfb');
$("#ajax-server-" + id).css('border', '1px solid #A4C7F5');
$(".ajax-server").css('display', 'block');
$(".div-server").css('clear', 'both');
$(".div-pannel").css('clear', 'both');
@ -118,28 +127,17 @@ function showOverviewServer(name, ip, id, service) {
} );
}
function ajaxActionServers(action, id, service) {
$.ajax( {
url: "/app/service/action/" + service + "/" + id + "/" + action,
success: function( data ) {
data = data.replace(/\s+/g,' ');
if( data == 'Bad config, check please ' ) {
toastr.error(data);
$.ajax({
url: "/service/" + service + "/" + id + "/" + action,
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
if (data.indexOf('error:') != '-1') {
toastr.error(data);
} else {
if (data.indexOf('warning: ') != '-1') {
toastr.warning(data);
} else {
location.reload();
}
}
location.reload();
}
},
error: function(){
alert(w.data_error);
}
} );
});
}
$( function() {
try {
@ -222,14 +220,14 @@ $( function() {
}
});
});
function confirmAjaxAction(action, service, id) {
function confirmAjaxAction(action, service, id, name) {
let action_word = translate_div.attr('data-'+action);
$( "#dialog-confirm" ).dialog({
resizable: false,
height: "auto",
width: 400,
modal: true,
title: action_word + " " + id + "?",
title: action_word + " " + name + "?",
buttons: [{
text: action_word,
click: function () {
@ -244,13 +242,7 @@ function confirmAjaxAction(action, service, id) {
}
} else if (service == "waf") {
ajaxActionServers(action, id, 'waf_haproxy');
} else if (service == "nginx") {
ajaxActionServers(action, id, service);
} else if (service == "keepalived") {
ajaxActionServers(action, id, service);
} else if (service == "apache") {
ajaxActionServers(action, id, service);
} else if (service == "waf_nginx") {
} else {
ajaxActionServers(action, id, service);
}
}
@ -276,7 +268,7 @@ function updateHapWIServer(id, service_name) {
active = '1';
}
$.ajax({
url: "/app/service/" + service_name + "/tools/update",
url: "/service/" + service_name + "/tools/update",
data: {
server_id: id,
name: $('#server-name-' + id).val(),
@ -301,7 +293,7 @@ function updateHapWIServer(id, service_name) {
}
function change_pos(pos, id) {
$.ajax({
url: "/app/service/position/" + id + "/" + pos,
url: "/service/position/" + id + "/" + pos,
// data: {
// token: $('#token').val()
// },
@ -313,14 +305,14 @@ function change_pos(pos, id) {
}
function showBytes(serv) {
$.ajax( {
url: "/app/service/haproxy/bytes",
url: "/service/haproxy/bytes",
data: {
showBytes: serv
},
type: "POST",
beforeSend: function() {
$("#show_bin_bout").html('<img class="loading_small_bin_bout" src="/app/static/images/loading.gif" />');
$("#sessions").html('<img class="loading_small_bin_bout" src="/app/static/images/loading.gif" />');
$("#show_bin_bout").html('<img class="loading_small_bin_bout" src="/static/images/loading.gif" />');
$("#sessions").html('<img class="loading_small_bin_bout" src="/static/images/loading.gif" />');
},
success: function( data ) {
data = data.replace(/\s+/g,' ');
@ -335,13 +327,13 @@ function showBytes(serv) {
}
function showNginxConnections(serv) {
$.ajax( {
url: "/app/service/nginx/connections",
url: "/service/nginx/connections",
data: {
nginxConnections: serv
},
type: "POST",
beforeSend: function() {
$("#sessions").html('<img class="loading_small_bin_bout" src="/app/static/images/loading.gif" />');
$("#sessions").html('<img class="loading_small_bin_bout" src="/static/images/loading.gif" />');
},
success: function( data ) {
data = data.replace(/\s+/g,' ');
@ -356,13 +348,13 @@ function showNginxConnections(serv) {
}
function showApachekBytes(serv) {
$.ajax( {
url: "/app/service/apache/bytes",
url: "/service/apache/bytes",
data: {
apachekBytes: serv
},
type: "POST",
beforeSend: function() {
$("#sessions").html('<img class="loading_small_bin_bout" src="/app/static/images/loading.gif" />');
$("#sessions").html('<img class="loading_small_bin_bout" src="/static/images/loading.gif" />');
},
success: function( data ) {
data = data.replace(/\s+/g,' ');
@ -377,13 +369,13 @@ function showApachekBytes(serv) {
}
function keepalivedBecameMaster(serv) {
$.ajax( {
url: "/app/service/keepalived/become-master",
url: "/service/keepalived/become-master",
data: {
keepalivedBecameMaster: serv
},
type: "POST",
beforeSend: function() {
$("#bin_bout").html('<img class="loading_small_bin_bout" src="/app/static/images/loading.gif" />');
$("#bin_bout").html('<img class="loading_small_bin_bout" src="/static/images/loading.gif" />');
},
success: function( data ) {
data = data.replace(/\s+/g,' ');
@ -405,7 +397,7 @@ function showUsersOverview() {
// },
type: "GET",
beforeSend: function() {
$("#users-table").html('<img class="loading_small_bin_bout" style="padding-left: 100%;padding-top: 40px;padding-bottom: 40px;" src="/app/static/images/loading.gif" />');
$("#users-table").html('<img class="loading_small_bin_bout" style="padding-left: 100%;padding-top: 40px;padding-bottom: 40px;" src="/static/images/loading.gif" />');
},
success: function( data ) {
data = data.replace(/\s+/g,' ');
@ -419,14 +411,14 @@ function showUsersOverview() {
}
function showSubOverview() {
$.ajax( {
url: "/app/overview/sub",
url: "/overview/sub",
// data: {
// show_sub_ovw: 1,
// token: $('#token').val()
// },
type: "GET",
beforeSend: function() {
$("#sub-table").html('<img class="loading_small_bin_bout" style="padding-left: 40%;padding-top: 40px;padding-bottom: 40px;" src="/app/static/images/loading.gif" />');
$("#sub-table").html('<img class="loading_small_bin_bout" style="padding-left: 40%;padding-top: 40px;padding-bottom: 40px;" src="/static/images/loading.gif" />');
},
success: function( data ) {
data = data.replace(/\s+/g,' ');
@ -443,7 +435,7 @@ function serverSettings(id, name) {
let for_word = translate_div.attr('data-for');
let service = $('#service').val();
$.ajax({
url: "/app/service/settings/" + service + "/" + id,
url: "/service/settings/" + service + "/" + id,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error:') != '-1') {
@ -500,7 +492,7 @@ function serverSettingsSave(id, name, service, dialog_id) {
service_restart = '1';
}
$.ajax({
url: "/app/service/settings/" + service,
url: "/service/settings/" + service,
data: {
serverSettingsSave: id,
serverSettingsEnterprise: haproxy_enterprise,
@ -525,38 +517,41 @@ function check_service_status(id, ip, service) {
return false;
}
NProgress.configure({showSpinner: false});
if (service == 'keepalived') return false;
if (service === 'keepalived') return false;
let server_div = $('#div-server-' + id);
$.ajax({
url: "/app/service/action/" + service + "/check-service",
data: {
server_ip: ip
},
type: "POST",
success: function (data) {
if (data.indexOf('logout') != '-1') {
url: "/service/" + service + "/" + id + "/status",
contentType: "application/json; charset=utf-8",
statusCode: {
401: function (xhr) {
sessionStorage.setItem('check-service', 0)
},
404: function (xhr) {
sessionStorage.setItem('check-service', 0)
}
data = data.replace(/\s+/g, ' ');
if (cur_url[0] == 'service') {
if (data.indexOf('up') != '-1') {
$('#div-server-' + id).addClass('div-server-head-up');
$('#div-server-' + id).removeClass('div-server-head-down');
} else if (data.indexOf('down') != '-1') {
$('#div-server-' + id).removeClass('div-server-head-up');
$('#div-server-' + id).addClass('div-server-head-down');
}
} else if (cur_url[0] == '') {
},
success: function (data) {
if (cur_url[0] === 'overview') {
let span_id = $('#' + service + "_" + id);
if (data.indexOf('up') != '-1') {
if (data.status === 'failed') {
span_id.addClass('serverDown');
span_id.removeClass('serverUp');
span_id.attr('title', 'Service is down')
} else {
span_id.addClass('serverUp');
span_id.removeClass('serverDown');
if (span_id.attr('title').indexOf('Service is down') != '-1') {
span_id.attr('title', 'Service running')
}
} else if (data.indexOf('down') != '-1') {
span_id.addClass('serverDown');
span_id.removeClass('serverUp');
span_id.attr('title', 'Service is down')
}
} else {
console.log(data.length)
if (data.status === 'failed') {
server_div.removeClass('div-server-head-up');
server_div.addClass('div-server-head-down');
} else {
server_div.addClass('div-server-head-up');
server_div.removeClass('div-server-head-down');
}
}
}
@ -565,10 +560,10 @@ function check_service_status(id, ip, service) {
}
function ShowOverviewLogs() {
$.ajax( {
url: "/app/overview/logs",
url: "/overview/logs",
type: "GET",
beforeSend: function() {
$("#overview-logs").html('<img class="loading_small_bin_bout" style="padding-left: 40%;padding-top: 40px;padding-bottom: 40px;" src="/app/static/images/loading.gif" />');
$("#overview-logs").html('<img class="loading_small_bin_bout" style="padding-left: 40%;padding-top: 40px;padding-bottom: 40px;" src="/static/images/loading.gif" />');
},
success: function( data ) {
data = data.replace(/\s+/g,' ');

View File

@ -5,7 +5,7 @@ function showRuntime() {
saveCheck = "";
}
$.ajax({
url: "/app/runtimeapi/action/" + $("#serv").val(),
url: "/runtimeapi/action/" + $("#serv").val(),
data: {
servaction: $('#servaction').val(),
servbackend: $("#servbackend").val(),
@ -25,7 +25,7 @@ $( function() {
$("#maxconn_select").on('selectmenuchange', function () {
let server_ip = $('#maxconn_select').val();
$.ajax({
url: "/app/runtimeapi/maxconn/" + $('#maxconn_select').val(),
url: "/runtimeapi/maxconn/" + $('#maxconn_select').val(),
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error: ') != '-1') {
@ -47,7 +47,7 @@ $( function() {
});
$('#maxconnglobalform').submit(function () {
$.ajax({
url: "/app/runtimeapi/maxconn/global/" + $('#maxconn_global_select').val(),
url: "/runtimeapi/maxconn/global/" + $('#maxconn_global_select').val(),
data: {
maxconn: $('#maxconnintglobal').val(),
},
@ -65,7 +65,7 @@ $( function() {
});
$('#maxconnform').submit(function () {
$.ajax({
url: "/app/runtimeapi/maxconn/frontend/" + $('#maxconn_select').val(),
url: "/runtimeapi/maxconn/frontend/" + $('#maxconn_select').val(),
data: {
maxconn_frontend: $('#maxconnfront').val(),
maxconn: $('#maxconnint').val(),
@ -84,7 +84,7 @@ $( function() {
});
$('#maxconnbackform').submit(function () {
$.ajax({
url: "/app/runtimeapi/maxconn/backend/" + $('#maxconn_backend_select').val(),
url: "/runtimeapi/maxconn/backend/" + $('#maxconn_backend_select').val(),
data: {
maxconn_backend: $('#maxconnbackend').val(),
maxconn_backend_server: $('#maxconn_backend_server').val(),
@ -132,7 +132,7 @@ $( function() {
$('#backend_ip').val();
$('#backend_port').val();
$.ajax({
url: "/app/runtimeapi/backend/server/" + $('#ip_select').val() + "/" + $('#ipbackend').val() + "/" + $('#backend_server').val(),
url: "/runtimeapi/backend/server/" + $('#ip_select').val() + "/" + $('#ipbackend').val() + "/" + $('#backend_server').val(),
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error: ') != '-1') {
@ -150,7 +150,7 @@ $( function() {
});
$('#runtimeapiip').submit(function () {
$.ajax({
url: "/app/runtimeapi/server",
url: "/runtimeapi/server",
data: {
serv: $('#ip_select').val(),
backend_backend: $('#ipbackend').val(),
@ -176,7 +176,7 @@ $( function() {
check = 1;
}
$.ajax({
url: "/app/runtimeapi/server",
url: "/runtimeapi/server",
data: {
serv: $('#ip_select_server').val(),
backend_backend: $('#ipBackendServer').val(),
@ -200,7 +200,7 @@ $( function() {
});
$('#runtimeapiip_delete').submit(function () {
$.ajax({
url: "/app/runtimeapi/server",
url: "/runtimeapi/server",
data: {
serv: $('#ip_select_delete').val(),
backend_backend: $('#ipbackend_delete').val(),
@ -229,7 +229,7 @@ $( function() {
});
$("#table_serv_select").on('selectmenuchange', function () {
$.ajax({
url: "/app/runtimeapi/tables/" + $('#table_serv_select').val(),
url: "/runtimeapi/tables/" + $('#table_serv_select').val(),
success: function (data) {
data = data.replace(/\s+/g, '');
if (data.indexOf('error: ') != '-1') {
@ -254,7 +254,7 @@ $( function() {
});
$("#list_serv_select").on('selectmenuchange', function () {
$.ajax({
url: "/app/runtimeapi/list/" + $('#list_serv_select').val(),
url: "/runtimeapi/list/" + $('#list_serv_select').val(),
success: function (data) {
data = data.replace(/, /g, ',');
if (data.indexOf('error: ') != '-1') {
@ -292,7 +292,7 @@ $( function() {
function deleteTableEntry(id, table, ip) {
$(id).parent().parent().css("background-color", "#f2dede");
$.ajax( {
url: "/app/runtimeapi/table/" + $('#table_serv_select').val() + "/" + table + "/" + ip ,
url: "/runtimeapi/table/" + $('#table_serv_select').val() + "/" + table + "/" + ip ,
success: function( data ) {
if (data.indexOf('error: ') != '-1') {
toastr.error(data);
@ -304,7 +304,7 @@ function deleteTableEntry(id, table, ip) {
}
function clearTable(table) {
$.ajax( {
url: "/app/runtimeapi/table/clear/" + $('#table_serv_select').val() + "/" + table,
url: "/runtimeapi/table/clear/" + $('#table_serv_select').val() + "/" + table,
success: function( data ) {
if (data.indexOf('error: ') != '-1') {
toastr.error(data);
@ -316,7 +316,7 @@ function clearTable(table) {
}
function getTable() {
$.ajax({
url: "/app/runtimeapi/table/" + $('#table_serv_select').val() + "/" + $('#table_select').val(),
url: "/runtimeapi/table/" + $('#table_serv_select').val() + "/" + $('#table_select').val(),
success: function (data) {
if (data.indexOf('error:') != '-1') {
toastr.error(data);
@ -335,7 +335,7 @@ function getList() {
let list_name = $('#list_select option:selected').text().split('/')[1];
console.log(list_name)
$.ajax({
url: "/app/runtimeapi/list/" + $('#list_serv_select').val() + "/" + $('#list_select').val() + "/" + color + "/" + list_name,
url: "/runtimeapi/list/" + $('#list_serv_select').val() + "/" + $('#list_select').val() + "/" + color + "/" + list_name,
success: function (data) {
if (data.indexOf('error: ') != '-1') {
toastr.error(data);
@ -353,7 +353,7 @@ function deleteListIp(id, list_id, ip_id, ip) {
toastr.clear();
$(id).parent().parent().css("background-color", "#f2dede !important");
$.ajax({
url: "/app/runtimeapi/list/delete",
url: "/runtimeapi/list/delete",
data: {
serv: $('#list_serv_select').val(),
list_id_for_delete: list_id,
@ -382,7 +382,7 @@ function addNewIp() {
let ip = $('#list_add_ip_new_ip').val();
if (valid) {
$.ajax({
url: "/app/runtimeapi/list/add",
url: "/runtimeapi/list/add",
data: {
serv: $('#list_serv_select').val(),
list_ip_for_add: ip,
@ -405,7 +405,7 @@ function addNewIp() {
}
function getSessions() {
$.ajax({
url: "/app/runtimeapi/session/" + $('#sessions_serv_select').val(),
url: "/runtimeapi/session/" + $('#sessions_serv_select').val(),
success: function (data) {
if (data.indexOf('error: ') != '-1') {
toastr.error(data);
@ -421,7 +421,7 @@ function getSessions() {
}
function getSessionInfo(sess_id) {
$.ajax({
url: "/app/runtimeapi/session/" + $('#sessions_serv_select').val() + "/" + sess_id,
url: "/runtimeapi/session/" + $('#sessions_serv_select').val() + "/" + sess_id,
success: function (data) {
if (data.indexOf('danger') != '-1') {
toastr.error(data);
@ -449,7 +449,7 @@ function deleteSession(id, sess_id) {
toastr.clear();
$(id).parent().parent().css("background-color", "#f2dede !important");
$.ajax({
url: "/app/runtimeapi/session/delete/" +$('#sessions_serv_select').val() + "/" + sess_id,
url: "/runtimeapi/session/delete/" +$('#sessions_serv_select').val() + "/" + sess_id,
success: function (data) {
if (data.indexOf('error: ') != '-1') {
toastr.error(data);
@ -463,7 +463,7 @@ function deleteSession(id, sess_id) {
}
function get_backends(server_ip, backends_select_tag, ip_and_port=0) {
$.ajax({
url: "/app/runtimeapi/backends/" + server_ip,
url: "/runtimeapi/backends/" + server_ip,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error: ') != '-1') {
@ -482,7 +482,7 @@ function get_backends(server_ip, backends_select_tag, ip_and_port=0) {
}
function get_backend_servers(server_ip, backend, servers_select_tag, ip_and_port=0) {
$.ajax({
url: "/app/runtimeapi/backend/servers/" + server_ip + "/" + backend,
url: "/runtimeapi/backend/servers/" + server_ip + "/" + backend,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error: ') != '-1') {

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@ function sort_by_status() {
function showSmon(action) {
let sort = '';
let location = window.location.href;
let cur_url = '/app/' + location.split('/').pop();
let cur_url = '/' + location.split('/').pop();
if (action === 'refresh') {
try {
sort = cur_url[1].split('&')[1];
@ -28,10 +28,10 @@ function showSmon(action) {
}
}
if (action === 'not_sort') {
window.history.pushState("SMON Dashboard", "SMON Dashboard", "/app/smon/dashboard");
window.history.pushState("SMON Dashboard", "SMON Dashboard", "/smon/dashboard");
}
$.ajax({
url: "/app/smon/refresh",
url: "/smon/refresh",
data: {
sort: sort,
token: $('#token').val()
@ -108,7 +108,7 @@ function addNewSmonServer(dialog_id, smon_id=0, edit=false) {
}
if (valid) {
$.ajax( {
url: '/app/smon/check',
url: '/smon/check',
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
type: method,
@ -155,7 +155,7 @@ function removeSmon(smon_id) {
$("#smon-"+smon_id).css("background-color", "#f2dede");
let jsonData = {'check_id': smon_id}
$.ajax( {
url: "/app/smon/check",
url: "/smon/check",
type: "DELETE",
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
@ -218,7 +218,7 @@ function openSmonDialog(check_type, smon_id=0, edit=false) {
}
function getCheckSettings(smon_id, check_type) {
$.ajax( {
url: "/app/smon/check/settings/" + smon_id + "/" + check_types[check_type],
url: "/smon/check/settings/" + smon_id + "/" + check_types[check_type],
type: "get",
async: false,
dataType: "json",
@ -270,7 +270,7 @@ function cloneSmom(id, check_type) {
}
function getSmonCheck(smon_id, check_id, dialog_id, new_check=false) {
$.ajax({
url: "/app/smon/check/" + smon_id + "/" + check_id,
url: "/smon/check/" + smon_id + "/" + check_id,
type: "get",
success: function (data) {
if (new_check) {
@ -336,7 +336,7 @@ function clear_check_vals() {
function show_statuses(dashboard_id, check_id, id_for_history_replace) {
show_smon_history_statuses(dashboard_id, id_for_history_replace);
$.ajax({
url: "/app/smon/history/cur_status/" + dashboard_id + "/" + check_id,
url: "/smon/history/cur_status/" + dashboard_id + "/" + check_id,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error:') != '-1' || data.indexOf('unique') != '-1') {
@ -350,7 +350,7 @@ function show_statuses(dashboard_id, check_id, id_for_history_replace) {
}
function show_smon_history_statuses(dashboard_id, id_for_history_replace) {
$.ajax({
url: "/app/smon/history/statuses/" + dashboard_id,
url: "/smon/history/statuses/" + dashboard_id,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error:') != '-1' || data.indexOf('unique') != '-1') {
@ -370,7 +370,7 @@ function show_smon_history_statuses(dashboard_id, id_for_history_replace) {
}
function smon_status_page_avg_status(page_id) {
$.ajax({
url: "/app/smon/status/avg/" + page_id,
url: "/smon/status/avg/" + page_id,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error:') != '-1' || data.indexOf('unique') != '-1') {
@ -388,7 +388,7 @@ function smon_status_page_avg_status(page_id) {
}
function smon_manage_status_page_avg_status(page_id) {
$.ajax({
url: "/app/smon/status/avg/" + page_id,
url: "/smon/status/avg/" + page_id,
success: function (data) {
data = data.replace(/\s+/g, ' ');
if (data.indexOf('error:') != '-1' || data.indexOf('unique') != '-1') {
@ -468,7 +468,7 @@ function createStatusPageStep2(edited, page_id) {
add_word = translate_div.attr('data-edit');
if ($("#enabled-check > div").length == 0) {
$.ajax({
url: "/app/smon/status/checks/" + page_id,
url: "/smon/status/checks/" + page_id,
async: false,
type: "GET",
success: function (data) {
@ -544,7 +544,7 @@ function createStatusPage(dialog_id) {
checks.push(check_id);
});
$.ajax({
url: '/app/smon/status-page',
url: '/smon/status-page',
type: 'POST',
data: {
name: name_id.val(),
@ -575,7 +575,7 @@ function editStatusPage(dialog_id, page_id) {
checks.push(check_id);
});
$.ajax({
url: '/app/smon/status-page',
url: '/smon/status-page',
type: 'PUT',
data: {
page_id: page_id,
@ -649,7 +649,7 @@ function confirmDeleteStatusPage(id) {
}
function deleteStatusPage(page_id) {
$.ajax({
url: '/app/smon/status-page',
url: '/smon/status-page',
type: 'DELETE',
data: {
page_id: page_id,
@ -667,7 +667,7 @@ function deleteStatusPage(page_id) {
function checkAgentLimit() {
let return_value = false;
$.ajax({
url: '/app/smon/agent/count',
url: '/smon/agent/count',
async: false,
success: function (data) {
data = data.replace(/\s+/g, ' ');
@ -772,7 +772,7 @@ function addAgent(dialog_id, agent_id=0, edit=false, reconfigure=false) {
}
if (valid) {
$.ajax({
url: "/app/smon/agent",
url: "/smon/agent",
type: method,
data: JSON.stringify(agent_data),
contentType: "application/json; charset=utf-8",
@ -795,7 +795,7 @@ function addAgent(dialog_id, agent_id=0, edit=false, reconfigure=false) {
}
function getAgentSettings(agent_id) {
$.ajax({
url: "/app/smon/agent/settings/" + agent_id,
url: "/smon/agent/settings/" + agent_id,
async: false,
success: function (data) {
$('#new-agent-name').val(data['name']);
@ -815,7 +815,7 @@ function getAgentSettings(agent_id) {
}
function getFreeServers() {
$.ajax({
url: "/app/smon/agent/free",
url: "/smon/agent/free",
async: false,
contentType: "application/json; charset=utf-8",
success: function (data) {
@ -838,7 +838,7 @@ function cleanAgentAddForm() {
}
function getAgent(agent_id, new_agent=false) {
$.ajax({
url: "/app/smon/agent/" + agent_id,
url: "/smon/agent/" + agent_id,
success: function (data) {
data = data.replace(/^\s+|\s+$/g, '');
if (data.indexOf('error:') != '-1') {
@ -857,7 +857,7 @@ function getAgent(agent_id, new_agent=false) {
}
function getAgentVersion(server_ip, agent_id){
$.ajax({
url: '/app/smon/agent/version/' + server_ip,
url: '/smon/agent/version/' + server_ip,
type: 'get',
data: {agent_id: agent_id},
success: function (data){
@ -872,7 +872,7 @@ function getAgentVersion(server_ip, agent_id){
}
function getAgentUptime(server_ip, agent_id){
$.ajax({
url: '/app/smon/agent/uptime/' + server_ip,
url: '/smon/agent/uptime/' + server_ip,
type: 'get',
data: {agent_id: agent_id},
success: function (data){
@ -889,7 +889,7 @@ function getAgentUptime(server_ip, agent_id){
}
function getAgentStatus(server_ip, agent_id){
$.ajax({
url: '/app/smon/agent/status/' + server_ip,
url: '/smon/agent/status/' + server_ip,
type: 'get',
data: {agent_id: agent_id},
success: function (data){
@ -919,7 +919,7 @@ function getAgentStatus(server_ip, agent_id){
}
function getAgentTotalChecks(server_ip, agent_id){
$.ajax({
url: '/app/smon/agent/checks/' + server_ip,
url: '/smon/agent/checks/' + server_ip,
type: 'get',
data: {agent_id: agent_id},
success: function (data){
@ -956,7 +956,7 @@ function confirmDeleteAgent(id) {
}
function removeAgent(id, dialog_id) {
$.ajax({
url: "/app/smon/agent",
url: "/smon/agent",
type: "delete",
data: {agent_id: id},
success: function (data){
@ -994,7 +994,7 @@ function confirmAjaxAction(action, id, server_ip) {
}
function agentAction(action, id, server_ip, dialog_id) {
$.ajax({
url: "/app/smon/agent/action/"+ action,
url: "/smon/agent/action/"+ action,
type: "post",
data: {agent_id: id, server_ip: server_ip},
success: function (data) {
@ -1012,7 +1012,7 @@ function agentAction(action, id, server_ip, dialog_id) {
var charts = []
function getSmonHistoryCheckData(server) {
$.ajax({
url: "/app/smon/history/metric/" + server,
url: "/smon/history/metric/" + server,
success: function (result) {
let data = [];
data.push(result.chartData.curr_con);

View File

@ -1,23 +1,23 @@
$( function() {
$( "#ha-cluster" ).on('selectmenuchange',function() {
let cluster_id = $( "#ha-cluster option:selected" ).val();
if (cluster_id != '------') {
$("#cluster_id").on('selectmenuchange', function () {
let cluster_id = $("#cluster_id option:selected").val();
if (cluster_id != '------' && cluster_id != '' && cluster_id != undefined) {
getHAClusterVIPS(cluster_id);
} else {
clearUdpVip();
}
});
$("#new-udp-ip").autocomplete({
$("#ip").autocomplete({
source: function (request, response) {
if (!checkIsServerFiled('#serv')) return false;
if (request.term == "") {
request.term = 1
}
$.ajax({
url: "/app/server/show/ip/" + $("#serv").val(),
url: `/server/${$("#serv").val()}/ip`,
contentType: "application/json; charset=UTF-8",
success: function (data) {
data = data.replace(/\s+/g, ' ');
response(data.split(" "));
response(data);
}
});
},
@ -30,8 +30,9 @@ $( function() {
});
});
function getHAClusterVIPS(cluster_id) {
let vip_id = $('#vip');
$.ajax({
url: `/app/ha/cluster/${cluster_id}/vips`,
url: api_prefix + `/ha/cluster/${cluster_id}/vips`,
async: false,
contentType: "application/json; charset=utf-8",
success: function (data) {
@ -40,11 +41,11 @@ function getHAClusterVIPS(cluster_id) {
return false;
} else {
clearUdpVip();
$('#new-udp-vip').append('<option value="------" selected>------</option>')
vip_id.append('<option value="------" selected>------</option>')
data.forEach(function (obj) {
$('#new-udp-vip').append('<option value="' + obj.id + '">' + obj.vip + '</option>')
vip_id.append('<option value="' + obj.id + '">' + obj.vip + '</option>')
});
$('#new-udp-vip').selectmenu("refresh");
vip_id.selectmenu("refresh");
}
}
});
@ -67,35 +68,39 @@ function createUDPListener(edited=false, listener_id=0, clean=true) {
$('.new-udp-servers-tr').show();
}
$.ajax({
url: `/app/udp/listener/${listener_id}/settings`,
url: `${api_prefix}/udp/listener/${listener_id}`,
type: "GET",
async: false,
contentType: "application/json; charset=utf-8",
success: function (data) {
$('#new-listener-name').val(data.name.replaceAll("'", ""));
$('#name').val(data.name.replaceAll("'", ""));
$('#new-listener-type').val(place);
$('#new-listener-port').val(data.port);
$('#new-listener-desc').val(data.desc.replaceAll("'", ""));
$('#port').val(data.port);
$('#lb_algo').val(data.lb_algo).change();
$('#lb_algo').selectmenu('refresh');
$('#desc').val(data.description.replaceAll("'", ""));
if (place === 'cluster') {
$.when(getHAClusterVIPS(data.cluster_id)).done(function () {
$("#new-udp-vip option").filter(function () {
$("#vip option").filter(function () {
return $(this).text() == data.vip;
}).attr('selected', true);
$("#new-udp-vip").selectmenu('refresh');
$("#vip").selectmenu('refresh');
});
$("#ha-cluster").val(data.cluster_id).change();
$("#ha-cluster").attr('disabled', 'disabled');
$("#ha-cluster").selectmenu('refresh');
$("#cluster_id").val(data.cluster_id).change();
$("#cluster_id").attr('disabled', 'disabled');
$("#cluster_id").selectmenu('refresh');
} else {
$("#serv").val(data.server_id).change();
$("#serv").attr('disabled', 'disabled');
$("#serv").selectmenu('refresh');
$('#new-udp-ip').val(data.vip);
$('#ip').val(data.vip);
}
$('#new-udp-servers-td').empty();
$('#new-udp-servers-td').append('<a class="link add-server" title="Add backend server" onclick="createBackendServer()"></a>');
for(let server in data.config) {
createBackendServer(server, data.config[server]['port'], data.config[server]['weight']);
data.config = JSON.stringify(data.config);
let config = JSON.parse(data.config)
for(let server of config) {
createBackendServer(server.backend_ip, server.port, server.weight);
}
}
});
@ -206,20 +211,20 @@ function createUDPListenerStep2(edited, listener_id, place) {
dialog_div.dialog('open');
}
function validateUDPListenerForm(place) {
if ($('#new-listener-name').val() == '') {
if ($('#name').val() == '') {
toastr.error('error: Fill in the Name field');
return false;
}
if ($('#new-listener-port').val() == '') {
if ($('#port').val() == '') {
toastr.error('error: Fill in the Port field');
return false;
}
if (place == 'server') {
if ($('#new-udp-ip').val() == '') {
if ($('#ip').val() == '') {
toastr.error('error: Fill in the IP field');
return false;
}
if (!ValidateIPaddress($('#new-udp-ip').val())) {
if (!ValidateIPaddress($('#ip').val())) {
toastr.error('error: Wrong IP');
return false;
}
@ -228,7 +233,7 @@ function validateUDPListenerForm(place) {
return false;
}
} else {
if ($('#ha-cluster option:selected').val().indexOf('--') != '-1') {
if ($('#cluster_id option:selected').val().indexOf('--') != '-1') {
toastr.error('error: Select a HA cluster');
return false;
}
@ -240,11 +245,11 @@ function validateUDPListenerForm(place) {
toastr.error('error: Fill in the Weight field');
return false;
}
if ($('#new-udp-vip option:selected').val().indexOf('--') != '-1') {
if ($('#vip option:selected').val().indexOf('--') != '-1') {
toastr.error('error: Select the VIP address');
return false;
}
if (!ValidateIPaddress($('#new-udp-vip option:selected').text())) {
if (!ValidateIPaddress($('#vip option:selected').text())) {
toastr.error('error: Wrong VIP');
return false;
}
@ -256,35 +261,52 @@ function getFormData($form) {
$("#serv").selectmenu('refresh');
let unindexed_array = $form.serializeArray();
let indexed_array = {};
indexed_array['servers'] = {};
indexed_array['config'] = [];
$.map(unindexed_array, function (n, i) {
indexed_array[n['name']] = n['value'];
if (n['name'] === 'serv') {
indexed_array['server_id'] = n['value'];
} else {
indexed_array[n['name']] = n['value'];
}
});
$('.servers').each(function () {
let ip = $(this).children("input[name='new-udp-server']").val();
if (ip === undefined || ip === '') {
let backend_ip = $(this).children("input[name='new-udp-server']").val();
if (backend_ip === undefined || backend_ip === '') {
return;
}
let port = $(this).children("input[name='new-udp-port']").val();
let weight = $(this).children("input[name='new-udp-weight']").val();
indexed_array['servers'][ip] = {port, weight};
indexed_array['config'].push({backend_ip, port, weight});
});
indexed_array['ha-cluster'] = $('#ha-cluster').val();
indexed_array['new-udp-router_id'] = $('#new-udp-vip').val();
indexed_array['new-udp-vip'] = $('#new-udp-vip option:selected').text();
if ($('#cluster_id').val()) {
indexed_array['cluster_id'] = $('#cluster_id').val();
} else {
indexed_array['cluster_id'] = null;
}
if ($('#new-listener-type').val() === 'cluster') {
indexed_array['router_id'] = $('#vip').val();
indexed_array['vip'] = $('#vip option:selected').text();
} else {
indexed_array['vip'] = $('#ip').val();
}
$("#serv").attr('disabled', 'disabled');
$("#serv").selectmenu('refresh');
return indexed_array;
}
function saveUdpListener(jsonData, dialog_id, listener_id=0, edited=0, reconfigure=0) {
let req_method = 'POST';
let url = api_prefix + "/udp/listener";
if (reconfigure) {
jsonData['reconfigure'] = 1;
}
if (edited) {
req_method = 'PUT';
jsonData['listener_id'] = listener_id;
url = api_prefix + "/udp/listener/" + listener_id;
}
$.ajax({
url: "/app/udp/listener",
url: url,
type: req_method,
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
@ -299,18 +321,18 @@ function saveUdpListener(jsonData, dialog_id, listener_id=0, edited=0, reconfigu
$("#listener-" + listener_id).removeClass("update");
}, 2500);
} else {
listener_id = data.listener_id;
getUDPListener(data.listener_id, true);
listener_id = data.id;
getUDPListener(listener_id, true);
}
if (reconfigure) {
NProgress.start();
$.when(Reconfigure(listener_id)).done(function () {
dialog_id.dialog("close");
NProgress.done();
});
} else {
// if (reconfigure) {
// NProgress.start();
// $.when(Reconfigure(listener_id)).done(function () {
// dialog_id.dialog("close");
// NProgress.done();
// });
// } else {
dialog_id.dialog("close");
}
// }
toastr.success('Listener ' + data.status);
}
}
@ -318,7 +340,7 @@ function saveUdpListener(jsonData, dialog_id, listener_id=0, edited=0, reconfigu
}
function Reconfigure(listener_id) {
return $.ajax({
url: "/app/install/udp",
url: "/install/udp",
data: JSON.stringify({listener_id: listener_id}),
contentType: "application/json; charset=utf-8",
async: false,
@ -334,7 +356,7 @@ function Reconfigure(listener_id) {
}
function getUDPListener(listener_id, new_listener=false) {
$.ajax({
url: "/app/udp/listener/" + listener_id,
url: "/udp/listener/" + listener_id,
success: function (data) {
data = data.replace(/^\s+|\s+$/g, '');
if (data.indexOf('error:') != '-1') {
@ -373,17 +395,23 @@ function confirmDeleteListener(listener_id) {
});
}
function deleteListener(listener_id) {
let jsonData = {'listener_id': listener_id}
$.ajax({
url: "/app/udp/listener",
url: api_prefix + "/udp/listener/" + listener_id,
type: "DELETE",
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
statusCode: {
204: function (xhr) {
$('#listener-' + listener_id).remove();
},
404: function (xhr) {
$('#listener-' + listener_id).remove();
}
},
success: function (data) {
if (data) {
if (data.status === "failed") {
toastr.error(data.error);
}
}
}
});
@ -391,17 +419,16 @@ function deleteListener(listener_id) {
function clearListenerDialog(edited=0) {
$('#new-listener-name').val('');
$('#new-listener-desc').val('');
$('#ha-cluster-master-interface').val('');
$('#new-udp-ip').val('');
$('#vrrp-ip').prop("readonly", false);
$('#new-listener-port').val('');
$("#ha-cluster").attr('disabled', false);
$("#cluster_id").attr('disabled', false);
$("#serv").attr('disabled', false);
clearUdpVip()
$('#new-udp-servers-td').empty();
$('#new-udp-servers-td').append('<a class="link add-server" title="Add backend server" onclick="createBackendServer()"></a>');
createBackendServer();
let selects = ['new-udp-type', 'ha-cluster', 'new-udp-vip', 'serv']
let selects = ['new-udp-type', 'cluster_id', 'vip', 'serv']
for (let select of selects) {
unselectSelectMenu(select);
}
@ -412,9 +439,9 @@ function unselectSelectMenu(select_id) {
$('#' + select_id).selectmenu("refresh");
}
function clearUdpVip() {
$('#new-udp-vip').selectmenu( "destroy" );
$('#new-udp-vip').empty();
$('#new-udp-vip').selectmenu();
$('#vip').selectmenu( "destroy" );
$('#vip').empty();
$('#vip').selectmenu();
}
function confirmUdpBalancerAction(action, listener_id) {
let action_word = translate_div.attr('data-'+action);
@ -441,7 +468,7 @@ function confirmUdpBalancerAction(action, listener_id) {
}
function ajaxActionListener(action, listener_id) {
$.ajax({
url: `/app/udp/listener/${listener_id}/${action}`,
url: `${api_prefix}/udp/listener/${listener_id}/${action}`,
type: "GET",
contentType: "application/json; charset=utf-8",
success: function (data) {
@ -470,18 +497,29 @@ function createBackendServer(server='', port='', weight='1') {
$.getScript(awesome);
}
function checkStatus(listener_id) {
if (sessionStorage.getItem('check-service-udp') == 0) {
if (sessionStorage.getItem('check-service-udp-'+listener_id) == 0) {
return false;
}
NProgress.configure({showSpinner: false});
let listener_div = $('#listener-' + listener_id);
$.ajax({
url: "/app/udp/listener/" + listener_id + "/check",
url: api_prefix + "/udp/listener/" + listener_id,
contentType: "application/json; charset=utf-8",
statusCode: {
404: function (xhr) {
$('#listener-' + listener_id).remove();
},
403: function (xhr) {
sessionStorage.setItem('check-service-udp-'+listener_id, 0);
},
500: function (xhr) {
sessionStorage.setItem('check-service-udp-'+listener_id, 0);
}
},
success: function (data) {
try {
if (data.indexOf('logout') != '-1') {
sessionStorage.setItem('check-service-udp', 0);
sessionStorage.setItem('check-service-udp-'+listener_id, 0);
}
} catch (e) {}
@ -501,6 +539,14 @@ function checkStatus(listener_id) {
listener_div.removeClass('div-server-head-down');
listener_div.attr('title', 'Not all services are UP');
}
$(`#listener-name-${listener_id}`).text(data.name.replaceAll("'", ""));
if (data.description === '') {
$(`#listener-desc-${listener_id}`).text('');
} else {
$(`#listener-desc-${listener_id}`).text(`(${data.description.replaceAll("'", "")})`);
}
$(`#port-${listener_id}`).text(data.port);
$(`#vip-${listener_id}`).text(data.vip);
}
});
NProgress.configure({showSpinner: true});

View File

@ -13,9 +13,16 @@ const delete_word = translate_div.attr('data-delete');
const back_word = translate_div.attr('data-back');
// JS scripts URL
const scriptPath = "/app/static/js"
const scriptPath = "/static/js"
const script = `${scriptPath}/script.js`;
const overview = `${scriptPath}/overview.js`;
const configShow = `${scriptPath}/configshow.js`;
const awesome = `${scriptPath}/fontawesome.min.js`;
const ha = `${scriptPath}/ha.js`;
const waf = `${scriptPath}/waf.js`
// csrf_token
const csrf_token = Cookies.get('csrf_access_token');
// API prefix
const api_prefix = '/api'

View File

@ -1,27 +1,26 @@
var waf = "/app/static/js/waf.js"
function showOverviewWaf(serv, hostnamea) {
let service = cur_url[1];
function showOverviewWaf(serv, hostname) {
let service = cur_url[0];
if (service == 'haproxy') {
$.getScript('/app/static/js/chart.min-4.3.0.js');
$.getScript('/static/js/chart.min-4.3.0.js');
showWafMetrics();
}
let i;
for (i = 0; i < serv.length; i++) {
showOverviewWafCallBack(serv[i], hostnamea[i])
showOverviewWafCallBack(serv[i], hostname[i])
}
$.getScript(overview);
$.getScript(waf);
}
function showOverviewWafCallBack(serv, hostnamea) {
let service = cur_url[1];
function showOverviewWafCallBack(serv, hostname) {
let service = cur_url[0];
$.ajax({
url: "/app/waf/overview/" + service + "/" + serv,
url: "/waf/overview/" + service + "/" + serv,
beforeSend: function () {
$("#" + hostnamea).html('<img class="loading_small" src="/app/static/images/loading.gif" />');
$("#" + hostname).html('<img class="loading_small" src="/static/images/loading.gif" />');
},
success: function (data) {
$("#" + hostnamea).empty();
$("#" + hostnamea).html(data)
$("#" + hostname).empty();
$("#" + hostname).html(data)
$("input[type=submit], button").button();
$("input[type=checkbox]").checkboxradio();
$.getScript(overview);
@ -36,7 +35,7 @@ function metrics_waf(name) {
}
name = name.split('metrics')[1]
$.ajax({
url: "/app/waf/metric/enable/" + enable + "/" + name,
url: "/waf/metric/enable/" + enable + "/" + name,
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
@ -53,9 +52,9 @@ function metrics_waf(name) {
function installWaf(ip1) {
$("#ajax").html('');
$("#ajax").html(wait_mess);
let service = cur_url[1];
let service = cur_url[0];
$.ajax({
url: "/app/install/waf/" + service + "/" + ip1,
url: "/install/waf/" + service + "/" + ip1,
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
@ -73,9 +72,9 @@ function installWaf(ip1) {
function changeWafMode(id) {
let waf_mode = $('#' + id + ' option:selected').val();
let server_hostname = id.split('_')[0];
let service = cur_url[1];
let service = cur_url[0];
$.ajax({
url: "/app/waf/" + service + "/mode/" + server_hostname + "/" + waf_mode,
url: "/waf/" + service + "/mode/" + server_hostname + "/" + waf_mode,
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
@ -103,7 +102,7 @@ function waf_rules_en(id) {
}
let serv = cur_url[2];
$.ajax({
url: "/app/waf/" + serv + "/rule/" + id + "/" + enable,
url: "/waf/" + serv + "/rule/" + id + "/" + enable,
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data.status === 'failed') {
@ -147,7 +146,7 @@ function addNewConfig() {
let new_rule_name = new_rule_name_id.val();
let new_rule_description = new_rule_description_id.val();
let new_rule_file = new_rule_name.replaceAll(' ', '_');
let service = cur_url[1];
let service = cur_url[0];
let serv = cur_url[2];
service = escapeHtml(service);
new_rule_name = escapeHtml(new_rule_name);
@ -160,7 +159,7 @@ function addNewConfig() {
"new_rule_file": new_rule_file
}
$.ajax({
url: "/app/waf/" + service + "/" + serv + "/rule/create",
url: "/waf/" + service + "/" + serv + "/rule/create",
data: JSON.stringify(jsonData),
contentType: "application/json; charset=utf-8",
type: "POST",
@ -168,7 +167,7 @@ function addNewConfig() {
if (data.status === 'failed') {
toastr.error(data.error);
} else {
window.location.replace("/app/waf/" + service + "/" + serv + "/rule/" + data.id);
window.location.replace("/waf/" + service + "/" + serv + "/rule/" + data.id);
}
}
});

View File

@ -20,7 +20,7 @@
{% set header_params = {'add-header': 'add-header', 'set-header': 'set-header', 'del-header': 'del-header'} %}
{% set if_values = {'1':'Host name starts with','2':'Host name ends with','3':'Path starts with','4':'Path ends with', '6': 'Src ip'} %}
<script src="/app/static/js/add.js"></script>
<script src="/static/js/add.js"></script>
<div id="tabs">
<ul>
<li><a href="#create" title="{{lang.words.add|title()}} {{lang.words.proxy}}: {{lang.words.create|title()}} {{lang.words.proxy}} - Roxy-WI">{{lang.words.create|title()}} {{lang.words.proxy}}</a></li>
@ -38,7 +38,7 @@
<ul id='browse_histroy'></ul>
{% include 'include/add_proxy.html' %}
<div id="listen">
<form name="add-listener" id="add-listener" action="/app/add/haproxy/add" method="post">
<form name="add-listener" id="add-listener" action="/add/haproxy/add" method="post">
<table class="add-table">
<caption><h3>{{lang.words.add|title()}} {{lang.words.listener}}</h3></caption>
<tr>
@ -301,7 +301,7 @@
<!-- Second tabs -->
<div id="frontend">
<form name="add-frontend" id="add-frontend" action="/app/add/haproxy/add" method="post">
<form name="add-frontend" id="add-frontend" action="/add/haproxy/add" method="post">
<table>
<caption><h3>{{lang.words.add|title()}} {{lang.words.frontend}}</h3></caption>
<tr>
@ -492,7 +492,7 @@
<!-- Third tabs -->
<div id="backend">
<form name="add-backend" id="add-backend" action="/app/add/haproxy/add" method="post">
<form name="add-backend" id="add-backend" action="/add/haproxy/add" method="post">
<table>
<caption><h3>{{lang.words.add|title()}} {{lang.words.backend}}</h3></caption>
<tr>
@ -873,7 +873,7 @@
</div>
</div>
<div id="userlist">
<form name="add-userlist" id="add-userlist" action="/app/add/haproxy/userlist" method="post">
<form name="add-userlist" id="add-userlist" action="/add/haproxy/userlist" method="post">
<table>
<caption><h3>{{lang.words.add|title()}} {{lang.words.userlists}}</h3></caption>
<tr>
@ -956,7 +956,7 @@
</div>
</div>
<div id="peers">
<form name="add-peers" id="add-peers" action="/app/add/haproxy/peers" method="post">
<form name="add-peers" id="add-peers" action="/add/haproxy/peers" method="post">
<table>
<caption><h3>{{lang.words.add|title()}} Peer</h3></caption>
<tr>

View File

@ -5,7 +5,7 @@
{% from 'include/input_macros.html' import input, checkbox, select %}
{% set balance_params = dict() %}
{% set balance_params = {'ip_hash':'ip_hash','least_conn':'least_conn','random':'random', 'round_robin': 'round-robin'} %}
<script src="/app/static/js/add_nginx.js"></script>
<script src="/static/js/add_nginx.js"></script>
<div id="tabs">
<ul>
<li><a href="#create" title="{{lang.words.add|title()}} {{lang.words.proxy}}: {{lang.words.add|title()}} {{lang.words.proxy}} - Roxy-WI">{{lang.words.add|title()}} {{lang.words.proxy}}</a></li>
@ -14,7 +14,7 @@
<ul id='browse_histroy'></ul>
{% include 'include/add_nginx_proxy.html' %}
<div id="upstream">
<form name="add-upstream" id="add-upstream" action="/app/add/nginx/upstream" method="post">
<form name="add-upstream" id="add-upstream" action="/add/nginx/upstream" method="post">
<table class="add-table">
<caption><h3>{{lang.words.add|title()}} upstream</h3></caption>
<tr>

Some files were not shown because too many files have changed in this diff Show More