v1.10.2.3

Afax, bugs, design
pull/19/head
Aidaho12 2018-04-11 09:30:46 +06:00
parent 541bfb2b2f
commit 23f45cb30e
10 changed files with 196 additions and 197 deletions

View File

@ -42,7 +42,7 @@ print('<option value="show">Show</option>'
'</td><td>'
'<input type="checkbox" name="save" id="save" value="123" title="Save changes after restart">'
'</td><td>'
'<a class="ui-button ui-widget ui-corner-all" id="show" title="Show stats" onclick="showRuntime()">Show</a>'
'<a class="ui-button ui-widget ui-corner-all" id="show" title="Enter" onclick="showRuntime()">Enter</a>'
'</td></form>'
'</tr></table>'
'<div id="ajax">'

View File

@ -160,7 +160,7 @@ def head(title):
def links():
print('<nav class="menu">'
'<ul>'
'<li><a title="Statistics, monitoring and logs" class="stats">Stats</a>'
'<li><span style="color: #fff" title="Statistics, monitoring and logs" class="stats">Stats</span>'
'<ul>'
'<li><a href=/cgi-bin/overview.py title="Server and service status" class="overview-link">Overview</a> </li>'
'<li><a href=/cgi-bin/viewsttats.py title="View Stats" class="stats">Stats</a> </li>'
@ -169,7 +169,7 @@ def links():
'</ul>'
'</li>'
'<li><a href=/cgi-bin/edit.py title="Runtime API" class="runtime">Runtime API</a> </li>'
'<li><a class="config-show">Configs</a>'
'<li><span style="color: #fff" title="Actions with configs" class="config-show">Configs</span>'
'<ul>'
'<li><a href=/cgi-bin/configshow.py title="Show Config" class="config-show">Show</a></li> '
'<li><a href=/cgi-bin/diff.py title="Compare Configs" class="compare">Compare</a></li>')
@ -180,7 +180,7 @@ def links():
'<li><a href=/cgi-bin/config.py title="Edit Config" class="edit">Edit</a> </li>')
print('</ul></li>')
if is_admin(level = 1):
print('<li><a class="version">Versions</a>'
print('<li><span style="color: #fff" title="Actions with configs" class="version">Versions</span>'
'<ul>'
'<li><a href=/cgi-bin/configver.py title="Upload old versions configs" class="upload">Upload</a></li>')
if is_admin():
@ -191,7 +191,7 @@ def links():
show_login_links()
print('</ul>'
'</nav>'
'<div class="copyright-menu">HAproxy-WI v1.10.2.2</div>')
'<div class="copyright-menu">HAproxy-WI v1.10.2.3</div>')
def show_login_links():
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
@ -214,10 +214,10 @@ def get_auto_refresh(h2):
print('<h2>')
print('<span>%s</span>' % h2)
print('<span class="auto-refresh">'
'<a id="0"><img style="margin-top: 10px; margin-left: -23px; position: fixed;" src=/image/pic/update.png alt="restart" class="icon"> Auto-refresh</a>'
'<a id="1" style="display: none;"><img style="margin-top: 10px; margin-left: -23px; position: fixed;" src=/image/pic/update.png alt="restart" class="icon"> Auto-refresh</a>'
'<a onclick="pauseAutoRefresh()" title="Pause auto-refresh" class="auto-refresh-pause" style="display: none;"></a>'
'<a onclick="pauseAutoResume()" title="Resume auto-refresh" class="auto-refresh-resume" style="display: none;"></a>'
'<a id="0"><img style="margin-top: 3px; margin-left: -23px; position: fixed;" src=/image/pic/update.png alt="restart" class="icon"> Auto-refresh</a>'
'<a id="1" style="display: none;"><img style="margin-top: 3px; margin-left: -23px; position: fixed;" src=/image/pic/update.png alt="restart" class="icon"> Auto-refresh</a>'
'<a onclick="pauseAutoRefresh()" title="Pause auto-refresh" class="auto-refresh-pause" style="display: none; margin-top: 4px;"></a>'
'<a onclick="pauseAutoResume()" title="Resume auto-refresh" class="auto-refresh-resume" style="display: none; margin-top: 4px;"></a>'
'</span></h2>'
'<div class="auto-refresh-div">'
'<div class="auto-refresh-head">'

View File

@ -28,7 +28,7 @@ print('<table class="overview">'
'<td class="padding10">'
'<form action="logs.py" method="get">'
'<select autofocus required name="serv" id="serv">'
'<option disabled>Choose server</option>')
'<option disabled selected>Choose server</option>')
funct.choose_only_select(serv)

View File

@ -3,6 +3,7 @@ import html
import cgi
import os
import funct
import ovw
import configparser
from datetime import datetime
from pytz import timezone
@ -13,117 +14,15 @@ import matplotlib.pyplot as plt
form = cgi.FieldStorage()
serv = form.getvalue('serv')
servNew = form.getvalue('serNew')
funct.head("Show HAproxy config")
funct.check_config()
funct.check_login()
funct.chooseServer("map.py", "Show HAproxy map", "n", onclick="showMap()")
path_config = "haproxy-webintarface.config"
config = configparser.ConfigParser()
config.read(path_config)
time_zone = config.get('main', 'time_zone')
hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir')
haproxy_config_path = config.get('haproxy', 'haproxy_config_path')
stats_port= config.get('haproxy', 'stats_port')
fullpath = config.get('main', 'fullpath')
if serv is not None:
fmt = "%Y-%m-%d.%H:%M:%S"
now_utc = datetime.now(timezone(time_zone))
cfg = hap_configs_dir + serv + "-" + now_utc.strftime(fmt) + ".cfg"
funct.chooseServer("map.py", "Show HAproxy map", "n")
def is_neighbors(G, neighbor):
for line in nx.generate_edgelist(G, data=False):
if neighbor in line:
return True
break
if form.getvalue('serv') is not None and form.getvalue('open') is not None :
print('<a name="map"></a>')
print("<h3>Map from %s</h3><br />" % serv)
G = nx.DiGraph()
funct.get_config(serv, cfg)
conf = open(cfg, "r")
node = ""
line_new2 = [1,""]
i = 1200
k = 1200
j = 0
m = 0
for line in conf:
if "listen" in line or "frontend" in line:
if "stats" not in line:
node = line
i = i - 500
if line.find("backend") == 0:
node = line
i = i - 500
G.add_node(node,pos=(k,i),label_pos=(k,i+150))
if "bind" in line:
bind = line.split(":")
if stats_port not in bind[1]:
bind[1] = bind[1].strip(' ')
bind = bind[1].split("crt")
node = node.strip(' \t\n\r')
node = node + ":" + bind[0]
G.add_node(node,pos=(k,i),label_pos=(k,i+150))
if "server " in line or "use_backend" in line or "default_backend" in line and "stats" not in line:
if "timeout" not in line and "default-server" not in line and "#use_backend" not in line and "stats" not in line:
i = i - 300
j = j + 1
if "check" in line:
line_new = line.split("check")
else:
line_new = line.split("if ")
if "server" in line:
line_new1 = line_new[0].split("server")
line_new[0] = line_new1[1]
line_new2 = line_new[0].split(":")
line_new[0] = line_new2[0]
line_new[0] = line_new[0].strip(' \t\n\r')
line_new2[1] = line_new2[1].strip(' \t\n\r')
if j % 2 == 0:
G.add_node(line_new[0],pos=(k+250,i-350),label_pos=(k+225,i-100))
else:
G.add_node(line_new[0],pos=(k-250,i-50),label_pos=(k-225,i+180))
if line_new2[1] != "":
G.add_edge(node, line_new[0], port=line_new2[1])
else:
G.add_edge(node,line_new[0])
os.system("/bin/rm -f " + cfg)
os.chdir("%s/cgi-bin/" % fullpath)
pos=nx.get_node_attributes(G,'pos')
pos_label=nx.get_node_attributes(G,'label_pos')
edge_labels = nx.get_edge_attributes(G,'port')
try:
plt.figure(10,figsize=(9.5,15))
nx.draw(G, pos, with_labels=False, font_weight='bold', width=3, alpha=0.1,linewidths=5)
nx.draw_networkx_nodes(G,pos, node_color="skyblue", node_size=100, alpha=0.8, node_shape="p")
nx.draw_networkx_labels(G,pos=pos_label, alpha=1, font_color="green", font_size=10)
nx.draw_networkx_edges(G,pos, width=0.5,alpha=0.5, edge_color="#5D9CEB",arrows=False)
nx.draw_networkx_edge_labels(G, pos,label_pos=0.5,font_color="blue", labels=edge_labels, font_size=8)
plt.savefig("map.png")
plt.show()
except Exception as e:
print("!!! There was an issue, " + str(e))
commands = [ "mv %s/cgi-bin/map.png %s" % (fullpath, fullpath)]
funct.ssh_command("localhost", commands)
print('<img src="/map.png" alt="map">')
print('<div id="ajax">')
if form.getvalue('serv') is not None:
ovw.get_map(serv)
print('</div>')
funct.footer()

View File

@ -4,6 +4,7 @@ import cgi
import json
import subprocess
import funct
import ovw
import configparser
options = [ "acl", "http-request", "http-response", "set-uri", "set-url", "set-header", "add-header", "del-header", "replace-header", "path_beg", "url_beg()", "urlp_sub()", "tcpka", "tcplog", "forwardfor", "option" ]
@ -70,28 +71,9 @@ if form.getvalue('action') is not None and serv is not None:
funct.ssh_command(serv, commands)
else:
print("Bad config, check please")
if serv is not None and form.getvalue('rows') is not None:
rows = form.getvalue('rows')
grep = form.getvalue('grep')
if grep is not None:
grep_act = '|grep'
else:
grep_act = ''
grep = ''
syslog_server_enable = config.get('logs', 'syslog_server_enable')
if syslog_server_enable is None or syslog_server_enable == "0":
local_path_logs = config.get('logs', 'local_path_logs')
syslog_server = serv
commands = [ 'sudo tail -%s %s %s %s' % (rows, local_path_logs, grep_act, grep) ]
else:
commands = [ 'sudo tail -%s /var/log/%s/syslog.log %s %s' % (rows, serv, grep_act, grep) ]
syslog_server = config.get('logs', 'syslog_server')
print('<div id"logs">')
funct.ssh_command(syslog_server, commands, show_log="1")
print('</div>')
if form.getvalue('act') == "overview":
ovw.get_overview()
if serv is not None and form.getvalue('act') == "stats":
import requests
@ -119,10 +101,31 @@ if serv is not None and form.getvalue('act') == "stats":
data = response.content
print(data.decode('utf-8'))
if form.getvalue('act') == "overview":
import ovw
ovw.get_overview()
if serv is not None and form.getvalue('rows') is not None:
rows = form.getvalue('rows')
grep = form.getvalue('grep')
if grep is not None:
grep_act = '|grep'
else:
grep_act = ''
grep = ''
syslog_server_enable = config.get('logs', 'syslog_server_enable')
if syslog_server_enable is None or syslog_server_enable == "0":
local_path_logs = config.get('logs', 'local_path_logs')
syslog_server = serv
commands = [ 'sudo tail -%s %s %s %s' % (rows, local_path_logs, grep_act, grep) ]
else:
commands = [ 'sudo tail -%s /var/log/%s/syslog.log %s %s' % (rows, serv, grep_act, grep) ]
syslog_server = config.get('logs', 'syslog_server')
print('<div id"logs">')
funct.ssh_command(syslog_server, commands, show_log="1")
print('</div>')
if serv is not None and form.getvalue('act') == "showMap":
ovw.get_map(serv)
if form.getvalue('servaction') is not None:
server_state_file = config.get('haproxy', 'server_state_file')
haproxy_sock = config.get('haproxy', 'haproxy_sock')

View File

@ -2,9 +2,6 @@
import html
import cgi
import funct
import configparser
import json
import listserv as listhap
import ovw
funct.head("Overview")

View File

@ -2,13 +2,19 @@ import funct
import configparser
import json
path_config = "haproxy-webintarface.config"
config = configparser.ConfigParser()
config.read(path_config)
time_zone = config.get('main', 'time_zone')
cgi_path = config.get('main', 'cgi_path')
fullpath = config.get('main', 'fullpath')
stats_port= config.get('haproxy', 'stats_port')
haproxy_config_path = config.get('haproxy', 'haproxy_config_path')
status_command = config.get('haproxy', 'status_command')
hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir')
def get_overview():
path_config = "haproxy-webintarface.config"
config = configparser.ConfigParser()
config.read(path_config)
haproxy_config_path = config.get('haproxy', 'haproxy_config_path')
status_command = config.get('haproxy', 'status_command')
cgi_path = config.get('main', 'cgi_path')
USERS = cgi_path + '/users'
try:
@ -105,4 +111,103 @@ def get_overview():
funct.ssh_command(listhap.get(i), commands1)
print('</pre></td></tr>')
print('<tr></table>')
print('<tr></table>')
def get_map(serv):
import os
from datetime import datetime
from pytz import timezone
import networkx as nx
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
fmt = "%Y-%m-%d.%H:%M:%S"
now_utc = datetime.now(timezone(time_zone))
cfg = hap_configs_dir + serv + "-" + now_utc.strftime(fmt) + ".cfg"
print('<center>')
print("<h3>Map from %s</h3><br />" % serv)
G = nx.DiGraph()
funct.get_config(serv, cfg)
conf = open(cfg, "r")
node = ""
line_new2 = [1,""]
i = 1200
k = 1200
j = 0
m = 0
for line in conf:
if "listen" in line or "frontend" in line:
if "stats" not in line:
node = line
i = i - 500
if line.find("backend") == 0:
node = line
i = i - 500
G.add_node(node,pos=(k,i),label_pos=(k,i+150))
if "bind" in line:
bind = line.split(":")
if stats_port not in bind[1]:
bind[1] = bind[1].strip(' ')
bind = bind[1].split("crt")
node = node.strip(' \t\n\r')
node = node + ":" + bind[0]
G.add_node(node,pos=(k,i),label_pos=(k,i+150))
if "server " in line or "use_backend" in line or "default_backend" in line and "stats" not in line:
if "timeout" not in line and "default-server" not in line and "#use_backend" not in line and "stats" not in line:
i = i - 300
j = j + 1
if "check" in line:
line_new = line.split("check")
else:
line_new = line.split("if ")
if "server" in line:
line_new1 = line_new[0].split("server")
line_new[0] = line_new1[1]
line_new2 = line_new[0].split(":")
line_new[0] = line_new2[0]
line_new[0] = line_new[0].strip(' \t\n\r')
line_new2[1] = line_new2[1].strip(' \t\n\r')
if j % 2 == 0:
G.add_node(line_new[0],pos=(k+250,i-350),label_pos=(k+225,i-100))
else:
G.add_node(line_new[0],pos=(k-250,i-50),label_pos=(k-225,i+180))
if line_new2[1] != "":
G.add_edge(node, line_new[0], port=line_new2[1])
else:
G.add_edge(node,line_new[0])
os.system("/bin/rm -f " + cfg)
os.chdir(cgi_path)
pos=nx.get_node_attributes(G,'pos')
pos_label=nx.get_node_attributes(G,'label_pos')
edge_labels = nx.get_edge_attributes(G,'port')
try:
plt.figure(10,figsize=(9.5,15))
nx.draw(G, pos, with_labels=False, font_weight='bold', width=3, alpha=0.1,linewidths=5)
nx.draw_networkx_nodes(G,pos, node_color="skyblue", node_size=100, alpha=0.8, node_shape="p")
nx.draw_networkx_labels(G,pos=pos_label, alpha=1, font_color="green", font_size=10)
nx.draw_networkx_edges(G,pos, width=0.5,alpha=0.5, edge_color="#5D9CEB",arrows=False)
nx.draw_networkx_edge_labels(G, pos,label_pos=0.5,font_color="blue", labels=edge_labels, font_size=8)
plt.savefig("map.png")
plt.show()
except Exception as e:
print("!!! There was an issue, " + str(e))
commands = [ "rm -f "+fullpath+"/map*.png", "mv %s/map.png %s/map%s.png" % (cgi_path, fullpath, now_utc.strftime(fmt)) ]
funct.ssh_command("localhost", commands)
print('<img src="/map%s.png" alt="map">' % now_utc.strftime(fmt))
#commands = [ "rm -f %s/map%s.png" % (fullpath, now_utc.strftime(fmt))]
#funct.ssh_command("localhost", commands)

View File

@ -30,7 +30,7 @@
position: fixed;
z-index: 1031;
top: 15px;
right: 55px;
right: 175px;
}
#nprogress .spinner-icon {
width: 18px;

View File

@ -28,7 +28,7 @@ function setRefreshInterval(interval) {
if (interval == "0") {
Cookies.remove('auto-refresh');
pauseAutoRefresh();
$('.auto-refresh').append('<img style="margin-top: 10px; margin-left: -110px; position: fixed;" src=/image/pic/update.png alt="restart" class="icon">');
$('.auto-refresh').append('<img style="margin-top: 3px; margin-left: -110px; position: fixed;" src=/image/pic/update.png alt="restart" class="icon">');
$('#1').text('Auto-refresh');
$('#0').text('Auto-refresh');
$('.auto-refresh-pause').css('display', 'none');
@ -80,6 +80,12 @@ function hideAutoRefreshDiv() {
$('#0').css("display", "inline");
});
}
$( document ).ajaxSend(function( event, request, settings ) {
NProgress.start();
});
$( document ).ajaxComplete(function( event, request, settings ) {
NProgress.done();
});
function showOverview() {
$.ajax( {
url: "options.py",
@ -87,12 +93,6 @@ function showOverview() {
act: "overview",
},
type: "GET",
beforeSend: function () {
NProgress.start();
},
complete: function () {
NProgress.done();
},
success: function( data ) {
var form = $("#ajax").html();
$("#ajax").html(data);
@ -108,12 +108,6 @@ function showStats() {
serv: $("#serv").val()
},
type: "GET",
beforeSend: function () {
NProgress.start();
},
complete: function () {
NProgress.done();
},
success: function( data ) {
var form = $("#ajax").html();
$("#ajax").html(data);
@ -130,18 +124,29 @@ function showLog() {
grep: $("#grep").val(),
},
type: "GET",
beforeSend: function () {
NProgress.start();
},
complete: function () {
NProgress.done();
},
success: function( data ) {
var form = $("#ajax").html();
$("#ajax").html(data);
}
} );
}
function showMap() {
var unique = $.now();
$.ajax( {
url: "options.py",
data: {
serv: $("#serv").val(),
act: "showMap"
},
type: "GET",
success: function( data ) {
var form = $("#ajax").html();
$("#ajax").html(data);
window.history.pushState("Map", "Map", cur_url[0]+"?serv="+$("#serv").val());
}
} );
}
function showRuntime() {
if($('#save').prop('checked')) {
saveCheck = "on";
@ -157,12 +162,6 @@ function showRuntime() {
save: saveCheck
},
type: "GET",
beforeSend: function () {
NProgress.start();
},
complete: function () {
NProgress.done();
},
success: function( data ) {
var form = $("#ajax").html();
$("#ajax").html(data);
@ -178,12 +177,6 @@ function showCompare() {
right: $("#right").val()
},
type: "GET",
beforeSend: function () {
NProgress.start();
},
complete: function () {
NProgress.done();
},
success: function( data ) {
var form = $("#ajax").html();
$("#ajax").html(data);
@ -199,12 +192,6 @@ function showConfig() {
act: "configShow"
},
type: "GET",
beforeSend: function () {
NProgress.start();
},
complete: function () {
NProgress.done();
},
success: function( data ) {
var form = $("#ajax").html();
$("#ajax").html(data);
@ -214,6 +201,15 @@ function showConfig() {
}
$( function() {
$( "#serv" ).on('selectmenuchange',function() {
$("#show").css("pointer-events", "inherit");
$("#show").css("cursor", "pointer");
});
if ($( "#serv option:selected" ).val() == "Choose server") {
$("#show").css("pointer-events", "none");
$("#show").css("cursor", "not-allowed");
}
var pause = '<a onclick="pauseAutoRefresh()" title="Pause auto-refresh" class="auto-refresh-pause"></a>'
var autoRefresh = Cookies.get('auto-refresh');

View File

@ -19,9 +19,6 @@ h2 {
margin-top: 0px;
margin-bottom: 0px;
}
h2 span {
width: 300px;
}
h3 {
margin-top: 10px;
margin-bottom: 0px;
@ -90,7 +87,10 @@ pre {
padding-bottom: 10px;
}
.auto-refresh {
margin-left: 86%;
margin-left: auto;
float: right;
margin-top: 5px;
margin-right: 30px;
}
.auto-refresh a {
color: #fff !important;
@ -112,14 +112,13 @@ pre {
cursor: pointer;
}
.auto-refresh-head {
margin-top: 0;
font-size: 16px;
color: #2d2d2d;
font-weight: bold;
margin-left: 77%;
margin-left: 83%;
}
.auto-refresh-interval {
float: left;
float: right;
padding: 0px 15px;
margin-left: 75%;
}