diff --git a/api/api_funct.py b/api/api_funct.py index ce541e77..218ef43d 100644 --- a/api/api_funct.py +++ b/api/api_funct.py @@ -157,13 +157,15 @@ def get_server(server_id, service): 'master': s[6], 'creds': s[7] } - except Exception: - data = '' + 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 != 'apache' and service != 'nginx' and service != 'haproxy': + if service not in ('apache', 'nginx', 'haproxy', 'keepalived'): return dict(status='wrong service') try: servers = check_permit_to_server(server_id, service=service) @@ -240,9 +242,9 @@ def get_all_statuses(): def actions(server_id, action, service): - if action != 'start' and action != 'stop' and action != 'restart' and action != 'reload': + if action not in ('start', 'stop', 'restart', 'reload'): return dict(status='wrong action') - if service != 'apache' and service != 'nginx' and service != 'haproxy' and service != 'keepalived': + if service not in ('apache', 'nginx', 'haproxy', 'keepalived'): return dict(status='wrong service') try: @@ -254,7 +256,6 @@ def actions(server_id, action, service): 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) @@ -263,7 +264,6 @@ def actions(server_id, action, service): def runtime(server_id): - data = {} try: body = request.body.getvalue().decode('utf-8') json_loads = json.loads(body) @@ -275,7 +275,6 @@ def runtime(server_id): for s in servers: out = server_mod.ssh_command(s[2], cmd) - data = {server_id: {}} sep_data = out.split('\r\n') data = {server_id: sep_data} @@ -418,7 +417,7 @@ def edit_section(server_id, delete=0): def upload_config(server_id, **kwargs): service = kwargs.get('service') - if service != 'apache' and service != 'nginx' and service != 'haproxy': + if service not in ('apache', 'nginx', 'haproxy', 'keepalived'): return dict(status='wrong service') body = request.body.getvalue().decode('utf-8') @@ -592,7 +591,8 @@ def add_acl(server_id): 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: - status = "Cannot read section: " + str(e) + data = {server_id: {"error": f"Cannot read section: {e}"}} + return dict(error=data) try: config_read += acl @@ -601,9 +601,11 @@ def add_acl(server_id): with open(cfg, "w") as conf: conf.write(config) except IOError as e: - status = "Cannot read import config file: " + str(e) + data = {server_id: {"error": f"Cannot read import config file: {e}"}} + return dict(error=data) except Exception as e: - status = str(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) @@ -612,7 +614,8 @@ def add_acl(server_id): else: status = 'ACL has been added' except Exception as e: - status = str(e) + data = {server_id: {"error": f"{e}"}} + return dict(error=data) data = {'acl': status} return dict(data) @@ -623,19 +626,18 @@ def del_acl(server_id): 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) - status = '' for s in servers: - cfg = '/tmp/' + s[2] + '.cfg' 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: - status = str(e) + data = {server_id: {"error": f"{e}"}} + return dict(error=data) try: config_new_read = '' @@ -644,7 +646,8 @@ def del_acl(server_id): if line != '': config_new_read += line + '\n' except Exception as e: - status = 'Cannot delete ACL: ' + str(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) @@ -652,9 +655,11 @@ def del_acl(server_id): with open(cfg, "w") as conf: conf.write(config) except IOError as e: - status = "Cannot read import config file: " + str(e) + data = {server_id: {"error": f"Cannot read import config file: {e}"}} + return dict(error=data) except Exception as e: - status = 'Cannot delete ACL: ' + str(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) @@ -663,7 +668,8 @@ def del_acl(server_id): else: status = 'ACL has been deleted' except Exception as e: - status = str(e) + data = {server_id: {"error": f"{e}"}} + return dict(error=data) return dict(acl=status) diff --git a/app/add.py b/app/add.py index 221ca2de..a757119a 100644 --- a/app/add.py +++ b/app/add.py @@ -82,6 +82,7 @@ elif form.getvalue('mode') is not None: ssl = "" ssl_check = "" backend = "" + headers = '' acl = "" servers_split = "" new_listener = form.getvalue('listener') @@ -210,6 +211,20 @@ elif form.getvalue('mode') is not None: if form.getvalue('dynamic'): options_split += f" dynamic-cookie-key {form.getvalue('dynamic-cookie-key')}\n" + if form.getvalue('headers_method'): + headers_res = form.getlist('headers_res') + headers_method = form.getlist('headers_method') + header_name = form.getlist('header_name') + header_value = form.getlist('header_value') + i = 0 + + for h in headers_method: + if headers_method[i] != 'del-header': + headers += f' {headers_res[i]} {headers_method[i]} {header_name[i]} {header_value[i]}\n' + else: + headers += f' {headers_res[i]} {headers_method[i]} {header_name[i]}\n' + i += 1 + if form.getvalue('acl_if'): acl_if = form.getlist('acl_if') acl_value = form.getlist('acl_value') @@ -339,7 +354,7 @@ elif form.getvalue('mode') is not None: waf += " http-request deny if { var(txn.modsec.code) -m int gt 0 }\n" config_add = f"\n{name}\n{bind}{mode}{maxconn}{balance}{options_split}{cache_s}{filter_com}{compression_s}" \ - f"{waf}{acl}{backend}{servers_split}\n{cache_set}\n" + f"{waf}{headers}{acl}{backend}{servers_split}\n{cache_set}\n" if form.getvalue('new_userlist') is not None: name = f"userlist {form.getvalue('new_userlist')}\n" diff --git a/app/modules/alerting/alerting.py b/app/modules/alerting/alerting.py index bdc1c8cb..02a8acf2 100644 --- a/app/modules/alerting/alerting.py +++ b/app/modules/alerting/alerting.py @@ -56,10 +56,17 @@ def alert_routing( if alert_type == 'service' and setting.service_alert: try: telegram_send_mess(mes, level, channel_id=setting.telegram_id) + except Exception as e: + roxywi_common.logging('Roxy-WI server', f'error: unable to send message to Telegram: {e}', roxywi=1) + try: slack_send_mess(mes, level, channel_id=setting.slack_id) + except Exception as e: + roxywi_common.logging('Roxy-WI server', f'error: unable to send message to Slack: {e}', roxywi=1) + try: pd_send_mess(mes, level, server_ip, service_id, alert_type, channel_id=setting.pd_id) except Exception as e: - roxywi_common.logging('Roxy-WI server', f'error: unable to send message: {e}', roxywi=1) + roxywi_common.logging('Roxy-WI server', f'error: unable to send message to PagerDuty: {e}', roxywi=1) + if setting.email: send_email_to_server_group(subject, mes, level, group_id) @@ -67,10 +74,16 @@ def alert_routing( if alert_type == 'backend' and setting.backend_alert: try: telegram_send_mess(mes, level, channel_id=setting.telegram_id) + except Exception as e: + roxywi_common.logging('Roxy-WI server', f'error: unable to send message to Telegram: {e}', roxywi=1) + try: slack_send_mess(mes, level, channel_id=setting.slack_id) + except Exception as e: + roxywi_common.logging('Roxy-WI server', f'error: unable to send message to Slack: {e}', roxywi=1) + try: pd_send_mess(mes, level, server_ip, service_id, alert_type, channel_id=setting.pd_id) except Exception as e: - roxywi_common.logging('Roxy-WI server', f'error: unable to send message: {e}', roxywi=1) + roxywi_common.logging('Roxy-WI server', f'error: unable to send message to PagerDuty: {e}', roxywi=1) if setting.email: send_email_to_server_group(subject, mes, level, group_id) @@ -78,10 +91,16 @@ def alert_routing( if alert_type == 'maxconn' and setting.maxconn_alert: try: telegram_send_mess(mes, level, channel_id=setting.telegram_id) + except Exception as e: + roxywi_common.logging('Roxy-WI server', f'error: unable to send message to Telegram: {e}', roxywi=1) + try: slack_send_mess(mes, level, channel_id=setting.slack_id) + except Exception as e: + roxywi_common.logging('Roxy-WI server', f'error: unable to send message to Slack: {e}', roxywi=1) + try: pd_send_mess(mes, level, server_ip, service_id, alert_type, channel_id=setting.pd_id) except Exception as e: - roxywi_common.logging('Roxy-WI server', f'error: unable to send message: {e}', roxywi=1) + roxywi_common.logging('Roxy-WI server', f'error: unable to send message to PagerDuty: {e}', roxywi=1) if setting.email: send_email_to_server_group(subject, mes, level, group_id) diff --git a/app/templates/add.html b/app/templates/add.html index dbee4750..9efd9ee4 100644 --- a/app/templates/add.html +++ b/app/templates/add.html @@ -16,6 +16,8 @@ {% set observe = {'layer7':'layer7', 'layer4': 'layer4'} %} {% set on_error = {'mark-down':'mark-down', 'fastinter': 'fastinter', 'fail-check':'fail-check', 'sudden-death':'sudden-death'} %} +{% set header_res = {'http-response': 'response', 'http-request': 'request'} %} +{% set header_params = {'add-header': 'add-header', 'set-header': 'set-header', 'del-header': 'del-header'} %} {% set if_values = dict() %} {% set if_values = {'1':'Host name starts with','2':'Host name ends with','3':'Path starts with','4':'Path ends with', '6': 'Src ip'} %} @@ -120,23 +122,43 @@ +
{{lang.words.server|title()}} | -{{lang.words.actions|title()}} | -WAF {{lang.words.mode}} | +{{lang.words.actions|title()}} | +WAF {{lang.words.mode}} | {% if service == 'haproxy' %}{{lang.words.metrics|title()}} | {% endif %} diff --git a/inc/add.js b/inc/add.js index 1ad57ae5..64f80b2e 100644 --- a/inc/add.js +++ b/inc/add.js @@ -1229,6 +1229,30 @@ $( function() { $("#backend_checks_http_domain").removeAttr('required'); } }); + $( "#add_listener_header" ).on( "click", function() { + $( "#listener_header_div" ).show(); + $( "#listener_add_header" ).show(); + $( "#add_listener_header" ).hide(); + } ); + $( "#add_frontend_header" ).on( "click", function() { + $( "#frontend_header_div" ).show(); + $( "#frontend_add_header" ).show(); + $( "#add_frontend_header" ).hide(); + } ); + $( "#add_backend_header" ).on( "click", function() { + $( "#backend_header_div" ).show(); + $( "#backend_add_header" ).show(); + $( "#add_backend_header" ).hide(); + } ); + $("#listener_add_header").click(function(){ + make_actions_for_adding_header('#listener_header_div'); + }); + $("#frontend_add_header").click(function(){ + make_actions_for_adding_header('#frontend_header_div'); + }); + $("#backend_add_header").click(function(){ + make_actions_for_adding_header('#backend_header_div'); + }); $( "#add_listener_acl" ).on( "click", function() { $( "#listener_acl" ).show(); $( "#listener_add_acl" ).show(); @@ -1893,8 +1917,12 @@ function deleteId(id) { $('#frontend_bind').hide(); } } +var if_word = $('#translate').attr('data-if-title'); +var then_word = $('#translate').attr('data-then'); +var value_word = $('#translate').attr('data-value'); +var name_word = $('#translate').attr('data-name'); var acl_option = '