Meet Haproxy-wi 2.0! Now with DB and Admin web interface! Life has become easier, life has become more cheerful!
pull/19/head
Aidaho12 2018-04-16 13:01:44 +06:00
parent 95fd1a5ca5
commit 47dfa23d21
23 changed files with 1028 additions and 211 deletions

View File

@ -1,3 +1,5 @@
#Meet Haproxy-wi 2.0! Now with DB and Admin web interface! Life has become easier, life has become more cheerful!
# Haproxy web interface # Haproxy web interface
A simple web interface(user-frendly web GUI) for managing Haproxy servers. Leave your [feedback](https://github.com/Aidaho12/haproxy-wi/issues) A simple web interface(user-frendly web GUI) for managing Haproxy servers. Leave your [feedback](https://github.com/Aidaho12/haproxy-wi/issues)
@ -37,10 +39,19 @@ For Apache just do virtualhost with cgi-bin.
![alt text](image/7.jpeg "Overview page") ![alt text](image/7.jpeg "Overview page")
# Settings # Settings
Edit $HOME_HAPROXY-WI/cgi-bin/listserv.py, add your HAproxy servers. ```
cd $HOME_HAPROXY-WI/cgi-bin/
chmod +x *.py
```
Run create_db.py for DB createing
Edit $HOME_HAPROXY-WI/cgi-bin/haproxy-webintarface.config with your env Edit $HOME_HAPROXY-WI/cgi-bin/haproxy-webintarface.config with your env
Login http://haproxy-wi-server/users.py, and add: users, groups and servers. Default: admin/admin
![alt text](image/11.jpeg "Admin area")
Copy ssh key on all HAproxy servers Copy ssh key on all HAproxy servers
For Runtime API enable state file on HAproxt servers and need install socat on all haproxy servers: For Runtime API enable state file on HAproxt servers and need install socat on all haproxy servers:

View File

@ -1,9 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import html
import cgi import cgi
import listserv as listhap
import os import os
import funct import funct
import sql
import paramiko import paramiko
import configparser import configparser
import http.cookies import http.cookies
@ -23,6 +23,7 @@ funct.page_for_admin(level = 1)
haproxy_configs_server = config.get('configs', 'haproxy_configs_server') haproxy_configs_server = config.get('configs', 'haproxy_configs_server')
hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir')
form = cgi.FieldStorage() form = cgi.FieldStorage()
listhap = sql.get_dick_permit()
if form.getvalue('mode') is not None: if form.getvalue('mode') is not None:
serv = form.getvalue('serv') serv = form.getvalue('serv')
@ -141,8 +142,8 @@ print('<div id="tabs">'
'<select required name="serv" id="serv">' '<select required name="serv" id="serv">'
'<option disabled selected>Choose server</option>') '<option disabled selected>Choose server</option>')
for i in sorted(listhap.listhap): for i in listhap:
print('<option value="%s">%s</option>' % (listhap.listhap.get(i), i)) print('<option value="%s">%s</option>' % (i[2], i[1]))
print('</select>' print('</select>'
'<div class="tooltip tooltipTop"><b>Note:</b> If you reconfigure First server, second will reconfigured automatically</div>' '<div class="tooltip tooltipTop"><b>Note:</b> If you reconfigure First server, second will reconfigured automatically</div>'
@ -261,8 +262,8 @@ print('</td>'
'<select required name="serv" id="serv2">' '<select required name="serv" id="serv2">'
'<option disabled selected>Choose server</option>') '<option disabled selected>Choose server</option>')
for i in sorted(listhap.listhap): for i in listhap:
print('<option value="%s">%s</option>' % (listhap.listhap.get(i), i)) print('<option value="%s">%s</option>' % (i[2], i[1]))
print('</select>' print('</select>'
'<div class="tooltip tooltipTop"><b>Note:</b> If you reconfigure First server, second will reconfigured automatically</div>' '<div class="tooltip tooltipTop"><b>Note:</b> If you reconfigure First server, second will reconfigured automatically</div>'
@ -345,8 +346,8 @@ print('</td>'
'<select required name="serv">' '<select required name="serv">'
'<option disabled selected>Choose server</option>') '<option disabled selected>Choose server</option>')
for i in sorted(listhap.listhap): for i in listhap:
print('<option value="%s">%s</option>' % (listhap.listhap.get(i), i)) print('<option value="%s">%s</option>' % (i[2], i[1]))
print('</select>' print('</select>'
'<div class="tooltip tooltipTop"><b>Note:</b> If you reconfigure First server, second will reconfigured automatically</div>' '<div class="tooltip tooltipTop"><b>Note:</b> If you reconfigure First server, second will reconfigured automatically</div>'

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import html
import cgi import cgi
import listserv as listhap
import os import os
import http.cookies import http.cookies
import configparser import configparser

View File

@ -51,7 +51,7 @@ if serv is not None and form.getvalue('open') is not None:
print('</select>') print('</select>')
print('<input type="hidden" value="%s" name="serv">' % serv) print('<input type="hidden" value="%s" name="serv">' % serv)
print('<input type="hidden" value="open" name="open">') print('<input type="hidden" value="open" name="open">')
print('<p><button type="submit" value="Select" name="Select">Select</button></p></form>') print('<button type="submit" value="Select" name="Select">Select</button></form>')
Select = form.getvalue('Select') Select = form.getvalue('Select')
@ -65,7 +65,10 @@ if serv is not None and form.getvalue('open') is not None:
print('<input type="hidden" value="%s" name="serv">' % serv) print('<input type="hidden" value="%s" name="serv">' % serv)
print('<input type="hidden" value="%s" name="configver">' % configver) print('<input type="hidden" value="%s" name="configver">' % configver)
print('<input type="hidden" value="1" name="config">') print('<input type="hidden" value="1" name="config">')
print('<a name="conf"></a></center>') 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) funct.show_config(configver)
print('<center><p>') print('<center><p>')
funct.get_button("Just save", value="save") funct.get_button("Just save", value="save")

66
cgi-bin/create_db.py Normal file
View File

@ -0,0 +1,66 @@
#!/usr/bin/env python3
import sqlite3 as sqlite
def get_cur():
con = sqlite.connect("haproxy-wi.db", isolation_level=None)
cur = con.cursor()
return con, cur
def create_table():
con, cur = get_cur()
sql = """
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS `user` (
`id` INTEGER NOT NULL,
`username` VARCHAR ( 64 ) UNIQUE,
`email` VARCHAR ( 120 ) UNIQUE,
`password` VARCHAR ( 128 ),
`role` VARCHAR ( 128 ),
`groups` VARCHAR ( 120 ),
PRIMARY KEY(`id`)
);
INSERT INTO `user` (username, email, password, role, groups) VALUES ('admin','admin@localhost','admin','admin','1'),
('editor','editor@localhost','editor','editor','1'),
('guest','guest@localhost','guest','guest','1');
CREATE TABLE IF NOT EXISTS `servers` (
`id` INTEGER NOT NULL,
`hostname` VARCHAR ( 64 ) UNIQUE,
`ip` VARCHAR ( 64 ) UNIQUE,
`groups` VARCHAR ( 64 ),
PRIMARY KEY(`id`)
);
CREATE TABLE IF NOT EXISTS `roles_users` (
`user_id` INTEGER,
`role_id` INTEGER,
FOREIGN KEY(`user_id`) REFERENCES `user`(`id`),
FOREIGN KEY(`role_id`) REFERENCES `role`(`id`)
);
CREATE TABLE IF NOT EXISTS `role` (
`id` INTEGER NOT NULL,
`name` VARCHAR ( 80 ) UNIQUE,
`description` VARCHAR ( 255 ),
PRIMARY KEY(`id`)
);
INSERT INTO `role` (name, description) VALUES ('admin','Can do everything'),
('editor','Can edit configs'),
('guest','Read only access');
CREATE TABLE IF NOT EXISTS `groups` (
`id` INTEGER NOT NULL,
`name` VARCHAR ( 80 ) UNIQUE,
`description` VARCHAR ( 255 ),
PRIMARY KEY(`id`)
);
INSERT INTO `groups` (name, description) VALUES ('All','All servers enter in this group');
COMMIT;
"""
try:
cur.executescript(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
else:
print("DB was created")
cur.close()
con.close()
create_table()

View File

@ -19,7 +19,7 @@ config.read(path_config)
hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir')
funct.page_for_admin(level = 2) funct.page_for_admin(level = 1)
funct.chooseServer("delver.py", "Delete Versions HAproxy config", "n") funct.chooseServer("delver.py", "Delete Versions HAproxy config", "n")
if serv is not None and form.getvalue('open') is not None: if serv is not None and form.getvalue('open') is not None:

View File

@ -2,6 +2,7 @@
import html import html
import cgi import cgi
import funct import funct
import sql
form = cgi.FieldStorage() form = cgi.FieldStorage()
serv = form.getvalue('serv') serv = form.getvalue('serv')
@ -13,19 +14,19 @@ funct.check_config()
print('<h2>Runtime API</h2>' print('<h2>Runtime API</h2>'
'<table class="overview">' '<table class="overview">'
'<tr class="overviewHead">' '<tr class="overviewHead">'
'<td class="padding10">Server</td>' '<td class="padding10 first-collumn">Server</td>'
'<td>Disable/Enable server or output any information</td>' '<td>Disable/Enable server or output any information</td>'
'<td class="padding10">Command</td>' '<td class="padding10">Command</td>'
'<td>Save change</td>' '<td>Save change</td>'
'<td></td>' '<td></td>'
'</tr>' '</tr>'
'<tr>' '<tr>'
'<td class="padding10" style="width: 25%;">' '<td class="padding10 first-collumn" style="width: 25%;">'
'<form action="edit.py" method="get">' '<form action="edit.py" method="get">'
'<select required name="serv" id="serv">' '<select required name="serv" id="serv">'
'<option disabled selected>Choose server</option>') '<option disabled selected>Choose server</option>')
funct.choose_server_with_vip(serv) funct.choose_only_select(serv)
print('</select></td>' print('</select></td>'
'<td style="width: 30%;">' '<td style="width: 30%;">'
@ -40,7 +41,7 @@ print('<option value="show">Show</option>'
'<td>' '<td>'
'<input type="text" name="servbackend" id="servbackend" size=35 title="Frontend, backend/server, show: info, pools or help" required class="form-control">' '<input type="text" name="servbackend" id="servbackend" size=35 title="Frontend, backend/server, show: info, pools or help" required class="form-control">'
'</td><td>' '</td><td>'
'<input type="checkbox" name="save" id="save" value="123" title="Save changes after restart">' '<input type="checkbox" name="save" id="save" value="123">'
'</td><td>' '</td><td>'
'<a class="ui-button ui-widget ui-corner-all" id="show" title="Enter" onclick="showRuntime()">Enter</a>' '<a class="ui-button ui-widget ui-corner-all" id="show" title="Enter" onclick="showRuntime()">Enter</a>'
'</td></form>' '</td></form>'

View File

@ -3,10 +3,10 @@ import os
import paramiko import paramiko
import http.cookies import http.cookies
from paramiko import SSHClient from paramiko import SSHClient
import listserv as listhap
from datetime import datetime from datetime import datetime
from pytz import timezone from pytz import timezone
import configparser import configparser
import sql
def check_config(): def check_config():
path_config = "haproxy-webintarface.config" path_config = "haproxy-webintarface.config"
@ -64,9 +64,6 @@ def check_login(**kwargs):
role = cookie.get('role') role = cookie.get('role')
ref = os.environ.get("SCRIPT_NAME") ref = os.environ.get("SCRIPT_NAME")
if kwargs.get("admins_area") == "1" and role.value != "2":
print('<meta http-equiv="refresh" content="0; url=/">')
if login is None: if login is None:
print('<meta http-equiv="refresh" content="0; url=login.py?ref=%s">' % ref) print('<meta http-equiv="refresh" content="0; url=login.py?ref=%s">' % ref)
@ -76,15 +73,15 @@ def is_admin(**kwargs):
level = kwargs.get("level") level = kwargs.get("level")
if role is None: if role is None:
role = 0 role = 3
else: else:
role = int(role.value) role = int(role.value)
if level is None: if level is None:
level = 2 level = 1
try: try:
if level <= role: if role <= level:
return True return True
else: else:
return False return False
@ -164,6 +161,7 @@ def links():
'<ul>' '<ul>'
'<li><a href=/cgi-bin/overview.py title="Server and service status" class="overview-link">Overview</a> </li>' '<li><a href=/cgi-bin/overview.py title="Server and service status" class="overview-link">Overview</a> </li>'
'<li><a href=/cgi-bin/viewsttats.py title"Show stats" class="stats">Stats</a> </li>' '<li><a href=/cgi-bin/viewsttats.py title"Show stats" class="stats">Stats</a> </li>'
'<li><a href="http://172.28.5.106:3000/d/000000002/haproxy?refresh=1m&orgId=1" title="Mon" target="_blanck" class="mon">Monitoring</a> </li>'
'<li><a href=/cgi-bin/logs.py title="View logs" class="logs">Logs</a></li>' '<li><a href=/cgi-bin/logs.py title="View logs" class="logs">Logs</a></li>'
'<li><a href=/cgi-bin/map.py title="View map" class="map">Map</a></li>' '<li><a href=/cgi-bin/map.py title="View map" class="map">Map</a></li>'
'</ul>' '</ul>'
@ -173,25 +171,34 @@ def links():
'<ul>' '<ul>'
'<li><a href=/cgi-bin/configshow.py title="Show Config" class="config-show">Show</a></li> ' '<li><a href=/cgi-bin/configshow.py title="Show Config" class="config-show">Show</a></li> '
'<li><a href=/cgi-bin/diff.py title="Compare Configs" class="compare">Compare</a></li>') '<li><a href=/cgi-bin/diff.py title="Compare Configs" class="compare">Compare</a></li>')
if is_admin(level = 1): if is_admin(level = 2):
print('<li><a href=/cgi-bin/add.py#listner title="Add single listen" class="add">Add listen</a></li>' print('<li><a href=/cgi-bin/add.py#listner title="Add single listen" class="add">Add listen</a></li>'
'<li><a href=/cgi-bin/add.py#frontend title="Add single frontend" class="add">Add frontend</a></li>' '<li><a href=/cgi-bin/add.py#frontend title="Add single frontend" class="add">Add frontend</a></li>'
'<li><a href=/cgi-bin/add.py#backend title="Add single backend" class="add">Add backend</a></li>' '<li><a href=/cgi-bin/add.py#backend title="Add single backend" class="add">Add backend</a></li>'
'<li><a href=/cgi-bin/config.py title="Edit Config" class="edit">Edit</a> </li>') '<li><a href=/cgi-bin/config.py title="Edit Config" class="edit">Edit</a> </li>')
print('</ul></li>') print('</ul></li>')
if is_admin(level = 1): if is_admin(level = 2):
print('<li><a title="Actions with configs" class="version">Versions</a>' print('<li><a title="Actions with configs" class="version">Versions</a>'
'<ul>' '<ul>'
'<li><a href=/cgi-bin/configver.py title="Upload old versions configs" class="upload">Upload</a></li>') '<li><a href=/cgi-bin/configver.py title="Upload old versions configs" class="upload">Upload</a></li>')
if is_admin(): if is_admin():
print('<li><a href=/cgi-bin/delver.py title="Delete old versions configs" class="delete">Delete</a></li>') print('<li><a href=/cgi-bin/delver.py title="Delete old versions configs" class="delete">Delete</a></li>')
if is_admin(level = 1): if is_admin(level = 2):
print('</ul>' print('</ul>'
'</li>') '</li>')
show_login_links() show_login_links()
if is_admin():
print('<li><a title="Admin area" class="version">Admin area</a>'
'<ul>'
'<li><a href=/cgi-bin/users.py#users title="Actions with users" class="users">Users</a></li>'
'<li><a href=/cgi-bin/users.py#groups title="Actions with groups" class="group">Groups</a></li>'
'<li><a href=/cgi-bin/users.py#servers title="Actions with servers" class="runtime">Servers</a></li>'
'<li><a href=/cgi-bin/users.py#roles title="Users roles" class="role">Roles</a></li>'
'</ul>'
'</li>')
print('</ul>' print('</ul>'
'</nav>' '</nav>'
'<div class="copyright-menu">HAproxy-WI v1.10.2.3</div>' '<div class="copyright-menu">HAproxy-WI v2.0</div>'
'</div>') '</div>')
def show_login_links(): def show_login_links():
@ -488,69 +495,22 @@ def ssh_command(serv, commands, **kwargs):
print(stderr.read().decode(encoding='UTF-8')) print(stderr.read().decode(encoding='UTF-8'))
def get_group_permit():
import json
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
login = cookie.get('login')
USERS = fullpath + '/cgi-bin/users'
try:
with open(USERS, "r") as user:
pass
except IOError:
print("Can't load users DB")
for f in open(USERS, 'r'):
users = json.loads(f)
if login.value in users['login']:
group = users['group']
GROUPS = fullpath + '/cgi-bin/groups'
try:
with open(GROUPS, "r") as user:
pass
except IOError:
print("Can't load groups DB")
for f in open(GROUPS, 'r'):
groups = json.loads(f)
if group in groups['name']:
list = groups['lists']
break
else:
list = ""
return list
def get_dick_after_permit():
list_serv = get_group_permit()
if list_serv == "all":
from listserv import listhap as listhap
elif list_serv == "web":
from listserv import web as listhap
elif list_serv == "mysql":
from listserv import mysql as listhap
else:
from listserv import no_group as listhap
return listhap
def choose_only_select(serv, **kwargs): def choose_only_select(serv, **kwargs):
listhap = get_dick_after_permit() listhap = sql.get_dick_permit()
if kwargs.get("servNew"): if kwargs.get("servNew"):
servNew = kwargs.get("servNew") servNew = kwargs.get("servNew")
else: else:
servNew = "" servNew = ""
for i in sorted(listhap):
if listhap.get(i) == serv or listhap.get(i) == servNew: for i in listhap:
if i[2] == serv or i[2] == servNew:
selected = 'selected' selected = 'selected'
else: else:
selected = '' selected = ''
print('<option value="%s" %s>%s</option>' % (listhap.get(i), selected, i)) print('<option value="%s" %s>%s</option>' % (i[2], selected, i[1]))
def chooseServer(formName, title, note, **kwargs): def chooseServer(formName, title, note, **kwargs):
servNew = form.getvalue('serNew') servNew = form.getvalue('serNew')
@ -576,19 +536,3 @@ def chooseServer(formName, title, note, **kwargs):
print('<p><b>Note:</b> If you reconfigure First server, second will reconfigured automatically</p>') print('<p><b>Note:</b> If you reconfigure First server, second will reconfigured automatically</p>')
print('</center>') print('</center>')
def choose_server_with_vip(serv):
listhap.listhap = merge_two_dicts(listhap.listhap, listhap.listhap_vip)
for i in sorted(listhap.listhap):
if listhap.listhap.get(i) == serv:
selected = 'selected'
else:
selected = ''
print('<option value="%s" %s>%s</option>' % (listhap.listhap.get(i), selected, i))
def merge_two_dicts(x, y):
z = x.copy()
z.update(y)
return z

View File

@ -1,3 +0,0 @@
{ "name": "all", "lists": "all" }
{ "name": "mysql", "lists": "mysql" }
{ "name": "web", "lists": "web" }

View File

@ -1,7 +0,0 @@
listhap= {
'haproxy1': '172.28.0.1',
'haproxy2': '172.28.0.2'
}
list_hap_vip = {
'haproxy-vip': '172.28.0.3'
}

View File

@ -4,20 +4,13 @@ import html
import os import os
import funct import funct
import http.cookies import http.cookies
import json import sql
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
form = cgi.FieldStorage() form = cgi.FieldStorage()
ref = form.getvalue('ref') ref = form.getvalue('ref')
login = form.getvalue('login') login = form.getvalue('login')
password = form.getvalue('pass') password = form.getvalue('pass')
USERS = '/var/www/haproxy-wi/cgi-bin/users'
try:
with open(USERS, "r") as user:
pass
except IOError:
print("Can't load users DB")
def login_page(error): def login_page(error):
if error == "error": if error == "error":
@ -49,15 +42,15 @@ if login is None:
login_page("n") login_page("n")
if login is not None and password is not None: if login is not None and password is not None:
for f in open(USERS, 'r'): USERS = sql.select_users()
users = json.loads(f) for users in USERS:
if login in users['login'] and password == users['password']: if login in users[1] and password == users[3]:
if users['role'] == "admin": if users[4] == "admin":
role = 2
elif users['role'] == "editor":
role = 1 role = 1
elif users[4] == "editor":
role = 2
else: else:
role = 0 role = 3
c = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) c = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
c["login"] = login c["login"] = login
c["login"]["path"] = "/cgi-bin/" c["login"]["path"] = "/cgi-bin/"
@ -65,7 +58,7 @@ if login is not None and password is not None:
c["role"] = role c["role"] = role
c["role"]["path"] = "/cgi-bin/" c["role"]["path"] = "/cgi-bin/"
c["role"]["expires"] = "Wed May 18 03:33:20 2033" c["role"]["expires"] = "Wed May 18 03:33:20 2033"
c["group"] = users['group'] c["group"] = users[4]
c["group"]["path"] = "/cgi-bin/" c["group"]["path"] = "/cgi-bin/"
c["group"]["expires"] = "Wed May 18 03:33:20 2033" c["group"]["expires"] = "Wed May 18 03:33:20 2033"
print(c) print(c)

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import html import html
import cgi import cgi
import listserv as listhap
import funct import funct
import configparser import configparser
@ -19,13 +18,13 @@ config.read(path_config)
funct.get_auto_refresh("HAproxy logs") funct.get_auto_refresh("HAproxy logs")
print('<table class="overview">' print('<table class="overview">'
'<tr class="overviewHead">' '<tr class="overviewHead">'
'<td class="padding10">Server</td>' '<td class="padding10 first-collumn">Server</td>'
'<td>Number rows</td>' '<td>Number rows</td>'
'<td class="padding10">Ex for grep</td>' '<td class="padding10">Ex for grep</td>'
'<td> </td>' '<td> </td>'
'</tr>' '</tr>'
'<tr>' '<tr>'
'<td class="padding10">' '<td class="padding10 first-collumn">'
'<form action="logs.py" method="get">' '<form action="logs.py" method="get">'
'<select autofocus required name="serv" id="serv">' '<select autofocus required name="serv" id="serv">'
'<option disabled selected>Choose server</option>') '<option disabled selected>Choose server</option>')
@ -45,9 +44,9 @@ else:
grep = ' ' grep = ' '
print('</td><td><input type="number" name="rows" id="rows" %s class="form-control" required></td>' % rows) print('</td><td><input type="number" name="rows" id="rows" %s class="form-control" required></td>' % rows)
print('<td class="padding10"><input type="text" name="grep" id="grep" class="form-control" %s >' % grep) print('<td class="padding10 first-collumn"><input type="text" name="grep" id="grep" class="form-control" %s >' % grep)
print('</td>' print('</td>'
'<td class="padding10">' '<td class="padding10 first-collumn">'
'<a class="ui-button ui-widget ui-corner-all" id="show" title="Show logs" onclick="showLog()">Show</a>' '<a class="ui-button ui-widget ui-corner-all" id="show" title="Show logs" onclick="showLog()">Show</a>'
'</td>' '</td>'
'</form>' '</form>'

View File

@ -165,7 +165,7 @@ if serv is not None and act == "configShow":
funct.get_config(serv, cfg) funct.get_config(serv, cfg)
print('<script src="/inc/configshow.js"></script>') print('<a name="top"></a>')
print("<center><h3>Config from %s</h3>" % serv) print("<center><h3>Config from %s</h3>" % serv)
print('<p class="accordion-expand-holder">' print('<p class="accordion-expand-holder">'
'<a class="accordion-expand-all ui-button ui-widget ui-corner-all" href="#">Expand all</a>' '<a class="accordion-expand-all ui-button ui-widget ui-corner-all" href="#">Expand all</a>'

View File

@ -3,6 +3,7 @@ import configparser
import json import json
import os import os
import cgi import cgi
import sql
path_config = "haproxy-webintarface.config" path_config = "haproxy-webintarface.config"
config = configparser.ConfigParser() config = configparser.ConfigParser()
@ -18,23 +19,17 @@ hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir')
form = cgi.FieldStorage() form = cgi.FieldStorage()
def get_overview(): def get_overview():
USERS = cgi_path + '/users' USERS = sql.select_users()
try:
with open(USERS, "r") as user:
pass
except IOError:
print("Can't load users DB")
print('<table class="overview">') print('<table class="overview">')
if funct.is_admin(): if funct.is_admin():
print('<tr class="overviewHead">' print('<tr class="overviewHead">'
'<td class="padding10">Login</td>' '<td class="padding10 first-collumn">Login</td>'
'<td>Group</td>' '<td class="padding10">Email</td>'
'<td class="padding10">' '<td class="padding10">Group</td>'
'Role' '<td class="padding10">Role</td>'
'</td><td style="width: 200px;">' '<td style="width: 200px;">'
'<span class="add-button">' '<span class="add-button">'
'<a href="#" title="Show all users" id="show-all-users" style="color: #fff">' '<a href="#" title="Show all users" id="show-all-users" style="color: #fff">'
'Show all' 'Show all'
@ -45,55 +40,59 @@ def get_overview():
i = 0 i = 0
style = "" style = ""
for f in open(USERS, 'r'): for users in USERS:
i = i + 1 i = i + 1
users = json.loads(f)
if i is 4: if i is 4:
style = 'style="display: none;" class="show-users"' style = 'style="display: none;" class="show-users"'
print('<tr ' + style + '><td class="padding10 first-collumn">' + users['login'] +'</td><td class="second-collumn">') print('<tr ' + style + '><td class="padding10 first-collumn">' + users[1] +'</td><td class="second-collumn">')
print(users['group']+'</td><td>') print(users[2]+'</td><td>')
print(users['role']) GROUPS = sql.select_user_name_group(users[5])
for group in GROUPS:
print(group)
print('</td><td>')
print(users[4])
print('</td><td></td></tr>') print('</td><td></td></tr>')
print('</table>') print('</table>')
print('<table class="overview">' print('<table class="overview">'
'<tr class="overviewHead">' '<tr class="overviewHead">'
'<td class="padding10">Server</td>' '<td class="padding10 first-collumn"">Server</td>'
'<td class="padding10">' '<td class="padding10">'
'HAproxy status' 'HAproxy status'
'</td>' '</td>'
'<td class="padding10">' '<td class="padding10">'
'Action' 'Action'
'</td>' '</td>'
'<td>' '<td class="padding10">'
'Last edit' 'Last edit'
'</td>' '</td>'
'<td></td>'
'</tr>') '</tr>')
listhap = funct.get_dick_after_permit() listhap = sql.get_dick_permit()
commands = [ "ps -Af |grep [h]aproxy |wc -l" ] commands = [ "ps -Af |grep [h]aproxy |wc -l" ]
commands1 = [ "ls -l %s |awk '{ print $6\" \"$7\" \"$8}'" % haproxy_config_path ] commands1 = [ "ls -l %s |awk '{ print $6\" \"$7\" \"$8}'" % haproxy_config_path ]
for i in sorted(listhap): for server in listhap:
print('<tr><td class="padding10 first-collumn"><a href="#%s" title="Go to %s status" style="color: #000">%s</a></td><td class="second-collumn">' % (i, i, i)) print('<tr><td class="padding10 first-collumn"><a href="#%s" title="Go to %s status" style="color: #000">%s</a></td><td class="second-collumn">' % (server[1], server[1], server[1]))
funct.ssh_command(listhap.get(i), commands, server_status="1") funct.ssh_command(server[2], commands, server_status="1")
print('</td><td>') print('</td><td>')
if funct.is_admin(): if funct.is_admin():
print('<a id="%s" title="Start HAproxy service" onclick = "if (! confirm(\'Start service?\')) return false;"><img src=/image/pic/start.png alt="start" class="icon"></a>' % listhap.get(i)) print('<a id="%s" title="Start HAproxy service" onclick = "if (! confirm(\'Start service?\')) return false;"><img src=/image/pic/start.png alt="start" class="icon"></a>' % server[2])
print('<a id="%s" title="Stop HAproxy service" onclick = "if (! confirm(\'Stop service?\')) return false;"><img src=/image/pic/stop.png alt="start" class="icon"></a>' % listhap.get(i)) print('<a id="%s" title="Stop HAproxy service" onclick = "if (! confirm(\'Stop service?\')) return false;"><img src=/image/pic/stop.png alt="start" class="icon"></a>' % server[2])
print('<a id="%s" title="Restart HAproxy service" onclick = "if (! confirm(\'Restart service?\')) return false;"><img src=/image/pic/update.png alt="restart" class="icon"></a>' % listhap.get(i)) print('<a id="%s" title="Restart HAproxy service" onclick = "if (! confirm(\'Restart service?\')) return false;"><img src=/image/pic/update.png alt="restart" class="icon"></a>' % server[2])
print('<a href="/cgi-bin/configshow.py?serv=%s&open=open#conf" title="Show config"><img src=/image/pic/show.png alt="show" class="icon"></a>' % listhap.get(i)) print('<a href="/cgi-bin/configshow.py?serv=%s&open=open#conf" title="Show config"><img src=/image/pic/show.png alt="show" class="icon"></a>' % server[2])
print('<a href="/cgi-bin/config.py?serv=%s&open=open#conf" title="Edit config"><img src=/image/pic/edit.png alt="edit" class="icon"></a>' % listhap.get(i)) print('<a href="/cgi-bin/config.py?serv=%s&open=open#conf" title="Edit config"><img src=/image/pic/edit.png alt="edit" class="icon"></a>' % server[2])
print('<a href="/cgi-bin/diff.py?serv=%s&open=open#diff" title="Compare config"><img src=/image/pic/compare.png alt="compare" class="icon"></a>' % listhap.get(i)) print('<a href="/cgi-bin/diff.py?serv=%s&open=open#diff" title="Compare config"><img src=/image/pic/compare.png alt="compare" class="icon"></a>' % server[2])
print('<a href="/cgi-bin/map.py?serv=%s&open=open#map" title="Map listen/frontend/backend"><img src=/image/pic/map.png alt="map" class="icon"></a>' % listhap.get(i)) print('<a href="/cgi-bin/map.py?serv=%s&open=open#map" title="Map listen/frontend/backend"><img src=/image/pic/map.png alt="map" class="icon"></a>' % server[2])
print('</td><td>') print('</td><td>')
funct.ssh_command(listhap.get(i), commands1) funct.ssh_command(server[2], commands1)
print('</td><td></td></tr>') print('</td><td></td></tr>')
print('</table><table class="overview"><tr class="overviewHead">' print('</table><table class="overview"><tr class="overviewHead">'
'<td class="padding10">Server</td>' '<td class="padding10">Server</td>'
'<td class="padding10">' '<td>'
'HAproxy info' 'HAproxy info'
'</td>' '</td>'
'<td>' '<td>'
@ -106,12 +105,12 @@ def get_overview():
"haproxy -v |head -1", "haproxy -v |head -1",
status_command + "|grep Active | sed 's/^[ \t]*//'" ] status_command + "|grep Active | sed 's/^[ \t]*//'" ]
commands1 = [ "top -u haproxy -b -n 1" ] commands1 = [ "top -u haproxy -b -n 1" ]
for i in sorted(listhap): for server in sorted(listhap):
print('<tr><td class="overviewTr first-collumn"><a name="'+i+'"></a><h3 title="IP ' + listhap.get(i) + '">' + i + ':</h3></td>') print('<tr><td class="overviewTr first-collumn"><a name="'+server[1]+'"></a><h3 title="IP ' + server[2] + '">' + server[1] + ':</h3></td>')
print('<td class="overviewTd"><span>Total listen/frontend/backend:</span><pre>') print('<td class="overviewTd"><span>Total listen/frontend/backend:</span><pre>')
funct.ssh_command(listhap.get(i), commands) funct.ssh_command(server[2], commands)
print('</pre></td><td class="overviewTd"><pre>') print('</pre></td><td class="overviewTd"><pre>')
funct.ssh_command(listhap.get(i), commands1) funct.ssh_command(server[2], commands1)
print('</pre></td></tr>') print('</pre></td></tr>')
print('<tr></table>') print('<tr></table>')

412
cgi-bin/sql.py Normal file
View File

@ -0,0 +1,412 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-"
import sqlite3 as sqlite
import cgi
def get_cur():
con = sqlite.connect("haproxy-wi.db", isolation_level=None)
cur = con.cursor()
return con, cur
def add_user(user, email, password, role, group):
con, cur = get_cur()
sql = """INSERT INTO user (username, email, password, role, groups) VALUES ('%s', '%s', '%s', '%s', '%s')""" % (user, email, password, role, group)
try:
with con:
cur.executescript(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
cur.close()
con.close()
def update_user(user, email, password, role, group, id):
con, cur = get_cur()
sql = """update user set username = '%s',
email = '%s',
password = '%s',
role = '%s',
groups = '%s'
where id = '%s'""" % (user, email, password, role, group, id)
try:
with con:
cur.executescript(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
cur.close()
con.close()
def delete_user(id):
con, cur = get_cur()
sql = """delete from user where id = '%s'""" % (id)
try:
with con:
cur.executescript(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
else:
return True
cur.close()
def add_group(name, description):
con, cur = get_cur()
sql = """INSERT INTO groups (name, description) VALUES ('%s', '%s')""" % (name, description)
try:
with con:
cur.executescript(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
cur.close()
con.close()
def delete_group(id):
con, cur = get_cur()
sql = """delete from groups where id = '%s'""" % (id)
try:
with con:
cur.executescript(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
else:
return True
cur.close()
def update_group(name, descript, id):
con, cur = get_cur()
sql = """
update groups set
name = '%s',
description = '%s'
where id = '%s';
""" % (name, descript, id)
try:
with con:
cur.executescript(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
cur.close()
con.close()
def add_server(hostname, ip, group):
con, cur = get_cur()
sql = """INSERT INTO servers (hostname, ip, groups) VALUES ('%s', '%s', '%s')""" % (hostname, ip, group)
try:
with con:
cur.executescript(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
cur.close()
con.close()
def delete_server(id):
con, cur = get_cur()
sql = """delete from servers where id = '%s'""" % (id)
try:
with con:
cur.executescript(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
else:
return True
cur.close()
con.close()
def update_server(hostname, ip, group, id):
con, cur = get_cur()
sql = """update servers set
hostname = '%s',
ip = '%s',
groups = '%s'
where id = '%s'""" % (hostname, ip, group, id)
try:
with con:
cur.executescript(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
cur.close()
con.close()
def select_users(**kwargs):
con, cur = get_cur()
sql = """select * from user ORDER BY id"""
if kwargs.get("user") is not None:
sql = """select * from user where username='%s' """ % kwargs.get("user")
try:
cur.execute(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
else:
return cur.fetchall()
cur.close()
con.close()
def select_groups(**kwargs):
con, cur = get_cur()
sql = """select * from groups ORDER BY id"""
if kwargs.get("group") is not None:
sql = """select * from groups where name='%s' """ % kwargs.get("group")
try:
cur.execute(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
else:
return cur.fetchall()
cur.close()
con.close()
def select_user_name_group(id):
con, cur = get_cur()
sql = """select name from groups where id='%s' """ % id
try:
cur.execute(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
else:
return cur.fetchone()
cur.close()
con.close()
def get_groups_select(id, **kwargs):
print('<select id="%s" name="%s">' % (id, id))
print('<option disabled selected>Choose group</option>')
GROUPS = select_groups()
selected = ""
print(kwargs.get('selected'))
for group in GROUPS:
if kwargs.get('selected'):
selected1 = kwargs.get('selected')
selected1 = int(selected1)
if selected1 == group[0]:
selected = 'selected'
else:
selected = ""
print('<option value="%s" %s>%s</option>' % (group[0], selected, group[1]))
print('</select>')
def select_servers(**kwargs):
con, cur = get_cur()
sql = """select * from servers ORDER BY id"""
if kwargs.get("server") is not None:
sql = """select * from servers where hostname='%s' """ % kwargs.get("server")
try:
cur.execute(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
else:
return cur.fetchall()
cur.close()
con.close()
def get_dick_permit():
import http.cookies
import os
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
login = cookie.get('login')
con, cur = get_cur()
sql = """ select * from user where username = '%s' """ % login.value
try:
cur.execute(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
else:
for group in cur:
if group[5] == '1':
sql = """ select * from servers """
else:
sql = """ select * from servers where groups = '%s' """ % group[5]
try:
cur.execute(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
else:
return cur.fetchall()
cur.close()
con.close()
def show_update_servers():
SERVERS = select_servers()
print('<tr class="overviewHead">'
'<td class="padding10">Hostname</td>'
'<td>IP</td>'
'<td>Group</td>'
'<td></td>'
'</tr>')
for server in SERVERS:
print('<tr id="server-%s">' % server[0])
print('<td class="padding10"><input type="text" name="server-%s" value="%s" class="form-control" onclick="deleteServer(%s)"></td>' % (server[0], server[1], server[0]))
print('<td><input type="text" name="descript-%s" value="%s" class="form-control"></td>' % (server[0], server[2]))
print('<td>')
get_groups_select("123", selected=server[3])
print('</td>')
print('<td><a class="delete" onclick="removeServer(%s)" style="cursor: pointer;"></a></td>' % server[0])
print('</tr>')
def show_update_user(user):
USERS = select_users(user=user)
for users in USERS:
print('<tr id="user-%s">' % users[0])
print('<td class="padding10"><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]
get_roles_select(need_id_role, selected=users[4])
print('</td>')
print('<td>')
need_id_group = "usergroup-%s" % users[0]
get_groups_select(need_id_group, selected=users[5])
print('</td>')
print('<td><a class="update-row" onclick="updateUser(%s)" style="cursor: pointer;"></a></td>' % users[0])
print('<td><a class="delete" onclick="removeUser(%s)" style="cursor: pointer;"></a></td>' % users[0])
print('</tr>')
def show_update_server(server):
SERVERS = select_servers(server=server)
for server in SERVERS:
print('<tr id="server-%s">' % server[0])
print('<td class="padding10"><input type="text" name="hostname-%s" value="%s" class="form-control" onclick="deleteServer(%s)"></td>' % (server[0], server[1], server[0]))
print('<td><input type="text" name="ip-%s" value="%s" class="form-control"></td>' % (server[0], server[2]))
print('<td>')
get_groups_select("123", selected=server[3])
print('</td>')
print('<td><a class="update-row" onclick="updateServer(%s)" style="cursor: pointer;"></a></td>' % users[0])
print('<td><a class="delete" onclick="removeServer(%s)" style="cursor: pointer;"></a></td>' % server[0])
print('</tr>')
def show_update_group(group):
GROUPS = select_groups(group=group)
for group in GROUPS:
print('<tr id="group-%s">' % group[0])
print('<td class="padding10 first-collumn"><input type="text" name="name-%s" value="%s" class="form-control"></td>' % (group[0], group[1]))
print('<td><input type="text" name="descript-%s" value="%s" class="form-control" size="100"></td>' % (group[0], group[2]))
print('<td></td>')
print('<td></td>')
print('</tr>')
def select_roles(**kwargs):
con, cur = get_cur()
sql = """select * from role ORDER BY id"""
if kwargs.get("role") is not None:
sql = """select * from role where name='%s' """ % kwargs.get("group")
try:
cur.execute(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
else:
return cur.fetchall()
cur.close()
con.close()
def select_roles(**kwargs):
con, cur = get_cur()
sql = """select * from role ORDER BY id"""
if kwargs.get("roles") is not None:
sql = """select * from role where name='%s' """ % kwargs.get("roles")
try:
cur.execute(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
else:
return cur.fetchall()
cur.close()
con.close()
def get_roles_select(id, **kwargs):
print('<select id="%s" name="%s">' % (id, id))
print('<optin disabled selected>Choose role</option>')
ROLES = select_roles()
selected = ""
for role in ROLES:
if kwargs.get('selected'):
if kwargs.get('selected') == role[1]:
selected = "selected"
else:
selected = ""
print('<option value="%s" %s>%s</option>' % (role[1], selected, role[1]))
print('</select>')
form = cgi.FieldStorage()
if form.getvalue('newusername') is not None:
email = form.getvalue('newemail')
password = form.getvalue('newpassword')
role = form.getvalue('newrole')
group = form.getvalue('newgroupuser')
new_user = form.getvalue('newusername')
if password is None or role is None or group is None:
print('Content-type: text/html\n')
print("All fields must be completed")
else:
print('Content-type: text/html\n')
add_user(new_user, email, password, role, group)
show_update_user(new_user)
if form.getvalue('updateuser') is not None:
email = form.getvalue('email')
password = form.getvalue('password')
role = form.getvalue('role')
group = form.getvalue('usergroup')
new_user = form.getvalue('updateuser')
id = form.getvalue('id')
if password is None or role is None or group is None:
print('Content-type: text/html\n')
print("All fields must be completed")
else:
print('Content-type: text/html\n')
update_user(new_user, email, password, role, group, id)
if form.getvalue('userdel') is not None:
print('Content-type: text/html\n')
if delete_user(form.getvalue('userdel')):
print("Ok")
if form.getvalue('newserver') is not None:
hostname = form.getvalue('newserver')
ip = form.getvalue('newip')
group = form.getvalue('newservergroup')
if ip is None or group is None:
print('Content-type: text/html\n')
print("All fields must be completed")
else:
print('Content-type: text/html\n')
add_server(hostname, ip, group)
show_update_server(hostname)
if form.getvalue('serverdel') is not None:
print('Content-type: text/html\n')
if delete_server(form.getvalue('serverdel')):
print("Ok")
if form.getvalue('newgroup') is not None:
newgroup = form.getvalue('newgroup')
desc = form.getvalue('newdesc')
print('Content-type: text/html\n')
add_group(newgroup, desc)
show_update_group(newgroup)
if form.getvalue('groupdel') is not None:
print('Content-type: text/html\n')
if delete_group(form.getvalue('groupdel')):
print("Ok")
if form.getvalue('updategroup') is not None:
name = form.getvalue('updategroup')
descript = form.getvalue('descript')
id = form.getvalue('id')
if name is None:
print('Content-type: text/html\n')
print("All fields must be completed")
else:
print('Content-type: text/html\n')
update_group(name, descript, id)
if form.getvalue('updateserver') is not None:
name = form.getvalue('updateserver')
ip = form.getvalue('ip')
group = form.getvalue('servergroup')
id = form.getvalue('id')
if name is None or ip is None:
print('Content-type: text/html\n')
print("All fields must be completed")
else:
print('Content-type: text/html\n')
update_server(name, ip, group, id)

View File

@ -1,3 +0,0 @@
{ "login": "admin", "password": "admin", "role": "admin", "group": "all" }
{ "login": "Editor", "password": "Editor@123", "role": "editor", "group": "all" }
{ "login": "Guest", "password": "Guest@123", "role": "guest", "group": "all" }

165
cgi-bin/users.py Normal file
View File

@ -0,0 +1,165 @@
#!/usr/bin/env python3
import html
import cgi
import sys
import os
import funct
import sql
funct.head("Admin area: users manage")
funct.check_config()
funct.check_login()
funct.page_for_admin()
form = cgi.FieldStorage()
USERS = sql.select_users()
GROUPS = sql.select_groups()
SERVERS = sql.select_servers()
ROLES = sql.select_roles()
print('<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>'
'</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 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="update-row" onclick="updateUser(%s)" style="cursor: pointer;"></a></td>' % users[0])
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" 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><tr>')
for group in GROUPS:
print('<tr id="group-%s">' % group[0])
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="update-row" onclick="updateGroup(%s)" style="cursor: pointer;"></a></td>' % group[0])
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" 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></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><a class="update-row" onclick="updateServer(%s)" style="cursor: pointer;"></a></td>' % server[0])
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></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><a class="add" 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>')

View File

@ -3,7 +3,7 @@ import html
import cgi import cgi
import requests import requests
import funct import funct
import listserv as listhap import sql
import configparser import configparser
from requests_toolbelt.utils import dump from requests_toolbelt.utils import dump
@ -18,14 +18,29 @@ haproxy_pass = config.get('haproxy', 'password')
stats_port = config.get('haproxy', 'stats_port') stats_port = config.get('haproxy', 'stats_port')
stats_page = config.get('haproxy', 'stats_page') stats_page = config.get('haproxy', 'stats_page')
listhap.listhap = funct.merge_two_dicts(listhap.listhap, listhap.listhap_vip)
form = cgi.FieldStorage() form = cgi.FieldStorage()
serv = form.getvalue('serv') serv = form.getvalue('serv')
if serv is None: if serv is None:
first_serv = sorted(list(listhap.listhap.values())) first_serv = sql.get_dick_permit()
serv = first_serv[0] for i in first_serv:
serv = i[2]
break
print('<a name="top"></a><div class="container">')
funct.get_auto_refresh("HAproxy statistics")
print('<br />'
'<form style="padding-left: 20px;" action="viewsttats.py" method="get">'
'<select autofocus required name="serv" id="serv">'
'<option disabled>Choose server</option>')
funct.choose_only_select(serv)
print('</select>'
'<a class="ui-button ui-widget ui-corner-all" id="show" title="Show stats" onclick="showStats()">Show</a>'
'</form>')
try: try:
response = requests.get('http://%s:%s/%s' % (serv, stats_port, stats_page), auth=(haproxy_user, haproxy_pass)) response = requests.get('http://%s:%s/%s' % (serv, stats_port, stats_page), auth=(haproxy_user, haproxy_pass))
@ -42,25 +57,6 @@ except requests.exceptions.Timeout as errt:
except requests.exceptions.RequestException as err: except requests.exceptions.RequestException as err:
print ("OOps: Something Else",err) print ("OOps: Something Else",err)
for i in listhap.listhap:
if listhap.listhap.get(i) == serv:
servname = i
print('<div class="container">')
funct.get_auto_refresh("HAproxy statistics")
print('<br />'
'<form style="padding-left: 20px;" action="viewsttats.py" method="get">'
'<select autofocus required name="serv" id="serv">'
'<option disabled>Choose server</option>')
funct.choose_server_with_vip(serv)
print('</select>'
'<a class="ui-button ui-widget ui-corner-all" id="show" title="Show stats" onclick="showStats()">Show</a>'
'</form>')
data = response.content data = response.content
print('<a name="conf"></a><div id="ajax" style="margin-left: 10px;">') print('<a name="conf"></a><div id="ajax" style="margin-left: 10px;">')
print(data.decode('utf-8')) print(data.decode('utf-8'))
@ -68,4 +64,4 @@ print('</div>')
funct.head("Stats HAproxy configs") funct.head("Stats HAproxy configs")
print('</div>') print('</div>')
funct.footer()

BIN
image/11.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

View File

@ -21,6 +21,11 @@
font-family: "Font Awesome 5 Solid"; font-family: "Font Awesome 5 Solid";
content: "\f06e"; content: "\f06e";
} }
.mon::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f080";
}
.logs::before { .logs::before {
display: none; display: none;
font-family: "Font Awesome 5 Solid"; font-family: "Font Awesome 5 Solid";
@ -76,3 +81,28 @@
font-family: "Font Awesome 5 Solid"; font-family: "Font Awesome 5 Solid";
content: "\f007"; content: "\f007";
} }
.update-row::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f01e";
}
.users::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f234";
}
.group::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f039";
}
.role::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f2b9";
}
.add:before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f00c";
}

View File

@ -206,6 +206,8 @@ function showConfig() {
success: function( data ) { success: function( data ) {
$("#ajax").html(data); $("#ajax").html(data);
window.history.pushState("Show config", "Show config", cur_url[0]+"?serv="+$("#serv").val()+"&open=open"); window.history.pushState("Show config", "Show config", cur_url[0]+"?serv="+$("#serv").val()+"&open=open");
var urlConfigShowJs = '/inc/configshow.js';
$.getScript(urlConfigShowJs);
} }
} ); } );
} }
@ -268,7 +270,7 @@ $( function() {
if( data == 'Bad config, check please ' ) { if( data == 'Bad config, check please ' ) {
alert(data); alert(data);
} else { } else {
document.location.reload(); showOverview();
} }
}, },
error: function(){ error: function(){
@ -294,7 +296,7 @@ $( function() {
var cur_url = '/cgi-bin/' + location.split('/').pop(); var cur_url = '/cgi-bin/' + location.split('/').pop();
cur_url = cur_url.split('?'); cur_url = cur_url.split('?');
$('.menu li').each(function () { $('.menu ').each(function () {
var link = $(this).find('a').attr('href'); var link = $(this).find('a').attr('href');
if (cur_url[0] == link) if (cur_url[0] == link)
@ -583,13 +585,4 @@ $( function() {
$("#optionsInput2").append(ui.item.value + " ") $("#optionsInput2").append(ui.item.value + " ")
} }
}); });
input = $('<tr><td><input type="text" name="login-add" value="" class="form-control"></td> <td><input type="passwrod" name="passwrod-add" value="" class="form-control"></td> <td><input type="text" name="role-add" value="" class="form-control"></td><td><input type="text" name="groups-add" value="" class="form-control"></td></tr>'); });
$( "#add-user" ).click( function(){
$( "#users-table" ).append(input);
});
} );
function removeUser(id) {
document.getElementById(id).parentNode.removeChild(document.getElementById(id));
return false;
}

View File

@ -146,7 +146,7 @@ pre {
} }
.configShow, .diff { .configShow, .diff {
margin-left: 16%; margin-left: 16%;
height: 78%; //height: 78%;
overflow: auto; overflow: auto;
width: 70%; width: 70%;
border: 1px solid #DCDCDC; border: 1px solid #DCDCDC;
@ -278,9 +278,6 @@ pre {
padding-left: 15px; padding-left: 15px;
font-size: 15px; font-size: 15px;
} }
.first-collumn {
width: 200px;
}
.serverUp, .serverDown { .serverUp, .serverDown {
padding: 3px; padding: 3px;
border-radius: 3px; border-radius: 3px;
@ -305,9 +302,12 @@ pre {
} }
.padding10 { .padding10 {
padding: 10px; padding: 10px;
padding-left: 15px; padding-left: 0px;
border: none; border: none;
width: 25%; width: 23%;
}
.first-collumn {
padding-left: 15px;
} }
.ro { .ro {
border: none; border: none;
@ -397,6 +397,9 @@ pre {
border-radius: 5px !important; border-radius: 5px !important;
color: #fff !important; color: #fff !important;
} }
.ui-tabs-nav {
padding-left: 20px !important;
}
a { a {
background-color: transparent; background-color: transparent;
} }
@ -499,6 +502,9 @@ a:focus {
margin-right: -15px; margin-right: -15px;
margin-left: -15px; margin-left: -15px;
} }
.update {
background-color: rgb(0,168,107) !important;
}
label { label {
display: inline-block; display: inline-block;

212
inc/users.js Normal file
View File

@ -0,0 +1,212 @@
$( function() {
$('#add-user').click(function() {
$.ajax( {
url: "sql.py",
data: {
newusername: $('#new-username').val(),
newpassword: $('#new-password').val(),
newemail: $('#new-email').val(),
newrole: $('#new-role').val(),
newgroupuser: $('#new-group').val()
},
type: "GET",
success: function( data ) {
if (data == "All fields must be completed ") {
alert(data);
} else {
$("#ajax-users").append(data);
$( "#ajax-users tr td" ).addClass( "update", 1000, callbackUser );
$.getScript(url);
}
}
} );
});
$('#add-group').click(function() {
$.ajax( {
url: "sql.py",
data: {
newgroup: $('#new-group-add').val(),
newdesc: $('#new-desc').val(),
},
type: "GET",
success: function( data ) {
$("#ajax-group").append(data);
$( "#ajax-group tr td" ).addClass( "update", 1000, callbackGroup );
window.location.reload();
}
} );
});
$('#add-server').click(function() {
$.ajax( {
url: "sql.py",
data: {
newserver: $('#new-server-add').val(),
newip: $('#new-ip').val(),
newservergroup: $('#new-server-group-add').val(),
},
type: "GET",
success: function( data ) {
data = data.replace(/\s+/g,' ');
if (data == "All fields must be completed ") {
alert(data);
} else {
$("#ajax-servers").append(data);
$( "#ajax-servers tr td" ).addClass( "update", 1000, callback );
$.getScript(url);
}
}
} );
});
function callbackUser() {
setTimeout(function() {
$( "#ajax-users tr td" ).removeClass( "update" );
}, 2500 );
}
function callback() {
setTimeout(function() {
$( "#ajax-servers tr td" ).removeClass( "update" );
}, 2500 );
}
function callbackGroup() {
setTimeout(function() {
$( "#ajax-group tr td" ).removeClass( "update" );
}, 2500 );
}
$('#add-user-button').click(function() {
if ($('#user-add-table').css('display', 'none')) {
$('#user-add-table').show("blind", "fast");
}
});
$('#add-group-button').click(function() {
if ($('#group-add-table').css('display', 'none')) {
$('#group-add-table').show("blind", "fast");
}
});
$('#add-server-button').click(function() {
if ($('#server-add-table').css('display', 'none')) {
$('#server-add-table').show("blind", "fast");
}
});
} );
function removeUser(id) {
$("#user-"+id).css("background-color", "#f36223");
$.ajax( {
url: "sql.py",
data: {
userdel: id,
},
type: "GET",
success: function( data ) {
data = data.replace(/\s+/g,' ');
if(data == "Ok ") {
$("#user-"+id).remove();
}
}
} );
}
function removeServer(id) {
$("#server-"+id).css("background-color", "#f36223");
$.ajax( {
url: "sql.py",
data: {
serverdel: id,
},
type: "GET",
success: function( data ) {
data = data.replace(/\s+/g,' ');
if(data == "Ok ") {
$("#server-"+id).remove();
}
}
} );
}
function removeGroup(id) {
$("#group-"+id).css("background-color", "#f36223");
$.ajax( {
url: "sql.py",
data: {
groupdel: id,
},
type: "GET",
success: function( data ) {
data = data.replace(/\s+/g,' ');
if(data == "Ok ") {
$("#group-"+id).remove();
}
}
} );
}
function updateUser(id) {
$.ajax( {
url: "sql.py",
data: {
updateuser: $('#login-'+id).val(),
password: $('#password-'+id).val(),
email: $('#email-'+id).val(),
role: $('#role-'+id).val(),
usergroup: $('#usergroup-'+id+' option:selected' ).val(),
id: id
},
type: "GET",
success: function( data ) {
data = data.replace(/\s+/g,' ');
if (data == "All fields must be completed ") {
alert(data);
} else {
$("#user-"+id).addClass( "update", 1000 );
setTimeout(function() {
$( "#user-"+id ).removeClass( "update" );
}, 2500 );
}
}
} );
}
function updateGroup(id) {
$.ajax( {
url: "sql.py",
data: {
updategroup: $('#name-'+id).val(),
descript: $('#descript-'+id).val(),
id: id
},
type: "GET",
success: function( data ) {
data = data.replace(/\s+/g,' ');
if (data == "All fields must be completed ") {
alert(data);
} else {
$("#group-"+id).addClass( "update", 1000 );
setTimeout(function() {
$( "#group-"+id ).removeClass( "update" );
}, 2500 );
}
}
} );
}
function updateServer(id) {
$.ajax( {
url: "sql.py",
data: {
updateserver: $('#hostname-'+id).val(),
ip: $('#ip-'+id).val(),
servergroup: $('#servergroup-'+id+' option:selected' ).val(),
id: id
},
type: "GET",
success: function( data ) {
data = data.replace(/\s+/g,' ');
if (data == "All fields must be completed ") {
alert(data);
} else {
$("#server-"+id).addClass( "update", 1000 );
setTimeout(function() {
$( "#server-"+id ).removeClass( "update" );
}, 2500 );
}
}
} );
}