diff --git a/app/funct.py b/app/funct.py index 5dfcd430..b1dc2b8d 100644 --- a/app/funct.py +++ b/app/funct.py @@ -200,7 +200,7 @@ def keep_action_history(service: str, action: str, server_ip: str, login: str, u sql.insert_action_history(service, action, server_id, user_id, user_ip) except Exception as e: - logging('localhost', 'Cannot save a history: ' + srt(e), haproxywi=1) + logging('localhost', 'Cannot save a history: ' + str(e), haproxywi=1) def telegram_send_mess(mess, **kwargs): @@ -1701,7 +1701,6 @@ def get_services_status(): cmd = "apt list --installed 2>&1 |grep " + service_name + "|awk '{print $2}'|sed 's/-/./'" else: cmd = "rpm -q " + service_name + "|awk -F\"" + service_name + "\" '{print $2}' |awk -F\".noa\" '{print $1}' |sed 's/-//1' |sed 's/-/./'" - print(cmd) service_ver, stderr = subprocess_execute(cmd) try: @@ -1988,3 +1987,12 @@ def is_restarted(server_ip, action): if sql.is_serv_protected(server_ip) and int(user_role) > 2: print('error: This server is protected. You cannot ' + action + ' it') sys.exit() + + +def return_user_status(): + import sql + + user_status = sql.select_user_status() + user_plan = sql.select_user_plan() + + return user_status, user_plan diff --git a/app/ha.py b/app/ha.py index 555ec4cf..194151e3 100644 --- a/app/ha.py +++ b/app/ha.py @@ -16,6 +16,12 @@ try: except Exception: pass +try: + user_status, user_plan = funct.return_user_status() +except Exception as e: + user_status, user_plan = 0, 0 + funct.logging('localhost', 'Cannot get a user plan: ' + str(e), haproxywi=1) + output_from_parsed_template = template.render(h2=1, title="Create and configure HA cluster", @@ -24,5 +30,7 @@ output_from_parsed_template = template.render(h2=1, serv=serv, selects=servers, user_services=user_services, + user_status=user_status, + user_plan=user_plan, token=token) print(output_from_parsed_template) diff --git a/app/options.py b/app/options.py index a9f0ac32..2cc0b894 100644 --- a/app/options.py +++ b/app/options.py @@ -496,8 +496,14 @@ if form.getvalue('action_service') is not None: cmd = "sudo systemctl disable %s --now" % serv elif action == "start": cmd = "sudo systemctl enable %s --now" % serv + if not sql.select_user_status(): + print('warning: The service is disabled because you are not subscribed. Read here about subscriptions') + sys.exit() elif action == "restart": cmd = "sudo systemctl restart %s --now" % serv + if not sql.select_user_status(): + print('warning: The service is disabled because you are not subscribed. Read here about subscriptions') + sys.exit() output, stderr = funct.subprocess_execute(cmd) funct.logging('localhost', ' The service ' + serv + ' has been ' + action + 'ed', haproxywi=1, login=1) @@ -4178,4 +4184,4 @@ if form.getvalue('show_sub_ovw'): env = Environment(loader=FileSystemLoader('templates/'), autoescape=True) template = env.get_template('ajax/show_sub_ovw.html') template = template.render(sub=sql.select_user_all()) - print(template) \ No newline at end of file + print(template) diff --git a/app/servers.py b/app/servers.py index 1ba5bf0b..0034fe89 100644 --- a/app/servers.py +++ b/app/servers.py @@ -19,6 +19,11 @@ try: except Exception as e: pass +try: + user_status, user_plan = funct.return_user_status() +except Exception as e: + user_status, user_plan = 0, 0 + funct.logging('localhost', 'Cannot get a user plan: ' + str(e), haproxywi=1) output_from_parsed_template = template.render(title="Servers: ", role=role, @@ -37,5 +42,7 @@ output_from_parsed_template = template.render(title="Servers: ", geoip_country_codes=geoip_country_codes, user_services=user_services, ldap_enable=ldap_enable, + user_status=user_status, + user_plan=user_plan, services=services) print(output_from_parsed_template) diff --git a/app/sql.py b/app/sql.py index 9dd5ce20..822d73b2 100755 --- a/app/sql.py +++ b/app/sql.py @@ -1236,13 +1236,13 @@ def select_waf_metrics(serv, **kwargs): if mysql_enable == '1': if kwargs.get('time_range') == '60': - date_from = "and date > now() - INTERVAL 60 minute and rowid % 2 = 0" + date_from = "and date > now() - INTERVAL 60 minute group by `date` div 100" elif kwargs.get('time_range') == '180': - date_from = "and date > now() - INTERVAL 180 minute and rowid % 5 = 0" + date_from = "and date > now() - INTERVAL 180 minute group by `date` div 200" elif kwargs.get('time_range') == '360': - date_from = "and date > now() - INTERVAL 360 minute and rowid % 7 = 0" + date_from = "and date > now() - INTERVAL 360 minute group by `date` div 300" elif kwargs.get('time_range') == '720': - date_from = "and date > now() - INTERVAL 720 minute and rowid % 9 = 0" + date_from = "and date > now() - INTERVAL 720 minute group by `date` div 500" else: date_from = "and date > now() - INTERVAL 30 minute" sql = """ select * from waf_metrics where serv = '{serv}' {date_from} order by `date` desc limit 60 """.format(serv=serv, date_from=date_from) @@ -1272,13 +1272,13 @@ def select_nginx_metrics(serv, **kwargs): if mysql_enable == '1': if kwargs.get('time_range') == '60': - date_from = "and date > now() - INTERVAL 60 minute and rowid % 2 = 0" + date_from = "and date > now() - INTERVAL 60 minute group by `date` div 100" elif kwargs.get('time_range') == '180': - date_from = "and date > now() - INTERVAL 180 minute and rowid % 5 = 0" + date_from = "and date > now() - INTERVAL 180 minute group by `date` div 200" elif kwargs.get('time_range') == '360': - date_from = "and date > now() - INTERVAL 360 minute and rowid % 7 = 0" + date_from = "and date > now() - INTERVAL 360 minute group by `date` div 400" elif kwargs.get('time_range') == '720': - date_from = "and date > now() - INTERVAL 720 minute and rowid % 9 = 0" + date_from = "and date > now() - INTERVAL 720 minute group by `date` div 500" else: date_from = "and date > now() - INTERVAL 30 minute" sql = """ select * from nginx_metrics where serv = '{serv}' {date_from} order by `date` desc limit 60 """.format(serv=serv, date_from=date_from) @@ -1462,16 +1462,16 @@ def select_metrics(serv, **kwargs): if mysql_enable == '1': if kwargs.get('time_range') == '60': - date_from = "and date > now() - INTERVAL 60 minute and rowid % 2 = 0" + date_from = "and date > now() - INTERVAL 60 minute group by `date` div 100" elif kwargs.get('time_range') == '180': - date_from = "and date > now() - INTERVAL 180 minute and rowid % 5 = 0" + date_from = "and date > now() - INTERVAL 180 minute group by `date` div 200" elif kwargs.get('time_range') == '360': - date_from = "and date > now() - INTERVAL 360 minute and rowid % 7 = 0" + date_from = "and date > now() - INTERVAL 360 minute group by `date` div 300" elif kwargs.get('time_range') == '720': - date_from = "and date > now() - INTERVAL 720 minute and rowid % 9 = 0" + date_from = "and date > now() - INTERVAL 720 minute group by `date` div 500" else: date_from = "and date > now() - INTERVAL 30 minute" - sql = """ select * from metrics where serv = '{serv}' {date_from} order by `date` desc """.format(serv=serv, date_from=date_from) + sql = """ select * from metrics where serv = '{serv}' {date_from} order by `date` asc """.format(serv=serv, date_from=date_from) else: if kwargs.get('time_range') == '60': date_from = "and date > datetime('now', '-60 minutes', 'localtime') and rowid % 2 = 0" @@ -1499,13 +1499,13 @@ def select_metrics_http(serv, **kwargs): if mysql_enable == '1': if kwargs.get('time_range') == '60': - date_from = "and date > now() - INTERVAL 60 minute and rowid % 2 = 0" + date_from = "and date > now() - INTERVAL 60 minute group by `date` div 100" elif kwargs.get('time_range') == '180': - date_from = "and date > now() - INTERVAL 180 minute and rowid % 5 = 0" + date_from = "and date > now() - INTERVAL 180 minute group by `date` div 200" elif kwargs.get('time_range') == '360': - date_from = "and date > now() - INTERVAL 360 minute and rowid % 7 = 0" + date_from = "and date > now() - INTERVAL 360 minute group by `date` div 300" elif kwargs.get('time_range') == '720': - date_from = "and date > now() - INTERVAL 720 minute and rowid % 9 = 0" + date_from = "and date > now() - INTERVAL 720 minute group by `date` div 500" else: date_from = "and date > now() - INTERVAL 30 minute" sql = """ select * from metrics_http_status where serv = '{serv}' {date_from} order by `date` desc """.format(serv=serv, date_from=date_from) @@ -3184,6 +3184,15 @@ def select_user_status(): return query_res +def select_user_plan(): + try: + query_res = UserName.get().Plan + except Exception: + return False + else: + return query_res + + def select_user_all(): try: query_res = UserName.select() diff --git a/app/templates/admin.html b/app/templates/admin.html index 1cf5c60c..4a9eff8e 100644 --- a/app/templates/admin.html +++ b/app/templates/admin.html @@ -96,7 +96,7 @@ Version Description - + @@ -111,13 +111,13 @@ Service - Current version + Current version Latest version - - + + Description - + diff --git a/app/templates/ajax/load_telegram.html b/app/templates/ajax/load_telegram.html index 237085a6..ea620683 100644 --- a/app/templates/ajax/load_telegram.html +++ b/app/templates/ajax/load_telegram.html @@ -14,7 +14,7 @@ {% endif %} - + {% for telegram in telegrams %} @@ -66,7 +66,7 @@ {% endif %} - + {% for slack in slacks %} diff --git a/app/templates/ajax/show_configs_files.html b/app/templates/ajax/show_configs_files.html index 64e38f04..411fca7e 100644 --- a/app/templates/ajax/show_configs_files.html +++ b/app/templates/ajax/show_configs_files.html @@ -45,11 +45,13 @@ $(document).ready(function() { $('#config_file_name').select2(); $('#finding_words_from').submit(function() { - if ($('#words').val() == '') { + let words = $('#words').val(); + if (words == '') { toastr.warning('Enter words for searching'); return false; } - findInConfig(); + findInConfig(words); + window.history.pushState("Find in config", "Find in config", cur_url[0] + '?service='+ $('#service').val()+'&serv='+$('#serv').val()+'&showConfigFiles&findInConfig='+ words); return false; }); $( "input[type=submit], button" ).button() diff --git a/app/templates/ajax/show_sub_ovw.html b/app/templates/ajax/show_sub_ovw.html index e9490022..2a00a11b 100644 --- a/app/templates/ajax/show_sub_ovw.html +++ b/app/templates/ajax/show_sub_ovw.html @@ -5,15 +5,17 @@ {% set plan = 'Enterprise' %} {% elif s.Plan == 'support' %} {% set plan = 'Premium' %} + {% elif s.Plan == 'Trial' %} + {% set plan = 'Trial' %} {% else %} {% set plan = 'Free' %} {% endif %} - Subscription plan + Plan {{plan}} - Subscription status + Status {% if plan == 'Free' %} N/A @@ -35,8 +37,14 @@ {% if plan == 'Free' %} N/A {% else %} - {{s.Method}} + {% if s.Method == 'Boosty' %} + Boosty + {% elif s.Method == 'Patreon' %} + Patreon + {% else %} + {{s.Method}} + {% endif %} {% endif %} -{% endfor %} \ No newline at end of file +{% endfor %} diff --git a/app/templates/ajax/show_system_info.html b/app/templates/ajax/show_system_info.html index 9641541c..5c45aec6 100644 --- a/app/templates/ajax/show_system_info.html +++ b/app/templates/ajax/show_system_info.html @@ -1,7 +1,7 @@ {% if not system_info %} - + {% else %} @@ -38,7 +38,7 @@ - + diff --git a/app/templates/config.html b/app/templates/config.html index 322586cc..60f26010 100644 --- a/app/templates/config.html +++ b/app/templates/config.html @@ -89,6 +89,14 @@ if (cur_url[1].split('&')[2] == 'showConfigFiles') { showConfigFiles(); } + if (cur_url[1].split('&')[3].split('=')[0] == 'findInConfig') { + var words = findGetParameter('findInConfig'); + waitForElm('#finding_words_from').then((elm) => { + $('#find_p').show(); + $('#words').val(words); + findInConfig(words); + }); + } if (cur_url[1].split('&')[3].split('=')[0] == 'config_file_name') { showConfigFilesForEditing(); } diff --git a/app/templates/ha.html b/app/templates/ha.html index 72a448cb..c15b9e96 100644 --- a/app/templates/ha.html +++ b/app/templates/ha.html @@ -7,6 +7,9 @@ +{% if user_status == 0 or user_plan == 'user' %} +{% include 'include/no_sub.html' %} +{% else %} @@ -149,4 +152,5 @@
-{% endblock %} \ No newline at end of file +{% endif %} +{% endblock %} diff --git a/app/templates/hapservers.html b/app/templates/hapservers.html index 2417901f..f4130dfb 100644 --- a/app/templates/hapservers.html +++ b/app/templates/hapservers.html @@ -79,9 +79,13 @@ let metrics = new Promise( (resolve, reject) => { {% for s in servers %} + {% if service == 'haproxy' %} getChartData(server_ip) getHttpChartData(server_ip) getWafChartData(server_ip) + {% elif service == 'nginx' %} + getNginxChartData(server_ip) + {% endif %} {% endfor %} }); metrics.then(); @@ -272,7 +276,7 @@ Stat {% endif %} {% if service != 'keepalived' %} - Log + Logs {% endif %} {% if role <= 2 %} Versions @@ -311,7 +315,7 @@
- +
{% endif %} diff --git a/app/templates/include/admin_servers.html b/app/templates/include/admin_servers.html index 7a8e1b41..a46cf620 100644 --- a/app/templates/include/admin_servers.html +++ b/app/templates/include/admin_servers.html @@ -1,4 +1,16 @@ {% from 'include/input_macros.html' import input, checkbox, copy_to_clipboard %} +{% if user_status == 0 or user_plan == 'user' %} + +{% endif %} {% if not adding %}

Create a new HA cluster

@@ -23,7 +35,7 @@ Protected diff --git a/app/templates/include/no_sub.html b/app/templates/include/no_sub.html new file mode 100644 index 00000000..a3fe929a --- /dev/null +++ b/app/templates/include/no_sub.html @@ -0,0 +1,22 @@ + +
+

+ {% if user_status == 0 %} + You are not subscribed. Please subscribe to have access to this feature. +

+ Read here about subscriptions +

+ {% elif user_plan == 'user' %} + This feature is not available for your plan. To change the plan, follow this link + {% endif %} +

+
+
+ Oops +
diff --git a/app/templates/metrics.html b/app/templates/metrics.html index 835fb8d7..2ad3086d 100644 --- a/app/templates/metrics.html +++ b/app/templates/metrics.html @@ -55,7 +55,7 @@ {% endif %}
- +
{% for s in servers %} {% if service != 'nginx' %} diff --git a/app/templates/ovw.html b/app/templates/ovw.html index 2e71d4b3..2687f4f1 100644 --- a/app/templates/ovw.html +++ b/app/templates/ovw.html @@ -55,7 +55,7 @@ @@ -76,7 +76,7 @@ @@ -327,7 +327,7 @@ diff --git a/app/templates/waf.html b/app/templates/waf.html index 94288dff..f050c072 100644 --- a/app/templates/waf.html +++ b/app/templates/waf.html @@ -98,7 +98,7 @@ @@ -122,7 +122,7 @@
- +
{% for s in servers %}
diff --git a/app/users.py b/app/users.py index 78c5d620..4f60c165 100644 --- a/app/users.py +++ b/app/users.py @@ -23,6 +23,12 @@ try: except Exception: pass +try: + user_status, user_plan = funct.return_user_status() +except Exception as e: + user_status, user_plan = 0, 0 + funct.logging('localhost', 'Cannot get a user plan: ' + str(e), haproxywi=1) + template = template.render(title="Admin area: Manage users", role=role, @@ -40,5 +46,7 @@ template = template.render(title="Admin area: Manage users", page="users.py", user_services=user_services, ldap_enable=ldap_enable, + user_status=user_status, + user_plan=user_plan, services=services) print(template) diff --git a/inc/awesome.css b/inc/awesome.css index aa8604c8..91d71824 100644 --- a/inc/awesome.css +++ b/inc/awesome.css @@ -73,6 +73,9 @@ .add .fa-clone, .plus .fa-plus, .plus-after .fa-plus, .minus-after .fa-minus { color: var(--green-color); } +.plus-after > .fa-plus, .minus-after > .fa-minus { + color: var(--blue-color); +} .add-proxy::before { display: none; font-family: "Font Awesome 5 Solid"; @@ -239,13 +242,16 @@ } .fa-pencil-alt{ padding-left: 7px; - color: #5cb85c !important; + color: var(--blue-color) !important; } .service-start::after { display: none; font-family: "Font Awesome 5 Solid"; content: "\f04b"; } +.refresh > .fa-sync-alt { + color: var(--blue-color) !important; +} .fa-play, .fa-stop, .fa-sync-alt { width: 3px; color: var(--green-color) !important; @@ -263,7 +269,7 @@ .service-restart > .fa-sync-alt { color: orange !important; } -.service-reload::after { +.service-reload::after, .refresh::after { display: none; font-family: "Font Awesome 5 Solid"; content: "\f2f1"; diff --git a/inc/images/oops.png b/inc/images/oops.png new file mode 100644 index 00000000..b76d73b9 Binary files /dev/null and b/inc/images/oops.png differ diff --git a/inc/images/sort_desc_disabled copy.png b/inc/images/sort_desc_disabled copy.png new file mode 100644 index 00000000..c9fdd8a1 Binary files /dev/null and b/inc/images/sort_desc_disabled copy.png differ diff --git a/inc/script.js b/inc/script.js index 7f972150..ecef045d 100644 --- a/inc/script.js +++ b/inc/script.js @@ -534,7 +534,9 @@ function showConfigFiles() { } else { toastr.clear(); $("#ajax-config_file_name").html(data); - window.history.pushState("Show config", "Show config", cur_url[0] + "?service=" + service + "&serv=" + $("#serv").val() + "&showConfigFiles"); + if (findGetParameter('findInConfig') === null) { + window.history.pushState("Show config", "Show config", cur_url[0] + "?service=" + service + "&serv=" + $("#serv").val() + "&showConfigFiles"); + } } } } ); @@ -809,7 +811,7 @@ $( function() { if($('#time_range_out_hour').val() != '' && $('#time_range_out_hour').val() != 'None') { var date1 = parseInt($('#time_range_out_hour').val(), 10) * 60 + parseInt($('#time_range_out_minut').val(), 10) } else { - var date1 = now.getHours() * 60 - 1 * 60; + var date1 = now.getHours() * 60 - 3 * 60; } if($('#time_range_out_hour').val() != '' && $('#time_range_out_hour').val() != 'None') { var date2 = parseInt($('#time_range_out_hour1').val(), 10) * 60 + parseInt($('#time_range_out_minut1').val(), 10) @@ -1361,7 +1363,7 @@ function changeUserPasswordItOwn(d) { } ); } } -function findInConfig() { +function findInConfig(words) { clearAllAjaxFields(); $.ajax( { url: "options.py", @@ -1369,7 +1371,7 @@ function findInConfig() { serv: $("#serv").val(), act: "findInConfigs", service: $("#service").val(), - words: $('#words').val(), + words: words, token: $('#token').val() }, type: "POST", @@ -1383,3 +1385,22 @@ function findInConfig() { } } ); } +function waitForElm(selector) { + return new Promise(resolve => { + if (document.querySelector(selector)) { + return resolve(document.querySelector(selector)); + } + + const observer = new MutationObserver(mutations => { + if (document.querySelector(selector)) { + resolve(document.querySelector(selector)); + observer.disconnect(); + } + }); + + observer.observe(document.body, { + childList: true, + subtree: true + }); + }); +} diff --git a/inc/style.css b/inc/style.css index d4636383..8f4e35b6 100644 --- a/inc/style.css +++ b/inc/style.css @@ -1,7 +1,7 @@ :root { --green-color: #5CB85C; --red-color: #be2424; - --blue-color: #5d9ceb; + --blue-color: #4a89dc; --link-dark-blue: #23527c; --light-blue-color: #d1ecf1; --menu-color: #06212a; @@ -50,11 +50,16 @@ ul#browse_histroy { ul#browse_histroy li { display: inline; } -ul#browse_histroy li+li:before { +ul#browse_histroy li:before { content: "/"; color: #767676; margin: 0 5px 0px 5px; } +ul#browse_histroy li+li:before { + content: "->"; + color: #767676; + margin: 0 5px 0px 5px; +} #browse_histroy a { color: #767676; font-size: 9.1px; @@ -408,7 +413,7 @@ pre { background-color: #ddd; } .add-button, .add-button-wi { - background-color: var(--green-color); + background-color: var(--blue-color); border-radius: 5px; color: #fff; padding: 5px 10px; @@ -417,10 +422,10 @@ pre { cursor: pointer; } .add-button:hover, .add-button-wi:hover { - background-color: #5bbf5b; + background-color: #5094ee; } .add-button:active, .add-button-wi:active { - background-color: #3e863e; + background-color: #5499f4; box-shadow: 0 1px #666; } .add-button-wi { diff --git a/inc/users.js b/inc/users.js index 37f90e1d..80ba6646 100644 --- a/inc/users.js +++ b/inc/users.js @@ -666,7 +666,7 @@ $( function() { $('#search_ldap_user').click(function() { var valid = true; toastr.clear(); - allFields = $( [] ).add( $('#new-username') ) + allFields = $( [] ).add( $('#new-username') ); allFields.removeClass( "ui-state-error" ); valid = valid && checkLength( $('#new-username'), "user name", 1 ); user = $('#new-username').val() @@ -2127,6 +2127,8 @@ function ajaxActionServies(action, service) { success: function( data ) { if (data.indexOf('error:') != '-1' || data.indexOf('Failed') != '-1') { toastr.error(data); + } else if (data.indexOf('warning: ') != '-1') { + toastr.warning(data); } else { window.history.pushState("services", "services", cur_url[0].split("#")[0] + "#services"); toastr.success('The ' + service + ' has been ' + action +'ed'); @@ -2502,7 +2504,7 @@ function showServerInfo(id, ip) { $.getScript(awesome); } } - }); + } ); } else { $('#server_info-'+id).hide(); $('#server_info_link-'+id).attr('title', 'Show System info');
- Slave for + Slave for Credentials Description - +
- +
- +
Log - +