Add "enable/disable" for servers. Bugs fixed
pull/19/head
Aidaho12 2018-04-19 11:22:44 +06:00
parent 54acd562e3
commit 6e97614910
11 changed files with 153 additions and 129 deletions

View File

@ -20,31 +20,23 @@ A simple web interface(user-frendly web GUI) for managing Haproxy servers. Leave
12. Telegram notification 12. Telegram notification
# Install # Install
Can be used as a service, or via fastaci apache + fastCGI(recommend, because it works faster).
How to use the service: For install just [dowload](https://github.com/Aidaho12/haproxy-wi/archive/master.zip) archive and untar somewhere:
For install just dowload archive and untar somewhere:
``` ```
$ cd /opt $ cd /var/www/
$ unzip master.zip $ unzip master.zip
$ mv haproxy-wi-master/ haproxy-wi $ mv haproxy-wi-master/ haproxy-wi
$ cd /opt/haproxy-wi $ cd haproxy-wi/cgi-bin
$ chmod +x install.sh $ chmod +x *.py
$ sudo ./install.sh $ ./create_db.py
``` ```
For Apache just do virtualhost with cgi-bin. For Apache do virtualhost with cgi-bin.
![alt text](image/haproxy-wi-overview.jpeg "Overview page") ![alt text](image/haproxy-wi-overview.jpeg "Overview page")
# Settings # Settings
``` ```
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
@ -63,15 +55,13 @@ For Runtime API enable state file on HAproxt servers and need install socat on a
``` ```
![alt text](image/haproxy-wi-logs.jpeg "View logs page") ![alt text](image/haproxy-wi-logs.jpeg "View logs page")
# Start and autostart if service # Update DB
```
systemctl enable haproxy-wi.service
systemctl start haproxy-wi.service
```
# Deb support For update db:
```
Sorry, but not use, because adapt yourself $ cd /var/www/haproxy-wi/cgi-bin
$ ./create_db.py
```
# Further development and support # Further development and support

View File

@ -44,7 +44,7 @@ if form.getvalue('serv') is not None and form.getvalue('open') is not None :
print('<form action="config.py" method="get">') print('<form action="config.py" method="get">')
print('<input type="hidden" value="%s" name="serv">' % serv) print('<input type="hidden" value="%s" name="serv">' % serv)
print('<input type="hidden" value="%s.old" name="oldconfig">' % cfg) print('<input type="hidden" value="%s.old" name="oldconfig">' % cfg)
print('<textarea name="config" rows="35" cols="100">%s</textarea>' % conf.read()) print('<textarea name="config" class="config" rows="35" cols="100">%s</textarea>' % conf.read())
print('<p>') print('<p>')
funct.get_button("Just save", value="save") funct.get_button("Just save", value="save")
funct.get_button("Save and restart") funct.get_button("Save and restart")

View File

@ -1,8 +1,23 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import sqlite3 as sqlite import sqlite3 as sqlite
import os
import sys
db = "haproxy-wi.db"
def check_db():
if os.path.isfile(db):
if os.path.getsize(db) > 100:
with open(db,'r', encoding = "ISO-8859-1") as f:
header = f.read(100)
if header.startswith('SQLite format 3'):
print("SQLite3 database has been detected.")
return False
else:
return True
def get_cur(): def get_cur():
con = sqlite.connect("haproxy-wi.db", isolation_level=None) con = sqlite.connect(db, isolation_level=None)
cur = con.cursor() cur = con.cursor()
return con, cur return con, cur
@ -63,4 +78,50 @@ def create_table():
cur.close() cur.close()
con.close() con.close()
create_table() def update_db_v_2_0_1():
con, cur = get_cur()
sql = """
ALTER TABLE `servers` ADD COLUMN type_ip INTEGER NOT NULL DEFAULT(0);
"""
try:
cur.executescript(sql)
except sqlite.Error as e:
if e.args[0] == 'duplicate column name: type_ip':
print('Updating... go to version 2.0.1.1')
return False
else:
print("An error occurred:", e.args[0])
return False
else:
print("DB was update to 2.0.1")
return True
cur.close()
con.close()
def update_db_v_2_0_1_1():
con, cur = get_cur()
sql = """
ALTER TABLE `servers` ADD COLUMN enable INTEGER NOT NULL DEFAULT(1);
"""
try:
cur.executescript(sql)
except sqlite.Error as e:
if e.args[0] == 'duplicate column name: enable':
print('Already updated. No run more. Thx =^.^=')
return False
else:
print("An error occurred:", e.args[0])
return False
else:
print("DB was update to 2.0.1.1")
return True
cur.close()
con.close()
if check_db():
create_table()
else:
print('DB already exists, try update')
if update_db_v_2_0_1():
print('DB was property update to version 2.0.1.')
update_db_v_2_0_1_1()

View File

@ -148,8 +148,6 @@ def head(title):
'</span>' '</span>'
'</a>' '</a>'
'</div>') '</div>')
if config.get('main', 'logo_enable') == "1":
print('<div><img src="%s" title="Logo" class="logo"></div>' % config.get('main', 'logo_path'))
links() links()
print('</div><div class="container">') print('</div><div class="container">')
@ -190,7 +188,7 @@ def links():
'</li>') '</li>')
print('</ul>' print('</ul>'
'</nav>' '</nav>'
'<div class="copyright-menu">HAproxy-WI v2.0.1</div>' '<div class="copyright-menu">HAproxy-WI v2.0.2</div>'
'</div>') '</div>')
def show_login_links(): def show_login_links():
@ -198,9 +196,9 @@ def show_login_links():
login = cookie.get('login') login = cookie.get('login')
if login is None: if login is None:
print('<li><a href=/cgi-bin/login.py? title="Login" class="login head-submenu">Login</a></li>') print('<li><a href=/cgi-bin/login.py? title="Login" class="login">Login</a></li>')
else: else:
print('<li><a href=/cgi-bin/login.py?logout=logout title="Logout, user name: %s" class="login head-submenu">Logout</a></li>' % login.value) print('<li><a href=/cgi-bin/login.py?logout=logout title="Logout, user name: %s" class="login">Logout</a></li>' % login.value)
def footer(): def footer():
print('</center></div>' print('</center></div>'

View File

@ -6,9 +6,6 @@ server_bind_ip = 0.0.0.0
server_port = 8000 server_port = 8000
log_path = %(fullpath)s/log/ log_path = %(fullpath)s/log/
time_zone = UTC time_zone = UTC
#Enable logo on top menu. Default disable
logo_enable = 0
logo_path = /logo.png
[configs] [configs]
#Server for save configs from HAproxy servers #Server for save configs from HAproxy servers

View File

@ -98,9 +98,9 @@ def update_group(name, descript, id):
cur.close() cur.close()
con.close() con.close()
def add_server(hostname, ip, group, typeip): def add_server(hostname, ip, group, typeip, enable):
con, cur = get_cur() con, cur = get_cur()
sql = """INSERT INTO servers (hostname, ip, groups, type_ip) VALUES ('%s', '%s', '%s', '%s')""" % (hostname, ip, group, typeip) sql = """INSERT INTO servers (hostname, ip, groups, type_ip, enable) VALUES ('%s', '%s', '%s', '%s', '%s')""" % (hostname, ip, group, typeip, enable)
try: try:
with con: with con:
cur.executescript(sql) cur.executescript(sql)
@ -125,14 +125,15 @@ def delete_server(id):
cur.close() cur.close()
con.close() con.close()
def update_server(hostname, ip, group, typeip, id): def update_server(hostname, ip, group, typeip, enable, id):
con, cur = get_cur() con, cur = get_cur()
sql = """update servers set sql = """update servers set
hostname = '%s', hostname = '%s',
ip = '%s', ip = '%s',
groups = '%s', groups = '%s',
type_ip = '%s' type_ip = '%s',
where id = '%s'""" % (hostname, ip, group, typeip, id) enable = '%s'
where id = '%s'""" % (hostname, ip, group, typeip, enable, id)
try: try:
with con: with con:
cur.executescript(sql) cur.executescript(sql)
@ -200,9 +201,11 @@ def get_groups_select(id, **kwargs):
def select_servers(**kwargs): def select_servers(**kwargs):
con, cur = get_cur() con, cur = get_cur()
sql = """select * from servers ORDER BY groups """ sql = """select * from servers where enable = '1' ORDER BY groups """
if kwargs.get("server") is not None: if kwargs.get("server") is not None:
sql = """select * from servers where hostname='%s' """ % kwargs.get("server") sql = """select * from servers where hostname='%s' """ % kwargs.get("server")
if kwargs.get("full") is not None:
sql = """select * from servers ORDER BY groups """
try: try:
cur.execute(sql) cur.execute(sql)
except sqlite.Error as e: except sqlite.Error as e:
@ -225,7 +228,24 @@ def get_type_ip_checkbox(id, **kwargs):
checked = 'checked' checked = 'checked'
else: else:
checked = "" checked = ""
print('<label for="typeip-%s"> Virt </label><input type="checkbox" id="typeip-%s" %s>' % (server[0],server[0], checked)) print('<label for="typeip-%s"></label><input type="checkbox" id="typeip-%s" %s>' % (server[0],server[0], checked))
cur.close()
con.close()
def get_enable_checkbox(id, **kwargs):
con, cur = get_cur()
sql = """select id, enable from servers where id='%s' """ % id
try:
cur.execute(sql)
except sqlite.Error as e:
print("An error occurred:", e.args[0])
else:
for server in cur.fetchall():
if server[1] == 1:
checked = 'checked'
else:
checked = ""
print('<label for="enable-%s"></label><input type="checkbox" id="enable-%s" %s>' % (server[0],server[0], checked))
cur.close() cur.close()
con.close() con.close()
@ -239,7 +259,7 @@ def get_dick_permit(**kwargs):
if kwargs.get('virt'): if kwargs.get('virt'):
type_ip = "" type_ip = ""
else: else:
type_ip = "type_ip = 0" type_ip = "and type_ip = 0"
try: try:
cur.execute(sql) cur.execute(sql)
except sqlite.Error as e: except sqlite.Error as e:
@ -247,13 +267,9 @@ def get_dick_permit(**kwargs):
else: else:
for group in cur: for group in cur:
if group[5] == '1': if group[5] == '1':
if kwargs.get('virt') is None: sql = """ select * from servers where enable = 1 %s """ % type_ip
type_ip = 'where ' + type_ip
sql = """ select * from servers %s """ % type_ip
else: else:
if kwargs.get('virt') is None: sql = """ select * from servers where groups like '%{group}%' and enable = 1 {type_ip} """.format(group=group[5], type_ip=type_ip)
type_ip = 'and ' + type_ip
sql = """ select * from servers where groups like '%{group}%' {type_ip} """.format(group=group[5], type_ip=type_ip)
try: try:
cur.execute(sql) cur.execute(sql)
except sqlite.Error as e: except sqlite.Error as e:
@ -273,12 +289,15 @@ def show_update_servers():
'</tr>') '</tr>')
for server in SERVERS: for server in SERVERS:
print('<tr id="server-%s">' % server[0]) print('<tr id="server-%s">' % server[0])
print('<td class="padding10 first-collumn"><input type="text" name="server-%s" value="%s" class="form-control"></td>' % (server[0], server[1])) print('<td class="padding10 first-collumn"><input type="text" id="server-%s" value="%s" class="form-control"></td>' % (server[0], server[1]))
print('<td><input type="text" name="descript-%s" value="%s" class="form-control"></td>' % (server[0], server[2])) print('<td><input type="text" id="descript-%s" value="%s" class="form-control"></td>' % (server[0], server[2]))
print('<td>') print('<td>')
get_groups_select("123", selected=server[3]) get_groups_select("123", selected=server[3])
print('</td>') print('</td>')
print('<td>') print('<td>')
get_enable_checkbox(server[0])
print('</td>')
print('<td>')
get_type_ip_checkbox(server[0]) get_type_ip_checkbox(server[0])
print('</td>') print('</td>')
print('<td><a class="delete" onclick="removeServer(%s)" style="cursor: pointer;"></a></td>' % server[0]) print('<td><a class="delete" onclick="removeServer(%s)" style="cursor: pointer;"></a></td>' % server[0])
@ -307,10 +326,14 @@ def show_update_server(server):
SERVERS = select_servers(server=server) SERVERS = select_servers(server=server)
for server in SERVERS: for server in SERVERS:
print('<tr id="server-%s">' % server[0]) print('<tr id="server-%s">' % server[0])
print('<td class="padding10 first-collumn"><input type="text" name="hostname-%s" value="%s" class="form-control"></td>' % (server[0], server[1])) 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" name="ip-%s" value="%s" class="form-control"></td>' % (server[0], server[2])) print('<td><input type="text" id="ip-%s" value="%s" class="form-control"></td>' % (server[0], server[2]))
print('<td>') print('<td>')
get_groups_select("123", selected=server[3]) need_id_group = "servergroup-%s" % server[0]
get_groups_select(need_id_group, selected=server[3])
print('</td>')
print('<td>')
get_enable_checkbox(server[0])
print('</td>') print('</td>')
print('<td>') print('<td>')
get_type_ip_checkbox(server[0]) get_type_ip_checkbox(server[0])
@ -412,12 +435,13 @@ if form.getvalue('newserver') is not None:
ip = form.getvalue('newip') ip = form.getvalue('newip')
group = form.getvalue('newservergroup') group = form.getvalue('newservergroup')
typeip = form.getvalue('typeip') typeip = form.getvalue('typeip')
enable = form.getvalue('enable')
if ip is None or group is None: if ip is None or group is None:
print('Content-type: text/html\n') print('Content-type: text/html\n')
print(error_mess) print(error_mess)
else: else:
print('Content-type: text/html\n') print('Content-type: text/html\n')
if add_server(hostname, ip, group, typeip): if add_server(hostname, ip, group, typeip, enable):
show_update_server(hostname) show_update_server(hostname)
if form.getvalue('serverdel') is not None: if form.getvalue('serverdel') is not None:
@ -453,11 +477,12 @@ if form.getvalue('updateserver') is not None:
ip = form.getvalue('ip') ip = form.getvalue('ip')
group = form.getvalue('servergroup') group = form.getvalue('servergroup')
typeip = form.getvalue('typeip') typeip = form.getvalue('typeip')
enable = form.getvalue('enable')
id = form.getvalue('id') id = form.getvalue('id')
if name is None or ip is None: if name is None or ip is None:
print('Content-type: text/html\n') print('Content-type: text/html\n')
print(error_mess) print(error_mess)
else: else:
print('Content-type: text/html\n') print('Content-type: text/html\n')
update_server(name, ip, group, typeip, id) update_server(name, ip, group, typeip, enable, id)

View File

@ -15,7 +15,7 @@ form = cgi.FieldStorage()
USERS = sql.select_users() USERS = sql.select_users()
GROUPS = sql.select_groups() GROUPS = sql.select_groups()
SERVERS = sql.select_servers() SERVERS = sql.select_servers(full=1)
ROLES = sql.select_roles() ROLES = sql.select_roles()
print('<script src="/inc/users.js"></script>' print('<script src="/inc/users.js"></script>'
@ -85,7 +85,7 @@ print('</div><div id="groups">'
'<td>Desciption</td>' '<td>Desciption</td>'
'<td></td>' '<td></td>'
'<td></td>' '<td></td>'
'</tr><tr>') '</tr>')
for group in GROUPS: for group in GROUPS:
print('<tr id="group-%s">' % group[0]) 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 class="padding10 first-collumn"><input type="text" id="name-%s" value="%s" class="form-control"></td>' % (group[0], group[1]))
@ -115,6 +115,8 @@ print('<br /><br /><table class="overview" id="group-add-table" style="display:
'<td class="padding10 first-collumn">Hostname</td>' '<td class="padding10 first-collumn">Hostname</td>'
'<td>IP</td>' '<td>IP</td>'
'<td>Group</td>' '<td>Group</td>'
'<td>Enable</td>'
'<td>Virt</td>'
'<td></td>' '<td></td>'
'<td></td>' '<td></td>'
'</tr>') '</tr>')
@ -127,6 +129,12 @@ for server in SERVERS:
need_id_group = "servergroup-%s" % server[0] need_id_group = "servergroup-%s" % server[0]
sql.get_groups_select(need_id_group, selected=server[3]) sql.get_groups_select(need_id_group, selected=server[3])
print('</td>') 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><a class="update-row" onclick="updateServer(%s)" style="cursor: pointer;"></a></td>' % server[0]) 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('<td><a class="delete" onclick="removeServer(%s)" style="cursor: pointer;"></a></td>' % server[0])
print('</tr>') print('</tr>')
@ -137,6 +145,8 @@ print('</table>'
'<td class="padding10 first-collumn">New hostname</td>' '<td class="padding10 first-collumn">New hostname</td>'
'<td>IP</td>' '<td>IP</td>'
'<td>Group</td>' '<td>Group</td>'
'<td>Enable</td>'
'<td>Virt</td>'
'<td></td>' '<td></td>'
'</tr>' '</tr>'
'<tr>' '<tr>'
@ -144,7 +154,9 @@ print('</table>'
'<td><input type="text" name="new-ip" id="new-ip" class="form-control"></td><td>') '<td><input type="text" name="new-ip" id="new-ip" class="form-control"></td><td>')
sql.get_groups_select("new-server-group-add") sql.get_groups_select("new-server-group-add")
print('</td>' print('</td>'
'<td><a class="add-admin" id="add-server" style="cursor: pointer;"></a></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><a class="add-admin" id="add-server" style="cursor: pointer;"></a></td>'
'</tr>') '</tr>')
print('</table>') print('</table>')

View File

@ -1,16 +0,0 @@
[Unit]
Description=Haproxy web interface
After=syslog.target network.target
[Service]
Type=simple
User=haproxy-wi
ExecStart=/opt/haproxy-wi/server.py >> /opt/haproxy-wi/log/haproxy-webface.log
RestartSec=2s
Restart=on-failure
TimeoutStopSec=1s
[Install]
WantedBy=multi-user.target

View File

@ -49,17 +49,22 @@ $( function() {
}); });
$('#add-server').click(function() { $('#add-server').click(function() {
$('#error').remove(); $('#error').remove();
var typeip; var typeip = 0;
var enable = 0;
if ($('#typeip').is(':checked')) { if ($('#typeip').is(':checked')) {
typeip = '1'; typeip = '1';
} }
if ($('#enable').is(':checked')) {
enable = '1';
}
$.ajax( { $.ajax( {
url: "sql.py", url: "sql.py",
data: { data: {
newserver: $('#new-server-add').val(), newserver: $('#new-server-add').val(),
newip: $('#new-ip').val(), newip: $('#new-ip').val(),
newservergroup: $('#new-server-group-add').val(), newservergroup: $('#new-server-group-add').val(),
typeip: typeip typeip: typeip,
enable: enable
}, },
type: "GET", type: "GET",
success: function( data ) { success: function( data ) {
@ -209,10 +214,14 @@ function updateGroup(id) {
} ); } );
} }
function updateServer(id) { function updateServer(id) {
var typeip; var typeip = 0;
var enable = 0;
if ($('#typeip-'+id).is(':checked')) { if ($('#typeip-'+id).is(':checked')) {
typeip = '1'; typeip = '1';
} }
if ($('#enable-'+id).is(':checked')) {
enable = '1';
}
$.ajax( { $.ajax( {
url: "sql.py", url: "sql.py",
data: { data: {
@ -220,6 +229,7 @@ function updateServer(id) {
ip: $('#ip-'+id).val(), ip: $('#ip-'+id).val(),
servergroup: $('#servergroup-'+id+' option:selected' ).val(), servergroup: $('#servergroup-'+id+' option:selected' ).val(),
typeip: typeip, typeip: typeip,
enable: enable,
id: id id: id
}, },
type: "GET", type: "GET",

View File

@ -1,33 +0,0 @@
#!/bin/bash
echo "Enter dir for HAproxy-WI. Default: [/opt/haproxy-wi]"
read DIR
echo "Enter user for HAproxy-WI. Defailt: [haproxy-wi]"
read USER
if [[ $DIR = "" ]]; then
DIR="/opt/haproxy-wi"
else
sed -i "s!/opt/haproxy-wi!$DIR!" haproxy-webintarface.config
sed -i "s!/opt/haproxy-wi!$DIR!" server.py
sed -i "s!/opt/haproxy-wi!$DIR!" haproxy-wi.service
fi
if [[ $USER = "" ]]; then
USER="haproxy-wi"
fi
echo "Install req"
pip3 install -r requirements.txt
echo "Add user $USER"
useradd $USER -d $DIR -s /sbin/nologin
chmod +x server.py
chmod +x cgi-bin/*.py
chown $USER:$USER -R *
echo "Creating service"
sed -i "s/haproxy-wi/$USER/" haproxy-wi.service
mv haproxy-wi.service /etc/systemd/system
systemctl daemon-reload

View File

@ -1,20 +0,0 @@
#!/usr/bin/env python3
import os, sys
import configparser
path_config = "/opt/haproxy-wi/haproxy-webintarface.config"
config = configparser.ConfigParser()
config.read(path_config)
log_path = config.get('main', 'log_path')
fullpath = config.get('main', 'fullpath')
server_bind_ip = config.get('main', 'server_bind_ip')
server_port = config.getint('main', 'server_port')
from http.server import HTTPServer, CGIHTTPRequestHandler
sys.stderr = open(log_path + '/haproxy-monitor.log', 'w')
webdir = fullpath
os.chdir(webdir)
server_address = (server_bind_ip, server_port)
httpd = HTTPServer(server_address, CGIHTTPRequestHandler)
httpd.serve_forever()