Pavel Loginov 2020-05-10 08:17:07 +02:00
parent c9b610cc70
commit a803e03801
27 changed files with 812 additions and 240 deletions

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import funct
import sql
@ -20,7 +21,9 @@ funct.page_for_admin(level = 2)
try:
user, user_id, role, token, servers = funct.get_users_params()
user_group = sql.get_user_group_by_uuid(user_id.value)
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
group = cookie.get('group')
user_group = group.value
except:
pass

View File

@ -131,6 +131,7 @@ def create_table(**kwargs):
CREATE TABLE IF NOT EXISTS `backups` ( `id` INTEGER NOT NULL, `server` VARCHAR ( 64 ), `rhost` VARCHAR ( 120 ), `rpath` VARCHAR ( 120 ), `type` VARCHAR ( 120 ), `time` VARCHAR ( 120 ), cred INTEGER, `description` VARCHAR ( 120 ), PRIMARY KEY(`id`));
CREATE TABLE IF NOT EXISTS `waf` (`server_id` INTEGER UNIQUE, metrics INTEGER);
CREATE TABLE IF NOT EXISTS `waf_metrics` (`serv` varchar(64), conn INTEGER, `date` DATETIME default '0000-00-00 00:00:00');
CREATE TABLE IF NOT EXISTS user_groups(user_id INTEGER NOT NULL, user_group_id INTEGER NOT NULL, UNIQUE(user_id,user_group_id));
"""
try:
cur.executescript(sql)
@ -451,9 +452,51 @@ def update_db_v_4_2_3(**kwargs):
con.close()
def update_db_v_4_3(**kwargs):
con, cur = get_cur()
sql = """
CREATE TABLE IF NOT EXISTS user_groups(user_id INTEGER NOT NULL, user_group_id INTEGER NOT NULL, UNIQUE(user_id,user_group_id));
"""
try:
cur.execute(sql)
con.commit()
except sqltool.Error as e:
if kwargs.get('silent') != 1:
if e.args[0] == 'duplicate column name: haproxy' or e == " 1060 (42S21): Duplicate column name 'haproxy' ":
print('Updating... go to version 4.3.0')
else:
print("An error occurred:", e)
return False
else:
return True
cur.close()
con.close()
def update_db_v_4_3_1(**kwargs):
con, cur = get_cur()
sql = """
insert OR IGNORE into user_groups(user_id, user_group_id) select id, groups from user;
"""
try:
cur.execute(sql)
con.commit()
except sqltool.Error as e:
if kwargs.get('silent') != 1:
if e.args[0] == 'duplicate column name: haproxy' or e == " 1060 (42S21): Duplicate column name 'haproxy' ":
print('DB was update to 4.3.0')
else:
print("An error occurred:", e)
return False
else:
return True
cur.close()
con.close()
def update_ver(**kwargs):
con, cur = get_cur()
sql = """update version set version = '4.2.3.0'; """
sql = """update version set version = '4.3.0.0'; """
try:
cur.execute(sql)
con.commit()
@ -478,6 +521,8 @@ def update_all():
update_db_v_41()
update_db_v_42()
update_db_v_4_2_3()
update_db_v_4_3()
update_db_v_4_3_1()
update_ver()
@ -496,6 +541,8 @@ def update_all_silent():
update_db_v_41(silent=1)
update_db_v_42(silent=1)
update_db_v_4_2_3(silent=1)
update_db_v_4_3(silent=1)
update_db_v_4_3_1(silent=1)
update_ver()

View File

@ -975,8 +975,8 @@ def check_group(group, role_id):
import sql
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
user_group = sql.get_user_group_by_uuid(user_id.value)
if user_group == group or user_group == '1' or role_id == 1:
id = sql.get_user_id_by_uuid(user_id.value)
if sql.select_user_groups(id, check_id=group) or role_id == 1:
return True
else:
logging('localhost', ' has tried to actions in not own group ', haproxywi=1, login=1)

View File

@ -19,4 +19,5 @@ CREATE TABLE IF NOT EXISTS `options` ( `id` INTEGER NOT NULL, `options` VARCHAR
CREATE TABLE IF NOT EXISTS `saved_servers` ( `id` INTEGER NOT NULL, `server` VARCHAR ( 64 ), `description` VARCHAR ( 120 ), `groups` VARCHAR ( 120 ), PRIMARY KEY(`id`));
CREATE TABLE IF NOT EXISTS `backups` ( `id` INTEGER NOT NULL, `server` VARCHAR ( 64 ), `rhost` VARCHAR ( 120 ), `rpath` VARCHAR ( 120 ), `time` VARCHAR ( 120 ), cred INTEGER, `description` VARCHAR ( 120 ), PRIMARY KEY(`id`));
CREATE TABLE IF NOT EXISTS `waf` (`server_id` INTEGER UNIQUE, metrics INTEGER);
CREATE TABLE IF NOT EXISTS `waf_metrics` (`serv` varchar(64), conn INTEGER, `date` DATETIME default '0000-00-00 00:00:00');
CREATE TABLE IF NOT EXISTS `waf_metrics` (`serv` varchar(64), conn INTEGER, `date` DATETIME default '0000-00-00 00:00:00');
CREATE TABLE IF NOT EXISTS user_groups(user_id INTEGER NOT NULL, user_group_id INTEGER NOT NULL, UNIQUE(user_id,user_group_id));

View File

@ -30,14 +30,21 @@ def send_cookie(login):
expires = datetime.datetime.utcnow() + datetime.timedelta(days=session_ttl)
user_uuid = str(uuid.uuid4())
user_token = str(uuid.uuid4())
sql.write_user_uuid(login, user_uuid)
sql.write_user_token(login, user_token)
id = sql.get_user_id_by_uuid(user_uuid)
user_groups = sql.select_user_groups(id, limit=1)
c = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
c["uuid"] = user_uuid
c["uuid"]["path"] = "/"
c["uuid"]["expires"] = expires.strftime("%a, %d %b %Y %H:%M:%S GMT")
c["group"] = user_groups
c["group"]["path"] = "/"
c["group"]["expires"] = expires.strftime("%a, %d %b %Y %H:%M:%S GMT")
print(c)
sql.write_user_uuid(login, user_uuid)
sql.write_user_token(login, user_token)
try:
funct.logging('locahost', ' '+sql.get_user_name_by_uuid(user_uuid)+' log in', haproxywi=1)
except:

View File

@ -8,7 +8,7 @@ form = funct.form
serv = form.getvalue('serv')
act = form.getvalue('act')
if form.getvalue('new_metrics') or form.getvalue('new_waf_metrics'):
if form.getvalue('new_metrics') or form.getvalue('new_waf_metrics') or form.getvalue('metrics_hapwi_ram') or form.getvalue('metrics_hapwi_cpu'):
print('Content-type: application/json\n')
else:
print('Content-type: text/html\n')
@ -275,10 +275,6 @@ if act == "overviewServers":
import asyncio
async def async_get_overviewServers(serv1, serv2, service):
server_status = ()
if service == 'haproxy':
commands = [ "top -u haproxy -b -n 1" ]
else:
commands = [ "top -u nginx -b -n 1" ]
if service == 'haproxy':
cmd = 'echo "show info" |nc %s %s -w 1|grep -e "Ver\|CurrConns\|Maxco\|MB\|Uptime:"' % (serv2, sql.get_setting('haproxy_sock_port'))
@ -295,7 +291,7 @@ if act == "overviewServers":
else:
out1 = ''
server_status = (serv1,serv2, out1, funct.ssh_command(serv2, commands))
server_status = (serv1,serv2, out1)
return server_status
async def get_runner_overviewServers(**kwargs):
@ -325,18 +321,6 @@ if act == "overviewServers":
ioloop.close()
if act == "overviewHapwi":
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/ajax'), autoescape=True)
template = env.get_template('/overviewHapwi.html')
cmd = "top -b -n 1 |head -12"
server_status, stderr = funct.subprocess_execute(cmd)
template = template.render(server_status=server_status,stderr=stderr)
print(template)
if form.getvalue('action'):
import requests
@ -1119,6 +1103,50 @@ if form.getvalue('table_metrics'):
print(template)
if form.getvalue('metrics_hapwi_ram'):
ip = form.getvalue('ip')
metrics = {}
metrics['chartData'] = {}
rams = ''
if ip == '1':
cmd = "free -m |grep Mem |awk '{print $3,$4,$5,$6,$7}'"
metric, error = funct.subprocess_execute(cmd)
else:
commands = [ "free -m |grep Mem |awk '{print $3,$4,$5,$6,$7}'" ]
metric, error = funct.subprocess_execute(commands[0])
for i in metric:
rams = i
metrics['chartData']['rams'] = rams
import json
print(json.dumps(metrics))
if form.getvalue('metrics_hapwi_cpu'):
ip = form.getvalue('ip')
metrics = {}
metrics['chartData'] = {}
cpus = ''
if ip == '1':
cmd = "top -b -n 1 |grep Cpu |awk -F':' '{print $2}'|awk -F' ' 'BEGIN{ORS=\" \";} { for (i=1;i<=NF;i+=2) print $i}'"
metric, error = funct.subprocess_execute(cmd)
else:
commands = [ "top -b -n 1 |grep Cpu |awk -F':' '{print $2}'|awk -F' ' 'BEGIN{ORS=\" \";} { for (i=1;i<=NF;i+=2) print $i}'" ]
metric, error = funct.subprocess_execute(commands[0])
for i in metric:
cpus = i
metrics['chartData']['cpus'] = cpus
import json
print(json.dumps(metrics))
if form.getvalue('new_metrics'):
serv = form.getvalue('server')
metric = sql.select_metrics(serv)
@ -1322,7 +1350,7 @@ if form.getvalue('newuser') is not None:
if funct.check_group(group, role_id):
if funct.is_admin(level=role_id):
if sql.add_user(new_user, email, password, role, group, activeuser):
if sql.add_user(new_user, email, password, role, activeuser):
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/'), autoescape=True)
template = env.get_template('ajax/new_user.html')
@ -1343,6 +1371,7 @@ if form.getvalue('userdel') is not None:
for u in user:
username = u[1]
if sql.delete_user(userdel):
sql.delete_user_groups(userdel)
funct.logging(username, ' has deleted user ', haproxywi=1, login=1)
print("Ok")
@ -1358,7 +1387,7 @@ if form.getvalue('updateuser') is not None:
if funct.check_group(group, role_id):
if funct.is_admin(level=role_id):
sql.update_user(new_user, email, role, group, id, activeuser)
sql.update_user(new_user, email, role, id, activeuser)
funct.logging(new_user, ' has updated user ', haproxywi=1, login=1)
else:
funct.logging(new_user, ' tried to privilege escalation', haproxywi=1, login=1)
@ -1629,3 +1658,44 @@ if form.getvalue('updatesettings') is not None:
if sql.update_setting(settings, val):
funct.logging('value '+val, ' changed settings '+settings, haproxywi=1, login=1)
print("Ok")
if form.getvalue('getusergroups'):
id = form.getvalue('getusergroups')
groups = []
u_g = sql.select_user_groups(id=id)
for g in u_g:
groups.append(g[0])
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/ajax'), autoescape=True)
template = env.get_template('/show_user_groups.html')
template = template.render(groups=sql.select_groups(), user_groups=groups,id=id)
print(template)
if form.getvalue('changeUserGroupId') is not None:
id = form.getvalue('changeUserGroupId')
groups = form.getvalue('changeUserGroups')
user = form.getvalue('changeUserGroupsUser')
if sql.delete_user_groups(id):
for group in groups:
if group[0] == ',':
continue
sql.update_user_groups(groups=group[0], id=id)
funct.logging('localhost', ' has upgraded groups for user: '+user, haproxywi=1, login=1)
if form.getvalue('getcurrentusergroup') is not None:
import http.cookies
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
group = cookie.get('group')
id = sql.get_user_id_by_uuid(user_id.value)
groups = sql.select_user_groups_with_names(id=id)
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/ajax'), autoescape=True)
template = env.get_template('/show_user_current_group.html')
template = template.render(groups=groups, group=group.value,id=id)
print(template)

View File

@ -67,7 +67,6 @@ except:
is_checker_worker = ''
is_metrics_worker = ''
token = ''
host = ''
template = template.render(h2 = 1,
@ -77,6 +76,7 @@ template = template.render(h2 = 1,
user = user,
users = users,
groups = groups,
users_groups = sql.select_user_groups_with_names(1, all=1),
roles = sql.select_roles(),
metrics_master = ''.join(metrics_master),
metrics_worker = ''.join(metrics_worker),

View File

@ -13,6 +13,10 @@ try:
user, user_id, role, token, servers = funct.get_users_params()
ldap_enable = sql.get_setting('ldap_enable')
grafana, stderr = funct.subprocess_execute("service grafana-server status |grep Active |awk '{print $1}'")
import http.cookies, os
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
group = cookie.get('group')
user_group = group.value
except:
pass
@ -20,12 +24,12 @@ except:
output_from_parsed_template = template.render(title = "Servers manage",
role = role,
user = user,
users = sql.select_users(),
users = sql.select_users(group=user_group),
groups = sql.select_groups(),
servers = sql.get_dick_permit(virt=1, disable=0),
roles = sql.select_roles(),
masters = sql.select_servers(get_master_servers=1, uuid=user_id.value),
group = sql.get_user_group_by_uuid(user_id.value),
group = user_group,
sshs = sql.select_ssh(),
telegrams = sql.get_user_telegram_by_uuid(user_id.value),
token = token,

View File

@ -31,12 +31,12 @@ def get_cur():
return con, cur
def add_user(user, email, password, role, group, activeuser):
def add_user(user, email, password, role, activeuser):
con, cur = get_cur()
if password != 'aduser':
sql = """INSERT INTO user (username, email, password, role, groups, activeuser) VALUES ('%s', '%s', '%s', '%s', '%s', '%s')""" % (user, email, funct.get_hash(password), role, group, activeuser)
sql = """INSERT INTO user (username, email, password, role, activeuser) VALUES ('%s', '%s', '%s', '%s', '%s')""" % (user, email, funct.get_hash(password), role, activeuser)
else:
sql = """INSERT INTO user (username, email, role, groups, ldap_user, activeuser) VALUES ('%s', '%s', '%s', '%s', '1', '%s')""" % (user, email, role, group, activeuser)
sql = """INSERT INTO user (username, email, role, ldap_user, activeuser) VALUES ('%s', '%s', '%s', '1', '%s')""" % (user, email, role, activeuser)
try:
cur.execute(sql)
con.commit()
@ -49,14 +49,47 @@ def add_user(user, email, password, role, group, activeuser):
cur.close()
con.close()
def update_user(user, email, role, group, id, activeuser):
def update_user(user, email, role, id, activeuser):
con, cur = get_cur()
sql = """update user set username = '%s',
email = '%s',
role = '%s',
groups = '%s',
role = '%s',
activeuser = '%s'
where id = '%s'""" % (user, email, role, group, activeuser, id)
where id = '%s'""" % (user, email, role, activeuser, id)
try:
cur.execute(sql)
con.commit()
except sqltool.Error as e:
funct.out_error(e)
con.rollback()
return False
else:
return True
cur.close()
con.close()
def update_user_groups(groups, id):
con, cur = get_cur()
sql = """insert into user_groups(user_id, user_group_id) values('%s', '%s')""" % (id, groups)
try:
cur.execute(sql)
con.commit()
except sqltool.Error as e:
funct.out_error(e)
con.rollback()
return False
else:
return True
cur.close()
con.close()
def delete_user_groups(id):
con, cur = get_cur()
sql = """delete from user_groups
where user_id = '%s'""" % (id)
try:
cur.execute(sql)
con.commit()
@ -252,6 +285,9 @@ def select_users(**kwargs):
sql = """select * from user where username='%s' """ % kwargs.get("user")
if kwargs.get("id") is not None:
sql = """select * from user where id='%s' """ % kwargs.get("id")
if kwargs.get("group") is not None:
sql = """ select user.* from user left join user_groups as groups on user.id = groups.user_id where groups.user_group_id = '%s' group by id;
""" % kwargs.get("group")
try:
cur.execute(sql)
except sqltool.Error as e:
@ -259,7 +295,57 @@ def select_users(**kwargs):
else:
return cur.fetchall()
cur.close()
con.close()
con.close()
def select_user_groups(id, **kwargs):
con, cur = get_cur()
sql = """select user_group_id from user_groups where user_id = '%s' """ % id
if kwargs.get("limit") is not None:
sql = """select user_group_id from user_groups where user_id = '%s' limit 1 """ % id
if kwargs.get("check_id") is not None:
sql = """select * from user_groups where user_id='%s' and user_group_id = '%s' """ % (id, kwargs.get("check_id"))
try:
cur.execute(sql)
except sqltool.Error as e:
funct.out_error(e)
else:
if kwargs.get("check_id") is not None:
for g in cur.fetchall():
if g[0] is None:
return False
else:
return True
elif kwargs.get("limit") is not None:
for g in cur.fetchall():
return g[0]
else:
return cur.fetchall()
cur.close()
con.close()
def select_user_groups_with_names(id, **kwargs):
con, cur = get_cur()
if kwargs.get("all") is not None:
sql = """select user_groups.user_id, groups.name from user_groups
left join groups as groups on user_groups.user_group_id = groups.id """
else:
sql = """select user_groups.user_group_id, groups.name from user_groups
left join groups as groups on user_groups.user_group_id = groups.id
where user_groups.user_id = '%s' """ % id
try:
cur.execute(sql)
except sqltool.Error as e:
funct.out_error(e)
else:
if kwargs.get("limit") is not None:
for g in cur.fetchall():
return g[0]
else:
return cur.fetchall()
cur.close()
con.close()
def select_groups(**kwargs):
@ -398,6 +484,7 @@ def get_token(uuid):
cur.close()
con.close()
def delete_uuid(uuid):
con, cur = get_cur()
sql = """ delete from uuid where uuid = '%s' """ % uuid
@ -409,6 +496,7 @@ def delete_uuid(uuid):
cur.close()
con.close()
def delete_old_uuid():
con, cur = get_cur()
if mysql_enable == '1':
@ -427,6 +515,7 @@ def delete_old_uuid():
cur.close()
con.close()
def update_last_act_user(uuid):
con, cur = get_cur()
session_ttl = get_setting('session_ttl')
@ -444,6 +533,7 @@ def update_last_act_user(uuid):
cur.close()
con.close()
def get_user_name_by_uuid(uuid):
con, cur = get_cur()
sql = """ select user.username from user left join uuid as uuid on user.id = uuid.user_id where uuid.uuid = '%s' """ % uuid
@ -457,6 +547,20 @@ def get_user_name_by_uuid(uuid):
cur.close()
con.close()
def get_user_id_by_uuid(uuid):
con, cur = get_cur()
sql = """ select user.id from user left join uuid as uuid on user.id = uuid.user_id where uuid.uuid = '%s' """ % uuid
try:
cur.execute(sql)
except sqltool.Error as e:
funct.out_error(e)
else:
for user_id in cur.fetchall():
return user_id[0]
cur.close()
con.close()
def get_user_role_by_uuid(uuid):
con, cur = get_cur()
@ -487,19 +591,6 @@ def get_role_id_by_name(name):
cur.close()
con.close()
def get_user_group_by_uuid(uuid):
con, cur = get_cur()
sql = """ select user.groups from user left join uuid as uuid on user.id = uuid.user_id where uuid.uuid = '%s' """ % uuid
try:
cur.execute(sql)
except sqltool.Error as e:
funct.out_error(e)
else:
for user_id in cur.fetchall():
return user_id[0]
cur.close()
con.close()
def get_user_telegram_by_uuid(uuid):
con, cur = get_cur()
@ -513,6 +604,7 @@ def get_user_telegram_by_uuid(uuid):
cur.close()
con.close()
def get_telegram_by_ip(ip):
con, cur = get_cur()
sql = """ select telegram.* from telegram left join servers as serv on serv.groups = telegram.groups where serv.ip = '%s' """ % ip
@ -525,22 +617,25 @@ def get_telegram_by_ip(ip):
cur.close()
con.close()
def get_dick_permit(**kwargs):
import http.cookies
import os
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
if kwargs.get('username'):
user = kwargs.get('username')
grp = '1'
else:
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
group = cookie.get('group')
grp = group.value
user = get_user_id_by_uuid(user_id.value)
disable = ''
haproxy = ''
nginx = ''
keepalived = ''
ip = ''
con, cur = get_cur()
if kwargs.get('username'):
sql = """ select * from user where username = '%s' """ % kwargs.get('username')
else:
sql = """ select * from user where username = '%s' """ % get_user_name_by_uuid(user_id.value)
if kwargs.get('virt'):
type_ip = ""
else:
@ -555,18 +650,15 @@ def get_dick_permit(**kwargs):
nginx = "and nginx = 1"
if kwargs.get('keepalived'):
nginx = "and keepalived = 1"
try:
cur.execute(sql)
except sqltool.Error as e:
print("An error occurred:", e)
else:
for group in cur:
if group[5] == '1':
sql = """ select * from servers where enable = 1 %s %s %s """ % (disable, type_ip, nginx)
else:
sql = """ select * from servers where groups like '%{group}%' and (enable = 1 {disable}) {type_ip} {ip} {haproxy} {nginx} {keepalived}
""".format(group=group[5], disable=disable, type_ip=type_ip, ip=ip, haproxy=haproxy, nginx=nginx, keepalived=keepalived)
if select_user_groups(user, check_id=grp):
con, cur = get_cur()
if grp == '1':
sql = """ select * from servers where enable = 1 %s %s %s """ % (disable, type_ip, nginx)
else:
sql = """ select * from servers where groups like '%{group}%' and (enable = 1 {disable}) {type_ip} {ip} {haproxy} {nginx} {keepalived}
""".format(group=grp, disable=disable, type_ip=type_ip, ip=ip, haproxy=haproxy, nginx=nginx, keepalived=keepalived)
try:
cur.execute(sql)
except sqltool.Error as e:
@ -574,8 +666,11 @@ def get_dick_permit(**kwargs):
else:
return cur.fetchall()
cur.close()
con.close()
cur.close()
con.close()
else:
print('Atata!')
def is_master(ip, **kwargs):
@ -1171,18 +1266,18 @@ def select_servers_metrics_for_master():
def select_servers_metrics(uuid, **kwargs):
con, cur = get_cur()
sql = """ select * from user where username = '%s' """ % get_user_name_by_uuid(uuid)
try:
cur.execute(sql)
except sqltool.Error as e:
print("An error occurred:", e)
else:
for group in cur:
if group[5] == '1':
sql = """ select ip from servers where enable = 1 and metrics = '1' """
else:
sql = """ select ip from servers where groups like '%{group}%' and metrics = '1'""".format(group=group[5])
import http.cookies
import os
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
group = cookie.get('group')
group = group.value
id = get_user_id_by_uuid(user_id.value)
if select_user_groups(id, check_id=group) is not None:
if group == '1':
sql = """ select ip from servers where enable = 1 and metrics = '1' """
else:
sql = """ select ip from servers where groups like '%{group}%' and metrics = '1'""".format(group=group)
try:
cur.execute(sql)
except sqltool.Error as e:
@ -1195,19 +1290,18 @@ def select_servers_metrics(uuid, **kwargs):
def select_table_metrics(uuid):
con, cur = get_cur()
groups = ""
sql = """ select * from user where username = '%s' """ % get_user_name_by_uuid(uuid)
try:
cur.execute(sql)
except sqltool.Error as e:
print("An error occurred:", e)
else:
for group in cur:
if group[5] == '1':
groups = ""
else:
groups = "and servers.groups like '%{group}%' ".format(group=group[5])
import http.cookies
import os
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
group = cookie.get('group')
group = group.value
id = get_user_id_by_uuid(user_id.value)
if select_user_groups(id, check_id=group) is not None:
if group == '1':
groups = ""
else:
groups = "and servers.groups like '%{group}%' ".format(group=group)
if mysql_enable == '1':
sql = """
select ip.ip, hostname, avg_sess_1h, avg_sess_24h, avg_sess_3d, max_sess_1h, max_sess_24h, max_sess_3d, avg_cur_1h, avg_cur_24h, avg_cur_3d, max_con_1h, max_con_24h, max_con_3d from

View File

@ -53,16 +53,7 @@
</select>
</td>
<td>
<select id="usergroup-{{user.0}}" name="usergroup-{{user.0}}">
<option disabled selected>Choose group</option>
{% for group in groups %}
{% if user.5 == group.0|string() %}
<option value="{{ group.0 }}" selected>{{ group.1 }}</option>
{% else %}
<option value="{{ group.0 }}">{{ group.1 }}</option>
{% endif %}
{% endfor %}
</select>
<span title="Change user groups" style="cursor: pointer; margin-left: 15px;" class="div-pic" onclick="openChangeUserGroupDialog('{{user.0}}')">
</td>
<td>
<a class="add" onclick="cloneUser({{user.0}})" id="clone-{{user.0}}" title="Clone {{user.1}}" style="cursor: pointer;"></a>
@ -603,6 +594,9 @@
</table>
</div>
{% include 'include/change_pass_form.html' %}
<div id="change-user-groups-dialog" style="display: none;">
<div id="change-user-groups-form"></div>
</div>
<style>
.ui-selectmenu-button.ui-button {
width: 10em;
@ -612,45 +606,41 @@
}
</style>
<script>
$( function() {
{% for user in users %}
$("#role-{{user.0}}" ).selectmenu({
width: 100
});
$("#usergroup-{{user.0}}" ).selectmenu({
width: 100
});
{% endfor %}
{% for server in servers %}
$("#servergroup-{{ server.0}}" ).selectmenu({
width: 100
});
$("#slavefor-{{server.0}}" ).selectmenu({
width: 130
});
$("#credentials-{{server.0}}" ).selectmenu({
width: 150
});
{% endfor %}
{% for ssh in sshs %}
if (window.matchMedia('(max-width: 1280px)').matches) {
$("#sshgroup-{{ ssh.0}}" ).selectmenu({
width: 100
});
}
{% endfor %}
{% for server in backups %}
$("#backup-time-{{ server.0}}" ).selectmenu({
width: 100
});
$("#backup-type-{{server.0}}" ).selectmenu({
width: 130
});
$("#backup-credentials-{{server.0}}" ).selectmenu({
width: 150
});
{% endfor %}
$( function() {
{% for user in users %}
$("#role-{{user.0}}" ).selectmenu({
width: 100
});
{% endfor %}
{% for server in servers %}
$("#servergroup-{{ server.0}}" ).selectmenu({
width: 100
});
$("#slavefor-{{server.0}}" ).selectmenu({
width: 130
});
$("#credentials-{{server.0}}" ).selectmenu({
width: 150
});
{% endfor %}
{% for ssh in sshs %}
if (window.matchMedia('(max-width: 1280px)').matches) {
$("#sshgroup-{{ ssh.0}}" ).selectmenu({
width: 100
});
</script>
}
{% endfor %}
{% for server in backups %}
$("#backup-time-{{ server.0}}" ).selectmenu({
width: 100
});
$("#backup-type-{{server.0}}" ).selectmenu({
width: 130
});
$("#backup-credentials-{{server.0}}" ).selectmenu({
width: 150
});
{% endfor %}
});
</script>
{% endblock %}

View File

@ -16,16 +16,7 @@
{% if page != "servers.py" %}
{% if page != "servers.py#users" %}
<td>
<select id="usergroup-{{user.0}}" name="usergroup-{{user.0}}">
<option disabled selected>Choose group</option>
{% for group in groups %}
{% if user.5 == group.0|string() %}
<option value="{{ group.0 }}" selected>{{ group.1 }}</option>
{% else %}
<option value="{{ group.0 }}">{{ group.1 }}</option>
{% endif %}
{% endfor %}
</select>
<span title="Change user groups" style="cursor: pointer; margin-left: 15px;" class="div-pic" onclick="openChangeUserGroupDialog('{{user.0}}')">
</td>
{% endif %}
{% endif %}

View File

@ -1,5 +1,5 @@
{%- for service in service_status -%}
<div class="server-info">
<div class="server-info" style="height: 100%;">
{% if service_page == 'nginx' %}
<div class="server-name" style="padding-bottom: 0px;">
{% else %}
@ -18,13 +18,16 @@
</div>
{% endif %}
{% if service_page == 'nginx' %}
<div class="top-info" style="margin-top: 5px;">
<div class="top-info" style="margin-top: 5px; width: 100%;">
{% else %}
<div class="top-info">
<div class="top-info" style="width: 550px;">
{% endif %}
<pre>
{{ service.3 }}
</pre>
</div>
<div style="height: 140px;width: 50%;float: left; margin:0; padding:0;">
<canvas id="cpu" role="img"></canvas>
</div>
<div style="height: 140px;width: 50%;float: right;margin:0; padding:0;">
<canvas id="ram" role="img"></canvas>
</div>
</div>
</div>
{% endfor %}

View File

@ -0,0 +1,15 @@
<table class="overview" style="border: none;">
<tr style="border: none;">
<td style="border: none">
<select id="newCurrentGroup" name="newCurrentGroup" >
{% for g in groups %}
{% if g.0|string() == group|string() %}
<option value="{{ g.0 }}" selected>{{ g.1 }}</option>
{% else %}
<option value="{{ g.0 }}">{{ g.1 }}</option>
{% endif %}
{% endfor %}
</select>
</td>
</tr>
</table>

View File

@ -0,0 +1,70 @@
<style>
.select-css {
display: block;
font-size: 16px;
font-family: sans-serif;
font-weight: 700;
color: #444;
line-height: 1.3;
padding: .6em 1.4em .5em .8em;
width: 80%;
max-width: 90%;
box-sizing: border-box;
margin: 0;
border: 1px solid #aaa;
box-shadow: 0 1px 0 1px rgba(0,0,0,.04);
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
background-color: #f9fcf9;
background-size: .65em auto, 100%;
}
.select-css::-ms-expand {
display: none;
}
.select-css:hover {
border-color: #888;
}
.select-css:focus {
border-color: #aaa;
box-shadow: 0 0 1px 3px rgba(59, 153, 252, .7);
box-shadow: 0 0 0 3px -moz-mac-focusring;
color: #222;
outline: none;
}
.select-css option {
font-weight:normal;
padding: 3px;
margin-left: 0;
padding-right: 1200px;
padding-left: 10px;
}
*[dir="rtl"] .select-css, :root:lang(ar) .select-css, :root:lang(iw) .select-css {
background-position: left .7em top 50%, 0 0;
padding: .6em .8em .5em 1.4em;
}
.select-css:disabled, .select-css[aria-disabled=true] {
color: graytext;
background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22graytext%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E'),
linear-gradient(to bottom, #ffffff 0%,#e5e5e5 100%);
}
.select-css:disabled:hover, .select-css[aria-disabled=true] {
border-color: #aaa;
}
</style>
<table class="overview">
<tr style="border: none;">
<td class="padding20" style="width: 40%;"><b>Choose groups</b></td>
<td>
<select id="usergroup-{{id}}" name="usergroup-{{id}}" multiple class="select-css">
{% for group in groups %}
{% if group.0 in user_groups %}
<option value="{{ group.0 }}" selected>{{ group.1 }}</option>
{% else %}
<option value="{{ group.0 }}">{{ group.1 }}</option>
{% endif %}
{% endfor %}
</select>
</td>
</tr>
</table>

View File

@ -259,12 +259,15 @@
</a>
</div>
<div class="footer-div">
<a href="https://github.com/Aidaho12/haproxy-wi/" class="footer-link" target="_blank">Github</a>
<a href="https://haproxy-wi.org/cabinet.py" class="footer-link" target="_blank" title="Privet cabinet for donaters">Cabinet</a>
<a href="https://github.com/Aidaho12/haproxy-wi/issues" class="footer-link" target="_blank">Help</a>
<a href="https://haproxy-wi.org/contacts.py" class="footer-link" target="_blank">Contact</a>
<a href="https://haproxy-wi.org" class="footer-link" target="_blank">About</a>
<a href="https://haproxy-wi.org" class="footer-link" target="_blank" title="About HAProxy-WI">About</a>
<a href="https://haproxy-wi.org/cloud.py" class="footer-link" target="_blank" title="HAProxy-WI Cloud">Cloud</a>
</div>
</div>
<div id="current-user-groups-dialog" style="display: none;">
<div id="current-user-groups-form"></div>
</div>
</body>
</html>

View File

@ -30,6 +30,22 @@
host = host.replace(/\./g, '\\.');
hostnamea.push(host)
{% endfor %}
$( function() {
$( ".sortable" ).sortable({
revert: true,
placeholder: "ui-state-highlight"
});
$( ".sortable" ).disableSelection();
$( ".sortable" ).sortable({
stop: function(event, ui) {
var itemOrder = $('.sortable').sortable("toArray");
for (var i = 0; i < itemOrder.length; i++) {
console.log("Position: " + i + " ID: " + itemOrder[i]);
}
}
});
});
</script>
<div id="up-pannel" class="sortable">
{% if servers|length == 0 %}

View File

@ -1,4 +1,5 @@
{% if user %}
<span id="changeCurrentGroup" class="menu-bar login" title="Change current group" style="margin-top: 7px;margin-left: -10px;cursor: pointer;"></span>
<a href=/app/login.py?logout=logout title="Logout, user name: {{ user }}" class="login"> Logout</a>
{% else %}
<a href=/app/login.py title="Login" class="login"> Login</a>

View File

@ -30,6 +30,14 @@ th, tr, td {
{% endfor %}
<script>
$( function() {
$( "#sortable" ).sortable({
revert: true,
items: "> div",
placeholder: "ui-state-highlight"
});
$( "sortable" ).disableSelection();
} );
function showMetrics() {
let metrics = new Promise(
(resolve, reject) => {

View File

@ -1,5 +1,8 @@
{% extends "base.html" %}
{% block content %}
<link href="/inc/chart.min.css" rel="stylesheet">
<script src="/inc/metrics.js"></script>
<script src="/inc/chart.min.js"></script>
<script src="/inc/overview.js"></script>
<script>
$("#secIntervals").css("display", "none");
@ -31,7 +34,7 @@
</a>
</td>
<td class="padding10">
Keealived
Keepalived
</td>
<td class="padding10">
<a href="/app/waf.py" title="WAf servers overview" class="logs_link">
@ -66,9 +69,13 @@
</td>
</tr>
<tr>
<td style="width:90%" colspan="2">
<pre style="margin: 0;" id="ajaxHapwi">
</pre>
<td style="width:100%" colspan="2">
<div style="height: 140px;width: 50%;float: left; margin:0; padding:0;">
<canvas id="cpu" role="img"></canvas>
</div>
<div style="height: 140px;width: 50%;float: right;margin:0; padding:0;">
<canvas id="ram" role="img"></canvas>
</div>
</td>
</tr>
</table>
@ -194,7 +201,7 @@
<table class="overview-wi">
<tr class="overviewHead">
<td class="padding10 first-collumn-wi">Login</td>
<td class="second-collumn">Group</td>
<td class="second-collumn">Groups</td>
<td>Role</td>
<td>
<span class="add-button-wi">
@ -204,22 +211,23 @@
</span>
</td>
</tr>
{% set counter = 0 -%}
{% set counter = 0 %}
{% for USER in users %}
{% set counter = counter + loop.index0 %}
{% if counter <= 2 %}
<tr class="{{ loop.cycle('odd', 'even') }}">
<td class="padding10 first-collumn-wi">
<a href="users.py#users" title="Edit user" class="logs_link div-pic">
{{ USER.1 }}
{{ USER.1 }}
</a>
</td>
{% for group in groups %}
{% if USER.5 == group.0|string() %}
<td class="third-collumn-wi">{{ group.1 }}</td>
{% endif %}
{% endfor %}
<td class="third-collumn-wi">
{% for group in users_groups %}
{% if USER.0|string() == group.0|string() %}
{{ group.1 }}{{ "," if not loop.last }}
{% endif %}
{% endfor %}
</td>
<td colspan="2">{{ USER.4 }}</td>
</tr>
{% else %}
@ -229,11 +237,13 @@
{{ USER.1 }}
</a>
</td>
{% for group in groups %}
{% if group.0|string() == USER.5 %}
<td class="third-collumn-wi">{{ group.1 }}</td>
{% endif %}
{% endfor %}
<td class="third-collumn-wi">
{% for group in users_groups %}
{% if group.0|string() == USER.0|string() %}
{{ group.1 }}{{ "," if not loop.last }}
{% endif %}
{% endfor %}
</td>
<td colspan="2">{{ USER.4 }}</td>
</tr>
{% endif %}
@ -340,4 +350,4 @@
showOverview(ip, hostnamea)
</script>
{% endblock %}
{% endblock %}

View File

@ -35,7 +35,6 @@
</tr>
<tr>
{% for user in users %}
{% if user.5 == group %}
<tr id="user-{{user.0}}" class="{{ loop.cycle('odd', 'even') }}">
{% include 'include/admin_users.html' %}
<td>
@ -59,7 +58,6 @@
<a class="delete" onclick="confirmDeleteUser({{user.0}})" title="Delete user {{user.1}}" style="cursor: pointer;"></a>
</td>
</tr>
{% endif %}
{% endfor %}
</table>
<br /><span class="add-button" title="Add user" id="add-user-button">+ Add</span>

View File

@ -41,6 +41,10 @@ try:
for dirpath, dirnames, filenames in os.walk(log_path):
for file in filenames:
curpath = os.path.join(dirpath, file)
try:
funct.subprocess_execute('sudo chown apache:apache '+curpath)
except:
pass
file_modified = datetime.datetime.fromtimestamp(os.path.getmtime(curpath))
if datetime.datetime.now() - file_modified > datetime.timedelta(hours=time_storage_hours):
os.remove(curpath)

View File

@ -229,4 +229,9 @@
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f2f1";
}
.menu-bar::before {
display: none;
font-family: "Font Awesome 5 Solid";
content: "\f0c9";
}

View File

@ -151,5 +151,132 @@ function loadMetrics() {
}
});
}
function getChartDataHapWiRam(ip) {
$.ajax({
url: "options.py",
data: {
metrics_hapwi_ram: '1',
ip: ip,
token: $('#token').val()
},
beforeSend: function() {
$('#ram').html('<img class="loading_hapwi_overview" src="/inc/images/loading.gif" />')
},
type: "POST",
success: function (result) {
var data = [];
data.push(result.chartData.rams);
renderChartHapWiRam(data);
}
});
}
function renderChartHapWiRam(data) {
var ctx = 'ram'
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ['used','free','shared','buff/cache','avaliable'],
datasets: [
{
data: data[0].split(' '),
backgroundColor: [
'#ff6384',
'#36a2eb',
'#ff9f40',
'#ffcd56',
'#4bc0c0',
]
}
]
},
options: {
maintainAspectRatio: false,
title: {
display: true,
text: "RAM usage in Mb",
fontSize: 15,
padding: 0,
},
legend: {
display: true,
align: 'start',
position: 'left',
labels: {
fontColor: 'rgb(255, 99, 132)',
defaultFontSize: 2,
fontColor: 'black',
defaultFontFamily: 'BlinkMacSystemFont',
boxWidth: 13,
padding: 5
},
}
}
});
}
function getChartDataHapWiCpu(ip) {
$.ajax({
url: "options.py",
data: {
metrics_hapwi_cpu: '1',
ip: ip,
token: $('#token').val()
},
type: "POST",
success: function (result) {
var data = [];
data.push(result.chartData.cpus);
renderChartHapWiCpu(data);
}
});
}
function renderChartHapWiCpu(data) {
var ctx = 'cpu'
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ['user','sys','nice','idle','wait','hi','si','steal'],
datasets: [
{
data: data[0].split(' '),
backgroundColor: [
'#ff6384',
'#36a2eb',
'#ff9f40',
'#ffcd56',
'#4bc0c0',
'#5d9ceb',
'#4bc0c0',
]
}
]
},
options: {
maintainAspectRatio: false,
title: {
display: true,
text: "CPU usage in %",
fontSize: 15,
padding: 0,
},
legend: {
display: true,
position: 'left',
align: 'end',
labels: {
fontColor: 'rgb(255, 99, 132)',
defaultFontSize: 2,
defaultFontFamily: 'BlinkMacSystemFont',
fontColor: 'black',
boxWidth: 13,
padding: 5
},
}
}
});
}

View File

@ -1,20 +1,8 @@
var cur_url = window.location.href.split('/').pop();
cur_url = cur_url.split('?');
function showOverviewHapWI() {
$.ajax( {
url: "options.py",
data: {
act: "overviewHapwi",
token: $('#token').val()
},
beforeSend: function() {
$('#ajaxHapwi').html('<img class="loading_hapwi_overview" src="/inc/images/loading.gif" />')
},
type: "POST",
success: function( data ) {
$("#ajaxHapwi").html(data);
}
} );
getChartDataHapWiCpu('1')
getChartDataHapWiRam('1')
}
function showHapservers(serv, hostnamea, service) {
var i;
@ -113,35 +101,38 @@ function showOverviewServer(name,ip,id, service) {
$("#div-pannel-"+id).insertBefore('#up-pannel')
$("#ajax-server-"+id).html(data);
$.getScript("/inc/fontawesome.min.js")
getChartDataHapWiRam()
getChartDataHapWiCpu()
}
} );
}
function ajaxActionServers(action, id) {
var bad_ans = 'Bad config, check please';
$.ajax( {
url: "options.py",
data: {
action_hap: action,
serv: id,
token: $('#token').val()
},
success: function( data ) {
data = data.replace(/\s+/g,' ');
if( data == 'Bad config, check please ' ) {
alert(data);
} else {
if (cur_url[0] == "hapservers.py") {
location.reload()
} else {
setTimeout(showOverview(ip, hostnamea), 2000)
}
}
},
error: function(){
alert(w.data_error);
}
} );
}
function ajaxActionServers(action, id) {
var bad_ans = 'Bad config, check please';
$.ajax( {
url: "options.py",
data: {
action_hap: action,
serv: id,
token: $('#token').val()
},
success: function( data ) {
data = data.replace(/\s+/g,' ');
if( data == 'Bad config, check please ' ) {
alert(data);
} else {
if (cur_url[0] == "hapservers.py") {
location.reload()
} else {
setTimeout(showOverview(ip, hostnamea), 2000)
}
}
},
error: function(){
alert(w.data_error);
}
} );
}
function ajaxActionNginxServers(action, id) {
var bad_ans = 'Bad config, check please';
$.ajax( {

View File

@ -664,6 +664,41 @@ $( function() {
$("#label_select_all").text("Select all");
}
});
$('#changeCurrentGroup').click(function() {
$.ajax( {
url: "options.py",
data: {
getcurrentusergroup: 1,
token: $('#token').val()
},
type: "POST",
success: function( data ) {
if (data.indexOf('danger') != '-1') {
$("#ajax").html(data);
} else {
$('.alert-danger').remove();
$('#current-user-groups-form').html(data);
$( "select" ).selectmenu();
$( "#current-user-groups-dialog" ).dialog({
resizable: false,
height: "auto",
width: 290,
modal: true,
title: "Change a new current group",
buttons: {
"Change": function() {
$( this ).dialog( "close" );
changeCurrentGroupF();
},
Cancel: function() {
$( this ).dialog( "close" );
}
}
});
}
}
} );
});
$('#runtimeapiform').submit(function() {
showRuntime();
@ -901,3 +936,9 @@ function listHistroy() {
}
createHistroy()
listHistroy()
function changeCurrentGroupF(){
Cookies.remove('group');
Cookies.set('group', $('#newCurrentGroup').val(), { path: '/app' });
location.reload();
}

View File

@ -659,6 +659,9 @@ caption {
color: #777;
text-align: left;
}
caption h3 {
font-size: 1.2em;
}
td,th {
padding: 0;
text-align: left;
@ -1026,17 +1029,14 @@ label {
width: 100px;
}
}
.loading, .loading_full_page, .loading_hapwi_overview {
width: 100px;
height: 100px;
.loading, .loading_full_page {
width: 50px;
height: 50px;
margin-left: 100%;
}
.loading_full_page {
margin-left: 45%;
}
.loading_hapwi_overview{
margin-left: 40%;
}
.loading_small {
width: 39px;
height: 39px;

View File

@ -835,7 +835,11 @@ function addUser() {
});
} else {
$('.alert-danger').remove();
$("#ajax-users").append(data);
$("#ajax-users").append(data);
var getId = new RegExp('[0-9]+');
var id = data.match(getId);
console.log(id[0])
addUserGroup(id[0]);
}
}
} );
@ -1306,12 +1310,7 @@ function removeBackup(id) {
function updateUser(id) {
$('.alert-danger').remove();
cur_url[0] = cur_url[0].split('#')[0]
console.log(cur_url[0])
if (cur_url[0] != "servers.py") {
var usergroup = $('#usergroup-'+id+' option:selected' ).val();
} else {
var usergroup = $('#usergroup-'+id ).val();
}
var usergroup = Cookies.get('group');
var activeuser = 0;
if ($('#activeuser-'+id).is(':checked')) {
activeuser = '1';
@ -1636,6 +1635,9 @@ function checkSshConnect(ip) {
function openChangeUserPasswordDialog(id) {
changeUserPasswordDialog(id);
}
function openChangeUserGroupDialog(id) {
changeUserGroupDialog(id);
}
function changeUserPasswordDialog(id) {
$( "#user-change-password-table" ).dialog({
autoOpen: true,
@ -1698,4 +1700,75 @@ function changeUserPassword(id, d) {
}
} );
}
}
function changeUserGroupDialog(id) {
$.ajax( {
url: "options.py",
data: {
getusergroups: id,
token: $('#token').val()
},
type: "POST",
success: function( data ) {
if (data.indexOf('danger') != '-1') {
$("#ajax").html(data);
} else {
$('.alert-danger').remove();
$('#change-user-groups-form').html(data);
$( "#change-user-groups-dialog" ).dialog({
resizable: false,
height: "auto",
width: 450,
modal: true,
title: "Change "+$('#login-'+id).val()+" groups",
buttons: {
"Save": function() {
$( this ).dialog( "close" );
changeUserGroup(id);
},
Cancel: function() {
$( this ).dialog( "close" );
}
}
});
}
}
} );
}
function changeUserGroup(id) {
var groups = $('#usergroup-'+id).val().toString();
$.ajax( {
url: "options.py",
data: {
changeUserGroupId: id,
changeUserGroups: groups,
changeUserGroupsUser: $('#login-'+id).val(),
token: $('#token').val()
},
type: "POST",
success: function( data ) {
$("#user-"+id).addClass( "update", 1000 );
setTimeout(function() {
$( "#user-"+id ).removeClass( "update" );
}, 2500 );
}
} );
}
function addUserGroup(id) {
$.ajax( {
url: "options.py",
data: {
changeUserGroupId: id,
changeUserGroups: $('#new-group').val(),
changeUserGroupsUser: 'new',
token: $('#token').val()
},
type: "POST",
success: function( data ) {
$("#user-"+id).addClass( "update", 1000 );
setTimeout(function() {
$( "#user-"+id ).removeClass( "update" );
}, 2500 );
}
} );
}