Pavel Loginov 3 years ago
parent ef91b0a831
commit 69ad8101bc

@ -12,7 +12,8 @@ Web interface(user-friendly web GUI, alerting, monitoring and secure) for managi
![alt text](https://roxy-wi.org/inc/images/viewstat.png "HAProxy state page")
# Features:
1. Installation and updating HAProxy, Nginx and Keepalived with Roxy-WI
1. Installation and updating HAProxy, Nginx and Keepalived with Roxy-WI as system service
1. Installation and updating HAProxy and Nginx with Roxy-WI as Docker service
2. Installation and updating Grafana, Prometheus servers with Roxy-WI
3. Installation and updating HAProxy and Nginx exporters with Roxy-WI
4. Server provisioning on AWS, DigitalOcean and G-Core Labs
@ -125,4 +126,4 @@ and check executeble py files
If you see plain text, check section "Directory" in httpd conf
[Read more] (https://roxy-wi.org/troubleshooting.py)
[Read more](https://roxy-wi.org/troubleshooting.py)

@ -805,7 +805,6 @@ def update_db_v_5_3_0(**kwargs):
print("An error occurred:", e)
def update_db_v_5_3_1(**kwargs):
cursor = conn.cursor()
sql = """
@ -823,8 +822,46 @@ def update_db_v_5_3_1(**kwargs):
print("Updating... DB has been updated to version 5.3.1")
def update_db_v_5_3_2(**kwargs):
try:
Setting.insert(param='checker_maxconn_threshold', value=90, section='monitoring',
desc='Threshold value for alerting, in %').execute()
except Exception as e:
if kwargs.get('silent') != 1:
if (
str(e) == 'columns param, group are not unique' or
str(e) == '(1062, "Duplicate entry \'checker_maxconn_threshold-1\' for key \'param\'")' or
str(e) == 'UNIQUE constraint failed: settings.param, settings.group'
):
pass
else:
print("An error occurred:", e)
else:
if kwargs.get('silent') != 1:
print('Updating... DB has been updated to version 5.3.2')
def update_db_v_5_3_2_2(**kwargs):
cursor = conn.cursor()
sql = """
ALTER TABLE `servers` ADD COLUMN keepalived_alert INTEGER NOT NULL DEFAULT 0;
"""
try:
cursor.execute(sql)
except Exception as e:
if kwargs.get('silent') != 1:
if e.args[0] == 'duplicate column name: keepalived_alert' or str(e) == '(1060, "Duplicate column name \'keepalived_alert\'")':
print('Updating... DB has been updated to version 5.3.2')
else:
print("An error occurred:", e)
else:
print("Updating... DB has been updated to version 5.3.2")
def update_ver():
query = Version.update(version='5.3.1.0')
query = Version.update(version='5.3.2.0')
try:
query.execute()
except:
@ -858,6 +895,8 @@ def update_all():
update_db_v_5_2_6()
update_db_v_5_3_0()
update_db_v_5_3_1()
update_db_v_5_3_2()
update_db_v_5_3_2_2()
update_ver()
@ -888,6 +927,8 @@ def update_all_silent():
update_db_v_5_2_6(silent=1)
update_db_v_5_3_0(silent=1)
update_db_v_5_3_1(silent=1)
update_db_v_5_3_2(silent=1)
update_db_v_5_3_2_2(silent=1)
update_ver()

@ -62,6 +62,7 @@ class Server(BaseModel):
protected = IntegerField(constraints=[SQL('DEFAULT 0')])
nginx_metrics = IntegerField(constraints=[SQL('DEFAULT 0')])
keepalived_active = IntegerField(constraints=[SQL('DEFAULT 0')])
keepalived_alert = IntegerField(constraints=[SQL('DEFAULT 0')])
class Meta:
table_name = 'servers'

@ -119,6 +119,8 @@ def logging(server_ip, action, **kwargs):
import http.cookies
import distro
login = ''
log_path = get_config_var('main', 'log_path')
try:
user_group = get_user_group()
@ -817,15 +819,21 @@ def install_nginx(server_ip, **kwargs):
def update_haproxy_wi(service):
import distro
restart_service = ''
if distro.id() == 'ubuntu':
try:
if service == 'roxy-wi-keep_alive':
service = 'roxy-wi-keep-alive'
except Exception:
pass
cmd = 'sudo -S apt-get update && sudo apt-get install ' + service +' && sudo systemctl restart ' + service
if service == 'roxy-wi':
restart_service = ' && sudo systemctl restart ' + service
cmd = 'sudo -S apt-get update && sudo apt-get install ' + service + restart_service
else:
cmd = 'sudo -S yum -y update ' + service +' && sudo systemctl restart ' + service
cmd = 'sudo -S yum -y update ' + service + restart_service
output, stderr = subprocess_execute(cmd)
print(output)
print(stderr)

@ -2051,7 +2051,7 @@ if form.getvalue('updatehapwiserver') is not None:
service = form.getvalue('service_name')
sql.update_hapwi_server(hapwi_id, alert, metrics, active, service)
server_ip = sql.select_server_ip_by_id(hapwi_id)
funct.logging(server_ip, 'the server ' + name, ' has been updated ', haproxywi=1, login=1, keep_history=1, service=service)
funct.logging(server_ip, 'The server ' + name + ' has been updated ', haproxywi=1, login=1, keep_history=1, service=service)
if form.getvalue('updateserver') is not None:
name = form.getvalue('updateserver')
@ -2780,9 +2780,14 @@ if form.getvalue('geoip_install'):
if form.getvalue('nettools_icmp_server_from'):
server_from = form.getvalue('nettools_icmp_server_from')
server_to = form.getvalue('nettools_icmp_server_to')
server_to = funct.is_ip_or_dns(server_to)
action = form.getvalue('nettools_action')
stderr = ''
if server_to == '':
print('warning: enter a correct IP or DNS name')
sys.exit()
if action == 'nettools_ping':
action_for_sending = 'ping -c 4 -W 1 -s 56 -O '
elif action == 'nettools_trace':
@ -2800,17 +2805,31 @@ if form.getvalue('nettools_icmp_server_from'):
print('error: '+stderr)
sys.exit()
for i in output:
if i == ' ':
if i == ' ' or i == '':
continue
i = i.strip()
print(i + '<br>')
if 'PING' in i:
print('<span style="color: var(--link-dark-blue); display: block; margin-top: -20px;">')
elif 'no reply' in i or 'no answer yet' in i or 'Too many hops' in i or '100% packet loss' in i:
print('<span style="color: var(--red-color);">')
elif 'ms' in i and '100% packet loss' not in i:
print('<span style="color: var(--green-color);">')
else:
print('<span>')
print(i + '</span><br />')
if form.getvalue('nettools_telnet_server_from'):
server_from = form.getvalue('nettools_telnet_server_from')
server_to = form.getvalue('nettools_telnet_server_to')
server_to = funct.is_ip_or_dns(server_to)
port_to = form.getvalue('nettools_telnet_port_to')
stderr = ''
if server_to == '':
print('warning: enter a correct IP or DNS name')
sys.exit()
if server_from == 'localhost':
action_for_sending = 'echo "exit"|nc ' + server_to + ' ' + port_to + ' -t -w 1s'
output, stderr = funct.subprocess_execute(action_for_sending)
@ -2819,7 +2838,7 @@ if form.getvalue('nettools_telnet_server_from'):
output = funct.ssh_command(server_from, action_for_sending, raw=1)
if stderr != '':
print('error: '+stderr[5:-1])
print('error: <b>' + stderr[5:] + '</b>')
sys.exit()
count_string = 0
for i in output:
@ -2827,7 +2846,7 @@ if form.getvalue('nettools_telnet_server_from'):
continue
i = i.strip()
if i == 'Ncat: Connection timed out.':
print('error: ' + i[5:-1])
print('error: <b>' + i[5:] + '</b>')
break
print(i + '<br>')
count_string += 1
@ -2837,9 +2856,14 @@ if form.getvalue('nettools_telnet_server_from'):
if form.getvalue('nettools_nslookup_server_from'):
server_from = form.getvalue('nettools_nslookup_server_from')
dns_name = form.getvalue('nettools_nslookup_name')
dns_name = funct.is_ip_or_dns(dns_name)
record_type = form.getvalue('nettools_nslookup_record_type')
stderr = ''
if dns_name == '':
print('warning: enter a correct DNS name')
sys.exit()
action_for_sending = 'dig ' + dns_name + ' ' + record_type + ' |grep -e "SERVER\|' + dns_name + '"'
if server_from == 'localhost':
@ -2852,7 +2876,7 @@ if form.getvalue('nettools_nslookup_server_from'):
print('error: '+stderr[5:-1])
sys.exit()
count_string = 0
print('<b>There are the next records for ' + dns_name + ' domain:</b> <br />')
print('<b style="display: block; margin-top:10px;">The <i style="color: var(--blue-color)">' + dns_name + '</i> domain has the following records:</b>')
for i in output:
if 'dig: command not found.' in i:
print('error: Install bind-utils before using NSLookup')
@ -2860,13 +2884,13 @@ if form.getvalue('nettools_nslookup_server_from'):
if ';' in i and ';; SERVER:' not in i:
continue
if 'SOA' in i and record_type != 'SOA':
print('<b>There are not any records for this type')
print('<b style="color: red">There are not any records for this type')
break
if ';; SERVER:' in i:
i = i[10:-1]
i = i[10:]
print('<br><b>From NS server:</b><br>')
i = i.strip()
print(i + '<br>')
print('<i>' + i + '</i><br>')
count_string += 1
if form.getvalue('portscanner_history_server_id'):

@ -259,10 +259,10 @@ def update_hapwi_server(server_id, alert, metrics, active, service_name):
try:
if service_name == 'nginx':
update_hapwi = Server.update(nginx_alert=alert, metrics=metrics, nginx_active=active,
nginx_metrics=metrics).where(
Server.server_id == server_id)
nginx_metrics=metrics).where(Server.server_id == server_id)
elif service_name == 'keepalived':
update_hapwi = Server.update(keepalived_active=active).where(Server.server_id == server_id)
update_hapwi = Server.update(keepalived_alert=alert, keepalived_active=active).where(
Server.server_id == server_id)
else:
update_hapwi = Server.update(alert=alert, metrics=metrics, active=active).where(
Server.server_id == server_id)
@ -1766,7 +1766,7 @@ def get_setting(param, **kwargs):
param == 'syslog_server_enable' or param == 'smon_check_interval' or
param == 'checker_check_interval' or param == 'port_scan_interval' or
param == 'smon_keep_history_range' or param == 'checker_keep_history_range' or
param == 'portscanner_keep_history_range'
param == 'portscanner_keep_history_range' or param == 'checker_maxconn_threshold'
):
return int(setting.value)
else:
@ -1852,6 +1852,23 @@ def select_nginx_alert(**kwargs):
return query_res
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')))
else:
query = Server.select(Server.ip).where((Server.keepalived_alert == 1) & (Server.enable == 1))
try:
query_res = query.execute()
except Exception as e:
out_error(e)
else:
return query_res
def select_keep_alive():
query = Server.select(Server.ip).where(Server.active == 1)
try:

@ -101,8 +101,10 @@
{% set additional_status_class = 'div-server-head-down' %}
{% endif %}
{% elif service == 'keepalived' %}
{% set checker_desc = 'Checker monitors Keepalived services. If Keepalived service is down, Checker will alert via Telegram and/or Slack' %}
{% set is_auto_start_enabled = s.8.0.22 %}
{% set action_service = 'keepalived' %}
{% set is_checker_enabled = s.8.0.23 %}
{% if s.5.0.1 == 'active' %}
{% set additional_status_class = 'div-server-head-up' %}
{% else %}
@ -212,13 +214,15 @@
{% endif %}
</div>
<div class="server-act-links" id="server-{{s.8.0.0|string()}}-{{service}}">
{% if role <= 2 and service != 'keepalived' %}
{% if role <= 2 %}
{% set id = 'alert-' + s.8.0.0|string() %}
{% if is_checker_enabled == 1 %}
{{ checkbox(id, title=checker_desc, value='1', desc='Checker', checked='checked') }}
{% else %}
{{ checkbox(id, title=checker_desc, value='1', desc='Checker') }}
{% endif %}
{% endif %}
{% if role <= 2 and service != 'keepalived' %}
{% set id = 'metrics-' + s.8.0.0|string() %}
{% if is_metrics_enabled == 1 %}
{{ checkbox(id, title='Collecting metrics is enabled', value='1', desc='Metrics', checked='checked') }}
@ -226,12 +230,14 @@
{{ checkbox(id, title='Enable collecting metrics', value='1', desc='Metrics') }}
{% endif %}
{% endif %}
{% if role <= 2 %}
{% set id = 'active-' + s.8.0.0|string() %}
{% if is_auto_start_enabled == 1 %}
{{ checkbox(id, title='Auto Start is enabled', value='1', desc='Auto Start', checked='checked') }}
{% else %}
{{ checkbox(id, title='Enable Auto Start', value='1', desc='Auto Start') }}
{% endif %}
{% endif %}
</div>
<div class="server-act-links">
<a href="/app/config.py?service={{service}}&serv={{s.2}}&showConfig" class="ui-button ui-widget ui-corner-all" title="Open running config">Config</a>

@ -1,16 +1,13 @@
{% extends "base.html" %}
{% block content %}
{% from 'include/input_macros.html' import input, checkbox, select %}
{% if servers|length == 0 %}
{% include 'include/getstarted.html' %}
{% else %}
<style>
.ping_pre {
display: block;
padding: 9.5px;
padding: 10px;
margin: 0 0 10px;
font-family: 'Courier New', monospace;
font-size: 13px;
font-size: 14px;
line-height: 1.42857143;
color: #333;
word-break: break-all;
@ -23,8 +20,8 @@
<table class="overview">
<caption><h3>ICMP</h3></caption>
<tr class="overviewHead">
<th class="padding10 first-collumn">From server</th>
<th class="padding10 first-collumn">To server</th>
<th class="padding10 first-collumn">From</th>
<th class="padding10 first-collumn">To</th>
<th class="padding10 first-collumn"></th>
<th></th>
</tr>
@ -55,8 +52,8 @@
<table class="overview">
<caption><h3>Check port</h3></caption>
<tr class="overviewHead">
<th class="padding10 first-collumn">From server</th>
<th class="padding10 first-collumn">To server</th>
<th class="padding10 first-collumn">From</th>
<th class="padding10 first-collumn">To</th>
<th class="padding10 first-collumn">Port</th>
<th></th>
</tr>
@ -87,7 +84,7 @@
<table class="overview">
<caption><h3>NSLookup</h3></caption>
<tr class="overviewHead">
<th class="padding10 first-collumn">From server</th>
<th class="padding10 first-collumn">From</th>
<th class="padding10 first-collumn">Record type</th>
<th class="padding10 first-collumn">DNS name</th>
<th></th>
@ -121,8 +118,8 @@
<div id="ajax-nettools" style="padding: 20px;"></div>
<script>
$("#nettools_nslookup_record_type" ).selectmenu({
width: 175
});
width: 175
});
$( "#nettools_telnet_form" ).on("click", ":submit", function(e){
$('#ajax-nettools').html('');
var frm = $('#nettools_telnet_form');
@ -145,13 +142,16 @@
success: function( data ) {
data = data.replace('\n', '<br>');
if (data.indexOf('error: ') != '-1' || data.indexOf('Fatal') != '-1' || data.indexOf('Error(s)') != '-1') {
$('#ajax-nettools').html('<div class="alert alert-warning">'+data+'</div>');
$('#ajax-nettools').html('<div class="ping_pre">'+data+'</div>');
} else if (data.indexOf('warning: ') != '-1') {
toastr.clear();
toastr.warning(data)
} else {
toastr.clear();
if (data.indexOf('') != '-1') {
$('#ajax-nettools').html('<div class="alert alert-success"><b>Connection has been successful</b></div>');
$('#ajax-nettools').html('<div class="ping_pre"><b>Connection has been successful</b></div>');
} else {
$('#ajax-nettools').html('<div class="alert alert-success"><b>Connection has been successful</b>:<br /><br />'+data+'</div>');
$('#ajax-nettools').html('<div class="ping_pre"><b>Connection has been successful</b>:<br /><br />'+data+'</div>');
}
}
}
@ -178,6 +178,9 @@
if (data.indexOf('error: ') != '-1' || data.indexOf('Fatal') != '-1' || data.indexOf('Error(s)') != '-1') {
toastr.clear();
toastr.error(data);
} else if (data.indexOf('warning: ') != '-1') {
toastr.clear();
toastr.warning(data)
} else {
toastr.clear();
$('#ajax-nettools').html('<div class="ping_pre">'+data+'</div>');
@ -206,6 +209,9 @@
if (data.indexOf('error: ') != '-1' || data.indexOf('Fatal') != '-1' || data.indexOf('Error(s)') != '-1') {
toastr.clear();
toastr.error(data);
} else if (data.indexOf('warning: ') != '-1') {
toastr.clear();
toastr.warning(data)
} else {
toastr.clear();
$('#ajax-nettools').html('<div class="ping_pre">'+data+'</div>');
@ -215,5 +221,4 @@
event.preventDefault();
});
</script>
{% endif %}
{% endblock %}
Loading…
Cancel
Save