diff --git a/README.md b/README.md index 646c34ed..458a1ec1 100644 --- a/README.md +++ b/README.md @@ -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 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") # 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 +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 For Runtime API enable state file on HAproxt servers and need install socat on all haproxy servers: diff --git a/cgi-bin/add.py b/cgi-bin/add.py index 51282b88..74cbb1d2 100644 --- a/cgi-bin/add.py +++ b/cgi-bin/add.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 import html import cgi -import listserv as listhap import os import funct +import sql import paramiko import configparser import http.cookies @@ -23,6 +23,7 @@ funct.page_for_admin(level = 1) haproxy_configs_server = config.get('configs', 'haproxy_configs_server') hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') form = cgi.FieldStorage() +listhap = sql.get_dick_permit() if form.getvalue('mode') is not None: serv = form.getvalue('serv') @@ -141,8 +142,8 @@ print('
' '' '
Note: If you reconfigure First server, second will reconfigured automatically
' @@ -261,8 +262,8 @@ print('' '' '
Note: If you reconfigure First server, second will reconfigured automatically
' @@ -345,8 +346,8 @@ print('' '' '
Note: If you reconfigure First server, second will reconfigured automatically
' diff --git a/cgi-bin/config.py b/cgi-bin/config.py index f86f2e46..bd240c7b 100644 --- a/cgi-bin/config.py +++ b/cgi-bin/config.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 import html import cgi -import listserv as listhap import os import http.cookies import configparser diff --git a/cgi-bin/configver.py b/cgi-bin/configver.py index 099d1d7f..0f1944e4 100644 --- a/cgi-bin/configver.py +++ b/cgi-bin/configver.py @@ -51,7 +51,7 @@ if serv is not None and form.getvalue('open') is not None: print('') print('' % serv) print('') - print('

') + print('') Select = form.getvalue('Select') @@ -65,7 +65,10 @@ if serv is not None and form.getvalue('open') is not None: print('' % serv) print('' % configver) print('') - print('') + print('') + print('

' + 'Expand all' + '

') funct.show_config(configver) print('

') funct.get_button("Just save", value="save") diff --git a/cgi-bin/create_db.py b/cgi-bin/create_db.py new file mode 100644 index 00000000..179a61b6 --- /dev/null +++ b/cgi-bin/create_db.py @@ -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() \ No newline at end of file diff --git a/cgi-bin/delver.py b/cgi-bin/delver.py index 23dd0924..5818115a 100644 --- a/cgi-bin/delver.py +++ b/cgi-bin/delver.py @@ -19,7 +19,7 @@ config.read(path_config) 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") if serv is not None and form.getvalue('open') is not None: diff --git a/cgi-bin/edit.py b/cgi-bin/edit.py index a6d18739..6933792c 100644 --- a/cgi-bin/edit.py +++ b/cgi-bin/edit.py @@ -2,6 +2,7 @@ import html import cgi import funct +import sql form = cgi.FieldStorage() serv = form.getvalue('serv') @@ -13,19 +14,19 @@ funct.check_config() print('

Runtime API

' '' '' - '' + '' '' '' '' '' '' '' - '' '' diff --git a/cgi-bin/funct.py b/cgi-bin/funct.py index 181b29da..ec91ec8c 100644 --- a/cgi-bin/funct.py +++ b/cgi-bin/funct.py @@ -3,10 +3,10 @@ import os import paramiko import http.cookies from paramiko import SSHClient -import listserv as listhap from datetime import datetime from pytz import timezone import configparser +import sql def check_config(): path_config = "haproxy-webintarface.config" @@ -63,10 +63,7 @@ def check_login(**kwargs): login = cookie.get('login') role = cookie.get('role') ref = os.environ.get("SCRIPT_NAME") - - if kwargs.get("admins_area") == "1" and role.value != "2": - print('') - + if login is None: print('' % ref) @@ -76,15 +73,15 @@ def is_admin(**kwargs): level = kwargs.get("level") if role is None: - role = 0 + role = 3 else: role = int(role.value) if level is None: - level = 2 + level = 1 try: - if level <= role: + if role <= level: return True else: return False @@ -164,6 +161,7 @@ def links(): '' @@ -173,25 +171,34 @@ def links(): '') - if is_admin(level = 1): + if is_admin(level = 2): print('
  • Versions' '
      ' '
    • Upload
    • ') if is_admin(): print('
    • Delete
    • ') - if is_admin(level = 1): + if is_admin(level = 2): print('
    ' '
  • ') show_login_links() + if is_admin(): + print('
  • Admin area' + '' + '
  • ') print('' '' - '' + '' '') def show_login_links(): @@ -488,69 +495,22 @@ def ssh_command(serv, commands, **kwargs): 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): - listhap = get_dick_after_permit() + listhap = sql.get_dick_permit() if kwargs.get("servNew"): servNew = kwargs.get("servNew") else: 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' else: selected = '' - print('' % (listhap.get(i), selected, i)) + print('' % (i[2], selected, i[1])) def chooseServer(formName, title, note, **kwargs): servNew = form.getvalue('serNew') @@ -575,20 +535,4 @@ def chooseServer(formName, title, note, **kwargs): if note == "y": print('

    Note: If you reconfigure First server, second will reconfigured automatically

    ') print('') - -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('' % (listhap.listhap.get(i), selected, i)) -def merge_two_dicts(x, y): - z = x.copy() - z.update(y) - return z - - - diff --git a/cgi-bin/groups b/cgi-bin/groups deleted file mode 100644 index 14a46c95..00000000 --- a/cgi-bin/groups +++ /dev/null @@ -1,3 +0,0 @@ -{ "name": "all", "lists": "all" } -{ "name": "mysql", "lists": "mysql" } -{ "name": "web", "lists": "web" } \ No newline at end of file diff --git a/cgi-bin/listserv.py b/cgi-bin/listserv.py deleted file mode 100644 index 181b72ce..00000000 --- a/cgi-bin/listserv.py +++ /dev/null @@ -1,7 +0,0 @@ -listhap= { - 'haproxy1': '172.28.0.1', - 'haproxy2': '172.28.0.2' - } -list_hap_vip = { - 'haproxy-vip': '172.28.0.3' - } diff --git a/cgi-bin/login.py b/cgi-bin/login.py index c13ac953..0c077026 100644 --- a/cgi-bin/login.py +++ b/cgi-bin/login.py @@ -4,20 +4,13 @@ import html import os import funct import http.cookies -import json +import sql cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) form = cgi.FieldStorage() ref = form.getvalue('ref') login = form.getvalue('login') 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): if error == "error": @@ -49,15 +42,15 @@ if login is None: login_page("n") if login is not None and password is not None: - for f in open(USERS, 'r'): - users = json.loads(f) - if login in users['login'] and password == users['password']: - if users['role'] == "admin": - role = 2 - elif users['role'] == "editor": + USERS = sql.select_users() + for users in USERS: + if login in users[1] and password == users[3]: + if users[4] == "admin": role = 1 + elif users[4] == "editor": + role = 2 else: - role = 0 + role = 3 c = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) c["login"] = login c["login"]["path"] = "/cgi-bin/" @@ -65,7 +58,7 @@ if login is not None and password is not None: c["role"] = role c["role"]["path"] = "/cgi-bin/" 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"]["expires"] = "Wed May 18 03:33:20 2033" print(c) diff --git a/cgi-bin/logs.py b/cgi-bin/logs.py index 7ed9aac3..c31a349d 100644 --- a/cgi-bin/logs.py +++ b/cgi-bin/logs.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 import html import cgi -import listserv as listhap import funct import configparser @@ -19,13 +18,13 @@ config.read(path_config) funct.get_auto_refresh("HAproxy logs") print('
    ServerServerDisable/Enable server or output any informationCommandSave change
    ' + '' '
    ' '
    ' @@ -40,7 +41,7 @@ print('' '' '' '' - '' + '' '' 'Enter' '
    ' '' - '' + '' '' '' '' '' '' - '' % rows) -print('' - '' '' diff --git a/cgi-bin/options.py b/cgi-bin/options.py index 6a20357d..5f3be826 100644 --- a/cgi-bin/options.py +++ b/cgi-bin/options.py @@ -165,7 +165,7 @@ if serv is not None and act == "configShow": funct.get_config(serv, cfg) - print('') + print('') print("

    Config from %s

    " % serv) print('

    ' 'Expand all' diff --git a/cgi-bin/ovw.py b/cgi-bin/ovw.py index 540eecf4..d4f19f43 100644 --- a/cgi-bin/ovw.py +++ b/cgi-bin/ovw.py @@ -3,6 +3,7 @@ import configparser import json import os import cgi +import sql path_config = "haproxy-webintarface.config" config = configparser.ConfigParser() @@ -18,23 +19,17 @@ hap_configs_dir = config.get('configs', 'haproxy_save_configs_dir') form = cgi.FieldStorage() def get_overview(): - USERS = cgi_path + '/users' - - try: - with open(USERS, "r") as user: - pass - except IOError: - print("Can't load users DB") + USERS = sql.select_users() print('

    ServerServerNumber rowsEx for grep
    ' + '' '
    ' '
    ' % grep) +print('' % grep) print('' + '' 'Show' '
    ') if funct.is_admin(): print('' - '' - '' - '' + '' + '' + '' + '') print('
    LoginGroup' - 'Role' - '' + 'LoginEmailGroupRole' '' '' 'Show all' @@ -45,55 +40,59 @@ def get_overview(): i = 0 style = "" - for f in open(USERS, 'r'): + for users in USERS: i = i + 1 - users = json.loads(f) if i is 4: style = 'style="display: none;" class="show-users"' - print('
    ' + users['login'] +'') - print(users['group']+'') - print(users['role']) + print('
    ' + users[1] +'') + print(users[2]+'') + GROUPS = sql.select_user_name_group(users[5]) + for group in GROUPS: + print(group) + print('') + print(users[4]) print('
    ') print('' '' - '' + '' '' '' - '' + '' '') - listhap = funct.get_dick_after_permit() + listhap = sql.get_dick_permit() commands = [ "ps -Af |grep [h]aproxy |wc -l" ] commands1 = [ "ls -l %s |awk '{ print $6\" \"$7\" \"$8}'" % haproxy_config_path ] - for i in sorted(listhap): - print('') print('
    ServerServer' 'HAproxy status' '' 'Action' '' + '' 'Last edit' '
    %s' % (i, i, i)) - funct.ssh_command(listhap.get(i), commands, server_status="1") + for server in listhap: + print('
    %s' % (server[1], server[1], server[1])) + funct.ssh_command(server[2], commands, server_status="1") print('') if funct.is_admin(): - print('start' % listhap.get(i)) - print('start' % listhap.get(i)) - print('restart' % listhap.get(i)) - print('show' % listhap.get(i)) - print('edit' % listhap.get(i)) - print('compare' % listhap.get(i)) - print('map' % listhap.get(i)) + print('start' % server[2]) + print('start' % server[2]) + print('restart' % server[2]) + print('show' % server[2]) + print('edit' % server[2]) + print('compare' % server[2]) + print('map' % server[2]) print('') - funct.ssh_command(listhap.get(i), commands1) + funct.ssh_command(server[2], commands1) print('
    ' '' - '' '') + for server in sorted(listhap): + print('') print('') print('
    Server' + '' 'HAproxy info' '' @@ -106,12 +105,12 @@ def get_overview(): "haproxy -v |head -1", status_command + "|grep Active | sed 's/^[ \t]*//'" ] commands1 = [ "top -u haproxy -b -n 1" ] - for i in sorted(listhap): - print('

    ' + i + ':

    ' + server[1] + ':

    Total listen/frontend/backend:
    ')
    -		funct.ssh_command(listhap.get(i), commands)
    +		funct.ssh_command(server[2], commands)
     		print('
    ')
    -		funct.ssh_command(listhap.get(i), commands1)
    +		funct.ssh_command(server[2], commands1)
     		print('
    ') diff --git a/cgi-bin/sql.py b/cgi-bin/sql.py new file mode 100644 index 00000000..d230e4cc --- /dev/null +++ b/cgi-bin/sql.py @@ -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('') + +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('' + 'Hostname' + 'IP' + 'Group' + '' + '') + for server in SERVERS: + print('' % server[0]) + print('' % (server[0], server[1], server[0])) + print('' % (server[0], server[2])) + print('') + get_groups_select("123", selected=server[3]) + print('') + print('' % server[0]) + print('') + +def show_update_user(user): + USERS = select_users(user=user) + for users in USERS: + print('' % users[0]) + print('' % (users[0], users[1])) + print('' % (users[0], users[3])) + print('' % (users[0], users[2])) + print('') + need_id_role = "role-%s" % users[0] + get_roles_select(need_id_role, selected=users[4]) + print('') + print('') + need_id_group = "usergroup-%s" % users[0] + get_groups_select(need_id_group, selected=users[5]) + print('') + print('' % users[0]) + print('' % users[0]) + print('') + +def show_update_server(server): + SERVERS = select_servers(server=server) + for server in SERVERS: + print('' % server[0]) + print('' % (server[0], server[1], server[0])) + print('' % (server[0], server[2])) + print('') + get_groups_select("123", selected=server[3]) + print('') + print('' % users[0]) + print('' % server[0]) + print('') + +def show_update_group(group): + GROUPS = select_groups(group=group) + for group in GROUPS: + print('' % group[0]) + print('' % (group[0], group[1])) + print('' % (group[0], group[2])) + print('') + print('') + print('') + +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('') +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) + \ No newline at end of file diff --git a/cgi-bin/users b/cgi-bin/users deleted file mode 100644 index 79692c13..00000000 --- a/cgi-bin/users +++ /dev/null @@ -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" } diff --git a/cgi-bin/users.py b/cgi-bin/users.py new file mode 100644 index 00000000..214c623f --- /dev/null +++ b/cgi-bin/users.py @@ -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('' + '
    ' + '' + '
    ' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '') + +for users in USERS: + print('' % users[0]) + print('' % (users[0], users[1])) + print('' % (users[0], users[3])) + print('' % (users[0], users[2])) + print('') + print('') + print('' % users[0]) + print('' % users[0]) + print('') +print('
    Login namePasswordEmailRoleGroup
    ') + need_id_role = "role-%s" % users[0] + sql.get_roles_select(need_id_role, selected=users[4]) + print('') + need_id_group = "usergroup-%s" % users[0] + sql.get_groups_select(need_id_group, selected=users[5]) + print('
    ' + '
    + Add') + +print('

    ' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '') +print('') + +print('
    ' + '' + '' + '' + '' + '' + '' + '') +for group in GROUPS: + print('' % group[0]) + print('' % (group[0], group[1])) + print('' % (group[0], group[2])) + print('' % group[0]) + print('' % group[0]) + print('') +print('
    NameDesciption
    ' + '
    + Add') + +print('

    ' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' +'' +'
    ' +'
    ' + '' + '' + '' + '' + '' + '' + '' + '') + +for server in SERVERS: + print('' % server[0]) + print('' % (server[0], server[1])) + print('' % (server[0], server[2])) + print('') + print('' % server[0]) + print('' % server[0]) + print('') +print('
    HostnameIPGroup
    ') + need_id_group = "servergroup-%s" % server[0] + sql.get_groups_select(need_id_group, selected=server[3]) + print('
    ' + '
    + Add' + '

    ' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '') +print('') + +print('
    ' + '' + '' + '' + '' + '' + '' + '') +for role in ROLES: + print('' % role[0]) + print('' % ( role[1])) + print('' % (role[2])) + print('') + +print('
    NameDesciption
    %s%s
    ') \ No newline at end of file diff --git a/cgi-bin/viewsttats.py b/cgi-bin/viewsttats.py index 4bf4b5a7..f15671c8 100644 --- a/cgi-bin/viewsttats.py +++ b/cgi-bin/viewsttats.py @@ -3,7 +3,7 @@ import html import cgi import requests import funct -import listserv as listhap +import sql import configparser from requests_toolbelt.utils import dump @@ -18,14 +18,29 @@ haproxy_pass = config.get('haproxy', 'password') stats_port = config.get('haproxy', 'stats_port') stats_page = config.get('haproxy', 'stats_page') -listhap.listhap = funct.merge_two_dicts(listhap.listhap, listhap.listhap_vip) - form = cgi.FieldStorage() serv = form.getvalue('serv') if serv is None: - first_serv = sorted(list(listhap.listhap.values())) - serv = first_serv[0] + first_serv = sql.get_dick_permit() + for i in first_serv: + serv = i[2] + break + +print('
    ') + +funct.get_auto_refresh("HAproxy statistics") + +print('
    ' + '
    ' + '' + 'Show' + '
    ') try: 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: print ("OOps: Something Else",err) -for i in listhap.listhap: - if listhap.listhap.get(i) == serv: - servname = i - -print('
    ') - -funct.get_auto_refresh("HAproxy statistics") - -print('
    ' - '
    ' - '' - 'Show' - '
    ') - data = response.content print('
    ') print(data.decode('utf-8')) @@ -68,4 +64,4 @@ print('
    ') funct.head("Stats HAproxy configs") print('
    ') - +funct.footer() diff --git a/image/11.jpeg b/image/11.jpeg new file mode 100644 index 00000000..c5cde35e Binary files /dev/null and b/image/11.jpeg differ diff --git a/inc/awesome.css b/inc/awesome.css index 016191c3..fd54f6c2 100644 --- a/inc/awesome.css +++ b/inc/awesome.css @@ -21,6 +21,11 @@ font-family: "Font Awesome 5 Solid"; content: "\f06e"; } +.mon::before { + display: none; + font-family: "Font Awesome 5 Solid"; + content: "\f080"; +} .logs::before { display: none; font-family: "Font Awesome 5 Solid"; @@ -75,4 +80,29 @@ display: none; font-family: "Font Awesome 5 Solid"; 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"; } \ No newline at end of file diff --git a/inc/script.js b/inc/script.js index ce3f217e..dfb8ea40 100644 --- a/inc/script.js +++ b/inc/script.js @@ -206,6 +206,8 @@ function showConfig() { success: function( data ) { $("#ajax").html(data); 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 ' ) { alert(data); } else { - document.location.reload(); + showOverview(); } }, error: function(){ @@ -294,7 +296,7 @@ $( function() { var cur_url = '/cgi-bin/' + location.split('/').pop(); cur_url = cur_url.split('?'); - $('.menu li').each(function () { + $('.menu ').each(function () { var link = $(this).find('a').attr('href'); if (cur_url[0] == link) @@ -583,13 +585,4 @@ $( function() { $("#optionsInput2").append(ui.item.value + " ") } }); - input = $(' '); - $( "#add-user" ).click( function(){ - $( "#users-table" ).append(input); - }); -} ); - -function removeUser(id) { - document.getElementById(id).parentNode.removeChild(document.getElementById(id)); - return false; -} \ No newline at end of file +}); \ No newline at end of file diff --git a/inc/style.css b/inc/style.css index 9c006c3d..70de6513 100644 --- a/inc/style.css +++ b/inc/style.css @@ -146,7 +146,7 @@ pre { } .configShow, .diff { margin-left: 16%; - height: 78%; + //height: 78%; overflow: auto; width: 70%; border: 1px solid #DCDCDC; @@ -278,9 +278,6 @@ pre { padding-left: 15px; font-size: 15px; } -.first-collumn { - width: 200px; -} .serverUp, .serverDown { padding: 3px; border-radius: 3px; @@ -305,9 +302,12 @@ pre { } .padding10 { padding: 10px; - padding-left: 15px; + padding-left: 0px; border: none; - width: 25%; + width: 23%; +} +.first-collumn { + padding-left: 15px; } .ro { border: none; @@ -397,6 +397,9 @@ pre { border-radius: 5px !important; color: #fff !important; } +.ui-tabs-nav { + padding-left: 20px !important; + } a { background-color: transparent; } @@ -499,6 +502,9 @@ a:focus { margin-right: -15px; margin-left: -15px; } +.update { + background-color: rgb(0,168,107) !important; +} label { display: inline-block; diff --git a/inc/users.js b/inc/users.js new file mode 100644 index 00000000..3c74f18b --- /dev/null +++ b/inc/users.js @@ -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 ); + } + } + } ); +} \ No newline at end of file