Welcome, Jinja2!
code is optimized
pull/19/head
Aidaho12 2018-05-05 18:40:41 +06:00
parent 8c8ddc1820
commit ef9ffe530c
38 changed files with 1962 additions and 1436 deletions

View File

@ -5,20 +5,37 @@ import os
from configparser import ConfigParser, ExtendedInterpolation from configparser import ConfigParser, ExtendedInterpolation
import funct import funct
import sql import sql
import http
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('add.html')
form = cgi.FieldStorage()
funct.head("Add") print('Content-type: text/html\n')
funct.check_config()
funct.check_login() funct.check_login()
funct.page_for_admin(level = 2)
try:
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
user = sql.get_user_name_by_uuid(user_id.value)
servers = sql.get_dick_permit()
except:
pass
output_from_parsed_template = template.render(title = "Add",
role = sql.get_user_role_by_uuid(user_id.value),
user = user,
selects = servers,
add = form.getvalue('add'),
conf_add = form.getvalue('conf'))
print(output_from_parsed_template)
path_config = "haproxy-webintarface.config" path_config = "haproxy-webintarface.config"
config = ConfigParser(interpolation=ExtendedInterpolation()) config = ConfigParser(interpolation=ExtendedInterpolation())
config.read(path_config) config.read(path_config)
funct.page_for_admin(level = 2)
hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir')
cert_path = config.get('haproxy', 'cert_path') cert_path = config.get('haproxy', 'cert_path')
listhap = sql.get_dick_permit()
form = cgi.FieldStorage()
if form.getvalue('mode') is not None: if form.getvalue('mode') is not None:
serv = form.getvalue('serv') serv = form.getvalue('serv')
@ -54,9 +71,7 @@ if form.getvalue('mode') is not None:
ssl_check = " ssl verify" ssl_check = " ssl verify"
else: else:
ssl_check = "" ssl_check = ""
if not ip and form.getvalue('port') is not None: if not ip and form.getvalue('port') is not None:
bind = " bind *:"+ port + " " + ssl + "\n" bind = " bind *:"+ port + " " + ssl + "\n"
elif port is not None: elif port is not None:
@ -112,369 +127,9 @@ if form.getvalue('mode') is not None:
if master[0] != None: if master[0] != None:
funct.upload_and_restart(master[0], cfg) funct.upload_and_restart(master[0], cfg)
if funct.upload_and_restart(serv, cfg): funct.upload_and_restart(serv, cfg)
print('<meta http-equiv="refresh" content="5; url=add.py?add=%s&conf=%s">' % (name, config_add)) print('<meta http-equiv="refresh" content="5; url=add.py?add=%s&conf=%s">' % (name, config_add))
print('</div>') print('</div>')
if form.getvalue('add') is not None:
print('<div class="added"><h3 class="addSuc"> ' + form.getvalue('add') + ' was successfully added</h3>')
print('<div class="line3">')
print(form.getvalue('conf'))
print('</div></div>')
print('<div id="tabs">'
'<ul>'
'<li><a href="#listen">Listen</a></li>'
'<li><a href="#frontend">Frontend</a></li>'
'<li><a href="#backend">Backend</a></li>'
'<li><a href="#ssl">SSL certificates</a></li>'
'</ul>'
'<div id="listen">'
'<form name="add-listner" action="add.py">'
'<table>'
'<caption><h3 style="margin-left: 20px; margin-bottom: 10px;">Add listen</h3></caption>'
'<tr>'
'<td class="addName">Select server: </td>'
'<td class="addOption">'
'<select required name="serv" id="serv">'
'<option disabled selected>Choose server</option>')
for i in listhap:
print('<option value="%s">%s</option>' % (i[2], i[1]))
print('</select>'
'<div class="tooltip tooltipTop"><b>Note:</b> If you reconfigure Master server, Slave will reconfigured automatically</div>'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">Name:</td>'
'<td class="addOption">'
'<input type="text" name="listner" id="name" required title="Name Listner" placeholder="web_80" class="form-control">'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">IP and Port:</td>'
'<td class="addOption">'
'<input type="text" name="ip" id="ip" title="" size="15" placeholder="172.28.0.1" class="form-control"><b>:</b>'
'<input type="number" name="port" id="listen-port" required title="Port for bind listen" size="5" placeholder="8080" class="form-control">'
'<div class="tooltip tooltipTop">IP for bind listner, <b>if empty will be assignet on all IPs</b>. Start typing ip, or press down.<br>If you use <b>VRRP keep in blank</b>. If you assign an IP, the slave will not start</div>'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">Mode: </td>'
'<td class="addOption">'
'<select required name="mode" id="listen-mode-select">'
'<option value="http" selected>http</option>'
'<option value="tcp">tcp</option>'
'</select>'
'<span id="https-listen-span">'
'<label for="https-listen" style="margin-top: 5px;" title="Enable ssl">ssl?</label>'
'<input type="checkbox" id="https-listen" name="ssl" value="https" >'
'</span>'
'<div id="https-hide-listen" style="display: none;">'
'<br /><span class="tooltip tooltipTop">Enter name to pem file, or press down:</span><br />'
'<input type="text" name="cert" placeholder="some_cert.pem" class="form-control" size="39" id="path-cert-listen"> or upload: <input type="file" name="file"><br />'
'<label for="ssl-check-listen" style="margin-top: 5px;">Disable ssl verify on servers?</label><input type="checkbox" id="ssl-check-listen" name="ssl-check" value="ssl-check" checked>'
'</div>'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">Balance: </td>'
'<td class="addOption">'
'<select required name="balance">'
'<option value="roundrobin" selected>roundrobin</option>'
'<option value="source">source</option>'
'<option value="leastconn">leastconn</option>'
'<option value="first">first</option>'
'<option value="rdp-cookie">rdp-cookie</option>'
'</select>'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">Optinons:</td>'
'<td class="addOption">'
'<label for="options-listen-show" style="margin-top: 5px;" title="Set options">Set</label><input type="checkbox" id="options-listen-show">'
'<div id="options-listen-show-div" style="display: none;">'
'<div class="tooltip">'
'<span style="padding-right: 10px;" class="form-control">Start typing options: </span>'
'<input type="text" id="options" class="form-control">'
'<span style="padding-left: 10px;">'
'or press down. <a href="http://cbonte.github.io/haproxy-dconv/1.7/configuration.html" target="_blanck" style="color: #23527c" title="HAproxy docs">Read more about options</a>'
'</span>'
'</div>'
'<textarea name="option" title="Options thru" id="optionsInput" cols=80 placeholder="acl test hdr_beg(host) -i some_host"></textarea>'
'</div>'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">Servers:</td>'
'<td class="addOption">'
'<textarea name="servers" required title="Backend servers" cols=80 placeholder="hostname ip:port"></textarea>'
'<div>'
'<label for="controlgroup-listen-show" style="margin-top: 5px;" title="Change default check">Cusmot check params</label>'
'<input type="checkbox" id="controlgroup-listen-show" name="default-check" value="1">'
'<span class="tooltip tooltipTop"> Default params: inter 2000 rise 2 fall 5</span>'
'</div>'
'<div class="controlgroup" id="controlgroup-listen" style="display: none;">'
'<label for="check-servers-listen" title="Ebable servers check">Check</label>'
'<input type="checkbox" id="check-servers-listen" name="check-servers" checked value="1">'
'<select name="inter" id="inter-listen">'
'<option value="inter" disabled selected>inter</option>'
'<option value="1000">1000</option>'
'<option value="2000">2000</option>'
'<option value="3000">3000</option>'
'</select>'
'<select name="rise" id="rise-listen">'
'<option value="rise" disabled selected>rise</option>'
'<option value="1">1</option>'
'<option value="2">2</option>'
'<option value="3">3</option>'
'</select>'
'<select name="fall" id="fall-listen">'
'<option value="fall" disabled selected>fall</option>'
'<option value="4">4</option>'
'<option value="5">5</option>'
'<option value="6">6</option>'
'</select>'
'</div>'
'</td>'
'</tr>'
'<tr>'
'<td class="addButton">')
funct.get_button("Add Listen")
print('</td>'
'</tr>'
'</form>'
'</table></div>'
'<!-- Second tabs -->'
'<div id="frontend">'
'<form name="add-frontend" action="add.py">'
'<table>'
'<caption><h3 style="margin-left: 20px; margin-bottom: 10px;">Add frontend</h3></caption>'
'<tr>'
'<td class="addName">Select server: </td>'
'<td class="addOption">'
'<select required name="serv" id="serv2">'
'<option disabled selected>Choose server</option>')
for i in listhap:
print('<option value="%s">%s</option>' % (i[2], i[1]))
print('</select>'
'<div class="tooltip tooltipTop"><b>Note:</b> If you reconfigure Master server, Slave will reconfigured automatically</div>'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">Name:</td>'
'<td class="addOption">'
'<input type="text" name="frontend" id="frontend" required title="Name frontend" placeholder="web_80" class="form-control">'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">IP and Port:</td>'
'<td class="addOption">'
'<input type="text" name="ip" id="ip1" size="15" placeholder="172.28.0.1" class="form-control"><b>:</b>'
'<input type="number" name="port" required title="Port for bind frontend" placeholder="8080" class="form-control">'
'<div class="tooltip tooltipTop">IP for bind listner, <b>if empty will be assignet on all IPs</b>. Start typing ip, or press down.<br>If you use <b>VRRP keep in blank</b>. If you assign an IP, the slave will not start</div>'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">Mode: </td>'
'<td class="addOption">'
'<select required name="mode" id="frontend-mode-select">'
'<option value="http" selected>http</option>'
'<option value="tcp">tcp</option>'
'</select>'
'<span id="https-frontend-span">'
'<label for="https-frontend" style="margin-top: 5px;">ssl?</label>'
'<input type="checkbox" id="https-frontend" name="ssl" value="https">'
'</span>'
'<div id="https-hide-frontend" style="display: none;">'
'<br /><span class="tooltip tooltipTop">Enter name to pem file, or press down:</span><br />'
'<input type="text" name="cert" placeholder="some_cert.pem" class="form-control" size="39" id="path-cert-frontend">'
'</div>'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">Optinons:</td>'
'<td class="addOption">'
'<label for="options-frontend-show" style="margin-top: 5px;" title="Set options">Set</label><input type="checkbox" id="options-frontend-show">'
'<div id="options-frontend-show-div" style="display: none;">'
'<div style="font-size: 12px; padding-bottom: 10px;">'
'<span style="padding-right: 10px;">Start typing options: </span>'
'<input type="text" id="options1" class="form-control">'
'<span style="padding-left: 10px;">'
'or press down. <a href="http://cbonte.github.io/haproxy-dconv/1.7/configuration.html" target="_blanck" style="color: #23527c" title="HAproxy docs">Read more about options</a>'
'</span>'
'</div>'
'<textarea name="option" title="Options thru" cols=80 id="optionsInput1" placeholder="acl test hdr_beg(host) -i some_host"></textarea>'
'</div>'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">Default backend</td>'
'<td class="addOption">'
'<div style="font-size: 12px; padding-bottom: 10px;">Start typing backend, or press down</div>'
'<input name="backend" id="backends" required size="30" placeholder="some_backend" class="form-control">'
'<span style="font-size: 12px; padding-left: 10px;"> .</span>'
'<p style="font-size: 12px"><b>Note:</b> If backend don\'t exist, you must <a href="#" style="color: #23527c" title="Create backend" id="redirectBackend">create backend first</a>.</p>'
'</td>'
'</tr>'
'<tr>'
'<td class="addButton">')
funct.get_button("Add Frontend")
print('</td>'
'</tr>'
'</form></table>'
'</div>'
'<!-- Third tabs -->'
'<div id="backend">'
'<form name="add-backend" action="add.py">'
'<table>'
'<caption><h3 style="margin-left: 20px; margin-bottom: 10px;">Add backend</h3></caption>'
'<tr>'
'<td class="addName">Select server: </td>'
'<td class="addOption">'
'<select required name="serv" id="serv3">'
'<option disabled selected>Choose server</option>')
for i in listhap:
print('<option value="%s">%s</option>' % (i[2], i[1]))
print('</select>'
'<div class="tooltip tooltipTop"><b>Note:</b> If you reconfigure Master server, Slave will reconfigured automatically</div>'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">Name:</td>'
'<td class="addOption">'
'<input type="text" name="backend" id="backend" required title="Name backend" placeholder="web_80" class="form-control">'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">Mode: </td>'
'<td class="addOption">'
'<select required name="mode" id="backend-mode-select">'
'<option value="http" selected>http</option>'
'<option value="tcp">tcp</option>'
'</select>'
'<span id="https-backend-span">'
'<label for="https-backend" style="margin-top: 5px;">Ssl enabled on frontend?</label>'
'<input type="checkbox" id="https-backend" name="ssl" value="https">'
'</span>'
'<div id="https-hide-backend" style="display: none;">'
'<br /><span class="tooltip tooltipTop">Enter name to pem file, or press down:</span><br />'
'<input type="text" name="cert" placeholder="some_cert.pem" class="form-control" size="39" id="path-cert-backend"><br />'
'<label for="ssl-check" style="margin-top: 5px;">Disable ssl verify on servers?</label><input type="checkbox" id="ssl-check" name="ssl-check" value="ssl-check" checked>'
'</div>'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">Balance: </td>'
'<td class="addOption">'
'<select required name="balance">'
'<option value="roundrobin" selected>roundrobin</option>'
'<option value="source">source</option>'
'<option value="leastconn">leastconn</option>'
'<option value="first">first</option>'
'<option value="rdp-cookie">rdp-cookie</option>'
'</select>'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">Optinons:</td>'
'<td class="addOption">'
'<label for="options-backend-show" style="margin-top: 5px;" title="Set options">Set</label><input type="checkbox" id="options-backend-show">'
'<div id="options-backend-show-div" style="display: none;">'
'<div style="font-size: 12px; padding-bottom: 10px;">'
'<span style="padding-right: 10px;">Start typing options: </span>'
'<input type="text" id="options2" class="form-control">'
'<span style="padding-left: 10px;">'
'or press down. <a href="http://cbonte.github.io/haproxy-dconv/1.7/configuration.html" target="_blanck" style="color: #23527c" title="HAproxy docs">Read more about options</a>'
'</span>'
'</div>'
'<textarea name="option" title="Options thru" cols=80 id="optionsInput2" placeholder="acl test hdr_beg(host) -i some_host"></textarea>'
'</div>'
'</td>'
'</tr>'
'<tr>'
'<td class="addName">Servers:</td>'
'<td class="addOption">'
'<textarea name="servers" title="Backend servers" required cols=80 placeholder="hostname ip:port"></textarea>'
'<div>'
'<label for="controlgroup-backend-show" style="margin-top: 5px;" title="Change default check" >Cusmot check params</label>'
'<input type="checkbox" id="controlgroup-backend-show" name="default-check">'
'<span class="tooltip tooltipTop"> Default params: inter 2000 rise 2 fall 5</span>'
'</div>'
'<div class="controlgroup" id="controlgroup-backend" style="display: none;">'
'<label for="check-servers-backend" title="Ebable servers check">Check</label>'
'<input type="checkbox" id="check-servers-backend" name="check-servers" checked value="1">'
'<select name="inter" id="inter-backend">'
'<option value="inter" disabled selected>inter</option>'
'<option value="1000">1000</option>'
'<option value="2000">2000</option>'
'<option value="3000">3000</option>'
'</select>'
'<select name="rise" id="rise-backend">'
'<option value="rise" disabled selected>rise</option>'
'<option value="1">1</option>'
'<option value="2">2</option>'
'<option value="3">3</option>'
'</select>'
'<select name="fall" id="fall-backend">'
'<option value="fall" disabled selected>fall</option>'
'<option value="4">4</option>'
'<option value="5">5</option>'
'<option value="6">6</option>'
'</select>'
'</div>'
'</td>'
'</tr>'
'<tr>'
'<td class="addButton">')
funct.get_button("Add Backend")
print('</td>'
'</tr>'
'</form></table></div>'
'<div id="ssl">'
'<table>'
'<tr class="overviewHead">'
'<td class="padding10 first-collumn">Upload SSL certificates</td>'
'<td>'
'Certificate name'
'</td>'
'<td>'
'<span title="This pem file will be used to create https connection with haproxy">Paste certificate content here(?)</span>'
'</td>'
'</tr>'
'<tr style="width: 50%;">'
'<td class="first-collumn" valign="top" style="padding-top: 15px;">'
'<select required id="serv4">'
'<option disabled selected>Choose server</option>')
for i in listhap:
print('<option value="%s">%s</option>' % (i[2], i[1]))
print('</select>'
'</td>'
'<td valign="top" style="padding-top: 27px;">'
'<input type="text" id="ssl_name" class="form-control">'
'</td>'
'<td style="padding-top: 15px; padding-bottom: 15px;">'
'<textarea id="ssl_cert" cols="50" rows="5"></textarea><br /><br />'
'<a class="ui-button ui-widget ui-corner-all" id="ssl_key_upload" title="Upload ssl certificates">Upload</a>'
'</td>'
'</tr>'
'</table>'
'<div id="ajax-ssl"></div>'
'</div>')
funct.footer()

View File

@ -6,15 +6,26 @@ import http.cookies
from configparser import ConfigParser, ExtendedInterpolation from configparser import ConfigParser, ExtendedInterpolation
import funct import funct
import sql import sql
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('config.html')
print('Content-type: text/html\n')
funct.check_login()
funct.page_for_admin(level = 2)
form = cgi.FieldStorage() form = cgi.FieldStorage()
serv = form.getvalue('serv') serv = form.getvalue('serv')
servNew = form.getvalue('serNew') config_read = ""
cfg = ""
stderr = ""
aftersave = ""
funct.head("Edit HAproxy config") try:
funct.check_config() cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
funct.check_login() user_id = cookie.get('uuid')
funct.page_for_admin(level = 1) user = sql.get_user_name_by_uuid(user_id.value)
servers = sql.get_dick_permit()
except:
pass
path_config = "haproxy-webintarface.config" path_config = "haproxy-webintarface.config"
config = ConfigParser(interpolation=ExtendedInterpolation()) config = ConfigParser(interpolation=ExtendedInterpolation())
@ -23,8 +34,6 @@ config.read(path_config)
log_path = config.get('main', 'log_path') log_path = config.get('main', 'log_path')
hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir')
funct.chooseServer("config.py", "Edit HAproxy config", "y")
if serv is not None: if serv is not None:
cfg = hap_configs_dir + serv + "-" + funct.get_data('config') + ".cfg" cfg = hap_configs_dir + serv + "-" + funct.get_data('config') + ".cfg"
@ -38,18 +47,10 @@ if form.getvalue('serv') is not None and form.getvalue('open') is not None :
try: try:
conf = open(cfg, "r") conf = open(cfg, "r")
config_read = conf.read()
except IOError: except IOError:
print('<div class="alert alert-danger">Can\'t read import config file</div>') print('<div class="alert alert-danger">Can\'t read import config file</div>')
print("<center><h3>Config from %s</h3>" % serv)
print('<form action="config.py" method="get">')
print('<input type="hidden" value="%s" name="serv">' % serv)
print('<input type="hidden" value="%s.old" name="oldconfig">' % cfg)
print('<textarea name="config" class="config" rows="35" cols="100">%s</textarea>' % conf.read())
print('<p>')
funct.get_button("Just save", value="save")
funct.get_button("Save and restart")
print('</p></form>')
conf.close conf.close
os.system("/bin/mv %s %s.old" % (cfg, cfg)) os.system("/bin/mv %s %s.old" % (cfg, cfg))
@ -63,27 +64,33 @@ if form.getvalue('serv') is not None and form.getvalue('config') is not None:
config = form.getvalue('config') config = form.getvalue('config')
oldcfg = form.getvalue('oldconfig') oldcfg = form.getvalue('oldconfig')
save = form.getvalue('save') save = form.getvalue('save')
aftersave = 1
try: try:
with open(cfg, "a") as conf: with open(cfg, "a") as conf:
conf.write(config) conf.write(config)
except IOError: except IOError:
print("Can't read import config file") print("Can't read import config file")
print('<center><div class="alert alert-info">New config was saved as: %s </div></center>' % cfg)
MASTERS = sql.is_master(serv) MASTERS = sql.is_master(serv)
for master in MASTERS: for master in MASTERS:
if master[0] != None: if master[0] != None:
funct.upload_and_restart(master[0], cfg, just_save=save) funct.upload_and_restart(master[0], cfg, just_save=save)
funct.upload_and_restart(serv, cfg, just_save=save) stderr = funct.upload_and_restart(serv, cfg, just_save=save)
os.system("/bin/diff -ub %s %s >> %s/config_edit-%s.log" % (oldcfg, cfg, log_path, funct.get_data('logs'))) os.system("/bin/diff -ub %s %s >> %s/config_edit-%s.log" % (oldcfg, cfg, log_path, funct.get_data('logs')))
os.system("/bin/rm -f " + hap_configs_dir + "*.old") os.system("/bin/rm -f " + hap_configs_dir + "*.old")
print('</br><a href="viewsttats.py?serv=%s" target="_blank" title="View stats">Go to view stats</a> <br />' % serv) output_from_parsed_template = template.render(h2 = 1, title = "Edit Runnig HAProxy config",
role = sql.get_user_role_by_uuid(user_id.value),
funct.footer() action = "config.py",
user = user,
select_id = "serv",
serv = serv,
aftersave = aftersave,
config = config_read,
cfg = cfg,
selects = servers,
stderr = stderr,
note = 1)
print(output_from_parsed_template)

View File

@ -1,46 +1,27 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html
import cgi
import os import os
import sql
import http
import funct import funct
import paramiko from jinja2 import Environment, FileSystemLoader
from configparser import ConfigParser, ExtendedInterpolation env = Environment(loader=FileSystemLoader('templates/'))
from datetime import datetime template = env.get_template('config.html')
from pytz import timezone print('Content-type: text/html\n')
form = cgi.FieldStorage()
serv = form.getvalue('serv')
funct.head("Get Running Config")
funct.check_config()
funct.check_login() funct.check_login()
path_config = "haproxy-webintarface.config" try:
config = ConfigParser(interpolation=ExtendedInterpolation()) cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
config.read(path_config) user_id = cookie.get('uuid')
user = sql.get_user_name_by_uuid(user_id.value)
servers = sql.get_dick_permit()
except:
pass
ssh_keys = config.get('ssh', 'ssh_keys') output_from_parsed_template = template.render(h2 = 1, title = "Show Runnig config",
ssh_user_name = config.get('ssh', 'ssh_user_name') role = sql.get_user_role_by_uuid(user_id.value),
hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') user = user,
haproxy_config_path = config.get('haproxy', 'haproxy_config_path') onclick = "showConfig()",
select_id = "serv",
funct.chooseServer("configshow.py", "Get Running Config", "n", onclick="showConfig()") selects = servers,
note = 0)
print('<div id="ajax">') print(output_from_parsed_template)
if serv is not None and form.getvalue('open') is not None :
cfg = hap_configs_dir + serv + "-" + funct.get_data('config') + ".cfg"
funct.get_config(serv, cfg)
print("<center><h3>Config from %s</h3>" % serv)
print('<p class="accordion-expand-holder">'
'<a class="accordion-expand-all ui-button ui-widget ui-corner-all" href="#">Expand all</a>'
'</p>')
print('</center>')
funct.show_config(cfg)
os.system("/bin/rm -f " + cfg)
print('</div>')
funct.footer()

View File

@ -1,92 +1,83 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import html
import cgi import cgi
import os import os, http.cookies
import funct import funct
import sql import sql
from configparser import ConfigParser, ExtendedInterpolation from configparser import ConfigParser, ExtendedInterpolation
from jinja2 import Environment, FileSystemLoader
form = cgi.FieldStorage() env = Environment(loader=FileSystemLoader('templates/'))
serv = form.getvalue('serv') template = env.get_template('configver.html')
configver = form.getvalue('configver') print('Content-type: text/html\n')
funct.head("Old Versions HAproxy config")
funct.check_config()
funct.check_login() funct.check_login()
funct.page_for_admin(level = 2) funct.page_for_admin(level = 2)
form = cgi.FieldStorage()
serv = form.getvalue('serv')
config_read = ""
configver = ""
stderr = ""
aftersave = ""
try:
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
user = sql.get_user_name_by_uuid(user_id.value)
servers = sql.get_dick_permit()
except:
pass
path_config = "haproxy-webintarface.config" path_config = "haproxy-webintarface.config"
config = ConfigParser(interpolation=ExtendedInterpolation()) config = ConfigParser(interpolation=ExtendedInterpolation())
config.read(path_config) config.read(path_config)
form = cgi.FieldStorage()
serv = form.getvalue('serv')
configver = form.getvalue('configver')
hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir')
funct.chooseServer("configver.py#conf", "Old Versions HAproxy config", "y") def get_files():
if serv is not None and form.getvalue('open') is not None:
print('<center><h3>Choose old version</h3>')
print('<form action="configver.py#conf" method="get">')
print('<p><select autofocus required name="configver">')
print('<option disabled selected>Choose version</option>')
import glob import glob
file = set()
os.chdir(hap_configs_dir) return_files = set()
for files in glob.glob(os.path.join(hap_configs_dir,'*.cfg')):
for files in sorted(glob.glob('*.cfg')): file.add(files.split('/')[6])
ip = files.split("-") files = sorted(file, reverse=True)
for file in files:
ip = file.split("-")
if serv == ip[0]: if serv == ip[0]:
if configver == files: return_files.add(file)
selected = 'selected' return sorted(return_files, reverse=True)
else:
selected = ''
print('<option value="%s" %s>%s</option>' % (files, selected, files))
print('</select>')
print('<input type="hidden" value="%s" name="serv">' % serv)
print('<input type="hidden" value="open" name="open">')
print('<button type="submit" value="Select" name="Select">Select</button></form>')
Select = form.getvalue('Select')
if Select is not None:
configver = form.getvalue('configver')
funct.logging(serv, "open old config %s" % configver)
print("<h3>Config from %s, and version is: %s</h3>" % (serv, configver))
print('<form action="configver.py#conf" method="get">')
print('<input type="hidden" value="%s" name="serv">' % serv)
print('<input type="hidden" value="%s" name="configver">' % configver)
print('<input type="hidden" value="1" name="config">')
print('<a name="conf"></a>')
print('<p class="accordion-expand-holder">'
'<a class="accordion-expand-all ui-button ui-widget ui-corner-all" href="#">Expand all</a>'
'</p></center>')
funct.show_config(configver)
print('<center><p>')
funct.get_button("Just save", value="save")
funct.get_button("Upload and restart")
print('</p></form></center>')
if form.getvalue('serv') is not None and form.getvalue('config') is not None: if form.getvalue('serv') is not None and form.getvalue('config') is not None:
configver = form.getvalue('configver') configver = form.getvalue('configver')
configver = hap_configs_dir + configver configver = hap_configs_dir + configver
save = form.getvalue('save') save = form.getvalue('save')
try:
funct.logging(serv, "configver.py upload old config %s" % configver) funct.logging(serv, "configver.py upload old config %s" % configver)
except:
print("<center><b>Uploaded old config ver: %s </b></br></br></center>" % configver) pass
MASTERS = sql.is_master(serv) MASTERS = sql.is_master(serv)
for master in MASTERS: for master in MASTERS:
if master[0] != None: if master[0] != None:
funct.upload_and_restart(master[0], configver, just_save=save) funct.upload_and_restart(master[0], configver, just_save=save)
funct.upload_and_restart(serv, configver, just_save=save) stderr = funct.upload_and_restart(serv, configver, just_save=save)
aftersave = 1
print('</br><a href="viewsttats.py?serv=%s" target="_blank" title="View stats">Go to view stats</a> <br />' % serv)
funct.footer() output_from_parsed_template = template.render(h2 = 1, title = "Old Versions HAProxy config",
role = sql.get_user_role_by_uuid(user_id.value),
action = "configver.py",
user = user,
select_id = "serv",
serv = serv,
return_files = get_files(),
aftersave = aftersave,
config = config_read,
configver = configver,
selects = servers,
stderr = stderr,
open = form.getvalue('open'),
onclick = "showUploadConfig()",
note = 1)
print(output_from_parsed_template)

View File

@ -1,61 +1,76 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import html, http.cookies
import cgi import cgi
import os import os
import funct import funct, sql
from configparser import ConfigParser, ExtendedInterpolation from configparser import ConfigParser, ExtendedInterpolation
import glob import glob
from configparser import ConfigParser, ExtendedInterpolation
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('delver.html')
print('Content-type: text/html\n')
funct.check_login()
funct.page_for_admin()
form = cgi.FieldStorage() form = cgi.FieldStorage()
serv = form.getvalue('serv') serv = form.getvalue('serv')
stderr = ""
aftersave = ""
file = set()
funct.head("Old Versions HAproxy config") try:
funct.check_config() cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
funct.check_login() user_id = cookie.get('uuid')
user = sql.get_user_name_by_uuid(user_id.value)
servers = sql.get_dick_permit()
except:
pass
path_config = "haproxy-webintarface.config" path_config = "haproxy-webintarface.config"
config = ConfigParser(interpolation=ExtendedInterpolation()) config = ConfigParser(interpolation=ExtendedInterpolation())
config.read(path_config) config.read(path_config)
form = cgi.FieldStorage()
serv = form.getvalue('serv')
Select = form.getvalue('del')
hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir')
funct.page_for_admin() def get_files():
funct.chooseServer("delver.py", "Delete Versions HAproxy config", "n") import glob
file = set()
return_files = set()
for files in glob.glob(os.path.join(hap_configs_dir,'*.cfg')):
file.add(files.split('/')[6])
files = sorted(file, reverse=True)
for file in files:
ip = file.split("-")
if serv == ip[0]:
return_files.add(file)
return sorted(return_files, reverse=True)
if serv is not None and form.getvalue('open') is not None: if serv is not None and form.getvalue('open') is not None:
print('<center><h3>Choose old version</h3>')
print('<form action="delver.py#conf" method="get">'
'<label for="select_all" id="label_select_all"><b>Select all</b></label>'
'<input type="checkbox" id="select_all"><br />')
os.chdir(hap_configs_dir)
for files in sorted(glob.glob('*.cfg')):
ip = files.split("-")
if serv == ip[0]:
print('<label for="%s"> %s </label><input type="checkbox" value="%s" name="%s" id="%s"><br />' % (files, files, files, files, files))
print('<input type="hidden" value="%s" name="serv">' % serv)
print('<input type="hidden" value="open" name="open">')
print('<input type="hidden" value="del" name="del">')
print('<p>')
funct.get_button("Delete")
print('</p></form>')
Select = form.getvalue('del')
if Select is not None: if Select is not None:
os.chdir(hap_configs_dir) aftersave = 1
print("<b>The following files were deleted:</b><br />")
for get in form: for get in form:
if "cfg" in get: if "cfg" in get:
try: try:
os.remove(form.getvalue(get)) os.remove(os.path.join(hap_configs_dir, form.getvalue(get)))
print(form.getvalue(get) + "<br />") file.add(form.getvalue(get) + "<br />")
funct.logging(serv, "delver.py deleted config: %s" % form.getvalue(get)) funct.logging(serv, "delver.py deleted config: %s" % form.getvalue(get))
except OSError: except OSError:
print ("Error: %s - %s." % (e.filename,e.strerror)) stderr = "Error: %s - %s." % (e.filename,e.strerror)
print('<meta http-equiv="refresh" content="10; url=delver.py?serv=%s&open=open">' % form.getvalue('serv')) print('<meta http-equiv="refresh" content="10; url=delver.py?serv=%s&open=open">' % form.getvalue('serv'))
funct.footer() output_from_parsed_template = template.render(h2 = 1, title = "Delete old versions HAProxy config",
role = sql.get_user_role_by_uuid(user_id.value),
action = "delver.py",
user = user,
select_id = "serv",
serv = serv,
aftersave = aftersave,
return_files = get_files(),
selects = servers,
stderr = stderr,
open = form.getvalue('open'),
Select = form.getvalue('del'),
file = file)
print(output_from_parsed_template)

View File

@ -1,28 +1,28 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import os
import cgi import sql
import http
import funct import funct
import ovw import sql
from jinja2 import Environment, FileSystemLoader
form = cgi.FieldStorage() env = Environment(loader=FileSystemLoader('templates/'))
serv = form.getvalue('serv') template = env.get_template('config.html')
left = form.getvalue('left')
right = form.getvalue('right')
funct.head("Compare HAproxy configs") print('Content-type: text/html\n')
funct.check_config() funct.check_login()
funct.check_login()
funct.chooseServer("diff.py#diff", "Compare HAproxy configs", "n", onclick="showCompareConfigs()")
print('<div id="ajax-compare">') try:
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
user = sql.get_user_name_by_uuid(user_id.value)
servers = sql.get_dick_permit()
except:
pass
if serv is not None and form.getvalue('open') is not None : output_from_parsed_template = template.render(h2 = 1, title = "Compare configs",
ovw.show_compare_configs(serv) role = sql.get_user_role_by_uuid(user_id.value),
user = user,
print('</div><div id=ajax>') onclick = "showCompareConfigs()",
select_id = "serv",
if serv is not None and right is not None: selects = servers)
ovw.comapre_show() print(output_from_parsed_template)
print('</div>')
funct.footer()

View File

@ -1,52 +1,29 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import os
import cgi import sql
import http
import funct import funct
import sql import sql
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('runtimeapi.html')
form = cgi.FieldStorage() print('Content-type: text/html\n')
serv = form.getvalue('serv')
funct.head("Runtime API")
funct.check_login() funct.check_login()
funct.check_config()
print('<h2>Runtime API</h2>' try:
'<table class="overview">' cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
'<tr class="overviewHead">' user_id = cookie.get('uuid')
'<td class="padding10 first-collumn">Server</td>' user = sql.get_user_name_by_uuid(user_id.value)
'<td>Disable/Enable server or output any information</td>' servers = sql.get_dick_permit(virt=1)
'<td class="padding10">Command</td>' except:
'<td>Save change</td>' pass
'<td></td>'
'</tr>'
'<tr>'
'<td class="padding10 first-collumn" style="width: 25%;">'
'<form action="edit.py" method="get">'
'<select required name="serv" id="serv">'
'<option disabled selected>Choose server</option>')
funct.choose_only_select(serv, virt=1) output_from_parsed_template = template.render(h2 = 1,
title = "Runtime API",
print('</select></td>' role = sql.get_user_role_by_uuid(user_id.value),
'<td style="width: 30%;">' user = user,
'<select required name="servaction" id="servaction">' onclick = "showRuntime()",
'<option disabled selected>Choose action</option>') select_id = "serv",
if funct.is_admin(): selects = servers)
print('<option value="disable">Disable</option>') print(output_from_parsed_template)
print('<option value="enable">Enable</option>')
print('<option value="set">Set</option>')
print('<option value="show">Show</option>'
'</select></td>'
'<td>'
'<input type="text" name="servbackend" id="servbackend" size=35 title="Frontend, backend/server, show: info, pools or help" required class="form-control">'
'</td><td>'
'<label for="save"></label><input type="checkbox" name="save" id="save" value="123">'
'</td><td>'
'<a class="ui-button ui-widget ui-corner-all" id="show" title="Enter" onclick="showRuntime()">Enter</a>'
'</td></form>'
'</tr></table>'
'<div id="ajax">'
'</div>')
funct.footer()

View File

@ -121,189 +121,6 @@ def get_button(button, **kwargs):
if value is None: if value is None:
value = "" value = ""
print('<button type="submit" value="%s" name="%s" class="btn btn-default">%s</button>' % (value, value, button)) print('<button type="submit" value="%s" name="%s" class="btn btn-default">%s</button>' % (value, value, button))
def head(title):
print('Content-type: text/html\n')
print('<html><head><title>%s</title>' % title)
print('<link href="/image/pic/favicon.ico" rel="icon" type="image/png" />'
'<script>'
'FontAwesomeConfig = { searchPseudoElements: true, observeMutations: false };'
'</script>'
'<script defer src="/inc/fa-solid.min.js"></script>'
'<script defer src="/inc/fontawesome.min.js"></script>'
'<meta charset="UTF-8">'
'<link href="/inc/awesome.css" rel="stylesheet">'
'<link href="/inc/vertical_scrol/custom_scrollbar.css" rel="stylesheet">'
'<link href="/inc/style.css" rel="stylesheet">'
'<link href="/inc/nprogress.css" rel="stylesheet">'
'<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">'
'<script src="https://code.jquery.com/jquery-1.12.4.js"></script>'
'<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>'
'<script src="/inc/js-cookie.js"></script>'
'<script src="/inc/script.js"></script>'
'<script src="/inc/configshow.js"></script>'
'<script src="/inc/nprogress.js"></script>'
'<script src="/inc/vertical_scrol/custom_scrollbar.min.js"></script>'
'</head>'
'<body>'
'<a name="top"></a>'
'<div class="show_menu" style="display: none;">'
'<a href="#" id="show_menu" title="Show menu" style="margin-top: 30px;position: absolute;">'
'<span class="ui-state-default ui-corner-all">'
'<span class="ui-icon ui-icon-arrowthick-1-e" id="arrow"></span>'
'</span>'
'</a>'
'</div>'
'<div class="top-menu">'
'<div class="LogoText">'
'<span style="padding: 10px;">HAproxy-WI</span>'
'<a href="#" id="hide_menu" title="Hide menu" style="margin-left: 23px; position: absolute;">'
'<span class="ui-state-default ui-corner-all">'
'<span class="ui-icon ui-icon-arrowthick-1-w" id="arrow"></span>'
'</span>'
'</a>'
'</div>')
links()
print('</div><div class="container">')
def links():
print('<div class="top-link">'
'<nav class="menu">'
'<ul>'
'<li><a title="Statistics, monitoring and logs" class="stats">Stats</a>'
'<li><a href=/app/overview.py title="Server and service status" class="overview-link head-submenu">Overview</a> </li>'
'<li><a href=/app/viewsttats.py title"Show stats" class="stats head-submenu">Stats</a> </li>'
'<li><a href=/app/logs.py title="View logs" class="logs head-submenu">Logs</a></li>'
'<li><a href=/app/map.py title="View map" class="map head-submenu">Map</a></li>'
'</li>'
'<li><a href=/app/edit.py title="Runtime API" class="runtime">Runtime API</a> </li>'
'<li><a title="Actions with Haproxy configs" class="config-show">Haproxy</a>'
'<li><a href=/app/configshow.py title="Show Haproxy Config" class="config-show head-submenu">Show config</a></li> '
'<li><a href=/app/diff.py title="Compare Haproxy Configs" class="compare head-submenu">Compare configs</a></li>')
if is_admin(level = 2):
print('<li><a href=/app/add.py#listner title="Add single listen" class="add head-submenu">Add listen</a></li>'
'<li><a href=/app/add.py#frontend title="Add single frontend" class="add head-submenu">Add frontend</a></li>'
'<li><a href=/app/add.py#backend title="Add single backend" class="add head-submenu">Add backend</a></li>'
'<li><a href=/app/add.py#ssl title="Upload SSL cert" class="cert head-submenu">SSL</a></li>'
'<li><a href=/app/config.py title="Edit Haproxy Config" class="edit head-submenu">Edit config</a> </li>')
if is_admin():
print('<li><a href=/app/ihap.py title="Installation HAProxy" class="hap head-submenu">Installation</a> </li>')
print('</li>')
if is_admin():
print('<li><a title="Keepalived" class="ha">Keepalived</a>'
'<li><a href=/app/ha.py title="Create HA cluster" class="keepalived head-submenu">HA</a>'
'<li><a href=/app/keepalivedconfig.py title="Edit keepalived config" class="edit head-submenu">Edit config</a></li>')
if is_admin(level = 2):
print('<li><a title="Actions with configs" class="version">Versions</a>'
'<li><a href=/app/configver.py title="Upload old versions configs" class="upload head-submenu">Upload</a></li>')
if is_admin():
print('<li><a href=/app/delver.py title="Delete old versions configs" class="delete head-submenu">Delete</a></li>')
if is_admin(level = 2):
print('</li>')
show_login_links()
if is_admin():
print('<li><a title="Admin area" class="admin">Admin area</a>'
'<li><a href=/app/users.py#users title="Actions with users" class="users head-submenu">Users</a></li>'
'<li><a href=/app/users.py#groups title="Actions with groups" class="group head-submenu">Groups</a></li>'
'<li><a href=/app/users.py#servers title="Actions with servers" class="runtime head-submenu">Servers</a></li>'
'<li><a href=/app/users.py#roles title="Users roles" class="role head-submenu">Roles</a></li>'
'<li><a href=/app/settings.py title="View settings" class="settings head-submenu">View settings</a></li>'
'<li><a href=/app/viewlogs.py title="View users actions logs" class="logs head-submenu">View logs</a></li>'
'</li>')
print('</ul>'
'</nav>'
'<div class="copyright-menu">HAproxy-WI v2.4</div>'
'</div>')
def show_login_links():
import sql
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
if user_id is None:
print('<li><a href=/app/login.py? title="Login" class="login">Login</a></li>')
else:
print('<li><a href=/app/login.py?logout=logout title="Logout, user name: %s" class="login">Logout</a></li>' % sql.get_user_name_by_uuid(user_id.value))
def footer():
print('</center></div>'
'<center>'
'<h3 style="margin-left: 8%">'
'<a class="ui-button ui-widget ui-corner-all" href="#top" title="Move up">UP</a>'
'</h3><br />'
'</center>'
'</body></html>')
def get_auto_refresh(h2):
print('<h2>')
print('<span>%s</span>' % h2)
print('<span class="auto-refresh">'
'<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()" class="auto-refresh-pause" style="display: none; margin-top: 4px;"></a>'
'<a onclick="pauseAutoResume()" class="auto-refresh-resume" style="display: none; margin-top: 4px;"></a>'
'</span></h2>'
'<div class="auto-refresh-div">'
'<div class="auto-refresh-head">'
'Refresh Interval'
'</div>'
'<div class="auto-refresh-interval">'
'<div class="auto-refresh-ul">'
'<ul>'
'<li>'
'<a class="ui-button ui-widget ui-corner-all" onclick="setRefreshInterval(0)" title="Turn off auto-refresh">Off</a> '
'</li>'
'</ul>'
'</div>'
'<div class="auto-refresh-ul" id="secIntervals">'
'<ul>'
'<li>'
'<a title="Auto-refresh every 5 seconds" onclick="setRefreshInterval(5000)">5 seconds</a>'
'</li>'
'<li>'
'<a title="Auto-refresh every 10 seconds" onclick="setRefreshInterval(10000)">10 seconds</a>'
'</li>'
'<li>'
'<a title="Auto-refresh every 30 seconds" onclick="setRefreshInterval(30000)">30 seconds</a>'
'</li>'
'<li>'
'<a title="Auto-refresh ever 45 seconds" onclick="setRefreshInterval(45000)">45 seconds</a>'
'</li>'
'</ul>'
'</div>'
'<div class="auto-refresh-ul">'
'<ul>'
'<li>'
'<a title="Auto-refresh every 1 minute" onclick="setRefreshInterval(60000)">1 minute</a>'
'</li>'
'<li>'
'<a title="Auto-refresh every 5 minutes" onclick="setRefreshInterval(300000)">5 minutes</a>'
'</li>'
'<li>'
'<a title="Auto-refresh every 15 minutes" onclick="setRefreshInterval(900000)">15 minutes</a>'
'</li>'
'<li>'
'<a title="Auto-refresh ever 30 minutes" onclick="setRefreshInterval(1800000)">30 minutes</a>'
'</li>'
'</ul>'
'</div>'
'<div class="auto-refresh-ul">'
'<ul>'
'<li>'
'<a title="Auto-refresh every 1 hour" onclick="setRefreshInterval(3600000)">1 hour</a>'
'</li>'
'<li>'
'<a title="Auto-refresh every 2 hour" onclick="setRefreshInterval(7200000)">2 hour</a>'
'</li>'
'<li>'
'<a title="Auto-refresh every 12 hour" onclick="setRefreshInterval(43200000)">12 hour</a>'
'</li>'
'<li>'
'<a title="Auto-refresh ever 1 day" onclick="setRefreshInterval(86400000)">1 day</a>'
'</li>'
'</ul>'
'</div>'
'</div>'
'</div>')
def ssh_connect(serv, **kwargs): def ssh_connect(serv, **kwargs):
ssh = SSHClient() ssh = SSHClient()
@ -339,10 +156,8 @@ def ssh_connect(serv, **kwargs):
def get_config(serv, cfg, **kwargs): def get_config(serv, cfg, **kwargs):
if kwargs.get("keepalived"): if kwargs.get("keepalived"):
os.chdir(config.get('configs', 'kp_save_configs_dir'))
config_path = "/etc/keepalived/keepalived.conf" config_path = "/etc/keepalived/keepalived.conf"
else: else:
os.chdir(hap_configs_dir)
config_path = haproxy_config_path config_path = haproxy_config_path
ssh = ssh_connect(serv) ssh = ssh_connect(serv)
@ -433,7 +248,6 @@ def upload_and_restart(serv, cfg, **kwargs):
try: try:
ssh = ssh_connect(serv) ssh = ssh_connect(serv)
print('<center><div class="alert alert-info">connected to %s</div>' % serv)
except: except:
print('<center><div class="alert alert-danger">Connect fail</div>') print('<center><div class="alert alert-danger">Connect fail</div>')
sftp = ssh.open_sftp() sftp = ssh.open_sftp()
@ -446,32 +260,20 @@ def upload_and_restart(serv, cfg, **kwargs):
commands = [ "mv -f " + tmp_file + " /etc/keepalived/keepalived.conf", "systemctl restart keepalived" ] commands = [ "mv -f " + tmp_file + " /etc/keepalived/keepalived.conf", "systemctl restart keepalived" ]
else: else:
if kwargs.get("just_save") == "save": if kwargs.get("just_save") == "save":
commands = [ "/sbin/haproxy -q -c -f " + tmp_file, "mv -f " + tmp_file + " " + haproxy_config_path ] commands = [ "/sbin/haproxy -q -c -f " + tmp_file + "&& mv -f " + tmp_file + " " + haproxy_config_path ]
else: else:
commands = [ "/sbin/haproxy -q -c -f " + tmp_file, "mv -f " + tmp_file + " " + haproxy_config_path, restart_command ] commands = [ "/sbin/haproxy -q -c -f " + tmp_file + "&& mv -f " + tmp_file + " " + haproxy_config_path + " && " + restart_command ]
try: try:
if config.get('haproxy', 'firewall_enable') == "1": if config.get('haproxy', 'firewall_enable') == "1":
commands.extend(open_port_firewalld(cfg)) commands.extend(open_port_firewalld(cfg))
except: except:
print('<div class="alert alert-warning">Please check the config for the presence of the parameter - "firewall_enable". Mast be: "0" or "1". Firewalld configure not working now </div>') return 'Please check the config for the presence of the parameter - "firewall_enable". Mast be: "0" or "1". Firewalld configure not working now'
i = 0
for command in commands: for command in commands:
i = i + 1 stdin, stdout, stderr = ssh.exec_command(command)
stdin , stdout, stderr = ssh.exec_command(command)
if i == 1: return stderr.read().decode(encoding='UTF-8')
if not stderr.read():
print('<div class="alert alert-success">Config ok</div><pre>')
else:
print('<div class="alert alert-danger">In your config have errors, please check, and try again</div><br><br>')
return False
break
if i is not 1:
print(stderr.read().decode(encoding='UTF-8'))
return True
print('</center>')
ssh.close() ssh.close()
def open_port_firewalld(cfg): def open_port_firewalld(cfg):
@ -564,7 +366,7 @@ def server_status(stdout):
print('<span class="serverUp"> UP</span> running %s processes' % proc_count) print('<span class="serverUp"> UP</span> running %s processes' % proc_count)
else: else:
print('<span class="serverDown"> DOWN</span> running %s processes' % proc_count) print('<span class="serverDown"> DOWN</span> running %s processes' % proc_count)
def ssh_command(serv, commands, **kwargs): def ssh_command(serv, commands, **kwargs):
ssh = ssh_connect(serv) ssh = ssh_connect(serv)
@ -589,47 +391,3 @@ def ssh_command(serv, commands, **kwargs):
ssh.close() ssh.close()
def choose_only_select(serv, **kwargs):
import sql
if kwargs.get("virt"):
listhap = sql.get_dick_permit(virt=1)
else:
listhap = sql.get_dick_permit()
if kwargs.get("servNew"):
servNew = kwargs.get("servNew")
else:
servNew = ""
for i in listhap:
if i[2] == serv or i[2] == servNew:
selected = 'selected'
else:
selected = ''
print('<option value="%s" %s>%s</option>' % (i[2], selected, i[1]))
def chooseServer(formName, title, note, **kwargs):
servNew = form.getvalue('serNew')
print('<h2>' + title + '</h2><center>')
print('<h3>Choose server</h3>')
print('<form action=' + formName + ' method="get">')
print('<p><select autofocus required name="serv" id="serv">')
print('<option disabled>Choose server</option>')
choose_only_select(serv, servNew=servNew)
print('</select>')
if kwargs.get("onclick") is not None:
print('<a class="ui-button ui-widget ui-corner-all" id="show" title="Show config" onclick="%s">Show</a>' % kwargs.get("onclick"))
else:
get_button("Open", value="open")
print('</p></form>')
if note == "y":
print('<div class="alert alert-info"><b>Note:</b> If you reconfigure Master server, Slave will reconfigured automatically</div>')
print('</center>')

108
app/ha.py
View File

@ -1,93 +1,29 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import html, http.cookies
import cgi import cgi
import funct import os
import sql import funct, sql
from configparser import ConfigParser, ExtendedInterpolation from configparser import ConfigParser, ExtendedInterpolation
from jinja2 import Environment, FileSystemLoader
funct.head("HA") env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('ha.html')
print('Content-type: text/html\n')
funct.check_login() funct.check_login()
funct.page_for_admin() funct.page_for_admin()
form = cgi.FieldStorage()
serv = form.getvalue('serv')
path_config = "haproxy-webintarface.config" try:
config = ConfigParser(interpolation=ExtendedInterpolation()) cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
config.read(path_config) user_id = cookie.get('uuid')
serv = "" user = sql.get_user_name_by_uuid(user_id.value)
servers = sql.get_dick_permit()
print('<script src="/inc/users.js"></script>' except:
'<h2>Configure HA</h2>' pass
'<table class="overview">'
'<caption class="overviewHead"><h3 style="margin-left: 20px; margin-bottom: 10px;">Create new HA cluster</h3></caption>'
'<tr class="overviewHead">'
'<td class="padding10 first-collumn">Master</td>'
'<td>Slave</td>'
'<td>VRRP interface</td>'
'<td>VRRP IP</td>'
'<td><span title="Haproxy-WI will try install haproxy-1.18.5, if it does not work then haproxy-1.15">Install HAProxy(?)</span></td>'
'<td></td>'
'</tr>'
'<tr>'
'<td class="padding10 first-collumn">'
'<select id="master">'
'<option disable selected>Choose master</option>')
funct.choose_only_select(serv)
print('</select>'
'</td>'
'<td>'
'<select id="slave">'
'<option disable selected>Choose master</option>')
funct.choose_only_select(serv)
print('</select>'
'</td>'
'<td>'
'<input type="text" id="interface" class="form-control">'
'</td>'
'<td>'
'<input type="text" id="vrrp-ip" class="form-control">'
'</td>'
'<td>'
'<label for="hap"></label><input type="checkbox" id="hap">'
'</td>'
'<td>'
'<a class="ui-button ui-widget ui-corner-all" id="create" title="Create HA configuration">Create</a>'
'</td>'
'</table>'
'<table>'
'<caption class="overviewHead"><h3 style="margin-left: 20px; margin-bottom: 10px;">Or add VRRP to exist</h3></caption>'
'<tr class="overviewHead">'
'<td class="padding10 first-collumn">Master</td>'
'<td>Slave</td>'
'<td>VRRP interface</td>'
'<td>VRRP IP</td>'
'<td><span title="If checked Haproxy-WI will restart Keepalived">Restart Keepalived(?)</span></td>'
'<td></td>'
'</tr>'
'<tr>'
'<td class="padding10 first-collumn">'
'<select id="master-add">'
'<option disable selected>Choose master</option>')
funct.choose_only_select(serv)
print('</select>'
'</td>'
'<td>'
'<select id="slave-add">'
'<option disable selected>Choose master</option>')
funct.choose_only_select(serv)
print('</select>'
'</td>'
'<td>'
'<input type="text" id="interface-add" class="form-control">'
'</td>'
'<td>'
'<input type="text" id="vrrp-ip-add" class="form-control">'
'</td>'
'<td>'
'<label for="kp"></label><input type="checkbox" id="kp">'
'</td>'
'<td>'
'<a class="ui-button ui-widget ui-corner-all" id="add-vrrp" title="Add HA configuration">Add</a>'
'</td>'
'</table>'
'<div id="ajax"></div>')
output_from_parsed_template = template.render(h2 = 1, title = "Configure HA",
role = sql.get_user_role_by_uuid(user_id.value),
user = user,
serv = serv,
selects = servers)
print(output_from_parsed_template)

View File

@ -1,40 +1,29 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import html, http.cookies
import cgi import cgi
import funct import os
import sql import funct, sql
from configparser import ConfigParser, ExtendedInterpolation from configparser import ConfigParser, ExtendedInterpolation
from jinja2 import Environment, FileSystemLoader
funct.head("Installation HAProxy") env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('ihap.html')
print('Content-type: text/html\n')
funct.check_login() funct.check_login()
funct.page_for_admin() funct.page_for_admin()
form = cgi.FieldStorage()
path_config = "haproxy-webintarface.config" try:
config = ConfigParser(interpolation=ExtendedInterpolation()) cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
config.read(path_config) user_id = cookie.get('uuid')
proxy = config.get('main', 'proxy') user = sql.get_user_name_by_uuid(user_id.value)
serv = "" servers = sql.get_dick_permit()
except:
pass
output_from_parsed_template = template.render(h2 = 1, title = "Installation HAProxy",
role = sql.get_user_role_by_uuid(user_id.value),
user = user,
select_id = "haproxyaddserv",
selects = servers)
print(output_from_parsed_template)
print('<script src="/inc/users.js"></script>'
'<h2>Installation HAProxy</h2>'
'<table class="overview">'
'<tr class="overviewHead">'
'<td class="padding10 first-collumn">Note</td>'
'<td>Server</td>'
'<td></td>'
'</tr>'
'<tr>'
'<td class="padding10 first-collumn">'
'<b>Haproxy-WI will try install haproxy-1.18.5, if it does not work then haproxy-1.15</b>'
'</td>'
'<td class="padding10 first-collumn">'
'<select id="haproxyaddserv">'
'<option disable selected>Choose server</option>')
funct.choose_only_select(serv)
print('</select>'
'</td>'
'<td>'
'<a class="ui-button ui-widget ui-corner-all" id="install" title="Install HAProxy">Install</a>'
'</td>'
'</table>'
'<div id="ajax"></div>')

View File

@ -1,5 +1,4 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-"
import html import html
import cgi import cgi
import os import os
@ -7,16 +6,26 @@ import http.cookies
from configparser import ConfigParser, ExtendedInterpolation from configparser import ConfigParser, ExtendedInterpolation
import funct import funct
import sql import sql
import codecs from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('config.html')
print('Content-type: text/html\n')
funct.check_login()
funct.page_for_admin()
form = cgi.FieldStorage() form = cgi.FieldStorage()
serv = form.getvalue('serv') serv = form.getvalue('serv')
servNew = form.getvalue('serNew') config_read = ""
cfg = ""
stderr = ""
aftersave = ""
funct.head("Edit Running Keepalived config") try:
funct.check_config() cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
funct.check_login() user_id = cookie.get('uuid')
funct.page_for_admin(level = 1) user = sql.get_user_name_by_uuid(user_id.value)
servers = sql.is_master("123", master_slave=1)
except:
pass
path_config = "haproxy-webintarface.config" path_config = "haproxy-webintarface.config"
config = ConfigParser(interpolation=ExtendedInterpolation()) config = ConfigParser(interpolation=ExtendedInterpolation())
@ -25,29 +34,6 @@ config.read(path_config)
log_path = config.get('main', 'log_path') log_path = config.get('main', 'log_path')
kp_save_configs_dir = config.get('configs', 'kp_save_configs_dir') kp_save_configs_dir = config.get('configs', 'kp_save_configs_dir')
print('<h2>Edit Running Keepalived config</h2>'
'<center>'
'<h3>Choose server</h3>'
'<form action="keepalivedconfig.py" method="get">'
'<select name="serv">')
SERVERS = sql.is_master("123", master_slave=1)
for server in SERVERS:
if serv == server[1]:
selected = "selected"
else:
selected = ""
print('<option value="%s" %s>%s</option>' % (server[1],selected, server[0]))
if serv == server[3]:
selected = "selected"
else:
selected = ""
print('<option value="%s" %s>%s</option>' % (server[3], selected, server[2]))
print('</select>')
funct.get_button("Open", value="open")
print('</form>')
if serv is not None: if serv is not None:
cfg = kp_save_configs_dir+ serv + '-' + funct.get_data('config') + '.conf' cfg = kp_save_configs_dir+ serv + '-' + funct.get_data('config') + '.conf'
@ -61,18 +47,10 @@ if form.getvalue('serv') is not None and form.getvalue('open') is not None :
try: try:
conf = open(cfg, "r",encoding='utf-8', errors='ignore') conf = open(cfg, "r",encoding='utf-8', errors='ignore')
config_read = conf.read()
except IOError: except IOError:
print('<div class="alert alert-danger">Can\'t read import config file</div>') print('<div class="alert alert-danger">Can\'t read import config file</div>')
print("<center><h3>Config from %s</h3>" % serv)
print('<form action="" method="get">')
print('<input type="hidden" value="%s" name="serv">' % serv)
print('<input type="hidden" value="%s.old" name="oldconfig">' % cfg)
print('<textarea name="config" class="config" rows="35" cols="100">%s</textarea>' % conf.read())
print('<p>')
funct.get_button("Just save", value="save")
funct.get_button("Save and restart")
print('</p></form>')
conf.close conf.close
os.system("/bin/mv %s %s.old" % (cfg, cfg)) os.system("/bin/mv %s %s.old" % (cfg, cfg))
@ -86,21 +64,28 @@ if form.getvalue('serv') is not None and form.getvalue('config') is not None:
config = form.getvalue('config') config = form.getvalue('config')
oldcfg = form.getvalue('oldconfig') oldcfg = form.getvalue('oldconfig')
save = form.getvalue('save') save = form.getvalue('save')
aftersave = 1
try: try:
with open(cfg, "a") as conf: with open(cfg, "a") as conf:
conf.write(config) conf.write(config)
except IOError: except IOError:
print("Can't read import config file") print("Can't read import config file")
print('<center><br><div class="alert alert-info">New config was saved as: %s </div></center>' % cfg) stderr = funct.upload_and_restart(serv, cfg, just_save=save, keepalived=1)
funct.upload_and_restart(serv, cfg, just_save=save, keepalived=1)
os.system("/bin/diff -ub %s %s >> %s/config_edit-%s.log" % (oldcfg, cfg, log_path, funct.get_data('logs'))) os.system("/bin/diff -ub %s %s >> %s/config_edit-%s.log" % (oldcfg, cfg, log_path, funct.get_data('logs')))
os.system("/bin/rm -f kp_config/*.old") os.system("/bin/rm -f " + kp_save_configs_dir + "*.old")
print('</br><a href="viewsttats.py?serv=%s" target="_blank" title="View stats">Go to view stats</a> <br />' % serv) output_from_parsed_template = template.render(h2 = 1, title = "Edit Runnig Keepalived config",
role = sql.get_user_role_by_uuid(user_id.value),
funct.footer() action = "keepalivedconfig.py",
user = user,
select_id = "serv",
serv = serv,
aftersave = aftersave,
config = config_read,
cfg = cfg,
selects = servers,
stderr = stderr,
keepalived = 1)
print(output_from_parsed_template)

View File

@ -10,52 +10,52 @@ import create_db
import datetime import datetime
import uuid import uuid
from configparser import ConfigParser, ExtendedInterpolation from configparser import ConfigParser, ExtendedInterpolation
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('login.html')
form = cgi.FieldStorage()
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
form = cgi.FieldStorage() user_id = cookie.get('uuid')
ref = form.getvalue('ref') ref = form.getvalue('ref')
login = form.getvalue('login') login = form.getvalue('login')
password = form.getvalue('pass') password = form.getvalue('pass')
db_create = ""
error_log = ""
error = ""
path_config = "haproxy-webintarface.config" path_config = "haproxy-webintarface.config"
config = ConfigParser(interpolation=ExtendedInterpolation()) config = ConfigParser(interpolation=ExtendedInterpolation())
config.read(path_config) config.read(path_config)
def login_page(error): if ref is None:
if error == "error": ref = "/index.html"
funct.head("Login page")
printError = "<h2>Login page. Enter please</h2><br /><br /><b style='color: red'>Somthing wrong :( I'm sad about this, but try again!</b><br /><br />"
else:
printError = "<h2>Login page. Enter please</h2><br /><br />"
if create_db.check_db(): if form.getvalue('error'):
if create_db.create_table(): error_log = '<div class="alert alert-danger">Somthing wrong :( I\'m sad about this, but try again!</div><br /><br />'
print('<div class="alert alert-success">DB was created<br />')
create_db.update_all() try:
print('<br />Now you can login, default: admin/admin</div>') if config.get('main', 'session_ttl'):
create_db.update_all_silent() session_ttl = config.getint('main', 'session_ttl')
except:
error = '<center><div class="alert alert-danger">Can not find "session_ttl" parametr. Check into config, "main" section</div>'
pass
ref = form.getvalue('ref') try:
if ref is None: role = sql.get_user_role_by_uuid(user_id.value)
ref = "/index.html" user = sql.get_user_name_by_uuid(user_id.value)
except:
print('<center><form name="auth" action="login.py" class="form-horizontal" method="get">') role = ""
print(printError) user = ""
print('<label for="login">Login: </label> <input type="text" name="login" required class="form-control"><br /><br />') pass
print('<label for="pass">Pass: </label> <input type="password" name="pass" required class="form-control"><br /><br />')
print('<input type="hidden" value="%s" name="ref">' % ref)
print('<button type="submit" name="Login" value="Enter">Sign Up</button>')
print('</form></center>')
try: if create_db.check_db():
if config.get('main', 'session_ttl'): if create_db.create_table():
session_ttl = config.getint('main', 'session_ttl') create_db.update_all()
except: db_create = '<div class="alert alert-success">DB was created<br /><br />Now you can login, default: admin/admin</div>'
print('<center><div class="alert alert-danger">Can not find "session_ttl" parametr. Check into config, "main" section</div>') create_db.update_all_silent()
if form.getvalue('logout') is not None: if form.getvalue('logout'):
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
try: try:
sql.delete_uuid(user_id.value) sql.delete_uuid(user_id.value)
except: except:
@ -63,15 +63,9 @@ if form.getvalue('logout') is not None:
print("Set-cookie: uuid=; expires=Wed May 18 03:33:20 2003; path=/app/; httponly") print("Set-cookie: uuid=; expires=Wed May 18 03:33:20 2003; path=/app/; httponly")
print("Content-type: text/html\n") print("Content-type: text/html\n")
print('<meta http-equiv="refresh" content="0; url=/app/login.py">') print('<meta http-equiv="refresh" content="0; url=/app/login.py">')
if login is None:
funct.head("Login page")
login_page("n")
if login is not None and password is not None: if login is not None and password is not None:
if form.getvalue('ref') is None:
ref = "/index.html"
USERS = sql.select_users() USERS = sql.select_users()
session_ttl = config.getint('main', 'session_ttl') session_ttl = config.getint('main', 'session_ttl')
expires = datetime.datetime.utcnow() + datetime.timedelta(days=session_ttl) expires = datetime.datetime.utcnow() + datetime.timedelta(days=session_ttl)
@ -90,7 +84,18 @@ if login is not None and password is not None:
print('<html><head><title>Redirecting</title><meta charset="UTF-8">') print('<html><head><title>Redirecting</title><meta charset="UTF-8">')
print('<link href="/style.css" rel="stylesheet">') print('<link href="/style.css" rel="stylesheet">')
print('<meta http-equiv="refresh" content="0; url=%s">' % ref) print('<meta http-equiv="refresh" content="0; url=%s">' % ref)
sys.exit() sys.exit()
login_page("error")
print("Content-type: text/html\n")
funct.footer() print('<meta http-equiv="refresh" content="0; url=/app/login.py?error=1">')
if login is None:
print("Content-type: text/html\n")
output_from_parsed_template = template.render(h2 = 1, title = "Login page. Enter please",
role = role,
user = user,
error_log = error_log,
error = error,
ref = ref,
db_create = db_create)
print(output_from_parsed_template)

View File

@ -2,53 +2,46 @@
import html import html
import cgi import cgi
import funct import funct
import sql
import os, http
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('logs.html')
form = cgi.FieldStorage() form = cgi.FieldStorage()
serv = form.getvalue('serv')
funct.head("HAproxy Logs") if form.getvalue('grep') is None:
funct.check_config() grep = ""
else:
grep = form.getvalue('grep')
if form.getvalue('rows') is None:
rows = 10
else:
rows = form.getvalue('rows')
print('Content-type: text/html\n')
funct.check_login() funct.check_login()
funct.get_auto_refresh("HAproxy logs")
print('<table class="overview">' try:
'<tr class="overviewHead">' cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
'<td class="padding10 first-collumn">Server</td>' user_id = cookie.get('uuid')
'<td>Number rows</td>' user = sql.get_user_name_by_uuid(user_id.value)
'<td class="padding10">Ex for grep</td>' servers = sql.get_dick_permit()
'<td> </td>' except:
'</tr>' pass
'<tr>'
'<td class="padding10 first-collumn">'
'<form action="logs.py" method="get">'
'<select autofocus required name="serv" id="serv">'
'<option disabled selected>Choose server</option>')
funct.choose_only_select(serv) output_from_parsed_template = template.render(h2 = 1,
autorefresh = 1,
title = "Show logs",
role = sql.get_user_role_by_uuid(user_id.value),
user = user,
onclick = "showLog()",
select_id = "serv",
selects = servers,
serv = form.getvalue('serv'),
rows = rows,
grep = grep)
print(output_from_parsed_template)
print('</select>')
if serv is not None:
rows = 'value='+form.getvalue('rows')
else:
rows = 'value=10'
if form.getvalue('grep') is not None:
grep = 'value='+form.getvalue('grep')
else:
grep = ' '
print('</td><td><input type="number" name="rows" id="rows" %s class="form-control" required></td>' % rows)
print('<td class="padding10 first-collumn"><input type="text" name="grep" id="grep" class="form-control" %s >' % grep)
print('</td>'
'<td class="padding10 first-collumn">'
'<a class="ui-button ui-widget ui-corner-all" id="show" title="Show logs" onclick="showLog()">Show</a>'
'</td>'
'</form>'
'</tr></table>'
'<div id="ajax">'
'</div>'
'<script>'
'window.onload = showLog()'
'</script>')
funct.footer()

View File

@ -1,21 +1,28 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html
import cgi
import os import os
import sql
import http
import funct import funct
import ovw import sql
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('config.html')
form = cgi.FieldStorage() print('Content-type: text/html\n')
serv = form.getvalue('serv')
funct.head("Show HAproxy config")
funct.check_config()
funct.check_login() funct.check_login()
funct.chooseServer("map.py", "Show HAproxy map", "n", onclick="showMap()")
print('<div id="ajax">') try:
if serv is not None: cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
ovw.get_map(serv) user_id = cookie.get('uuid')
print('</div>') user = sql.get_user_name_by_uuid(user_id.value)
servers = sql.get_dick_permit()
funct.footer() except:
pass
output_from_parsed_template = template.render(h2 = 1, title = "Show Map",
role = sql.get_user_role_by_uuid(user_id.value),
user = user,
onclick = "showMap()",
select_id = "serv",
selects = servers)
print(output_from_parsed_template)

View File

@ -188,11 +188,15 @@ if serv is not None and act == "configShow":
import os import os
from datetime import datetime from datetime import datetime
from pytz import timezone from pytz import timezone
hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir')
cfg = hap_configs_dir + serv + "-" + funct.get_data('config') + ".cfg"
funct.get_config(serv, cfg) if form.getvalue('configver') is None:
cfg = hap_configs_dir + serv + "-" + funct.get_data('config') + ".cfg"
funct.get_config(serv, cfg)
else:
cfg = hap_configs_dir + form.getvalue('configver')
print('<a name="top"></a>') print('<a name="top"></a>')
print("<center><h3>Config from %s</h3>" % serv) print("<center><h3>Config from %s</h3>" % serv)
@ -202,8 +206,18 @@ if serv is not None and act == "configShow":
print('</center>') print('</center>')
funct.show_config(cfg) funct.show_config(cfg)
os.system("/bin/rm -f " + cfg) if form.getvalue('configver') is None:
os.system("/bin/rm -f " + cfg)
else:
print('<br><center>')
print('<form action="configver.py#conf" method="get">')
print('<input type="hidden" value="%s" name="serv">' % serv)
print('<input type="hidden" value="%s" name="configver">' % form.getvalue('configver'))
print('<input type="hidden" value="1" name="config">')
funct.get_button("Just save", value="save")
funct.get_button("Upload and restart")
print('</form></center>')
if form.getvalue('viewlogs') is not None: if form.getvalue('viewlogs') is not None:
viewlog = form.getvalue('viewlogs') viewlog = form.getvalue('viewlogs')
@ -213,7 +227,7 @@ if form.getvalue('viewlogs') is not None:
print('<div class="alert alert-warning">Please check the config for the presence of the parameter - "log_path". </div>') print('<div class="alert alert-warning">Please check the config for the presence of the parameter - "log_path". </div>')
try: try:
log = open(log_path + viewlog, "r") log = open(log_path + viewlog, "r",encoding='utf-8', errors='ignore')
except IOError: except IOError:
print('<div class="alert alert-danger">Can\'t read import log file</div>') print('<div class="alert alert-danger">Can\'t read import log file</div>')
sys.exit() sys.exit()

View File

@ -1,14 +1,24 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import funct, sql
import cgi import os, http
import funct from jinja2 import Environment, FileSystemLoader
import ovw env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('ovw.html')
funct.head("Overview")
funct.check_config() print('Content-type: text/html\n')
funct.check_login() funct.check_login()
funct.get_auto_refresh("Overview")
print("<script>if (cur_url[0] == 'overview.py') { $('#secIntervals').css('display', 'none');}</script>")
print('<script> window.onload = showOverview()</script><div id="ajax"></div>')
funct.footer() try:
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
user = sql.get_user_name_by_uuid(user_id.value)
except:
pass
output_from_parsed_template = template.render(h2 = 1,
autorefresh = 1,
title = "Overview",
role = sql.get_user_role_by_uuid(user_id.value),
user = user)
print(output_from_parsed_template)

View File

@ -1,32 +1,41 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import html, http
import cgi import cgi
import sys import sys
import os import os
import funct import funct, sql
from configparser import ConfigParser, ExtendedInterpolation from configparser import ConfigParser, ExtendedInterpolation
from jinja2 import Environment, FileSystemLoader
funct.head("Admin area: View settings") env = Environment(loader=FileSystemLoader('templates/'))
funct.check_config() template = env.get_template('viewsettings.html')
funct.check_login() form = cgi.FieldStorage()
funct.page_for_admin()
path_config = "haproxy-webintarface.config" path_config = "haproxy-webintarface.config"
config = ConfigParser(interpolation=ExtendedInterpolation()) config = ConfigParser(interpolation=ExtendedInterpolation())
config.read(path_config) config.read(path_config)
fullpath = config.get('main', 'fullpath') fullpath = config.get('main', 'fullpath')
print('<h2>Admin area: View settings</h2>' print('Content-type: text/html\n')
'<div id="ajax">' funct.check_login()
'<h3 style="padding-left: 30px; width:inherit; margin: 0" class="overviewHead padding10">Only view, edit you can here: {fullpath}/haproxy-webintarface.config</h3>' funct.page_for_admin()
'<pre>'.format(fullpath=fullpath)) try:
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
user = sql.get_user_name_by_uuid(user_id.value)
servers = sql.get_dick_permit()
except:
pass
config_items_section_name = {}
for section_name in config.sections(): for section_name in config.sections():
print('Section:', section_name) config_items_section_name[section_name] = {}
for name, value in config.items(section_name): for name, value in config.items(section_name):
print(' {} = {}'.format(name, value)) config_items_section_name[section_name][name] = value
print()
print('</div>')
funct.footer()
output_from_parsed_template = template.render(h2 = 1, title = "Admin area: View settings",
role = sql.get_user_role_by_uuid(user_id.value),
user = user,
fullpath = fullpath,
config_items_section_name = config_items_section_name)
print(output_from_parsed_template)

359
app/templates/add.html Normal file
View File

@ -0,0 +1,359 @@
{% extends "base.html" %}
{% block content %}
<div id="tabs">
<ul>
<li><a href="#listen">Listen</a></li>
<li><a href="#frontend">Frontend</a></li>
<li><a href="#backend">Backend</a></li>
<li><a href="#ssl">SSL certificates</a></li>
</ul>
<div id="listen">
<form name="add-listner" action="/app/add.py">
<table>
<caption><h3 style="margin-left: 20px; margin-bottom: 10px;">Add listen</h3></caption>
<tr>
<td class="addName">Select server: </td>
<td class="addOption">
<select required name="serv" id="serv">
<option disabled selected>Choose server</option>
{% for select in selects %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endfor %}
</select>
<div class="tooltip tooltipTop"><b>Note:</b> If you reconfigure Master server, Slave will reconfigured automatically</div>
</td>
</tr>
<tr>
<td class="addName">Name:</td>
<td class="addOption">
<input type="text" name="listner" id="name" required title="Name Listner" placeholder="web_80" class="form-control">
</td>
</tr>
<tr>
<td class="addName">IP and Port:</td>
<td class="addOption">
<input type="text" name="ip" id="ip" title="" size="15" placeholder="172.28.0.1" class="form-control"><b>:</b>
<input type="number" name="port" id="listen-port" required title="Port for bind listen" size="5" placeholder="8080" class="form-control">
<div class="tooltip tooltipTop">IP for bind listner, <b>if empty will be assignet on all IPs</b>. Start typing ip, or press down.<br>If you use <b>VRRP keep in blank</b>. If you assign an IP, the slave will not start</div>
</td>
</tr>
<tr>
<td class="addName">Mode: </td>
<td class="addOption">
<select required name="mode" id="listen-mode-select">
<option value="http" selected>http</option>
<option value="tcp">tcp</option>
</select>
<span id="https-listen-span">
<label for="https-listen" style="margin-top: 5px;" title="Enable ssl">ssl?</label>
<input type="checkbox" id="https-listen" name="ssl" value="https" >
</span>
<div id="https-hide-listen" style="display: none;">
<br /><span class="tooltip tooltipTop">Enter name to pem file, or press down:</span><br />
<input type="text" name="cert" placeholder="some_cert.pem" class="form-control" size="39" id="path-cert-listen"> or upload: <input type="file" name="file"><br />
<label for="ssl-check-listen" style="margin-top: 5px;">Disable ssl verify on servers?</label><input type="checkbox" id="ssl-check-listen" name="ssl-check" value="ssl-check" checked>
</div>
</td>
</tr>
<tr>
<td class="addName">Balance: </td>
<td class="addOption">
<select required name="balance">
<option value="roundrobin" selected>roundrobin</option>
<option value="source">source</option>
<option value="leastconn">leastconn</option>
<option value="first">first</option>
<option value="rdp-cookie">rdp-cookie</option>
</select>
</td>
</tr>
<tr>
<td class="addName">Optinons:</td>
<td class="addOption">
<label for="options-listen-show" style="margin-top: 5px;" title="Set options">Set</label><input type="checkbox" id="options-listen-show">
<div id="options-listen-show-div" style="display: none;">
<div class="tooltip">
<span style="padding-right: 10px;" class="form-control">Start typing options: </span>
<input type="text" id="options" class="form-control">
<span style="padding-left: 10px;">
or press down. <a href="http://cbonte.github.io/haproxy-dconv/1.7/configuration.html" target="_blanck" style="color: #23527c" title="HAproxy docs">Read more about options</a>
</span>
</div>
<textarea name="option" title="Options thru" id="optionsInput" cols=80 placeholder="acl test hdr_beg(host) -i some_host"></textarea>
</div>
</td>
</tr>
<tr>
<td class="addName">Servers:</td>
<td class="addOption">
<textarea name="servers" required title="Backend servers" cols=80 placeholder="hostname ip:port"></textarea>
<div>
<label for="controlgroup-listen-show" style="margin-top: 5px;" title="Change default check">Cusmot check params</label>
<input type="checkbox" id="controlgroup-listen-show" name="default-check" value="1">
<span class="tooltip tooltipTop"> Default params: inter 2000 rise 2 fall 5</span>
</div>
<div class="controlgroup" id="controlgroup-listen" style="display: none;">
<label for="check-servers-listen" title="Ebable servers check">Check</label>
<input type="checkbox" id="check-servers-listen" name="check-servers" checked value="1">
<select name="inter" id="inter-listen">
<option value="inter" disabled selected>inter</option>
<option value="1000">1000</option>
<option value="2000">2000</option>
<option value="3000">3000</option>
</select>
<select name="rise" id="rise-listen">
<option value="rise" disabled selected>rise</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select name="fall" id="fall-listen">
<option value="fall" disabled selected>fall</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</div>
</td>
</tr>
<tr>
<td class="addButton">
<button type="submit" value="" name="" class="btn btn-default">Add Listen</button>
</td>
</tr>
</form>
</table></div>
<!-- Second tabs -->
<div id="frontend">
<form name="add-frontend" action="/app/add.py">
<table>
<caption><h3 style="margin-left: 20px; margin-bottom: 10px;">Add frontend</h3></caption>
<tr>
<td class="addName">Select server: </td>
<td class="addOption">
<select required name="serv" id="serv2">
<option disabled selected>Choose server</option>
{% for select in selects %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endfor %}
</select>
<div class="tooltip tooltipTop"><b>Note:</b> If you reconfigure Master server, Slave will reconfigured automatically</div>
</td>
</tr>
<tr>
<td class="addName">Name:</td>
<td class="addOption">
<input type="text" name="frontend" id="frontend" required title="Name frontend" placeholder="web_80" class="form-control">
</td>
</tr>
<tr>
<td class="addName">IP and Port:</td>
<td class="addOption">
<input type="text" name="ip" id="ip1" size="15" placeholder="172.28.0.1" class="form-control"><b>:</b>
<input type="number" name="port" required title="Port for bind frontend" placeholder="8080" class="form-control">
<div class="tooltip tooltipTop">IP for bind listner, <b>if empty will be assignet on all IPs</b>. Start typing ip, or press down.<br>If you use <b>VRRP keep in blank</b>. If you assign an IP, the slave will not start</div>
</td>
</tr>
<tr>
<td class="addName">Mode: </td>
<td class="addOption">
<select required name="mode" id="frontend-mode-select">
<option value="http" selected>http</option>
<option value="tcp">tcp</option>
</select>
<span id="https-frontend-span">
<label for="https-frontend" style="margin-top: 5px;">ssl?</label>
<input type="checkbox" id="https-frontend" name="ssl" value="https">
</span>
<div id="https-hide-frontend" style="display: none;">
<br /><span class="tooltip tooltipTop">Enter name to pem file, or press down:</span><br />
<input type="text" name="cert" placeholder="some_cert.pem" class="form-control" size="39" id="path-cert-frontend">
</div>
</td>
</tr>
<tr>
<td class="addName">Optinons:</td>
<td class="addOption">
<label for="options-frontend-show" style="margin-top: 5px;" title="Set options">Set</label><input type="checkbox" id="options-frontend-show">
<div id="options-frontend-show-div" style="display: none;">
<div style="font-size: 12px; padding-bottom: 10px;">
<span style="padding-right: 10px;">Start typing options: </span>
<input type="text" id="options1" class="form-control">
<span style="padding-left: 10px;">
or press down. <a href="http://cbonte.github.io/haproxy-dconv/1.7/configuration.html" target="_blanck" style="color: #23527c" title="HAproxy docs">Read more about options</a>
</span>
</div>
<textarea name="option" title="Options thru" cols=80 id="optionsInput1" placeholder="acl test hdr_beg(host) -i some_host"></textarea>
</div>
</td>
</tr>
<tr>
<td class="addName">Default backend</td>
<td class="addOption">
<div style="font-size: 12px; padding-bottom: 10px;">Start typing backend, or press down</div>
<input name="backend" id="backends" required size="30" placeholder="some_backend" class="form-control">
<span style="font-size: 12px; padding-left: 10px;"> .</span>
<p style="font-size: 12px"><b>Note:</b> If backend don\t exist, you must <a href="#" style="color: #23527c" title="Create backend" id="redirectBackend">create backend first</a>.</p>
</td>
</tr>
<tr>
<td class="addButton">
<button type="submit" value="" name="" class="btn btn-default">Add Frontend</button>
</td>
</tr>
</form>
</table>
</div>
<!-- Third tabs -->
<div id="backend">
<form name="add-backend" action="/app/add.py">
<table>
<caption><h3 style="margin-left: 20px; margin-bottom: 10px;">Add backend</h3></caption>
<tr>
<td class="addName">Select server: </td>
<td class="addOption">
<select required name="serv" id="serv3">
<option disabled selected>Choose server</option>
{% for select in selects %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endfor %}
</select>
<div class="tooltip tooltipTop"><b>Note:</b> If you reconfigure Master server, Slave will reconfigured automatically</div>
</td>
</tr>
<tr>
<td class="addName">Name:</td>
<td class="addOption">
<input type="text" name="backend" id="backend" required title="Name backend" placeholder="web_80" class="form-control">
</td>
</tr>
<tr>
<td class="addName">Mode: </td>
<td class="addOption">
<select required name="mode" id="backend-mode-select">
<option value="http" selected>http</option>
<option value="tcp">tcp</option>
</select>
<span id="https-backend-span">
<label for="https-backend" style="margin-top: 5px;">Ssl enabled on frontend?</label>
<input type="checkbox" id="https-backend" name="ssl" value="https">
</span>
<div id="https-hide-backend" style="display: none;">
<br /><span class="tooltip tooltipTop">Enter name to pem file, or press down:</span><br />
<input type="text" name="cert" placeholder="some_cert.pem" class="form-control" size="39" id="path-cert-backend"><br />
<label for="ssl-check" style="margin-top: 5px;">Disable ssl verify on servers?</label><input type="checkbox" id="ssl-check" name="ssl-check" value="ssl-check" checked>
</div>
</td>
</tr>
<tr>
<td class="addName">Balance: </td>
<td class="addOption">
<select required name="balance">
<option value="roundrobin" selected>roundrobin</option>
<option value="source">source</option>
<option value="leastconn">leastconn</option>
<option value="first">first</option>
<option value="rdp-cookie">rdp-cookie</option>
</select>
</td>
</tr>
<tr>
<td class="addName">Optinons:</td>
<td class="addOption">
<label for="options-backend-show" style="margin-top: 5px;" title="Set options">Set</label><input type="checkbox" id="options-backend-show">
<div id="options-backend-show-div" style="display: none;">
<div style="font-size: 12px; padding-bottom: 10px;">
<span style="padding-right: 10px;">Start typing options: </span>
<input type="text" id="options2" class="form-control">
<span style="padding-left: 10px;">
or press down. <a href="http://cbonte.github.io/haproxy-dconv/1.7/configuration.html" target="_blanck" style="color: #23527c" title="HAproxy docs">Read more about options</a>
</span>
</div>
<textarea name="option" title="Options thru" cols=80 id="optionsInput2" placeholder="acl test hdr_beg(host) -i some_host"></textarea>
</div>
</td>
</tr>
<tr>
<td class="addName">Servers:</td>
<td class="addOption">
<textarea name="servers" title="Backend servers" required cols=80 placeholder="hostname ip:port"></textarea>
<div>
<label for="controlgroup-backend-show" style="margin-top: 5px;" title="Change default check" >Cusmot check params</label>
<input type="checkbox" id="controlgroup-backend-show" name="default-check">
<span class="tooltip tooltipTop"> Default params: inter 2000 rise 2 fall 5</span>
</div>
<div class="controlgroup" id="controlgroup-backend" style="display: none;">
<label for="check-servers-backend" title="Ebable servers check">Check</label>
<input type="checkbox" id="check-servers-backend" name="check-servers" checked value="1">
<select name="inter" id="inter-backend">
<option value="inter" disabled selected>inter</option>
<option value="1000">1000</option>
<option value="2000">2000</option>
<option value="3000">3000</option>
</select>
<select name="rise" id="rise-backend">
<option value="rise" disabled selected>rise</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select name="fall" id="fall-backend">
<option value="fall" disabled selected>fall</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</div>
</td>
</tr>
<tr>
<td class="addButton">
<button type="submit" value="" name="" class="btn btn-default">Add Backend</button>
</td>
</tr>
</form>
</table>
</div>
<div id="ssl">
<table>
<tr class="overviewHead">
<td class="padding10 first-collumn">Upload SSL certificates</td>
<td>
Certificate name
</td>
<td>
<span title="This pem file will be used to create https connection with haproxy">Paste certificate content here(?)</span>
</td>
</tr>
<tr style="width: 50%;">
<td class="first-collumn" valign="top" style="padding-top: 15px;">
<select required id="serv4">
<option disabled selected>Choose server</option>
{% for select in selects %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endfor %}
</select>
</td>
<td valign="top" style="padding-top: 27px;">
<input type="text" id="ssl_name" class="form-control">
</td>
<td style="padding-top: 15px; padding-bottom: 15px;">
<textarea id="ssl_cert" cols="50" rows="5"></textarea><br /><br />
<a class="ui-button ui-widget ui-corner-all" id="ssl_key_upload" title="Upload ssl certificates">Upload</a>
</td>
</tr>
</table>
<div id="ajax-ssl"></div>
</div>
{% if add %}
<div class="alert alert-success">
<h3>{{ add }} was success added</h3>
{{ conf_add }}
</div>
{% endif %}
{% endblock %}

303
app/templates/admin.html Normal file
View File

@ -0,0 +1,303 @@
{% extends "base.html" %}
{% block content %}
<script src="/inc/users.js"></script>
<div id="tabs">
<ul>
<li><a href="#users">Users</a></li>
<li><a href="#groups">Groups</a></li>
<li><a href="#servers">Servers</a></li>
<li><a href="#roles">Roles</a></li>
<li><a href="#cert">SSH key</a></li>
</ul>
<div id="users">
<table class="overview" id="ajax-users">
<tr class="overviewHead">
<td class="padding10 first-collumn">Login name</td>
<td>Password</td>
<td>Email</td>
<td>Role</td>
<td>Group</td>
<td></td>
<td></td>
</tr>
<tr>
{% for user in users %}
<tr id="user-{{user.0}}">
<td class="padding10 first-collumn"><input type="text" id="login-{{user.0}}" value="{{user.1}}" class="form-control"></td>
<td><input type="password" id="password-{{user.0}}" value="{{user.3}}" class="form-control"></td>
<td><input type="text" id="email-{{user.0}}" value="{{user.2}}" class="form-control"></td>
<td>
<select id="role-{{user.0}}" name="role-{{user.0}}">
<option disabled selected>Choose role</option>
{% for role in roles %}
{% if user.4 == role.1 %}
<option value="{{ role.1 }}" selected>{{ role.1 }}</option>
{% else %}
<option value="{{ role.1 }}">{{ role.1 }}</option>
{% endif %}
{% endfor %}
</select>
</td>
<td>
<select id="usergroup-{{user.0}}" name="usergroup-{{user.0}}">
<option disabled selected>Choose group</option>
{% for group in groups %}
{% if user.5 == group.0|string() %}
<option value="{{ group.0 }}" selected>{{ group.1 }}</option>
{% else %}
<option value="{{ group.0 }}">{{ group.1 }}</option>
{% endif %}
{% endfor %}
</select>
</td>
<td><a class="delete" onclick="removeUser({{user.0}})" style="cursor: pointer;"></a></td>
</tr>
{% endfor %}
</table>
<br /><span class="add-button" title="Add user" id="add-user-button">+ Add</span>
<br /><br />
<table class="overview" id="user-add-table" style="display: none;">
<tr class="overviewHead">
<td class="padding10 first-collumn">New user</td>
<td>Password</td>
<td>Email</td>
<td>Role</td>
<td>Group</td>
<td></td>
</tr>
<tr>
<td class="padding10 first-collumn">
<input type="text" name="new-username" id="new-username" class="form-control">
</td>
<td>
<input type="password" name="new-password" id="new-password" class="form-control">
</td>
<td>
<input type="text" name="new-email" id="new-email" class="form-control">
</td>
<td>
<select id="new-role" name="new-role">
<option disabled selected>Choose role</option>
{% for role in roles %}
<option value="{{ role.1 }}">{{ role.1 }}</option>
{% endfor %}
</select>
</td>
<td>
<select id="new-group" name="new-group">
<option disabled selected>Choose group</option>
{% for group in groups %}
<option value="{{ group.0 }}">{{ group.1 }}</option>
{% endfor %}
</select>
</td>
<td>
<a class="add-admin" id="add-user" style="cursor: pointer;"></a>
</td>
</tr>
</table>
</div>
<div id="groups">
<table class="overview" id="ajax-group">
<tr class="overviewHead">
<td class="padding10 first-collumn">Name</td>
<td>Desciption</td>
<td></td>
<td></td>
</tr>
{% for group in groups %}
<tr id="group-{{ group.0 }}">
{% if group.1 == All %}
<td class="padding10 first-collumn">{{ group.1 }}</td>
<td>{{ group.2 }}</td>
<td></td>
{% else %}
<td class="padding10 first-collumn">
<input type="text" id="name-{{ group.0 }}" value="{{ group.1 }}" class="form-control">
</td>
<td>
<input type="text" id="descript-{{ group.0 }}" value="{{ group.2 }}" class="form-control" size="100">
</td>
<td>
<a class="delete" onclick="removeGroup({{ group.0 }})" style="cursor: pointer;"></a>
</td>
{% endif %}
</tr>
{% endfor %}
</table>
<br /><span class="add-button" title="Add group" id="add-group-button">+ Add</span>
<br /><br />
<table class="overview" id="group-add-table" style="display: none;">
<tr class="overviewHead">
<td class="padding10 first-collumn">New group name</td>
<td>Desciption</td>
<td></td>
</tr>
<tr>
<td class="padding10 first-collumn">
<input type="text" name="new-group-add" id="new-group-add" class="form-control">
</td>
<td>
<input type="text" name="new-desc" id="new-desc" class="form-control" size="100">
</td>
<td>
<a class="add-admin" id="add-group" style="cursor: pointer;"></a>
</td>
</tr>
</table>
</div>
<div id="servers">
<table class="overview" id="ajax-servers">
<tr class="overviewHead">
<td class="padding10 first-collumn">Hostname</td>
<td>IP</td>
<td>Group</td>
<td>Enable</td>
<td><span title="Vitrual IP, something like VRRP">Virt(?)</span></td>
<td><span title="Actions with master config will automatically apply on slave">Slave for (?)</span></td>
<td></td>
<td></td>
</tr>
{% for server in servers %}
<tr id="server-{{server.0}}">
<td class="padding10 first-collumn">
<input type="text" id="hostname-{{server.0}}" value="{{server.1}}" class="form-control">
</td>
<td>
<input type="text" id="ip-{{server.0}}" value="{{server.2}}" class="form-control">
</td>
<td>
<select id="servergroup-{{server.0}}" name="servergroup-{{server.0}}">
<option disabled selected>Choose group</option>
{% for group in groups %}
{% if server.3 == group.0|string() %}
<option value="{{ group.0 }}" selected>{{ group.1 }}</option>
{% else %}
<option value="{{ group.0 }}">{{ group.1 }}</option>
{% endif %}
{% endfor %}
</select>
</td>
<td>
{% if server.5 == 1 %}
<label for="enable-{{server.0}}"></label><input type="checkbox" id="enable-{{server.0}}" checked>
{% else %}
<label for="enable-{{server.0}}"></label><input type="checkbox" id="enable-{{server.0}}">
{% endif %}
</td>
<td>
{% if server.4 == 1 %}
<label for="typeip-{{server.0}}"></label><input type="checkbox" id="typeip-{{server.0}}" checked>
{% else %}
<label for="typeip-{{server.0}}"></label><input type="checkbox" id="typeip-{{server.0}}">
{% endif %}
</td>
<td>
<select id="slavefor-{{server.0}}">
<option value="0" selected>Not slave</option>
{% for master in masters %}
{% if master.0 == server.6 %}
<option value="{{master.0}}" selected>{{master.1}}</option>
{% else %}
<option value="{{master.0}}">{{master.1}}</option>
{% endif %}
{% endfor %}
</select>
</td>
<td>
<a class="delete" onclick="removeServer({{server.0}})" style="cursor: pointer;"></a>
</td>
</tr>
{% endfor %}
</table>
<br /><span class="add-button" title="Add server" id="add-server-button">+ Add</span>
<br /><br />
<table class="overview" id="server-add-table" style="display: none;">
<tr class="overviewHead">
<td class="padding10 first-collumn">New hostname</td>
<td>IP</td>
<td>Group</td>
<td>Enable</td>
<td>Virt</td>
<td title="Actions with master config will automatically apply on slave">Slave for</td>
<td></td>
</tr>
<tr>
<td class="padding10 first-collumn">
<input type="text" name="new-server-add" id="new-server-add" class="form-control">
</td>
<td>
<input type="text" name="new-ip" id="new-ip" class="form-control">
</td>
<td>
<select id="new-server-group-add" name="new-server-group-add">
<option disabled selected>Choose group</option>
{% for group in groups %}
<option value="{{ group.0 }}">{{ group.1 }}</option>
{% endfor %}
</select>
</td>
<td>
<label for="enable"></label><input type="checkbox" id="enable" checked>
</td>
<td>
<label for="typeip"></label><input type="checkbox" id="typeip">
</td>
<td>
<select id="slavefor" value="0" selected>
<option>Not slave</option>
{% for master in masters %}
<option value="{{master.0}}">{{master.1}}</option>
{% endfor %}
</select>
</td>
<td>
<a class="add-admin" id="add-server" style="cursor: pointer;"></a>
</td>
</tr>
</table>
</div>
<div id="roles">
<table class="overview" id="ajax-group">
<tr class="overviewHead">
<td class="padding10 first-collumn">Name</td>
<td>Desciption</td>
<td></td>
<td></td>
</tr>
<tr>
{% for role in roles %}
<tr id="group-{{role.0}}">
<td class="padding10 first-collumn">{{role.1}}</td>
<td>{{role.2}}</td>
</tr>
{% endfor %}
</table>
</div>
<div id="cert">
<table id="ssh">
<tr class="overviewHead" style="width: 50%;">
<td class="padding10 first-collumn">Upload SSH Key</td>
<td>
<span title="Private key. Note: The public key must be pre-installed on all servers to which you plan to connect">Key(?)</span>
</td>
<td></td>
</tr>
<tr style="width: 50%;">
<td class="first-collumn" valign="top" style="padding-top: 15px;">
<b>Note:</b> Paste pem file content here
</td>
<td style="padding-top: 15px;">
<textarea id="ssh_cert" cols="50" rows="5"></textarea><br /><br />
<a class="ui-button ui-widget ui-corner-all" id="ssh_key_upload" title="Upload ssh key" onclick="uploadSsh()">Upload</a>
</td>
<td></td>
</tr>
</table>
<div id="ajax-ssh"></div>
</div>
</div>
{% endblock %}

188
app/templates/base.html Normal file
View File

@ -0,0 +1,188 @@
<html>
<head>
<title>{{title}} - HAproxy-WI</title>
<meta charset="UTF-8">
<link href="/image/pic/favicon.ico" rel="icon" type="image/png" />
<script>
FontAwesomeConfig = { searchPseudoElements: true, observeMutations: false };
</script>
<script defer src="/inc/fa-solid.min.js"></script>
<script defer src="/inc/fontawesome.min.js"></script>
<link href="/inc/awesome.css" rel="stylesheet">
<link href="/inc/vertical_scrol/custom_scrollbar.css" rel="stylesheet">
<link href="/inc/style.css" rel="stylesheet">
<link href="/inc/nprogress.css" rel="stylesheet">
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="/inc/js-cookie.js"></script>
<script src="/inc/script.js"></script>
<script src="/inc/configshow.js"></script>
<script src="/inc/nprogress.js"></script>
<script src="/inc/vertical_scrol/custom_scrollbar.min.js"></script>
</head>
<body>
<a name="top"></a>
<div class="show_menu" style="display: none;">
<a href="#" id="show_menu" title="Show menu" style="margin-top: 30px;position: absolute;">
<span class="ui-state-default ui-corner-all">
<span class="ui-icon ui-icon-arrowthick-1-e" id="arrow"></span>
</span>
</a>
</div>
<div class="top-menu">
<div class="LogoText">
<span style="padding: 10px;">HAproxy-WI</span>
<a href="#" id="hide_menu" title="Hide menu" style="margin-left: 16px;margin-top: -10px;position: absolute;">
<span class="ui-state-default ui-corner-all">
<span class="ui-icon ui-icon-arrowthick-1-w" id="arrow"></span>
</span>
</a>
</div>
<div class="top-link">
<nav class="menu">
<ul>
<li><a title="Statistics, monitoring and logs" class="stats">Stats</a>
<li><a href=/app/overview.py title="Server and service status" class="overview-link head-submenu">Overview</a> </li>
<li><a href=/app/viewsttats.py title"Show stats" class="stats head-submenu">Stats</a> </li>
<li><a href=/app/logs.py title="View logs" class="logs head-submenu">Logs</a></li>
<li><a href=/app/map.py title="View map" class="map head-submenu">Map</a></li>
</li>
<li><a href=/app/edit.py title="Runtime API" class="runtime">Runtime API</a> </li>
<li><a title="Actions with Haproxy configs" class="config-show">Haproxy</a>
<li><a href=/app/configshow.py title="Show Haproxy Config" class="config-show head-submenu">Show config</a></li>
<li><a href=/app/diff.py title="Compare Haproxy Configs" class="compare head-submenu">Compare configs</a></li>
{% if user %}
{% if role <= 2 %}
<li><a href=/app/add.py#listner title="Add single listen" class="add head-submenu">Add listen</a></li>
<li><a href=/app/add.py#frontend title="Add single frontend" class="add head-submenu">Add frontend</a></li>
<li><a href=/app/add.py#backend title="Add single backend" class="add head-submenu">Add backend</a></li>
<li><a href=/app/add.py#ssl title="Upload SSL cert" class="cert head-submenu">SSL</a></li>
<li><a href=/app/config.py title="Edit Haproxy Config" class="edit head-submenu">Edit config</a> </li>
{% endif %}
{% if role <= 1 %}
<li><a href=/app/ihap.py title="Installation HAProxy" class="hap head-submenu">Installation</a> </li>
{% endif %}
</li>
{% if role <= 1 %}
<li><a title="Keepalived" class="ha">Keepalived</a>
<li><a href=/app/ha.py title="Create HA cluster" class="keepalived head-submenu">HA</a></li>
<li><a href=/app/keepalivedconfig.py title="Edit keepalived config" class="edit head-submenu">Edit config</a></li>
</li>
{% endif %}
<li><a title="Actions with configs" class="version">Versions</a>
<li><a href=/app/configver.py title="Upload old versions configs" class="upload head-submenu">Upload</a></li>
{% if role <= 1 %}
<li><a href=/app/delver.py title="Delete old versions configs" class="delete head-submenu">Delete</a></li>
{% endif %}
</li>
{% if user %}
<li><a href=/app/login.py?logout=logout title="Logout, user name: {{ user }}" class="login">Logout</a></li>
{% else %}
<li><a href=/app/login.py title="Login" class="login">Login</a></li>
{% endif %}
{% if role <= 1 %}
<li><a title="Admin area" class="admin">Admin area</a>
<li><a href=/app/users.py#users title="Actions with users" class="users head-submenu">Users</a></li>
<li><a href=/app/users.py#groups title="Actions with groups" class="group head-submenu">Groups</a></li>
<li><a href=/app/users.py#servers title="Actions with servers" class="runtime head-submenu">Servers</a></li>
<li><a href=/app/users.py#roles title="Users roles" class="role head-submenu">Roles</a></li>
<li><a href=/app/settings.py title="View settings" class="settings head-submenu">View settings</a></li>
<li><a href=/app/viewlogs.py title="View users actions logs" class="logs head-submenu">View logs</a></li>
</li>
{% endif %}
{% endif %}
</ul>
</nav>
<div class="copyright-menu">HAproxy-WI v2.5</div>
</div>
</div>
<div class="container">
{% if h2 %}
<h2>
{{title}}
{% if autorefresh %}
<span class="auto-refresh">
<a onclick="pauseAutoRefresh()" class="auto-refresh-pause" style="display: none; margin-top: 4px;"></a>
<a onclick="pauseAutoResume()" class="auto-refresh-resume" style="display: none; margin-top: 4px;"></a>
<a id="0"><img src="/image/pic/update.png" alt="restart" class="icon"> Auto-refresh</a>
<a id="1" style="display: none;"><img src="/image/pic/update.png" alt="restart" class="icon"> Auto-refresh</a>
</span>
{% endif %}
</h2>
{% endif %}
{% if autorefresh %}
<div class="auto-refresh-div">
<div class="auto-refresh-head">
Refresh Interval
</div>
<div class="auto-refresh-interval">
<div class="auto-refresh-ul">
<ul>
<li>
<a class="ui-button ui-widget ui-corner-all" onclick="setRefreshInterval(0)" title="Turn off auto-refresh">Off</a>
</li>
</ul>
</div>
<div class="auto-refresh-ul" id="secIntervals">
<ul>
<li>
<a title="Auto-refresh every 5 seconds" onclick="setRefreshInterval(5000)">5 seconds</a>
</li>
<li>
<a title="Auto-refresh every 10 seconds" onclick="setRefreshInterval(10000)">10 seconds</a>
</li>
<li>
<a title="Auto-refresh every 30 seconds" onclick="setRefreshInterval(30000)">30 seconds</a>
</li>
<li>
<a title="Auto-refresh ever 45 seconds" onclick="setRefreshInterval(45000)">45 seconds</a>
</li>
</ul>
</div>
<div class="auto-refresh-ul">
<ul>
<li>
<a title="Auto-refresh every 1 minute" onclick="setRefreshInterval(60000)">1 minute</a>
</li>
<li>
<a title="Auto-refresh every 5 minutes" onclick="setRefreshInterval(300000)">5 minutes</a>
</li>
<li>
<a title="Auto-refresh every 15 minutes" onclick="setRefreshInterval(900000)">15 minutes</a>
</li>
<li>
<a title="Auto-refresh ever 30 minutes" onclick="setRefreshInterval(1800000)">30 minutes</a>
</li>
</ul>
</div>
<div class="auto-refresh-ul">
<ul>
<li>
<a title="Auto-refresh every 1 hour" onclick="setRefreshInterval(3600000)">1 hour</a>
</li>
<li>
<a title="Auto-refresh every 2 hour" onclick="setRefreshInterval(7200000)">2 hour</a>
</li>
<li>
<a title="Auto-refresh every 12 hour" onclick="setRefreshInterval(43200000)">12 hour</a>
</li>
<li>
<a title="Auto-refresh ever 1 day" onclick="setRefreshInterval(86400000)">1 day</a>
</li>
</ul>
</div>
</div>
</div>
{% endif %}
{% block content %}{% endblock %}
<div id="ajax-compare"></div>
<div id="ajax"></div>
</div>
<center style="margin-left: 8%;">
<h3>
<a class="ui-button ui-widget ui-corner-all" href="#top" title="Move up">UP</a>
</h3><br />
</center>
</body>
</html>

67
app/templates/config.html Normal file
View File

@ -0,0 +1,67 @@
{% extends "base.html" %}
{% block content %}
<center>
<h3>Choose server</h3>
<p>
<form action="{{ action }}" method="get">
<select autofocus required name="serv" id="{{ select_id }}">
<option disabled>Choose server</option>
{% for select in selects %}
{% if keepalived %}
{% if select.1 == serv %}
<option value="{{ select.1 }}" selected>{{ select.0 }}</option>
{% else %}
<option value="{{ select.1 }}">{{ select.0 }}</option>
{% endif %}
{% if select.3 == serv %}
<option value="{{ select.3 }}" selected>{{ select.2 }}</option>
{% else %}
<option value="{{ select.3 }}">{{ select.2 }}</option>
{% endif %}
{% else %}
{% if select.2 == serv %}
<option value="{{ select.2 }}" selected>{{ select.1 }}</option>
{% else %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endif %}
{% endif %}
{% endfor %}
</select>
{% if onclick %}
<a class="ui-button ui-widget ui-corner-all" id="show" title="Show config" onclick="{{ onclick }}">Show</a>
{% else %}
<button type="submit" value="open" name="open" class="btn btn-default">Open</button>
{% endif %}
</form>
</p>
{% if note %}
<div class="alert alert-info"><b>Note:</b> If you reconfigure Master server, Slave will reconfigured automatically</div>
{% endif %}
{% if config %}
<h3>Config from {{ serv }}</h3>
<form action="{{ action }}" name="saveconfig" method="get">
<input type="hidden" value="{{ serv }}" name="serv">
<input type="hidden" value="{{ cfg }}.old" name="oldconfig">
<textarea name="config" class="config" rows="35" cols="100">{{ config }}</textarea>
<p>
<button type="submit" value="save" name="save" class="btn btn-default">Just save</button>
<button type="submit" value="" name="" class="btn btn-default">Save and restart</button>
</p>
</form>
{% endif %}
{% if aftersave %}
<div class="alert alert-info">New config was saved as: {{ cfg }} </div>
<br><a href="viewsttats.py?serv={{ serv }}" target="_blank" title="View stats">Go to view stats</a>
{% if stderr %}
<div class="alert alert-danger">
Some errors:
<br>
<br>
{{stderr}}
</div>
{% else %}
<div class="alert alert-success">Config ok</div>
{% endif %}
{% endif %}
</center>
{% endblock %}

View File

@ -0,0 +1,56 @@
{% extends "base.html" %}
{% block content %}
<center>
<h3>Choose server</h3>
<p>
<form action="{{ action }}" method="get">
<select autofocus required name="serv" id="{{ select_id }}">
<option disabled>Choose server</option>
{% for select in selects %}
{% if select.2 == serv %}
<option value="{{ select.2 }}" selected>{{ select.1 }}</option>
{% else %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endif %}
{% endfor %}
</select>
<button type="submit" value="open" name="open" class="btn btn-default">Open</button>
</form>
</p>
{% if note %}
<div class="alert alert-info"><b>Note:</b> If you reconfigure Master server, Slave will reconfigured automatically</div>
{% endif %}
{% if open %}
<center>
<h3>Choose old version</h3>
<form action="configver.py#conf" method="get">
<p>
<select autofocus required name="configver" id="configver">
<option disabled selected>Choose version</option>
{% for file in return_files %}
<option {{file}}>{{file}}</option>
{% endfor %}
</select>
<input type="hidden" value="{{serv}}" name="serv">
<input type="hidden" value="open" name="open">
<a class="ui-button ui-widget ui-corner-all" id="show" title="Enter" onclick="{{ onclick }}">Select</a>
</p>
</form>
</center>
{% endif %}
{% if aftersave %}
<div class="alert alert-info">Uploaded old config ver: {{ configver }} </div>
<br><a href="viewsttats.py?serv={{ serv }}" target="_blank" title="View stats">Go to view stats</a>
{% if stderr %}
<div class="alert alert-danger">
Some errors:
<br>
<br>
{{stderr}}
</div>
{% else %}
<div class="alert alert-success">Config ok</div>
{% endif %}
{% endif %}
</center>
{% endblock %}

59
app/templates/delver.html Normal file
View File

@ -0,0 +1,59 @@
{% extends "base.html" %}
{% block content %}
<center>
<h3>Choose server</h3>
<p>
<form action="{{ action }}" method="get">
<select autofocus required name="serv" id="{{ select_id }}">
<option disabled>Choose server</option>
{% for select in selects %}
{% if select.2 == serv %}
<option value="{{ select.2 }}" selected>{{ select.1 }}</option>
{% else %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endif %}
{% endfor %}
</select>
<button type="submit" value="open" name="open" class="btn btn-default">Open</button>
</form>
</p>
{% if note %}
<div class="alert alert-info"><b>Note:</b> If you reconfigure Master server, Slave will reconfigured automatically</div>
{% endif %}
{% if open %}
<center>
<h3>Choose old version</h3>
<form action="delver.py#conf" method="get">
<label for="select_all" id="label_select_all"><b>Select all</b></label>
<input type="checkbox" id="select_all"><br />
{% for file in return_files %}
<label for="{{file}}"> {{file}} </label><input type="checkbox" value="{{file}}" name="{{file}}" id="{{file}}"><br />
{% endfor %}
<input type="hidden" value="{{serv}}" name="serv">
<input type="hidden" value="open" name="open">
<input type="hidden" value="del" name="del">
<p>
<button type="submit" value="" name="" class="btn btn-default">Delete</button>
</p>
</form>
</center>
{% endif %}
{% if aftersave %}
<div class="alert alert-info"><b>The following files were deleted:</b><br /> </div>
{% if stderr %}
<div class="alert alert-danger">
Some errors:
<br>
<br>
{{stderr}}
</div>
{% else %}
<div class="alert alert-success">
{% for f in file %}
{{f}}
{% endfor %}
</div>
{% endif %}
{% endif %}
</center>
{% endblock %}

88
app/templates/ha.html Normal file
View File

@ -0,0 +1,88 @@
{% extends "base.html" %}
{% block content %}
<script src="/inc/users.js"></script>
<table class="overview">
<caption class="overviewHead"><h3 style="margin-left: 20px; margin-bottom: 10px;">Create new HA cluster</h3></caption>
<tr class="overviewHead">
<td class="padding10 first-collumn">Master</td>
<td>Slave</td>
<td>VRRP interface</td>
<td>VRRP IP</td>
<td><span title="Haproxy-WI will try install haproxy-1.18.5, if it does not work then haproxy-1.15">Install HAProxy(?)</span></td>
<td></td>
</tr>
<tr>
<td class="padding10 first-collumn">
<select id="master">
<option disable selected>Choose master</option>
{% for select in selects %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endfor %}
</select>
</td>
<td>
<select id="slave">
<option disable selected>Choose master</option>
{% for select in selects %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endfor %}
</select>
</td>
<td>
<input type="text" id="interface" class="form-control">
</td>
<td>
<input type="text" id="vrrp-ip" class="form-control">
</td>
<td>
<label for="hap"></label><input type="checkbox" id="hap">
</td>
<td>
<a class="ui-button ui-widget ui-corner-all" id="create" title="Create HA configuration">Create</a>
</td>
</tr>
</table>
<table>
<caption class="overviewHead"><h3 style="margin-left: 20px; margin-bottom: 10px;">Or add VRRP to exist</h3></caption>
<tr class="overviewHead">
<td class="padding10 first-collumn">Master</td>
<td>Slave</td>
<td>VRRP interface</td>
<td>VRRP IP</td>
<td><span title="If checked Haproxy-WI will restart Keepalived">Restart Keepalived(?)</span></td>
<td></td>
</tr>
<tr>
<td class="padding10 first-collumn">
<select id="master-add">
<option disable selected>Choose master</option>
{% for select in selects %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endfor %}
</select>
</td>
<td>
<select id="slave-add">
<option disable selected>Choose master</option>
{% for select in selects %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endfor %}
</select>
</td>
<td>
<input type="text" id="interface-add" class="form-control">
</td>
<td>
<input type="text" id="vrrp-ip-add" class="form-control">
</td>
<td>
<label for="kp"></label><input type="checkbox" id="kp">
</td>
<td>
<a class="ui-button ui-widget ui-corner-all" id="add-vrrp" title="Add HA configuration">Add</a>
</td>
</tr>
</table>
<div id="ajax"></div>
{% endblock %}

27
app/templates/ihap.html Normal file
View File

@ -0,0 +1,27 @@
{% extends "base.html" %}
{% block content %}
<script src="/inc/users.js"></script>
<table class="overview">
<tr class="overviewHead">
<td class="padding10 first-collumn">Note</td>
<td>Server</td>
<td></td>
</tr>
<tr>
<td class="padding10 first-collumn">
<b>Haproxy-WI will try install haproxy-1.18.5, if it does not work then haproxy-1.15</b>
</td>
<td class="padding10 first-collumn">
<select autofocus required name="{{select_id}}" id="{{select_id}}">
<option disabled selected>Choose server</option>
{% for select in selects %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endfor %}
</select>
</td>
<td>
<a class="ui-button ui-widget ui-corner-all" id="install" title="Install HAProxy">Install</a>
</td>
</table>
<div id="ajax"></div>
{% endblock %}

15
app/templates/login.html Normal file
View File

@ -0,0 +1,15 @@
{% extends "base.html" %}
{% block content %}
<center>
<form name="auth" action="login.py" class="form-horizontal" method="get">
{{error_log}}
{{error}}
{{db_create}}
<br>
<label for="login">Login: </label><input type="text" name="login" required class="form-control"><br /><br />
<label for="pass">Pass: </label><input type="password" name="pass" required class="form-control"><br /><br />
<input type="hidden" value="{{reff}}" name="ref">
<button type="submit" name="Login" value="Enter">Sign Up</button>
</form>
</center>
{% endblock %}

43
app/templates/logs.html Normal file
View File

@ -0,0 +1,43 @@
{% extends "base.html" %}
{% block content %}
<table class="overview">
<tr class="overviewHead">
<td class="padding10 first-collumn">Server</td>
<td>Number rows</td>
<td class="padding10">Ex for grep</td>
<td> </td>
</tr>
<tr>
<td class="padding10 first-collumn">
<form action="logs.py" method="get">
<select autofocus required name="serv" id="serv">
<option disabled selected>Choose server</option>
{% for select in selects %}
{% if select.2 == serv %}
<option value="{{ select.2 }}" selected>{{ select.1 }}</option>
{% else %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endif %}
{% endfor %}
</select>
</td>
<td>
<input type="number" name="rows" id="rows" value="{{ rows }}" class="form-control" required>
</td>
<td class="padding10 first-collumn">
<input type="text" name="grep" id="grep" class="form-control" value="{{ grep }}" >
</td>
<td class="padding10 first-collumn">
<a class="ui-button ui-widget ui-corner-all" id="show" title="Show logs" onclick="{{ onclick }}">Show</a>
</form>
</td>
</tr>
</table>
<div id="ajax">
</div>
<script>
window.onload = showLog()
</script>
{% endblock %}

View File

@ -0,0 +1,53 @@
{% extends "base.html" %}
{% block content %}
<table class="overview">
<tr class="overviewHead">
<td class="padding10">Login</td>
<td class="padding10">Email</td>
<td>Group</td>
<td class="padding10">Role</td>
<td style="width: 200px;">
<span class="add-button">
<a href="#" title="Show all users" id="show-all-users" style="color: #fff">
Show all
</a>
</span>
</td>
</tr>
{% for user in users %}
<tr>
<td class="padding10 first-collumn"> {{ user.1 }}</td>
<td class="padding10"> {{ user.2 }}</td>
<td class="second-collumn">{{ user.5 }}</td>
<td>{{ user.4 }}</td>
<td></td>
</tr>
{% endfor %}
</table>
<table class="overview">
<tr class="overviewHead">
<td class="padding10">Server</td>
<td class="padding10">
HAproxy status
</td>
<td class="padding10">
Action
</td>
<td>
Last edit
</td>
</tr>
{% for server in servers %}
<tr>
<td class="padding10 first-collumn"><a title={{ server.1 }} style="color: #000">{{ server.1 }}</a></td>
<td class="second-collumn">{{ server.7 }}</td>
<td class="padding10">
<a href="/app/configshow.py?serv={{ server.2 }}&open=open#conf" title="Show config"><img src="/image/pic/show.png" alt="show" class="icon"></a>
<a href="/app/configshow.py?serv={{ server.2 }}&open=open#conf" title="Edit config"><img src="/image/pic/edit.png" alt="edit" class="icon"></a>
<a href="/app/configshow.py?serv={{ server.2 }}&open=open#conf" title="Compare config"><img src="/image/pic/compare.png" alt="compare" class="icon"></a>
<a href="/app/configshow.py?serv={{ server.2 }}&open=open#conf" title="Map listen/frontend/backend"><img src="/image/pic/map.png" alt="map" class="icon"></a>
</td>
</tr>
{% endfor %}
</table>
{% endblock %}

10
app/templates/ovw.html Normal file
View File

@ -0,0 +1,10 @@
{% extends "base.html" %}
{% block content %}
<script>
if (cur_url[0] == 'overview.py') {
$('#secIntervals').css('display', 'none');
}
window.onload = showOverview()
</script>
<div id="ajax"></div>
{% endblock %}

View File

@ -0,0 +1,46 @@
{% extends "base.html" %}
{% block content %}
<table class="overview">
<tr class="overviewHead">
<td class="padding10 first-collumn">Server</td>
<td>Disable/Enable server or output any information</td>
<td class="padding10">Command</td>
<td>Save change</td>
<td></td>
</tr>
<tr>
<td class="padding10 first-collumn" style="width: 25%;">
<form action= {{ action }} method="get">
<select autofocus required id="{{ select_id }}">
<option disabled>Choose server</option>
{% for select in selects %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endfor %}
</select>
</td>
<td style="width: 30%;">
<select required name="servaction" id="servaction">
<option disabled>Choose action</option>
{% if role <= 2 %}
<option value="disable">Disable</option>
<option value="enable">Enable</option>
<option value="set">Set</option>
{% endif %}
<option value="show" selected>Show</option>
</select>
</td>
<td>
<input type="text" name="servbackend" id="servbackend" size=35 title="Frontend, backend/server, show: info, pools or help" required class="form-control">
</td>
<td>
{% if role <= 2 %}
<label for="save"></label><input type="checkbox" name="save" id="save" value="123">
{% endif %}
</td>
<td>
<a class="ui-button ui-widget ui-corner-all" id="show" title="Enter" onclick="{{ onclick }}">Enter</a>
</td>
</form>
</tr>
</table>
{% endblock %}

View File

@ -0,0 +1,30 @@
{% extends "base.html" %}
{% block content %}
<center>
<h3>Choose server</h3>
<p>
<form action="{{ action }}" method="get">
<select autofocus required name="serv" id="{{ select_id }}">
<option disabled>Choose server</option>
{% for select in selects %}
{% if select == serv %}
<option value="{{ select }}" selected>{{ select }}</option>
{% else %}
<option value="{{ select }}">{{ select }}</option>
{% endif %}
{% endfor %}
</select>
{% if onclick %}
<a class="ui-button ui-widget ui-corner-all" id="show" title="Show config" onclick="{{ onclick }}">Show</a>
{% else %}
<button type="submit" value="open" name="open" class="btn btn-default">Open</button>
{% endif %}
</form>
</p>
</center>
<div id="ajax">
</div>
<script>
window.onload = viewLogs()
</script>
{% endblock %}

View File

@ -0,0 +1,15 @@
{% extends "base.html" %}
{% block content %}
<h3 style="padding-left: 30px; width:inherit; margin: 0" class="overviewHead padding10">Only view, edit you can here: {{ fullpath }}/haproxy-webintarface.config</h3>
<div style="padding-left: 40px;">
{% for name, value in config_items_section_name|dictsort(false) %}
<br><b>Section: {{name}}</b> <br>
<div style="padding-left:30px;">
{% for param, value2 in value|dictsort(false) %}
<br>{{param}} = {{value2}}
{% endfor %}
</div>
{% endfor %}
</div>
{% endblock %}

View File

@ -0,0 +1,20 @@
{% extends "base.html" %}
{% block content %}
<br />
<form style="padding-left: 20px;" action="viewsttats.py" method="get">
<select autofocus required name="serv" id="serv">
<option disabled>Choose server</option>
{% for select in selects %}
{% if select.2 == serv %}
<option value="{{ select.2 }}" selected>{{ select.1 }}</option>
{% else %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endif %}
{% endfor %}
</select>
<a class="ui-button ui-widget ui-corner-all" id="show" title="Show stats" onclick="{{ onclick }}">Show</a>
</form>
<div id="ajax" style="margin-left: 10px;"></div>
<script> window.onload = showStats()</script>
<link href="/inc/style.css" rel="stylesheet">
{% endblock %}

View File

@ -1,220 +1,32 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import html, http
import cgi import cgi
import sys import sys
import os import os
import funct import funct
import sql import sql
from jinja2 import Environment, FileSystemLoader
funct.head("Admin area: users manage") env = Environment(loader=FileSystemLoader('templates/'))
funct.check_config() template = env.get_template('admin.html')
funct.check_login()
funct.page_for_admin()
form = cgi.FieldStorage() form = cgi.FieldStorage()
USERS = sql.select_users() print('Content-type: text/html\n')
GROUPS = sql.select_groups() funct.check_login()
SERVERS = sql.select_servers(full=1) funct.page_for_admin()
ROLES = sql.select_roles() try:
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
user = sql.get_user_name_by_uuid(user_id.value)
servers = sql.get_dick_permit()
except:
pass
print('<script src="/inc/users.js"></script>' output_from_parsed_template = template.render(title = "Admin area: users manage",
'<div id="tabs">' role = sql.get_user_role_by_uuid(user_id.value),
'<ul>' user = user,
'<li><a href="#users">Users</a></li>' users = sql.select_users(),
'<li><a href="#groups">Groups</a></li>' groups = sql.select_groups(),
'<li><a href="#servers">Servers</a></li>' servers = sql.select_servers(full=1),
'<li><a href="#roles">Roles</a></li>' roles = sql.select_roles(),
'<li><a href="#cert">Ssh key</a></li>' masters = sql.select_servers(get_master_servers=1))
'</ul>' print(output_from_parsed_template)
'<div id="users">'
'<table class="overview" id="ajax-users">'
'<tr class="overviewHead">'
'<td class="padding10 first-collumn">Login name</td>'
'<td>Password</td>'
'<td>Email</td>'
'<td>Role</td>'
'<td>Group</td>'
'<td></td>'
'<td></td>'
'</tr><tr>')
for users in USERS:
print('<tr id="user-%s">' % users[0])
print('<td class="padding10 first-collumn"><input type="text" id="login-%s" value="%s" class="form-control"></td>' % (users[0], users[1]))
print('<td><input type="password" id="password-%s" value="%s" class="form-control"></td>' % (users[0], users[3]))
print('<td><input type="text" id="email-%s" value="%s" class="form-control"></td>' % (users[0], users[2]))
print('<td>')
need_id_role = "role-%s" % users[0]
sql.get_roles_select(need_id_role, selected=users[4])
print('</td>')
print('<td>')
need_id_group = "usergroup-%s" % users[0]
sql.get_groups_select(need_id_group, selected=users[5])
print('</td>')
print('<td><a class="delete" onclick="removeUser(%s)" style="cursor: pointer;"></a></td>' % users[0])
print('</tr>')
print('</table>'
'<br /><span class="add-button" title="Add user" id="add-user-button">+ Add</span>')
print('<br /><br /><table class="overview" id="user-add-table" style="display: none;">'
'<tr class="overviewHead">'
'<td class="padding10 first-collumn">New user</td>'
'<td>Password</td>'
'<td>Email</td>'
'<td>Role</td>'
'<td>Group</td>'
'<td></td>'
'</tr>'
'<tr>'
'<td class="padding10 first-collumn"><input type="text" name="new-username" id="new-username" class="form-control"></td>'
'<td><input type="password" name="new-password" id="new-password" class="form-control"></td>'
'<td><input type="text" name="new-email" id="new-email" class="form-control"></td><td>')
sql.get_roles_select("new-role")
print('</td><td>')
sql.get_groups_select("new-group")
print('</td>'
'<td><a class="add-admin" id="add-user" style="cursor: pointer;"></a></td>'
'</tr>')
print('</table>')
print('</div><div id="groups">'
'<table class="overview" id="ajax-group">'
'<tr class="overviewHead">'
'<td class="padding10 first-collumn">Name</td>'
'<td>Desciption</td>'
'<td></td>'
'<td></td>'
'</tr>')
i = 0
for group in GROUPS:
i = i + 1
print('<tr id="group-%s">' % group[0])
if i == 1:
print('<td class="padding10 first-collumn">%s</td>' % (group[1]))
print('<td>%s</td>' % (group[2]))
print('<td></td>')
else:
print('<td class="padding10 first-collumn"><input type="text" id="name-%s" value="%s" class="form-control"></td>' % (group[0], group[1]))
print('<td><input type="text" id="descript-%s" value="%s" class="form-control" size="100"></td>' % (group[0], group[2]))
print('<td><a class="delete" onclick="removeGroup(%s)" style="cursor: pointer;"></a></td>' % group[0])
print('</tr>')
print('</table>'
'<br /><span class="add-button" title="Add group" id="add-group-button">+ Add</span>')
print('<br /><br /><table class="overview" id="group-add-table" style="display: none;">'
'<tr class="overviewHead">'
'<td class="padding10 first-collumn">New group name</td>'
'<td>Desciption</td>'
'<td></td>'
'</tr>'
'<tr>'
'<td class="padding10 first-collumn"><input type="text" name="new-group-add" id="new-group-add" class="form-control"></td>'
'<td><input type="text" name="new-desc" id="new-desc" class="form-control" size="100"></td>'
'<td><a class="add-admin" id="add-group" style="cursor: pointer;"></a></td>'
'</tr>'
'</table>'
'</div>'
'<div id="servers">'
'<table class="overview" id="ajax-servers">'
'<tr class="overviewHead">'
'<td class="padding10 first-collumn">Hostname</td>'
'<td>IP</td>'
'<td>Group</td>'
'<td>Enable</td>'
'<td><span title="Vitrual IP, something like VRRP">Virt(?)</span></td>'
'<td><span title="Actions with master config will automatically apply on slave">Slave for (?)</span></td>'
'<td></td>'
'<td></td>'
'</tr>')
for server in SERVERS:
print('<tr id="server-%s">' % server[0])
print('<td class="padding10 first-collumn"><input type="text" id="hostname-%s" value="%s" class="form-control"></td>' % (server[0], server[1]))
print('<td><input type="text" id="ip-%s" value="%s" class="form-control"></td>' % (server[0], server[2]))
print('<td>')
need_id_group = "servergroup-%s" % server[0]
sql.get_groups_select(need_id_group, selected=server[3])
print('</td>')
print('<td>')
sql.get_enable_checkbox(server[0])
print('</td>')
print('<td>')
sql.get_type_ip_checkbox(server[0])
print('</td>')
print('<td><select id="slavefor-%s"><option value="0" selected>Not slave</option>' % server[0])
MASTERS = sql.select_servers(get_master_servers=1)
for master in MASTERS:
if master[0] == server[6]:
selected = "selected"
else:
selected = ""
print('<option value="%s" %s>%s</option>' % (master[0], selected, master[1]))
print('</select></td>')
print('<td><a class="delete" onclick="removeServer(%s)" style="cursor: pointer;"></a></td>' % server[0])
print('</tr>')
print('</table>'
'<br /><span class="add-button" title="Add server" id="add-server-button">+ Add</span>'
'<br /><br /><table class="overview" id="server-add-table" style="display: none;">'
'<tr class="overviewHead">'
'<td class="padding10 first-collumn">New hostname</td>'
'<td>IP</td>'
'<td>Group</td>'
'<td>Enable</td>'
'<td>Virt</td>'
'<td title="Actions with master config will automatically apply on slave">Slave for</td>'
'<td></td>'
'</tr>'
'<tr>'
'<td class="padding10 first-collumn"><input type="text" name="new-server-add" id="new-server-add" class="form-control"></td>'
'<td><input type="text" name="new-ip" id="new-ip" class="form-control"></td><td>')
sql.get_groups_select("new-server-group-add")
print('</td>'
'<td><label for="enable"></label><input type="checkbox" id="enable" checked></td>'
'<td><label for="typeip"></label><input type="checkbox" id="typeip"></td>'
'<td><select id="slavefor" value="0" selected><option>Not slave</option>')
MASTERS = sql.select_servers(get_master_servers=1)
for master in MASTERS:
print('<option value="%s">%s</option>' % (master[0], master[1]))
print('</select></td>'
'<td><a class="add-admin" id="add-server" style="cursor: pointer;"></a></td>'
'</tr>')
print('</table>')
print('</div><div id="roles">'
'<table class="overview" id="ajax-group">'
'<tr class="overviewHead">'
'<td class="padding10 first-collumn">Name</td>'
'<td>Desciption</td>'
'<td></td>'
'<td></td>'
'</tr><tr>')
for role in ROLES:
print('<tr id="group-%s">' % role[0])
print('<td class="padding10 first-collumn">%s</td>' % ( role[1]))
print('<td>%s</td>' % (role[2]))
print('</tr>')
print('</table>'
'</div>'
'<div id="cert">'
'<table id="ssh">'
'<tr class="overviewHead" style="width: 50%;">'
'<td class="padding10 first-collumn">Upload SSH Key</td>'
'<td>'
'<span title="Private key. Note: The public key must be pre-installed on all servers to which you plan to connect">Key(?)</span>'
'</td>'
'<td></td>'
'</tr>'
'<tr style="width: 50%;">'
'<td class="first-collumn" valign="top" style="padding-top: 15px;">'
'<b>Note:</b> Paste pem file content here'
'</td>'
'<td style="padding-top: 15px;">'
'<textarea id="ssh_cert" cols="50" rows="5"></textarea><br /><br />'
'<a class="ui-button ui-widget ui-corner-all" id="ssh_key_upload" title="Upload ssh key" onclick="uploadSsh()">Upload</a>'
'</td>'
'<td></td>'
'</table>'
'<div id="ajax-ssh"></div>'
'</div></div>')

View File

@ -1,39 +1,32 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import os
import cgi import sql
import os, sys import http, cgi
import funct import funct
from configparser import ConfigParser, ExtendedInterpolation import sql
import glob import glob
import datetime import datetime
from configparser import ConfigParser, ExtendedInterpolation
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('viewlogs.html')
form = cgi.FieldStorage() form = cgi.FieldStorage()
viewlog = form.getvalue('viewlogs')
funct.head("View logs")
funct.check_login()
funct.page_for_admin()
funct.get_auto_refresh("View logs")
path_config = "haproxy-webintarface.config" path_config = "haproxy-webintarface.config"
config = ConfigParser(interpolation=ExtendedInterpolation()) config = ConfigParser(interpolation=ExtendedInterpolation())
config.read(path_config) config.read(path_config)
print('Content-type: text/html\n')
try: try:
if config.get('main', 'log_path'): if config.get('main', 'log_path'):
log_path = config.get('main', 'log_path') log_path = config.get('main', 'log_path')
time_storage = config.getint('logs', 'log_time_storage') time_storage = config.getint('logs', 'log_time_storage')
except: except:
print('<center><div class="alert alert-danger">Can not find "log_path" and "log_time_storage" parametrs. Check into config</div>') print('<center><div class="alert alert-danger">Can not find "log_path" and "log_time_storage" parametrs. Check into config</div>')
try:
os.chdir(log_path)
except IOError: funct.check_login()
print('<center><div class="alert alert-danger">No such file or directory: "%s". Please check "log_path" in config and exist directory</div>' % log_path) funct.page_for_admin()
sys.exit()
print('<script src="/inc/users.js"></script>'
'<a name="top"></a>'
'<center><h3>Choose log file</h3><br />')
try: try:
time_storage_hours = time_storage * 24 time_storage_hours = time_storage * 24
for dirpath, dirnames, filenames in os.walk(log_path): for dirpath, dirnames, filenames in os.walk(log_path):
@ -46,22 +39,27 @@ except:
print('<center><div class="alert alert-danger" style="margin: 0; margin-bottom: 10px;">Can\'t delete old logs file. <br> Please check "log_time_storage" in config and <br>exist directory </div>') print('<center><div class="alert alert-danger" style="margin: 0; margin-bottom: 10px;">Can\'t delete old logs file. <br> Please check "log_time_storage" in config and <br>exist directory </div>')
pass pass
print('<select id="viewlogs">' try:
'<option disabled selected>Choose log</option>') cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
user = sql.get_user_name_by_uuid(user_id.value)
servers = sql.get_dick_permit()
except:
pass
for files in sorted(glob.glob('*.log'), reverse=True): def get_files():
if files == viewlog: file = set()
selected = 'selected' for files in glob.glob(os.path.join(log_path,'*.log')):
else: file.add(files.split('/')[5])
selected = '' return sorted(file, reverse=True)
print('<option value="%s" %s>%s</option>' % (files, selected, files))
output_from_parsed_template = template.render(h2 = 1,
print('</select>' autorefresh = 1,
'<a class="ui-button ui-widget ui-corner-all" id="show" title="Show stats" onclick="viewLogs()">Show</a>' title = "View logs",
'</center><br />' role = sql.get_user_role_by_uuid(user_id.value),
'<div id="ajax"></div>' user = user,
'<script>' onclick = "viewLogs()",
'window.onload = viewLogs()' serv = form.getvalue('viewlogs'),
'</script>') select_id = "viewlogs",
selects = get_files())
funct.footer() print(output_from_parsed_template)

View File

@ -1,39 +1,41 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import html, http, os
import cgi import cgi
import requests import requests
import funct import funct
import sql import sql
from configparser import ConfigParser, ExtendedInterpolation
from requests_toolbelt.utils import dump from requests_toolbelt.utils import dump
from jinja2 import Environment, FileSystemLoader
print("Content-type: text/html\n") env = Environment(loader=FileSystemLoader('templates/'))
template = env.get_template('viewstats.html')
form = cgi.FieldStorage() form = cgi.FieldStorage()
serv = form.getvalue('serv')
serv = form.getvalue('serv')
if serv is None: if serv is None:
first_serv = sql.get_dick_permit() first_serv = sql.get_dick_permit()
for i in first_serv: for i in first_serv:
serv = i[2] serv = i[2]
break break
print('<a name="top"></a><div class="container">') print('Content-type: text/html\n')
funct.check_login()
funct.get_auto_refresh("HAproxy statistics") try:
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
user = sql.get_user_name_by_uuid(user_id.value)
servers = sql.get_dick_permit(virt=1)
except:
pass
print('<br />' output_from_parsed_template = template.render(h2 = 1,
'<form style="padding-left: 20px;" action="viewsttats.py" method="get">' autorefresh = 1,
'<select autofocus required name="serv" id="serv">' title = "HAProxy statistics",
'<option disabled>Choose server</option>') role = sql.get_user_role_by_uuid(user_id.value),
user = user,
onclick = "showStats()",
select_id = "serv",
selects = servers,
serv = serv)
print(output_from_parsed_template)
funct.choose_only_select(serv, virt=1)
print('</select>'
'<a class="ui-button ui-widget ui-corner-all" id="show" title="Show stats" onclick="showStats()">Show</a>'
'</form>'
'<div id="ajax" style="margin-left: 10px;"></div>')
funct.head("Stats HAproxy configs")
print('</div><script> window.onload = showStats()</script>')
funct.footer()

View File

@ -10,4 +10,5 @@ numpy==1.14.0
matplotlib==2.1.2 matplotlib==2.1.2
urllib3==1.22 urllib3==1.22
future==0.13.1 future==0.13.1
mysql-connector-python==8.0.11 mysql-connector-python==8.0.11
Jinja2==2.10

View File

@ -10,6 +10,8 @@ chown -R apache:apache *
cd app/ cd app/
./update_db.py ./update_db.py
pip install -r requirements.txt
echo "" echo ""
echo "#################" echo "#################"
echo "Change in config:" echo "Change in config:"