From c45532cfe4c6276eff5e1c3c80762232d5afdcf1 Mon Sep 17 00:00:00 2001 From: Aidaho Date: Thu, 16 Nov 2023 10:58:37 +0300 Subject: [PATCH] v7.0.3.0 Changelog: https://roxy-wi.org/changelog#7.0.3 --- app/create_db.py | 2 +- app/modules/config/runtime.py | 180 +++++++++++++++++++--- app/modules/db/sql.py | 30 +++- app/modules/tools/smon.py | 17 +- app/routes/runtime/routes.py | 21 ++- app/routes/smon/routes.py | 90 +++++++---- app/templates/ajax/smon/status_pages.html | 5 +- app/templates/runtimeapi.html | 89 ++++++++++- inc/runtimeapi.js | 80 +++++++++- inc/smon.js | 116 +++++++++++--- 10 files changed, 527 insertions(+), 103 deletions(-) diff --git a/app/create_db.py b/app/create_db.py index c3c31044..682b6bbb 100644 --- a/app/create_db.py +++ b/app/create_db.py @@ -668,7 +668,7 @@ def update_db_v_6_3_18(): def update_ver(): try: - Version.update(version='7.0.2.0').execute() + Version.update(version='7.0.3.0').execute() except Exception: print('Cannot update version') diff --git a/app/modules/config/runtime.py b/app/modules/config/runtime.py index e09765c8..36a9137d 100644 --- a/app/modules/config/runtime.py +++ b/app/modules/config/runtime.py @@ -4,6 +4,7 @@ from flask import render_template import modules.db.sql as sql import modules.config.config as config_mod +import modules.config.section as section_mod import modules.server.server as server_mod import modules.roxywi.common as roxywi_common import modules.roxy_wi_tools as roxy_wi_tools @@ -121,25 +122,23 @@ def change_ip_and_port(serv, backend_backend, backend_server, backend_ip, backen if backend_port is None: return 'error: The backend port must be integer and not 0' - haproxy_sock_port = sql.get_setting('haproxy_sock_port') lines = '' - + sock_port = sql.get_setting('haproxy_sock_port') masters = sql.is_master(serv) + for master in masters: if master[0] is not None: - cmd = 'echo "set server %s/%s addr %s port %s check-port %s" |nc %s %s' % ( - backend_backend, backend_server, backend_ip, backend_port, backend_port, master[0], haproxy_sock_port) + cmd = f'echo "set server {backend_backend}/{backend_server} addr {backend_ip} port {backend_port} ' \ + f'check-port {backend_port}" |nc {master[0]} {sock_port}' output, stderr = server_mod.subprocess_execute(cmd) lines += output[0] roxywi_common.logging( - master[0], 'IP address and port have been changed. On: {}/{} to {}:{}'.format( - backend_backend, backend_server, backend_ip, backend_port - ), + master[0], f'IP address and port have been changed. On: {backend_backend}/{backend_server} to {backend_ip}:{backend_port}', login=1, keep_history=1, service='haproxy' ) - cmd = 'echo "set server %s/%s addr %s port %s check-port %s" |nc %s %s' % ( - backend_backend, backend_server, backend_ip, backend_port, backend_port, serv, haproxy_sock_port) + cmd = f'echo "set server {backend_backend}/{backend_server} addr {backend_ip} port {backend_port} ' \ + f'check-port {backend_port}" |nc {serv} {sock_port}' roxywi_common.logging( serv, f'IP address and port have been changed. On: {backend_backend}/{backend_server} to {backend_ip}:{backend_port}', @@ -148,18 +147,159 @@ def change_ip_and_port(serv, backend_backend, backend_server, backend_ip, backen output, stderr = server_mod.subprocess_execute(cmd) if stderr != '': - lines += 'error: ' + stderr[0] - else: - lines += output[0] - configs_dir = get_config_var.get_config_var('configs', 'haproxy_save_configs_dir') - cfg = f"{configs_dir}{serv}-{get_date.return_date('config')}.cfg" + return 'error: ' + stderr[0] - config_mod.get_config(serv, cfg) - cmd = 'string=`grep %s %s -n -A25 |grep "server %s" |head -1|awk -F"-" \'{print $1}\'` ' \ - '&& sed -Ei "$( echo $string)s/((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5]):[0-9]+/%s:%s/g" %s' % \ - (backend_backend, cfg, backend_server, backend_ip, backend_port, cfg) - server_mod.subprocess_execute(cmd) - config_mod.master_slave_upload_and_restart(serv, cfg, 'save', 'haproxy') + lines += output[0] + configs_dir = get_config_var.get_config_var('configs', 'haproxy_save_configs_dir') + cfg = f"{configs_dir}{serv}-{get_date.return_date('config')}.cfg" + + config_mod.get_config(serv, cfg) + cmd = 'string=`grep %s %s -n -A25 |grep "server %s" |head -1|awk -F"-" \'{print $1}\'` ' \ + '&& sed -Ei "$(echo $string)s/((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5]):[0-9]+/%s:%s/g" %s' % \ + (backend_backend, cfg, backend_server, backend_ip, backend_port, cfg) + server_mod.subprocess_execute(cmd) + config_mod.master_slave_upload_and_restart(serv, cfg, 'save', 'haproxy') + + return lines + + +def add_server_via_runtime( + server_ip: str, backend: str, server: str, backend_ip: str, backend_port: int, check: int, port_check: int +) -> tuple: + lines = '' + stderr = '' + check_cmd = '' + sock_port = sql.get_setting('haproxy_sock_port') + + if check: + check_cmd = 'check' + + commands = [ + f'echo "add server {backend}/{server} {backend_ip}:{backend_port} {check_cmd}"|nc {server_ip} {sock_port}', + ] + + if check: + commands.append(f'echo "enable health {backend}/{server}"|nc {server_ip} {sock_port}') + commands.append(f'echo "set server {backend}/{server} check-addr {server_ip} check-port {port_check}"|nc {server_ip} {sock_port}') + + commands.append(f'echo "set server {backend}/{server} state ready"|nc {server_ip} {sock_port}') + + for cmd in commands: + output, stderr = server_mod.subprocess_execute(cmd) + lines += output[0] + return lines, stderr + + +def delete_server_via_runtime(server_ip: str, backend: str, server: str) -> tuple: + lines = '' + stderr = '' + sock_port = sql.get_setting('haproxy_sock_port') + + commands = [ + f'echo "set server {backend}/{server} state maint"|nc {server_ip} {sock_port}', + f'echo "del server {backend}/{server} "|nc {server_ip} {sock_port}', + ] + + for cmd in commands: + output, stderr = server_mod.subprocess_execute(cmd) + lines += output[0] + return lines, stderr + + +def add_server( + server_ip: str, backend: str, server: str, backend_ip: str, backend_port: int, check: int, port_check: int +) -> str: + lines = '' + stderr = '' + check_cfg = '' + check = int(check) + masters = sql.is_master(server_ip) + + for master in masters: + if master[0] is not None: + line, error = add_server_via_runtime(master[0], backend, server, backend_ip, backend_port, check, port_check) + lines += f'{master[0]}: {line}
' + stderr += error + roxywi_common.logging( + master[0], f'A new backend server has been add: {backend}/{server}', login=1, keep_history=1, service='haproxy' + ) + + line, error = add_server_via_runtime(server_ip, backend, server, backend_ip, backend_port, check, port_check) + lines += f'{server_ip}: {line}
' + stderr += error + roxywi_common.logging( + server_ip, f'A new backend server has been add: {backend}/{server}', login=1, keep_history=1, service='haproxy' + ) + + if 'Already exists a server' in lines: + return f'error: {lines}' + + if stderr != '': + return f'error: {stderr}' + + if check: + check_cfg = f'check port {port_check}' + + configs_dir = get_config_var.get_config_var('configs', 'haproxy_save_configs_dir') + cfg = f"{configs_dir}{server_ip}-{get_date.return_date('config')}.cfg" + try: + config_mod.get_config(server_ip, cfg) + except Exception as e: + raise Exception(f'error: Cannot config section: {e}') + section_name_cmd = f'grep {backend} {cfg}' + section_name = server_mod.subprocess_execute(section_name_cmd) + + try: + start_line, end_line, return_config = section_mod.get_section_from_config(cfg, section_name[0][0]) + except Exception as e: + raise Exception(f'error: Cannot get config section: {e}') + new_end_line = int(end_line) + 1 + new_server_cfg = f'\ \server {backend_ip} {backend_ip}:{backend_port} {check_cfg}' + cmd = f"sed -i '{new_end_line} i {new_server_cfg}' {cfg}" + server_mod.subprocess_execute(cmd) + try: + config_mod.master_slave_upload_and_restart(server_ip, cfg, 'save', 'haproxy') + except Exception as e: + raise Exception(f'error: Cannot save a new config: {e}') + + return lines + + +def delete_server(server_ip: str, backend: str, server: str) -> str: + lines = '' + stderr = '' + masters = sql.is_master(server_ip) + + for master in masters: + if master[0] is not None: + line, error = delete_server_via_runtime(master[0], backend, server) + lines += f'{master[0]}: {line}
' + stderr += error + roxywi_common.logging( + master[0], f'Server has been deleted: {backend}/{server}', login=1, keep_history=1, service='haproxy' + ) + + line, error = delete_server_via_runtime(server_ip, backend, server) + lines += f'{server_ip}: {line}
' + stderr += error + roxywi_common.logging( + server_ip, f'Server has been deleted: {backend}/{server}', login=1, keep_history=1, service='haproxy' + ) + + if stderr != '': + return 'error: ' + stderr[0] + + if 'No such server' in lines: + return f'error: {lines}' + + configs_dir = get_config_var.get_config_var('configs', 'haproxy_save_configs_dir') + cfg = f"{configs_dir}{server_ip}-{get_date.return_date('config')}.cfg" + + config_mod.get_config(server_ip, cfg) + cmd = f'string=`grep {backend} {cfg} -n -A25 |grep "server {server}" |head -1|awk -F"-" \'{{print $1}}\'` && sed -i "$(echo $string)d" {cfg}' + print(cmd) + server_mod.subprocess_execute(cmd) + config_mod.master_slave_upload_and_restart(server_ip, cfg, 'save', 'haproxy') return lines diff --git a/app/modules/db/sql.py b/app/modules/db/sql.py index 92e45858..9489fa22 100755 --- a/app/modules/db/sql.py +++ b/app/modules/db/sql.py @@ -4193,19 +4193,37 @@ def add_status_page(name: str, slug: str, desc: str, group_id: int, checks: list try: last_id = SmonStatusPage.insert(name=name, slug=slug, group_id=group_id, desc=desc).execute() except Exception as e: - if '1062, "Duplicate entry' in str(e): + if 'Duplicate entry' in str(e): raise Exception('error: The Slug is already taken, please enter another one') else: out_error(e) else: - for check in checks: - try: - SmonStatusPageCheck.insert(page_id=last_id, check_id=int(check)).execute() - except Exception as e: - out_error(e) + add_status_page_checks(last_id, checks) return last_id +def edit_status_page(page_id: int, name: str, slug: str, desc: str) -> None: + try: + SmonStatusPage.update(name=name, slug=slug, desc=desc).where(SmonStatusPage.id == page_id).execute() + except Exception as e: + out_error(e) + + +def add_status_page_checks(page_id: int, checks: list) -> None: + for check in checks: + try: + SmonStatusPageCheck.insert(page_id=page_id, check_id=int(check)).execute() + except Exception as e: + out_error(e) + + +def delete_status_page_checks(page_id: int) -> None: + try: + SmonStatusPageCheck.delete().where(SmonStatusPageCheck.page_id == page_id).execute() + except Exception as e: + out_error(e) + + def select_status_pages(group_id: int): try: query_res = SmonStatusPage.select().where(SmonStatusPage.group_id == group_id).execute() diff --git a/app/modules/tools/smon.py b/app/modules/tools/smon.py index cbaa3800..d6b36b60 100644 --- a/app/modules/tools/smon.py +++ b/app/modules/tools/smon.py @@ -152,6 +152,20 @@ def create_status_page(name: str, slug: str, desc: str, checks: list) -> str: return render_template('ajax/smon/status_pages.html', pages=pages) +def edit_status_page(page_id: int, name: str, slug: str, desc: str, checks: list) -> str: + sql.delete_status_page_checks(page_id) + + try: + sql.add_status_page_checks(page_id, checks) + sql.edit_status_page(page_id, name, slug, desc) + except Exception as e: + return f'error: Cannot update update status page: {e}' + + pages = sql.select_status_page_by_id(page_id) + + return render_template('ajax/smon/status_pages.html', pages=pages) + + def show_status_page(slug: str) -> str: page = sql.select_status_page(slug) checks_status = {} @@ -175,8 +189,9 @@ def show_status_page(slug: str) -> str: desc = s.desc group = s.group check_type = s.check_type + en = s.en uptime = check_uptime(check_id) - checks_status[check_id] = {'uptime': uptime, 'name': name, 'desc': desc, 'group': group, 'check_type': check_type} + checks_status[check_id] = {'uptime': uptime, 'name': name, 'desc': desc, 'group': group, 'check_type': check_type, 'en': en} return render_template('smon/status_page.html', page=page, checks_status=checks_status) diff --git a/app/routes/runtime/routes.py b/app/routes/runtime/routes.py index a6886571..f9852515 100644 --- a/app/routes/runtime/routes.py +++ b/app/routes/runtime/routes.py @@ -61,18 +61,27 @@ def show_backend_server(server_ip, backend, backend_server): return f'{e}' -@bp.route('/change/ip', methods=['POST']) +@bp.route('/server', methods=['POST', 'PUT', 'DELETE']) def change_ip_port(): server_ip = common.is_ip_or_dns(request.form.get('serv')) backend_backend = common.checkAjaxInput(request.form.get('backend_backend')) backend_server = common.checkAjaxInput(request.form.get('backend_server')) backend_ip = common.checkAjaxInput(request.form.get('backend_ip')) backend_port = common.checkAjaxInput(request.form.get('backend_port')) - - try: - return runtime.change_ip_and_port(server_ip, backend_backend, backend_server, backend_ip, backend_port) - except Exception as e: - return f'{e}' + if request.method == 'PUT': + try: + return runtime.change_ip_and_port(server_ip, backend_backend, backend_server, backend_ip, backend_port) + except Exception as e: + return f'{e}' + elif request.method == 'POST': + check = common.checkAjaxInput(request.form.get('check')) + port_check = common.checkAjaxInput(request.form.get('port_check')) + try: + return runtime.add_server(server_ip, backend_backend, backend_server, backend_ip, backend_port, check, port_check) + except Exception as e: + return f'{e}' + elif request.method == 'DELETE': + return runtime.delete_server(server_ip, backend_backend, backend_server) @bp.route('/maxconn/') diff --git a/app/routes/smon/routes.py b/app/routes/smon/routes.py index 79719eba..a22cad0e 100644 --- a/app/routes/smon/routes.py +++ b/app/routes/smon/routes.py @@ -72,50 +72,74 @@ def smon_dashboard(dashboard_id, check_id): ) -@bp.route('/status-page') +@bp.route('/status-page', methods=['GET', 'POST', 'DELETE', 'PUT']) @login_required @get_user_params() def status_page(): - user_params = g.user_params - user_group = roxywi_common.get_user_group(id=1) - smon_list = sql.smon_list(user_group) - pages = sql.select_status_pages(user_group) - smon_status, stderr = smon_mod.return_smon_status() - user_subscription = roxywi_common.return_user_subscription() + if request.method == 'GET': + user_params = g.user_params + user_group = roxywi_common.get_user_group(id=1) + smon_list = sql.smon_list(user_group) + pages = sql.select_status_pages(user_group) + smon_status, stderr = smon_mod.return_smon_status() + user_subscription = roxywi_common.return_user_subscription() - return render_template( - 'smon/manage_status_page.html', role=user_params['role'], user=user_params['user'], lang=user_params['lang'], - user_status=user_subscription['user_status'], user_plan=user_subscription['user_plan'], smon_error=stderr, pages=pages, - token=user_params['token'], user_services=user_params['user_services'], smon=smon_list, smon_status=smon_status - ) + return render_template( + 'smon/manage_status_page.html', role=user_params['role'], user=user_params['user'], + lang=user_params['lang'], pages=pages, smon_status=smon_status, + user_status=user_subscription['user_status'], user_plan=user_subscription['user_plan'], smon_error=stderr, + token=user_params['token'], user_services=user_params['user_services'], smon=smon_list, + ) + elif request.method == 'POST': + name = common.checkAjaxInput(request.form.get('name')) + slug = common.checkAjaxInput(request.form.get('slug')) + desc = common.checkAjaxInput(request.form.get('desc')) + checks = json.loads(request.form.get('checks')) + + if not len(checks['checks']): + return 'error: Please check Checks for Status page' + + try: + return smon_mod.create_status_page(name, slug, desc, checks['checks']) + except Exception as e: + return f'{e}' + elif request.method == 'PUT': + page_id = int(request.form.get('page_id')) + name = common.checkAjaxInput(request.form.get('name')) + slug = common.checkAjaxInput(request.form.get('slug')) + desc = common.checkAjaxInput(request.form.get('desc')) + checks = json.loads(request.form.get('checks')) + + if not len(checks['checks']): + return 'error: Please check Checks for Status page' + + try: + return smon_mod.edit_status_page(page_id, name, slug, desc, checks['checks']) + except Exception as e: + return f'{e}' + elif request.method == 'DELETE': + page_id = int(request.form.get('page_id')) + try: + sql.delete_status_page(page_id) + except Exception as e: + return f'{e}' + else: + return 'ok' -@bp.post('/status-page/add') +@bp.route('/status/checks/') @login_required -def add_status_page(): - name = common.checkAjaxInput(request.form.get('name')) - slug = common.checkAjaxInput(request.form.get('slug')) - desc = common.checkAjaxInput(request.form.get('desc')) - checks = json.loads(request.form.get('checks')) - - if not len(checks['checks']): - return 'error: Please check Checks for Status page' - +def get_checks(page_id): + returned_check = [] try: - return smon_mod.create_status_page(name, slug, desc, checks['checks']) + checks = sql.select_status_page_checks(page_id) except Exception as e: - return f'{e}' + return f'error: Cannot get checks: {e}' + for check in checks: + returned_check.append(str(check.check_id)) -@bp.route('/status-page/delete/') -@login_required -def delete_status_page(page_id): - try: - sql.delete_status_page(page_id) - except Exception as e: - return f'{e}' - else: - return 'ok' + return jsonify(returned_check) @bp.route('/status/') diff --git a/app/templates/ajax/smon/status_pages.html b/app/templates/ajax/smon/status_pages.html index 32b76991..edb08d8c 100644 --- a/app/templates/ajax/smon/status_pages.html +++ b/app/templates/ajax/smon/status_pages.html @@ -5,11 +5,12 @@
{{page.name}} {% if page.desc %} - ({{page.desc|replace("'", "")}}) + ({{page.desc|replace("'", "")}}) {% endif %}
-
/app/smon/status/{{page.slug}}
+
/app/smon/status/{{page.slug}}
+
{% endfor %} diff --git a/app/templates/runtimeapi.html b/app/templates/runtimeapi.html index 03c15fe0..95c0b701 100644 --- a/app/templates/runtimeapi.html +++ b/app/templates/runtimeapi.html @@ -11,7 +11,7 @@
  • Runtime API
  • {% if role <= 3 %}
  • {{lang.words.change|title()}} Maxconn
  • -
  • {{lang.words.change|title()}} IP {{lang.words.and}} {{lang.words.port}}
  • +
  • {{lang.words.servers|title()}}
  • Stick Table
  • {{lang.words.lists|title()}}
  • {{lang.words.sessions|title()}}
  • @@ -185,12 +185,55 @@ -
    +
    +

    {{lang.words.add|title()}} {{lang.words.backend}} {{lang.words.servers}}

    - - + + + + + + + + + + + + + + + + + +
    {{lang.words.server|title()}}{{lang.words.select|title()}} {{lang.words.backend|title()}}{{lang.words.select|title()}} {{lang.words.server}}{{lang.words.select|title()}} {{lang.words.backend|title()}}{{lang.words.new|title()}} {{lang.words.server}} IP{{lang.words.new|title()}} {{lang.words.port}}{{lang.words.check|title()}}{{lang.words.new|title()}} {{lang.words.check}} {{lang.words.port}}
    +
    + +
    + + + {{ input('backend_ip_server', title=lang.words.set|title()+' '+lang.words.new + ' ' + lang.words.server + ' IP', required='required', size='16') }} + + {{ input('backend_port_server', title=lang.words.set|title()+' '+lang.words.new + ' ' + lang.words.server + ' ' + lang.words.port, type="number", required='required', style='width:60px') }} + + {{ checkbox('backend_server_check', value='1', checked='checked') }} + + {{ input('backend_port_server_check', title=lang.words.set|title()+' '+lang.words.new + ' ' + lang.words.server + '' + lang.words.check + ' ' + lang.words.port, type="number", required='required', style='width:60px') }} + + +
    + +

    {{lang.words.change|title()}} IP {{lang.words.and}} {{lang.words.port}} {{lang.words.backend}} {{lang.words.servers}}

    + + + + @@ -205,20 +248,50 @@ {% endfor %} - - + + +
    {{lang.words.server|title()}}{{lang.words.select|title()}} {{lang.words.backend|title()}}{{lang.words.select|title()}} {{lang.words.server}} {{lang.words.new|title()}} IP {{lang.words.new|title()}} {{lang.words.port}} + + {{ input('backend_ip', title=lang.words.set|title()+' '+lang.words.new + ' ' + lang.words.server + ' IP', required='required', size='16') }} - {{ input('backend_port', title=lang.words.set|title()+' '+lang.words.new + ' ' + lang.words.server + ' ' + lang.words.port, type="number", required='required', size='6') }} + {{ input('backend_port', title=lang.words.set|title()+' '+lang.words.new + ' ' + lang.words.server + ' ' + lang.words.port, type="number", required='required', style='width:60px') }} - + +
    + +

    {{lang.words.delete|title()}} {{lang.words.backend}} {{lang.words.servers}}

    + + + + + + + + + + + diff --git a/inc/runtimeapi.js b/inc/runtimeapi.js index 5441fff8..b21e0d8d 100644 --- a/inc/runtimeapi.js +++ b/inc/runtimeapi.js @@ -115,6 +115,23 @@ $( function() { let backend = $('#ipbackend').val(); get_backend_servers(server_ip, backend, '#backend_server', 1); }); + $("#ip_select_server").on('selectmenuchange', function () { + let server_ip = $('#ip_select_server').val(); + get_backends(server_ip, '#ipBackendServer', 0); + }); + $("#ip_select_delete").on('selectmenuchange', function () { + let server_ip = $('#ip_select_delete').val(); + get_backends(server_ip, '#ipbackend_delete', 0); + }); + $("#ipbackend_delete").on('selectmenuchange', function () { + let server_ip = $('#ip_select_delete').val(); + let backend = $('#ipbackend_delete').val(); + get_backend_servers(server_ip, backend, '#backend_server_delete', 0); + }); + $('#backend_port_server').on('input', function () { + var iNum = parseInt($('#backend_port_server').val()); + $('#backend_port_server_check').val(iNum); + }); $("#backend_server").on('selectmenuchange', function () { $('#backend_ip').val(); $('#backend_port').val(); @@ -137,7 +154,7 @@ $( function() { }); $('#runtimeapiip').submit(function () { $.ajax({ - url: "/app/runtimeapi/change/ip", + url: "/app/runtimeapi/server", data: { serv: $('#ip_select').val(), backend_backend: $('#ipbackend').val(), @@ -146,6 +163,35 @@ $( function() { backend_port: $('#backend_port').val(), token: $('#token').val() }, + type: "PUT", + success: function (data) { + data = data.replace(/\s+/g, ' '); + if (data.indexOf('error: ') != '-1' || data.indexOf('Invalid ') != '-1') { + toastr.error(data); + } else { + toastr.success(data); + } + } + }); + return false; + }); + $('#runtimeapiServerIp').submit(function () { + let check = 0; + if($('#backend_server_check').prop('checked')) { + check = 1; + } + $.ajax({ + url: "/app/runtimeapi/server", + data: { + serv: $('#ip_select_server').val(), + backend_backend: $('#ipBackendServer').val(), + backend_server: $('#backend_ip_server').val(), + backend_ip: $('#backend_ip_server').val(), + backend_port: $('#backend_port_server').val(), + check: check, + port_check: $('#backend_port_server_check').val(), + token: $('#token').val() + }, type: "POST", success: function (data) { data = data.replace(/\s+/g, ' '); @@ -158,6 +204,36 @@ $( function() { }); return false; }); + $('#runtimeapiip_delete').submit(function () { + $.ajax({ + url: "/app/runtimeapi/server", + data: { + serv: $('#ip_select_delete').val(), + backend_backend: $('#ipbackend_delete').val(), + backend_server: $('#backend_server_delete').val(), + token: $('#token').val() + }, + type: "DELETE", + success: function (data) { + data = data.replace(/\s+/g, ' '); + if (data.indexOf('error: ') != '-1' || data.indexOf('Invalid ') != '-1') { + toastr.error(data); + } else { + toastr.success(data); + } + } + }); + return false; + }); + $('#backend_server_check').click(function() { + if ($('#backend_server_check').prop('checked')) { + $('#backend_ip_server_check').prop('required', true); + $('#backend_port_server_check').prop('required', true); + } else { + $('#backend_ip_server_check').prop('required', false); + $('#backend_port_server_check').prop('required', false); + } + }); $("#table_serv_select").on('selectmenuchange', function () { $.ajax({ url: "/app/runtimeapi/tables/" + $('#table_serv_select').val(), @@ -431,7 +507,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({ diff --git a/inc/smon.js b/inc/smon.js index f985365d..b28e79a3 100644 --- a/inc/smon.js +++ b/inc/smon.js @@ -403,13 +403,19 @@ function show_smon_history_statuses(dashboard_id, id_for_history_replace) { } }); } -function createStatusPageStep1() { +function createStatusPageStep1(edited=false, page_id=0) { var add_word = $('#translate').attr('data-next'); var cancel_word = $('#translate').attr('data-cancel'); var next_word = $('#translate').attr('data-next'); - var smon_add_tabel_title = $( "#create-status-page-step-1-overview" ).attr('title'); + var smon_add_tabel_title = $("#create-status-page-step-1-overview").attr('title'); + if (edited) { + smon_add_tabel_title = $("#create-status-page-step-1-overview").attr('data-edit'); + $('#new-status-page-name').val($('#page_name-'+page_id).text()); + $('#new-status-page-slug').val($('#page_slug-'+page_id).text().split('/').pop()); + $('#new-status-page-desc').val($('#page_desc-'+page_id).text().replace('(','').replace(')','')); + } var regx = /^[a-z0-9_-]+$/; - var addSmonStatus = $( "#create-status-page-step-1" ).dialog({ + var addSmonStatus = $("#create-status-page-step-1").dialog({ autoOpen: false, resizable: false, height: "auto", @@ -432,7 +438,7 @@ function createStatusPageStep1() { return false; } if (!regx.test($('#new-status-page-slug').val())) { - toastr.error('error: Incorect Slug'); + toastr.error('error: Incorrect Slug'); return false; } if ($('#new-status-page-slug').val().indexOf('--') != '-1') { @@ -443,25 +449,44 @@ function createStatusPageStep1() { toastr.error('error: Fill in the Slug field'); return false; } - createStatusPageStep2(); + createStatusPageStep2(edited, page_id); $(this).dialog("close"); toastr.clear(); } }, { text: cancel_word, click: function () { - $(this).dialog("close"); - clearTips(); + clearStatusPageDialog($(this)); } }] }); addSmonStatus.dialog('open'); } -function createStatusPageStep2() { +function createStatusPageStep2(edited, page_id) { var add_word = $('#translate').attr('data-add'); var cancel_word = $('#translate').attr('data-cancel'); var back_word = $('#translate').attr('data-back'); var smon_add_tabel_title = $("#create-status-page-step-2-overview").attr('title'); + if (edited) { + smon_add_tabel_title = $("#create-status-page-step-2-overview").attr('data-edit'); + add_word = $('#translate').attr('data-edit'); + if ($("#enabled-check > div").length == 0) { + $.ajax({ + url: "/app/smon/status/checks/" + page_id, + async: false, + type: "GET", + success: function (data) { + if (data.indexOf('error:') != '-1') { + toastr.error(data); + } else { + for (let i = 0; i < data.length; i++) { + addCheckToStatus(data[i]); + } + } + } + }); + } + } var addSmonStatus = $("#create-status-page-step-2").dialog({ autoOpen: false, resizable: false, @@ -480,24 +505,38 @@ function createStatusPageStep2() { buttons: [{ text: add_word, click: function () { - createStatusPage($(this)); + if (edited) { + editStatusPage($(this), page_id); + } else { + createStatusPage($(this)); + } } }, { text: back_word, click: function () { $(this).dialog("close"); - createStatusPageStep1(); + createStatusPageStep1(edited, page_id); } }, { text: cancel_word, click: function () { - $(this).dialog("close"); - clearTips(); + clearStatusPageDialog($(this)); } }] }); addSmonStatus.dialog('open'); } +function clearStatusPageDialog(dialog_id) { + dialog_id.dialog("close"); + clearTips(); + $('#new-status-page-name').val(''); + $('#new-status-page-slug').val(''); + $('#new-status-page-desc').val(''); + $("#enabled-check > div").each((index, elem) => { + check_id = elem.id.split('-')[1] + removeCheckFromStatus(check_id); + }); +} function createStatusPage(dialog_id) { let name_id = $('#new-status-page-name'); let slug_id = $('#new-status-page-slug'); @@ -509,7 +548,7 @@ function createStatusPage(dialog_id) { checks.push(check_id); }); $.ajax({ - url: '/app/smon/status-page/add', + url: '/app/smon/status-page', type: 'POST', data: { name: name_id.val(), @@ -522,18 +561,43 @@ function createStatusPage(dialog_id) { if (data.indexOf('error:') != '-1' || data.indexOf('unique') != '-1') { toastr.error(data); } else { - toastr.clear(); - $("#smon_history_statuses").html(data); - for (let i = 0; i < checks.length; i++) { - removeCheckFromStatus(checks[i]); - console.log(checks[i]) - } - name_id.val(''); - slug_id.val(''); - dialog_id.dialog("close"); + clearStatusPageDialog(dialog_id); $("#pages").append(data); + $.getScript("/inc/fontawesome.min.js"); + } + } + }); +} +function editStatusPage(dialog_id, page_id) { + let name_id = $('#new-status-page-name'); + let slug_id = $('#new-status-page-slug'); + let desc_id = $('#new-status-page-desc'); + let checks = []; + let check_id = ''; + $("#enabled-check > div").each((index, elem) => { + check_id = elem.id.split('-')[1] + checks.push(check_id); + }); + $.ajax({ + url: '/app/smon/status-page', + type: 'PUT', + data: { + page_id: page_id, + name: name_id.val(), + slug: slug_id.val(), + desc: desc_id.val(), + checks: JSON.stringify({'checks': checks}) + }, + success: function (data) { + data = data.replace(/\s+/g, ' '); + if (data.indexOf('error:') != '-1' || data.indexOf('unique') != '-1') { + toastr.error(data); + } else { + clearStatusPageDialog(dialog_id); + $("#page_" + page_id).replaceWith(data); + $("#page_" + page_id).addClass("update", 1000); setTimeout(function () { - $("#user-" + id).removeClass("update"); + $("#page_" + page_id).removeClass("update"); }, 2500); $.getScript("/inc/fontawesome.min.js"); } @@ -595,7 +659,11 @@ function confirmDeleteStatusPage(id) { } function deleteStatusPage(page_id) { $.ajax({ - url: '/app/smon/status-page/delete/' + page_id, + url: '/app/smon/status-page', + type: 'DELETE', + data: { + page_id: page_id, + }, success: function (data) { data = data.replace(/\s+/g, ' '); if (data.indexOf('error:') != '-1' || data.indexOf('unique') != '-1') {
    {{lang.words.server|title()}}{{lang.words.select|title()}} {{lang.words.backend|title()}}{{lang.words.select|title()}} {{lang.words.server}}
    +
    + +
    + + + + +