pull/246/head
Pavel Loginov 2020-07-15 06:16:31 +02:00
parent a26482623f
commit fedf93c678
14 changed files with 1035 additions and 66 deletions

View File

@ -538,10 +538,48 @@ def update_db_v_4_3_2(**kwargs):
con.close()
def update_db_v_4_4(**kwargs):
con, cur = get_cur()
sql = """
CREATE TABLE IF NOT EXISTS `smon` (
`id` INTEGER NOT NULL,
`ip` INTEGER,
`port` INTEGER,
`status` INTEGER DEFAULT 1,
`en` INTEGER DEFAULT 1,
`desc` varchar(64),
`response_time` varchar(64),
`time_state` integer default 0,
`group` varchar(64),
`script` varchar(64),
`http` varchar(64),
`http_status` INTEGER DEFAULT 1,
`body` varchar(64),
`body_status` INTEGER DEFAULT 1,
`telegram_channel_id` INTEGER,
`user_group` INTEGER,
UNIQUE(ip, port, http, body),
PRIMARY KEY(`id`)
);"""
try:
cur.execute(sql)
con.commit()
except sqltool.Error as e:
if kwargs.get('silent') != 1:
if e.args[0] == 'duplicate column name: pos' or e == " 1060 (42S21): Duplicate column name 'pos' ":
print('DB was update to 4.4.0')
else:
print("An error occurred:", e)
return False
else:
return True
cur.close()
con.close()
def update_ver(**kwargs):
con, cur = get_cur()
sql = """update version set version = '4.3.3.0'; """
sql = """update version set version = '4.4.0.0'; """
try:
cur.execute(sql)
con.commit()
@ -570,6 +608,7 @@ def update_all():
update_db_v_4_3_0()
update_db_v_4_3_1()
update_db_v_4_3_2()
update_db_v_4_4()
update_ver()
@ -592,6 +631,7 @@ def update_all_silent():
update_db_v_4_3_0(silent=1)
update_db_v_4_3_1(silent=1)
update_db_v_4_3_2(silent=1)
update_db_v_4_4(silent=1)
update_ver()

View File

@ -128,7 +128,7 @@ def check_login(**kwargs):
import http.cookies
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_uuid = cookie.get('uuid')
ref = os.environ.get("SCRIPT_NAME")
ref = os.environ.get("REQUEST_URI")
sql.delete_old_uuid()

View File

@ -1832,3 +1832,102 @@ if form.getvalue('getcurrentusergroup') is not None:
template = env.get_template('/show_user_current_group.html')
template = template.render(groups=groups, group=group.value,id=id)
print(template)
if form.getvalue('newsmon') is not None:
import http.cookies
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_group = cookie.get('group')
user_group = user_group.value
server = form.getvalue('newsmon')
port = form.getvalue('newsmonport')
enable = form.getvalue('newsmonenable')
proto = form.getvalue('newsmonproto')
uri = form.getvalue('newsmonuri')
body = form.getvalue('newsmonbody')
group = form.getvalue('newsmongroup')
desc = form.getvalue('newsmondescription')
telegram = form.getvalue('newsmontelegram')
if sql.insert_smon(server, port, enable, proto, uri, body, group, desc, telegram, user_group):
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates'), autoescape=True)
template = env.get_template('ajax/show_new_smon.html')
template = template.render(smon=sql.select_smon(user_group,ip=server,port=port,proto=proto,uri=uri,body=body), telegrams=sql.get_user_telegram_by_group(user_group))
print(template)
funct.logging('SMON','Has been add a new server '+server+' to SMON ', haproxywi=1, login=1)
if form.getvalue('smondel') is not None:
import http.cookies
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_group = cookie.get('group')
user_group = user_group.value
id = form.getvalue('smondel')
if sql.delete_smon(id, user_group):
print('Ok')
if form.getvalue('showsmon') is not None:
import http.cookies
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_group = cookie.get('group')
user_group = user_group.value
sort = form.getvalue('sort')
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates'), autoescape=True)
template = env.get_template('ajax/smon_dashboard.html')
template = template.render(smon=sql.smon_list(user_group),sort=sort)
print(template)
if form.getvalue('updateSmonIp') is not None:
id = form.getvalue('id')
ip = form.getvalue('updateSmonIp')
port = form.getvalue('updateSmonPort')
en = form.getvalue('updateSmonEn')
http = form.getvalue('updateSmonHttp')
body = form.getvalue('updateSmonBody')
telegram = form.getvalue('updateSmonTelegram')
group = form.getvalue('updateSmonGroup')
desc = form.getvalue('updateSmonDesc')
try:
port = int(port)
except:
print('error: port must number')
sys.exit()
if port > 65535 or port < 0:
print('error: port must be 0-65535')
sys.exit()
if port == 80 and http == 'https':
print('error: Cannot be https with 80 port')
sys.exit()
if sql.update_smon(id, ip, port, body, telegram, group, desc, en):
print("Ok")
if form.getvalue('showBytes') is not None:
serv = form.getvalue('showBytes')
port = sql.get_setting('haproxy_sock_port')
bin_bout = []
cmd = "echo 'show stat' |nc "+serv+" "+port+" |cut -d ',' -f 1-2,9|grep -E '[0-9]'|awk -F',' '{sum+=$3;}END{print sum;}'"
bin, stderr = funct.subprocess_execute(cmd)
bin_bout.append(bin[0])
cmd = "echo 'show stat' |nc "+serv+" "+port+" |cut -d ',' -f 1-2,10|grep -E '[0-9]'|awk -F',' '{sum+=$3;}END{print sum;}'"
bin, stderr = funct.subprocess_execute(cmd)
bin_bout.append(bin[0])
cmd = "echo 'show stat' |nc "+serv+" "+port+" |cut -d ',' -f 1-2,5|grep -E '[0-9]'|awk -F',' '{sum+=$3;}END{print sum;}'"
bin, stderr = funct.subprocess_execute(cmd)
bin_bout.append(bin[0])
cmd = "echo 'show stat' |nc "+serv+" "+port+" |cut -d ',' -f 1-2,8|grep -E '[0-9]'|awk -F',' '{sum+=$3;}END{print sum;}'"
bin, stderr = funct.subprocess_execute(cmd)
bin_bout.append(bin[0])
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates'), autoescape=True)
template = env.get_template('ajax/bin_bout.html')
template = template.render(bin_bout=bin_bout,serv=serv)
print(template)

49
app/smon.py Normal file
View File

@ -0,0 +1,49 @@
#!/usr/bin/env python3
import funct
import sql
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'), autoescape=True)
template = env.get_template('smon.html')
smon_status = ''
stderr = ''
form = funct.form
action = form.getvalue('action')
sort = form.getvalue('sort')
print('Content-type: text/html\n')
funct.check_login()
try:
user, user_id, role, token, servers = funct.get_users_params()
import http.cookies
import os
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
group = cookie.get('group')
user_group = group.value
cmd = "systemctl status smon |grep Active |awk '{print $2}'"
smon_status, stderr = funct.subprocess_execute(cmd)
except:
pass
if action == 'add':
smon = sql.select_smon(user_group=user_group,action='add')
funct.page_for_admin(level=2)
title = "SMON Admin"
else:
smon = sql.smon_list(user_group)
title = "SMON Dashboard"
template = template.render(h2 = 1, title = title,
autoreœfresh = 1,
role = role,
user = user,
group = user_group,
telegrams = sql.get_user_telegram_by_group(user_group),
versions = funct.versions(),
smon = smon,
smon_status = smon_status,
smon_error = stderr,
action = action,
sort = sort,
token = token)
print(template)

View File

@ -605,6 +605,19 @@ def get_user_telegram_by_uuid(uuid):
con.close()
def get_user_telegram_by_group(group):
con, cur = get_cur()
sql = """ select telegram.* from telegram where groups = '%s' """ % group
try:
cur.execute(sql)
except sqltool.Error as e:
funct.out_error(e)
else:
return cur.fetchall()
cur.close()
con.close()
def get_telegram_by_ip(ip):
con, cur = get_cur()
sql = """ select telegram.* from telegram left join servers as serv on serv.groups = telegram.groups where serv.ip = '%s' """ % ip
@ -618,6 +631,19 @@ def get_telegram_by_ip(ip):
con.close()
def get_telegram_by_id(id):
con, cur = get_cur()
sql = """ select * from telegram where id = '%s' """ % id
try:
cur.execute(sql)
except sqltool.Error as e:
funct.out_error(e)
else:
return cur.fetchall()
cur.close()
con.close()
def get_dick_permit(**kwargs):
import http.cookies
import os
@ -1707,6 +1733,268 @@ def check_token_exists(token):
return False
def insert_smon(server, port, enable, proto, uri, body, group, desc, telegram, user_group):
try:
http = proto+':'+uri
except:
http = ''
con, cur = get_cur()
sql = """INSERT INTO smon (ip, port, en, `desc`, `group`, http, body, telegram_channel_id, user_group, `status`)
VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '3')
""" % (server, port, enable, desc, group, http, body, telegram, user_group)
try:
cur.execute(sql)
con.commit()
except sqltool.Error as e:
funct.out_error(e)
con.rollback()
return False
else:
return True
cur.close()
con.close()
def select_smon(user_group, **kwargs):
con, cur = get_cur()
if user_group == '1':
user_group = ''
else:
if kwargs.get('ip'):
user_group = "and user_group = '%s'" % user_group
else:
user_group = "where user_group='%s'" % user_group
if kwargs.get('ip'):
try:
http = kwargs.get('proto')+':'+kwargs.get('uri')
except:
http = ''
sql = """select id, ip, port, en, http, body, telegram_channel_id, `desc`, `group`, user_group from smon
where ip='%s' and port='%s' and http='%s' and body='%s' %s
""" % (kwargs.get('ip'), kwargs.get('port'), http, kwargs.get('body'), user_group)
elif kwargs.get('action') == 'add':
sql = """select id, ip, port, en, http, body, telegram_channel_id, `desc`, `group`, user_group from smon
%s order by `group`""" % user_group
else:
sql = """select * from `smon` %s """ % user_group
try:
cur.execute(sql)
except sqltool.Error as e:
funct.out_error(e)
else:
return cur.fetchall()
cur.close()
con.close()
def delete_smon(id, user_group):
con, cur = get_cur()
sql = """delete from smon
where id = '%s' and user_group = '%s' """ % (id, user_group)
try:
cur.execute(sql)
con.commit()
except sqltool.Error as e:
funct.out_error(e)
con.rollback()
return False
else:
return True
cur.close()
con.close()
def update_smon(id, ip, port, body, telegram, group, desc, en):
con, cur = get_cur()
sql = """ update smon set
ip = '%s',
port = '%s',
body = '%s',
telegram_channel_id = '%s',
`group` = '%s',
`desc` = '%s',
en = '%s'
where id = '%s'""" % (ip, port, body, telegram, group, desc, en, id)
try:
cur.execute(sql)
con.commit()
return True
except sqltool.Error as e:
funct.out_error(e)
con.rollback()
return False
cur.close()
con.close()
def select_en_service():
con, cur = get_cur()
sql = """ select ip, port, telegram_channel_id, id from smon where en = 1"""
try:
cur.execute(sql)
except sqltool.Error as e:
out_error(e)
else:
return cur.fetchall()
def select_status(id):
con, cur = get_cur()
sql = """ select status from smon where id = '%s' """ % (id)
try:
cur.execute(sql)
except sqltool.Error as e:
print("An error occurred:", e)
else:
for status in cur:
return status[0]
def select_http_status(id):
con, cur = get_cur()
sql = """ select http_status from smon where id = '%s' """ % (id)
try:
cur.execute(sql)
except sqltool.Error as e:
print("An error occurred:", e)
else:
for status in cur:
return status[0]
def select_body_status(id):
con, cur = get_cur()
sql = """ select body_status from smon where id = '%s' """ % (id)
try:
cur.execute(sql)
except sqltool.Error as e:
print("An error occurred:", e)
else:
for status in cur:
return status[0]
def select_script(id):
con, cur = get_cur()
sql = """ select script from smon where id = '%s' """ % (id)
try:
cur.execute(sql)
except sqltool.Error as e:
print("An error occurred:", e)
else:
for script in cur:
return script[0]
def select_http(id):
con, cur = get_cur()
sql = """ select http from smon where id = '%s' """ % (id)
try:
cur.execute(sql)
except sqltool.Error as e:
print("An error occurred:", e)
else:
for script in cur:
return script[0]
def select_body(id):
con, cur = get_cur()
sql = """ select body from smon where id = '%s' """ % (id)
try:
cur.execute(sql)
except sqltool.Error as e:
print("An error occurred:", e)
else:
for script in cur:
return script[0]
def change_status(status, id):
con, cur = get_cur()
sql = """ update smon set status = '%s' where id = '%s' """ % (status, id)
try:
cur.executescript(sql)
except sqltool.Error as e:
print("An error occurred:", e)
cur.close()
con.close()
def change_http_status(status, id):
con, cur = get_cur()
sql = """ update smon set http_status = '%s' where id = '%s' """ % (status, id)
try:
cur.executescript(sql)
except sqltool.Error as e:
print("An error occurred:", e)
cur.close()
con.close()
def change_body_status(status, id):
con, cur = get_cur()
sql = """ update smon set body_status = '%s' where id = '%s' """ % (status, id)
try:
cur.executescript(sql)
except sqltool.Error as e:
print("An error occurred:", e)
cur.close()
con.close()
def add_sec_to_state_time(time, id):
con, cur = get_cur()
sql = """ update smon set time_state = '%s' where id = '%s' """ % (time, id)
try:
cur.executescript(sql)
except sqltool.Error as e:
print("An error occurred:", e)
cur.close()
con.close()
def set_to_zero_time_state(id):
con, cur = get_cur()
sql = """ update smon set time_state = 0 where id = '%s' """ % (id)
try:
cur.executescript(sql)
except sqltool.Error as e:
print("An error occurred:", e)
cur.close()
con.close()
def response_time(time, id):
con, cur = get_cur()
sql = """ update smon set response_time = '%s' where id = '%s' """ % (time, id)
try:
cur.executescript(sql)
except sqltool.Error as e:
print("An error occurred:", e)
cur.close()
con.close()
def smon_list(user_group):
con, cur = get_cur()
if user_group == '1':
user_group = ''
else:
user_group = "where user_group='%s'" % user_group
sql = """ select ip,port,status,en,`desc`,response_time,time_state,`group`,script,http,http_status,body,body_status
from smon %s order by `group` desc """ % user_group
try:
cur.execute(sql)
except sqltool.Error as e:
out_error(e)
else:
return cur.fetchall()
form = funct.form
error_mess = '<span class="alert alert-danger" id="error">All fields must be completed <a title="Close" id="errorMess"><b>X</b></a></span>'

View File

@ -137,7 +137,7 @@
<th class="ip-field">IP</th>
<th class="checkbox-head"><span title="SSH port">Port</span></th>
<th class="group-field">Group</th>
<th class="checkbox-head">Enable</th>
<th class="checkbox-head">Enabled</th>
<th class="checkbox-head"><span title="Vitrual IP, something like VRRP">Virt</span></th>
<th class="checkbox-head">HAProxy</th>
<th class="checkbox-head">Nginx</th>

View File

@ -0,0 +1,142 @@
<div class="sort_menu">
<a href="#" title="Do not sort by status" onclick="showSmon('not_sort')">Do not sort</a> |
<a href="#" id="sort_by_status" title="Sort by status" onclick="sort_by_status()">Sort by status</a> |
<a href="#" title="Refresh page" onclick="showSmon('refresh');">Refresh</a>
<span style="padding-left: 20px;">
{% set down = [] %}
{% set up = [] %}
{% set dis = [] %}
{% for s in smon %}
{% if s.3 == 1 %}
{% if s.2 == 1 and s.10 == 1 and s.12 == 1 %}
{% if up.append('1') %} {% endif %}
{% else %}
{% if down.append('1') %} {% endif %}
{% endif %}
{% else %}
{% if dis.append(s.7) %} {% endif %}
{% endif %}
{% endfor %}
<b>Counting state: UP: {{up|length}}, DOWN: {{down|length}}, Disabled: {{dis|length}}</b>
<span>
</div>
{% set group = [] %}
{% set group_prev = [] %}
{%- for s in smon -%}
{% if s.7 %}
{% if s.7 not in group %}
<div class="smon_group">
<div class="group_name">
{{ s.7 }}
</div>
</div>
{% endif %}
{% if group.append(s.7) %} {% endif %}
{% endif %}
{% if s.3 == 1 %}
{% if s.2 == 1 and s.10 == 1 and s.12 == 1 %}
<div class="smon_services good">
{% else %}
<div class="smon_services err">
{% endif %}
{% else %}
<div class="smon_services dis">
{% endif %}
<div class="ip">
{% if s.0|string|length > 23 %}
<span style="font-size: 11px;">
{% elif s.0|string|length > 20 %}
<span style="font-size: 12px;">
{% elif s.0|string|length > 17 %}
<span style="font-size: 15px;">
{% else %}
<span>
{% endif %}
{{s.0}}:{{s.1}}
</span>
</div>
<div class="desc">
{% if s.4 != 'None' %}
<b>{{s.4}}</b>
{% else %}
Desc: None
{% endif %}
</div>
<div class="desc">
{% if s.3 == 1 %}
{% if s.2 == 1 and s.10 == 1 and s.12 == 1 %}
Uptime: <time class="timeago" datetime="{{s.6}}">{{s.6}}</time>
{% elif s.2 == 0 or s.10 == 0 or s.12 == 0 %}
Downtime: <time class="timeago" datetime="{{s.6}}">{{s.6}}</time>
{% else %}
Uptime: N/A
{% endif %}
{% else %}
Uptime: N/A
{% endif %}
</div>
<div class="res_time">
{% if s.3 == 1 %}
{% if s.2 == 1 %}
Resp time:
{% else %}
Last resp time:
{% endif %}
{% if s.5 %}
<span title="{{s.5}} ms">{{s.5|truncate(9)}} ms</span>
{% else %}
N/A
{% endif %}
{% else %}
N/A
{% endif %}
</div>
{% if s.3 == 1 %}
{% if s.2 == 1 and s.10 == 1 and s.12 == 1 %}
<div class="up">
<center>
UP
</center>
</div>
{% elif s.10 == 0 %}
<div class="down">
<center style="padding-top: 7px;">
HTTP IS FAILURE
</center>
</div>
{% elif s.12 == 0 %}
<div class="down">
<center style="padding-top: 7px;">
BODY IS FAILURE
</center>
</div>
{% elif s.2 == 3 %}
<div class="unknown">
<center style="padding-top: 7px;">
UNKNOWN
</center>
</div>
{% else %}
<div class="down">
<center style="padding-top: 7px;">
PORT IS DOWN
</center>
</div>
{% endif %}
{% else %}
<div class="disable">
<center>
Disabled
</center>
</div>
{% endif %}
</div>
{% endfor %}
<script>
jQuery(document).ready(function() {
jQuery("time.timeago").timeago();
})
{% if sort == 'by_status' %}
sort_by_status();
{% endif %}
</script>

View File

@ -88,6 +88,15 @@
<li><a href="/app/versions.py?service=keepalived" title="Actions with Keepalived configs versions" class="version head-submenu keepalived_versions">Versions</a></li>
</ul>
</li>
<li class="p_menu">
<a title="Simple monitoring network ports" class="stats">SMON</a>
<ul class="v_menu">
<li><a href="/app/smon.py?action=view" title="SMON dashboard" class="overview-link head-submenu">Dashborad</a></li>
{% if role <= 2 %}
<li><a href="/app/smon.py?action=add" title="SMON admin panel" class="edit head-submenu">Admin panel</a></li>
{% endif %}
</ul>
</li>
<li class="p_menu">
<a title="Servers manage" class="runtime">Servers</a>
<ul class="v_menu">

View File

@ -0,0 +1,84 @@
{% from 'include/input_macros.html' import input, checkbox %}
<td class="padding10 first-collumn" style="width: 150px;">
{% set id = 'smon-ip-' + s.0|string() %}
{{ input(id, value=s.1, size='20') }}
</td>
<td>
{% set id = 'smon-port-' + s.0|string() %}
{{ input(id, value=s.2, size='5') }}
</td>
<td class="checkbox">
{% set id = 'smon-enable-' + s.0|string() %}
{% if s.3 == 1 %}
{{ checkbox(id, checked='checked') }}
{% else %}
{{ checkbox(id) }}
{% endif %}
</td>
<td>
<span id="smon-proto1-{{s.0}}">{{ s.4.split(':')[0] }}</span>
{# {% if s.4|length > 0 %}
{% set values = dict() %}
{% set id = 'smon-proto-' + s.0|string() %}
{% set values = {'':'', 'http':'http','https':'https'} %}
{{ select(id, values=values, selected=s.4.split(':')[0]) }}
{% endif %} #}
</td>
<td id="smon-uri-{{s.0}}">
{% if s.4|length > 0 %}
{{ s.4.split(':')[1] }}
{% endif %}
</td>
<td>
{% set id = 'smon-body-' + s.0|string() %}
{% if s.5 != 'None' %}
{{ input(id, value=s.5, size='10') }}
{% else %}
{{ input(id, size='10') }}
{% endif %}
</td>
<td>
<select id="smon-telegram-{{s.0}}">
<option value="0">Disabled</option>
{% for t in telegrams %}
{% if s.6|int() == t.0|int() %}
<option value="{{t.0}}" selected>{{t.2}}</option>
{% else %}
<option value="{{t.0}}">{{t.2}}</option>
{% endif %}
{% endfor %}
</select>
</td>
<td>
{% set id = 'smon-group-' + s.0|string() %}
{% if s.8 != 'None' %}
{{ input(id, value=s.8, size='15') }}
{% else %}
{{ input(id, size='15') }}
{% endif %}
</td>
<td>
{% set id = 'smon-desc-' + s.0|string() %}
{% if s.7 != 'None' %}
{{ input(id, value=s.7, size='20') }}
{% else %}
{{ input(id, size='20') }}
{% endif %}
</td>
<!--<td>
<a class="add" onclick="cloneSmom({{s.0}})" id="clone-{{s.0}}" title="Clone {{s.1}}" style="cursor: pointer; color: #000;"></a>
</td>-->
<td>
<a class="delete" onclick="confirmDeleteSmon({{s.0}})" title="Delete server {{s.1}}" style="cursor: pointer; color: #000;"></a>
</td>
</tr>
<script>
$( function() {
$("#smon-telegram-{{s.0}}" ).selectmenu({
width: 170
});
$("#smon-proto-{{s.0}}" ).selectmenu({
width: 78
});
});
</script>

151
app/templates/smon.html Normal file
View File

@ -0,0 +1,151 @@
{% extends "base.html" %}
{% block content %}
{% from 'include/input_macros.html' import input, checkbox, select %}
<script src="/inc/users.js"></script>
<script src="/inc/fontawesome.min.js"></script>
<script src="/inc/jquery.timeago.js" type="text/javascript"></script>
{% if smon_error != '' %}
<center>
<h3>You do not have installed SMON service. Read <a href="https://haproxy-wi.org/services.py?service=smon"
title="Simple monitoring network ports with alerting via Telegram and WEB pannel" target="_blank">here</a> how install SMON service</h3>
</center>
{% elif smon_status.0 == 'failed' %}
<center>
<h3>SMON service is not run. Run the SMON service <a href="users.py#services" title="HAProxy-WI services" target="_blank">here</a> before use</h3>
</center>
{% elif smon|length == 0 and action != 'add' %}
<center>
<h3>You do not have added servers in SMON service. Create you first server <a href="smon.py?action=add" title="HAProxy-WI SMON" target="_blank">here</a> before use</h3>
</center>
{% else %}
{% if action == 'add' %}
<table class="overview" id="ajax-smon">
<thead>
<tr class="overviewHead">
<th class="padding10 first-collumn" style="width: 150px;">IP</th>
<th style="width: 10px;">Port</th>
<th style="width: 80px;">Enabled</th>
<th style="width: 80px;">Protocol</th>
<th>URI</th>
<th>Body</th>
<th style="width: 190px;">Telegram</th>
<th>Group</th>
<th>Description</th>
<!--<th></th>-->
<th></th>
</tr>
</thead>
<tbody>
{{env}}
{% for s in smon %}
<tr id="smon-{{s.0}}">
{% include 'include/smon_server.html' %}
{% endfor %}
</tbody>
</table>
<br /><span class="add-button" title="Add a new server" id="add-smon-button">+ Add</span>
<br /><br />
<div id="ajax"></div>
<div class="add-note addName alert-info" style="width: inherit; margin-right: 15px;">
You can read the description of all parameters <a href="https://haproxy-wi.org/services.py?service=smon" title="SMON service description" target="_blank">here</a>
</div>
<div id="smon-add-table" style="display: none;">
<table class="overview">
<tr>
<td colspan="2">
<p class="validateTips alert alert-success">
Form fields tag "<span class="need-field">*</span>" are required.
</p>
</td>
</tr>
<tr>
<td class="padding20">
IP
<span class="need-field">*</span>
</td>
<td>
{{ input('new-smon-ip') }}
</td>
</tr>
<tr>
<td class="padding20">
Port
<span class="need-field">*</span>
</td>
<td>
{{ input('new-smon-port', type='number', size='4') }}
</td>
</tr>
<tr>
<td class="padding20">
Enable
</td>
<td>
{{ checkbox('new-smon-enable', checked='checked') }}
</td>
</tr>
<tr>
<td class="padding20">
Protocol
</td>
<td>
{% set values = dict() %}
{% set values = {'':'', 'http':'http','https':'https'} %}
{{ select('new-smon-proto', values=values, selected='') }}
</td>
</tr>
<tr>
<td class="padding20">
URI
</td>
<td>
{{ input('new-smon-uri') }}
</td>
</tr>
<tr>
<td class="padding20">
Body
</td>
<td>
{{ input('new-smon-body') }}
</td>
</tr>
<tr>
<td class="padding20">
Telegram
</td>
<td>
<select id="new-smon-telegram">
<option value="0">Disabled</option>
{% for t in telegrams %}
<option value="{{t.0}}">{{t.2}}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td class="padding20">
Group
</td>
<td>
{{ input('new-smon-group') }}
</td>
</tr>
<tr>
<td class="padding20">
Description
</td>
<td>
{{ input('new-smon-description') }}
</td>
</tr>
</table>
{% include 'include/del_confirm.html' %}
{% else %}
<div class="main" id="smon_dashboard">
{% include 'ajax/smon_dashboard.html' %}
</div>
{% endif %}
</div>
{% endif %}
{% endblock %}

View File

@ -22,6 +22,7 @@ try:
"metrics_haproxy":"Master metrics service",
"prometheus":"Prometheus service",
"grafana-server":"Grafana service",
"smon":"Simple monitoring network ports",
"fail2ban": "Fail2ban service"}
for s, v in services_name.items():
cmd = "systemctl status %s |grep Act |awk '{print $2}'" %s

View File

@ -73,7 +73,25 @@ $( function() {
$(this).parent().find('a').css('padding-left', '20px');
$(this).find('a').css('padding-left', '30px');
$(this).find('a').css('border-left', '4px solid #5D9CEB');
}
} else if(cur_url[0] == 'smon.py' && cur_url[1].split('&')[0] == 'action=view' && link2 == 'smon.py?action=view'){
$(this).parent().css('display', 'contents');
$(this).parent().css('font-size', '13px');
$(this).parent().css('top', '0');
$(this).parent().css('left', '0');
$(this).parent().children().css('margin-left', '-20px');
$(this).parent().find('a').css('padding-left', '20px');
$(this).find('a').css('padding-left', '30px');
$(this).find('a').css('border-left', '4px solid #5D9CEB');
} else if(cur_url[0] == 'smon.py' && cur_url[1].split('&')[0] == 'action=add' && link2 == 'smon.py?action=add'){
$(this).parent().css('display', 'contents');
$(this).parent().css('font-size', '13px');
$(this).parent().css('top', '0');
$(this).parent().css('left', '0');
$(this).parent().children().css('margin-left', '-20px');
$(this).parent().find('a').css('padding-left', '20px');
$(this).find('a').css('padding-left', '30px');
$(this).find('a').css('border-left', '4px solid #5D9CEB');
}
});
});
@ -462,7 +480,6 @@ function viewLogs() {
var hour1 = $('#time_range_out_hour1').val()
var minut1 = $('#time_range_out_minut1').val()
var viewlogs = $('#viewlogs').val()
console.log(findGetParameter('viewlogs'))
if (viewlogs == null){
viewlogs = findGetParameter('viewlogs')
}
@ -918,25 +935,23 @@ function listHistroy() {
var link_text = []
for(let i = 0; i < browse_history.length; i++){
if (i == 0) {
if(browse_history[0] == browse_history[1]) {
continue
}
browse_history[0] = browse_history[1];
}
if (i == 1) {
if(browse_history[1] == browse_history[2]) {
continue
}
browse_history[1] = browse_history[2]
}
if (i == 2) {
browse_history[2] = cur_url[0]
if(cur_url[1] !== undefined) {
browse_history[2] = cur_url[0] + '?' + cur_url[1]
}else {
browse_history[2] = cur_url[0]
}
}
$( function() {
$('.menu li ul li').each(function () {
var link1 = $(this).find('a').attr('href');
var link2 = link1.split('/')[2]
if (browse_history[i] == link2) {
if (browse_history[i].split('?')[0] == link2) {
title[i] = $(this).find('a').attr('title');
link_text[i] = $(this).find('a').text();
history_link = '<li><a href="'+browse_history[i]+'" title="'+title[i]+'">'+link_text[i]+'</a></li>'
@ -955,3 +970,50 @@ function changeCurrentGroupF(){
Cookies.set('group', $('#newCurrentGroup').val(), { path: '/app', sameSite: 'Strict', Secure: 'True' });
location.reload();
}
function sort_by_status() {
$('<div id="err_services" style="clear: both;"></div>').appendTo('.main');
$('<div id="good_services" style="clear: both;"></div>').appendTo('.main');
$('<div id="dis_services" style="clear: both;"></div>').appendTo('.main');
$(".good").prependTo("#good_services");
$(".err").prependTo("#err_services");
$(".dis").prependTo("#dis_services");
$('.group').remove();
$('.group_name').detach();
window.history.pushState("SMON Dashboard", "SMON Dashboard", cur_url[0]+"?action=view&sort=by_status");
}
function showSmon(action) {
var sort = '';
if (action == 'refresh') {
try {
var location = window.location.href;
var cur_url = '/app/' + location.split('/').pop();
cur_url = cur_url.split('?');
cur_url[1] = cur_url[1].split('#')[0];
sort = cur_url[1].split('&')[1];
sort = sort.split('=')[1];
} catch (e) {
sort = '';
}
}
$.ajax( {
url: "options.py",
data: {
showsmon: 1,
sort: sort,
token: $('#token').val()
},
type: "POST",
success: function( data ) {
if (data.indexOf('error') != '-1') {
alert(data);
} else {
$("#smon_dashboard").html(data);
if (action == 'not_sort') {
window.history.pushState("SMON Dashboard", document.title, "smon.py?action=view");
} else {
window.history.pushState("SMON Dashboard", document.title, cur_url[0] + "?" + cur_url[1]);
}
}
}
} );
}

View File

@ -403,7 +403,7 @@ pre {
width: 100px;
}
.group-field, .slave-field {
min-width: 5%;
//min-width: 5%;
}
.slave-field {
padding-left: 10px;
@ -759,7 +759,7 @@ label {
#up-pannel {
margin-top: 15px;
}
.div-server, .div-server-hapwi {
.div-server, .div-server-hapwi, .bin_bout {
background-color: #fbfbfb;
border: 1px solid #A4C7F5;
height: 165px;
@ -820,7 +820,7 @@ label {
margin: 25px;
margin-left: 440px;
margin-bottom: 0;
width: 750px;
width: 778px;
display: none;
margin-top: px;
margin-bottom: 0px;
@ -845,9 +845,18 @@ label {
margin-top: 10px;
font-size: 10px;
}
.bin_bout {
width: 110px;
margin-left: 10px;
}
.bytes {
padding-top: 17px;
padding-bottom: 12px;
font-size: 17px;
font-weight: bold;
}
.update-icon {
float: right;
margin-right: 15px;
}
.span-link {
cursor: pointer;
@ -866,10 +875,9 @@ label {
.chart-container {
position: relative;
height: 300px;
width: 49%;
width: 48.8%;
float: left;
margin-top: 20px;
margin-left: 10px;
margin-left: 20px;
}
.restart, .reload, .stop, .stop-waf, .restart-waf {
padding-left: 4px;
@ -879,7 +887,6 @@ label {
}
.sort_menu {
clear: both;
margin-bottom: 20px;
}
.smon_group {
clear: both;
@ -889,10 +896,11 @@ label {
padding: 20px;
padding-left:15px;
padding-bottom: 0px;
padding-top: 10px;
}
.smon_services {
width: 190px;
height: 160px;
width: 192px;
height: 162px;
float: left;
background-color: #fbfbfb;;
margin: 10px;
@ -925,17 +933,27 @@ label {
.res_time {
height: 25px;
}
.up, .down, .disable {
.up, .down, .disable, .unknown {
height: 45px;
width: 177px;
font-size: 30px;
color: #fff;
}
.up {
background-color: #5CB85C;
color: #3c763d;
background-color: #dff0d8;
border-color: #d6e9c6;
}
.down {
background-color: red;
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
font-size: 22px;
}
.unknown {
color: #856404;
background-color: #fff3cd;
border-color: #ffeeba;
font-size: 22px;
}
.disable {
@ -955,6 +973,14 @@ label {
margin-right: -150px;
}
}
@media (max-width: 1600px) {
.ajax-server {
clear: both !important;
margin-left: 20px !important;
margin-bottom: 20px !important;
width: 89.3% !important;
}
}
@media (max-width: 1450px) {
.ajax-server, .div-backends {
clear: both !important;
@ -974,13 +1000,6 @@ label {
width: 90%;
height: 70px;
}
.ajax-server {
clear: both !important;
margin-left: 20px !important;
}
.div-backends {
width: 84.6% !important
}
#ssl_name {
width: 100px;
}
@ -1008,15 +1027,12 @@ label {
margin-right: -50px;
}
.ajax-server {
width: 88% !important;
min-width: 680px !important;
}
.haproxy-info {
width: 120px;
padding-left: 10px;
}
.div-backends {
width: 84.6% !important
}
#ssl_cert {
width: 60%;
}
@ -1025,11 +1041,6 @@ label {
#logo_span {
margin-left: -5%;
}
.chart-container {
position: relative;
height: 410px;
width: 95%;
}
.wrong-login {
margin-right: -150px;
}
@ -1037,9 +1048,6 @@ label {
width: 120px;
padding-left: 10px;
}
.div-backends {
width: 84.2% !important
}
#rows {
width: 50px;
}
@ -1053,11 +1061,6 @@ label {
margin-left: -12%;
border: none;
}
.chart-container {
position: relative;
height: 410px;
width: 95%;
}
.wrong-login {
margin-right: -260px;
}
@ -1089,11 +1092,6 @@ label {
margin-left: -12%;
border: none;
}
.chart-container {
position: relative;
height: 410px;
width: 95%;
}
.wrong-login {
margin-right: -210px;
}
@ -1119,11 +1117,15 @@ label {
.loading_full_page {
margin-left: 45%;
}
.loading_small {
.loading_small, .loading_small_bin_bout {
width: 39px;
height: 39px;
padding-left: 103%;
}
.loading_small_bin_bout {
padding-left: 30%;
padding-top: 50%;
}
.loading_small_haproxyservers {
width: 15px;
height: 15px;

View File

@ -740,6 +740,14 @@ $( function() {
var val = $(this).val();
updateSettings(id, val);
});
$( "#ajax-smon input" ).change(function() {
var id = $(this).attr('id').split('-');
updateSmon(id[2])
});
$( "#ajax-smon select" ).on('selectmenuchange',function() {
var id = $(this).attr('id').split('-');
updateSmon(id[2])
});
$('#new-ssh_enable').click(function() {
if ($('#new-ssh_enable').is(':checked')) {
$('#ssh_pass').css('display', 'none');
@ -1674,11 +1682,6 @@ function updateBackup(id) {
if ($( "#backup-type-"+id+" option:selected" ).val() == "Choose server" || $('#backup-rserver-'+id).val() == '' || $('#backup-rpath-'+id).val() == '') {
$("#ajax-backup").html('<div class="alert alert-danger" style="margin: 10px;">All fields must be completed</div>');
} else {
console.log($('#backup-credentials-'+id).val())
console.log($('#backup-rpath-'+id).val())
console.log($('#backup-type-'+id).val())
console.log($('#backup-server-'+id).text())
console.log($('#backup-rserver-'+id).val())
$.ajax( {
url: "options.py",
data: {
@ -1712,6 +1715,45 @@ function updateBackup(id) {
} );
}
}
function updateSmon(id) {
$('#error').remove();
var enable = 0;
if ($('#smon-enable-'+id).is(':checked')) {
enable = '1';
}
$.ajax( {
url: "options.py",
data: {
updateSmonIp: $('#smon-ip-'+id).val(),
updateSmonPort: $('#smon-port-'+id).val(),
updateSmonEn: enable,
updateSmonHttp: $('#smon-proto1-'+id).text(),
updateSmonBody: $('#smon-body-'+id).val(),
updateSmonTelegram: $('#smon-telegram-'+id).val(),
updateSmonGroup: $('#smon-group-'+id).val(),
updateSmonDesc: $('#smon-desc-'+id).val(),
id: id,
token: $('#token').val()
},
type: "POST",
success: function( data ) {
data = data.replace(/\s+/g,' ');
if (data.indexOf('error') != '-1') {
$("#ajax").html('<div class="alert alert-danger" style="margin: 10px;">'+data+'</div>');
$('#errorMess').click(function() {
$('#error').remove();
$('.alert-danger').remove();
});
} else {
$('.alert-danger').remove();
$("#smon-"+id).addClass( "update", 1000 );
setTimeout(function() {
$( "#smon-"+id ).removeClass( "update" );
}, 2500 );
}
}
} );
}
function showApacheLog(serv) {
var rows = $('#rows').val()
var grep = $('#grep').val()