mirror of https://github.com/Aidaho12/haproxy-wi
parent
59d5a8c0b0
commit
e99fc6b5ea
31
api/api.py
31
api/api.py
|
@ -53,13 +53,14 @@ def index():
|
|||
'haproxy/<id,hostname,ip>/action/start':'start HAProxy service by id or hostname or ip. METHOD: GET',
|
||||
'haproxy/<id,hostname,ip>/action/stop':'stop HAProxy service by id or hostname or ip. METHOD: GET',
|
||||
'haproxy/<id,hostname,ip>/action/restart':'restart HAProxy service by id or hostname or ip. METHOD: GET',
|
||||
'haproxy/<id,hostname,ip>/config':'get HAProxy config from the server by id or hostname or ip. METHOD: GET',
|
||||
'haproxy/<id,hostname,ip>/log':'show HAProxy log by id or hostname or ip. May to have config next headers: rows(format INT) default: 10 grep, waf(if needs WAF log) default: 0, start_hour(format: 24) default: 00, start_minute, end_hour(format: 24) default: 24, end_minute. METHOD: GET',
|
||||
'haproxy/<id,hostname,ip>/section':'show certain section, headers: section-name. METHOD: GET',
|
||||
'haproxy/<id,hostname,ip>/section/add':'add section to the HAProxy config by id or hostname or ip. Has to have config header with section and action header for action after upload. Section header must consist type: listen, frontend, etc. Action header accepts next value: save, test, reload and restart. Can be empty for just save. METHOD: POST',
|
||||
'haproxy/<id,hostname,ip>/section/edit':'edit section in the HAProxy config by id or hostname or ip. Has to have config header with section, action header for action after upload and body of a new section configuration. Section header must consist type: listen, frontend, etc. Action header accepts next value: save, test, reload and restart. Can be empty for just save. METHOD: POST',
|
||||
'haproxy/<id,hostname,ip>/acl':'add acl to certain section. Must be JSON body: "section-name", "if", "then", "if_value", "then_value" and "action" for action after upload. Action accepts next value: "save", "test", "reload" and "restart". METHOD: POST',
|
||||
'haproxy/<id,hostname,ip>/acl':'delete acl to certain section. Must be JSON body: "section-name", "if", "then", "if_value", "then_value" and "action" for action after upload. Action accepts next value: "save", "test", "reload" and "restart". METHOD: DELETE'
|
||||
'haproxy/<id,hostname,ip>/config':'get HAProxy config from a server by id or hostname or ip. METHOD: GET',
|
||||
'haproxy/<id,hostname,ip>/config':'upload HAProxy config to a server by id or hostname or ip. Body must consist a whole HAProxy config. METHOD: POST',
|
||||
'haproxy/<id,hostname,ip>/log':'show HAProxy logs by id or hostname or ip. May to have config next headers: rows(format INT) default: 10 grep, waf(if needs WAF log) default: 0, start_hour(format: 24) default: 00, start_minute, end_hour(format: 24) default: 24, end_minute. METHOD: GET',
|
||||
'haproxy/<id,hostname,ip>/section':'show a certain section, headers: section-name. METHOD: GET',
|
||||
'haproxy/<id,hostname,ip>/section/add':'add a section to the HAProxy config by id or hostname or ip. Has to have config header with section and action header for action after upload. Section header must consist type: listen, frontend, etc. Action header accepts next value: save, test, reload and restart. Can be empty for just save. METHOD: POST',
|
||||
'haproxy/<id,hostname,ip>/section/edit':'edit a section in the HAProxy config by id or hostname or ip. Has to have config header with section, action header for action after upload and body of a new section configuration. Section header must consist type: listen, frontend, etc. Action header accepts next value: save, test, reload and restart. Can be empty for just save. METHOD: POST',
|
||||
'haproxy/<id,hostname,ip>/acl':'add an acl to certain section. Must be JSON body: "section-name", "if", "then", "if_value", "then_value" and "action" for action after upload. Action accepts next value: "save", "test", "reload" and "restart". METHOD: POST',
|
||||
'haproxy/<id,hostname,ip>/acl':'delete an acl to certain section. Must be JSON body: "section-name", "if", "then", "if_value", "then_value" and "action" for action after upload. Action accepts next value: "save", "test", "reload" and "restart". METHOD: DELETE'
|
||||
}
|
||||
return dict(help=data)
|
||||
|
||||
|
@ -152,14 +153,14 @@ def callback(haproxy_id):
|
|||
if not check_login(required_service=1):
|
||||
return dict(error=_error_auth)
|
||||
return api_funct.get_config(haproxy_id)
|
||||
#
|
||||
#
|
||||
# @route('/haproxy/<haproxy_id>/config', method=['POST'])
|
||||
# @route('/haproxy/<haproxy_id:int>/config', method=['POST'])
|
||||
# def callback(haproxy_id):
|
||||
# if not check_login(required_service=1):
|
||||
# return dict(error=_error_auth)
|
||||
# return api_funct.upload_config(haproxy_id)
|
||||
|
||||
|
||||
@route('/haproxy/<haproxy_id>/config', method=['POST'])
|
||||
@route('/haproxy/<haproxy_id:int>/config', method=['POST'])
|
||||
def callback(haproxy_id):
|
||||
if not check_login(required_service=1):
|
||||
return dict(error=_error_auth)
|
||||
return api_funct.upload_config(haproxy_id)
|
||||
|
||||
|
||||
@route('/haproxy/<haproxy_id>/log', method=['GET'])
|
||||
|
|
|
@ -274,7 +274,7 @@ def edit_section(server_id):
|
|||
os.system("/bin/cp %s %s" % (cfg, cfg_for_save))
|
||||
out = funct.master_slave_upload_and_restart(ip, cfg, save, login=login)
|
||||
funct.logging('localhost', " section " + section_name + " has been edited via API", login=login)
|
||||
funct.logging(ip, 'section ' + section_name + ' has been edited via API', haproxywi=1, login=login,
|
||||
funct.logging(ip, 'Section ' + section_name + ' has been edited via API', haproxywi=1, login=login,
|
||||
keep_history=1, service='haproxy')
|
||||
|
||||
if out:
|
||||
|
@ -320,7 +320,7 @@ def upload_config(server_id):
|
|||
os.system("/bin/cp %s %s" % (cfg, cfg_for_save))
|
||||
out = funct.master_slave_upload_and_restart(ip, cfg, save, login=login)
|
||||
funct.logging('localhost', " config has been uploaded via API", login=login)
|
||||
funct.logging(ip, 'config has been uploaded via API', haproxywi=1, login=login,
|
||||
funct.logging(ip, 'Config has been uploaded via API', haproxywi=1, login=login,
|
||||
keep_history=1, service='haproxy')
|
||||
|
||||
if out:
|
||||
|
|
|
@ -859,7 +859,7 @@ def update_db_v_5_3_2_2(**kwargs):
|
|||
|
||||
|
||||
def update_ver():
|
||||
query = Version.update(version='5.3.3.0')
|
||||
query = Version.update(version='5.3.4.0')
|
||||
try:
|
||||
query.execute()
|
||||
except:
|
||||
|
|
|
@ -454,9 +454,24 @@ class ConfigVersion(BaseModel):
|
|||
class Meta:
|
||||
table_name = 'config_versions'
|
||||
|
||||
|
||||
class SystemInfo(BaseModel):
|
||||
id = AutoField()
|
||||
server_id = IntegerField()
|
||||
os_info = CharField()
|
||||
sys_info = CharField()
|
||||
cpu = CharField()
|
||||
ram = CharField()
|
||||
disks = CharField()
|
||||
network = TextField()
|
||||
|
||||
class Meta:
|
||||
table_name = 'system_info'
|
||||
|
||||
def create_tables():
|
||||
with conn:
|
||||
conn.create_tables([User, Server, Role, Telegram, Slack, UUID, Token, ApiToken, Groups, UserGroups, ConfigVersion,
|
||||
Setting, Cred, Backup, Metrics, WafMetrics, Version, Option, SavedServer, Waf, ActionHistory,
|
||||
PortScannerSettings, PortScannerPorts, PortScannerHistory, ProvidersCreds, ServiceSetting,
|
||||
ProvisionedServers, MetricsHttpStatus, SMON, WafRules, Alerts, GeoipCodes, NginxMetrics])
|
||||
ProvisionedServers, MetricsHttpStatus, SMON, WafRules, Alerts, GeoipCodes, NginxMetrics,
|
||||
SystemInfo])
|
||||
|
|
202
app/funct.py
202
app/funct.py
|
@ -440,11 +440,15 @@ def get_config(server_ip, cfg, **kwargs):
|
|||
sftp = ssh.open_sftp()
|
||||
except Exception as e:
|
||||
logging('localhost', str(e), haproxywi=1)
|
||||
sftp.close()
|
||||
ssh.close()
|
||||
return
|
||||
try:
|
||||
sftp.get(config_path, cfg)
|
||||
except Exception as e:
|
||||
logging('localhost', str(e), haproxywi=1)
|
||||
sftp.close()
|
||||
ssh.close()
|
||||
return
|
||||
try:
|
||||
sftp.close()
|
||||
|
@ -1523,10 +1527,28 @@ def check_is_server_in_group(server_ip):
|
|||
|
||||
|
||||
def check_service(server_ip, service_name):
|
||||
server_ip = is_ip_or_dns(server_ip)
|
||||
commands = ["systemctl is-active "+service_name]
|
||||
return ssh_command(server_ip, commands)
|
||||
|
||||
|
||||
def get_service_version(server_ip, service_name):
|
||||
server_ip = is_ip_or_dns(server_ip)
|
||||
if service_name == 'haproxy_exporter':
|
||||
commands = [ "/opt/prometheus/exporters/haproxy_exporter --version 2>&1 |head -1|awk '{print $3}'"]
|
||||
elif service_name == 'nginx_exporter':
|
||||
commands = ["/opt/prometheus/exporters/nginx_exporter 2>&1 |head -1 |awk -F\"=\" '{print $2}'|awk '{print $1}'"]
|
||||
elif service_name == 'node_exporter':
|
||||
commands = ["node_exporter --version 2>&1 |head -1|awk '{print $3}'"]
|
||||
|
||||
ver = ssh_command(server_ip, commands)
|
||||
|
||||
if ver != '':
|
||||
return ver
|
||||
else:
|
||||
return 'no'
|
||||
|
||||
|
||||
def get_services_status():
|
||||
import distro
|
||||
services = []
|
||||
|
@ -1586,3 +1608,183 @@ def is_service_active(server_ip: str, service_name: str):
|
|||
out = ssh_command(server_ip, cmd)
|
||||
out = out.strip()
|
||||
return True if 'active' == out else False
|
||||
|
||||
|
||||
def get_system_info(server_ip: str) -> bool:
|
||||
import json
|
||||
import sql
|
||||
server_ip = is_ip_or_dns(server_ip)
|
||||
if server_ip == '':
|
||||
return False
|
||||
|
||||
server_id = sql.select_server_id_by_ip(server_ip)
|
||||
|
||||
command = ["sudo lshw -quiet -json"]
|
||||
sys_info_returned = ssh_command(server_ip, command)
|
||||
command = ['sudo hostnamectl |grep "Operating System"|awk -F":" \'{print $2}\'']
|
||||
os_info = ssh_command(server_ip, command)
|
||||
os_info = os_info.strip()
|
||||
system_info = json.loads(sys_info_returned)
|
||||
|
||||
sys_info = {'hostname': system_info['id'], 'family': ''}
|
||||
cpu = {'cpu_model': '', 'cpu_core': 0, 'cpu_thread': 0, 'hz': 0}
|
||||
network = {}
|
||||
ram = {'slots': 0, 'size': 0}
|
||||
disks = {}
|
||||
|
||||
try:
|
||||
sys_info['family'] = system_info['configuration']['family']
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
for i in system_info['children']:
|
||||
if i['class'] == 'network':
|
||||
try:
|
||||
ip = i['configuration']['ip']
|
||||
except Exception:
|
||||
ip = ''
|
||||
network[i['logicalname']] = {'description': i['description'],
|
||||
'mac': i['serial'],
|
||||
'ip': ip}
|
||||
for k, j in i.items():
|
||||
if isinstance(j, list):
|
||||
for b in j:
|
||||
try:
|
||||
if b['class'] == 'processor':
|
||||
cpu['cpu_model'] = b['product']
|
||||
cpu['cpu_core'] += 1
|
||||
cpu['hz'] = round(int(b['capacity']) / 1000000)
|
||||
try:
|
||||
cpu['cpu_thread'] += int(b['configuration']['threads'])
|
||||
except Exception:
|
||||
cpu['cpu_thread'] = 1
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
if b['id'] == 'memory':
|
||||
ram['size'] = round(b['size'] / 1073741824)
|
||||
for memory in b['children']:
|
||||
ram['slots'] += 1
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
if b['class'] == 'bridge':
|
||||
if 'children' in b:
|
||||
for s in b['children']:
|
||||
if s['class'] == 'network':
|
||||
if 'children' in s:
|
||||
for net in s['children']:
|
||||
network[net['logicalname']] = {'description': net['description'],
|
||||
'mac': net['serial']}
|
||||
if s['class'] == 'storage':
|
||||
for p, pval in s.items():
|
||||
if isinstance(pval, list):
|
||||
for disks_info in pval:
|
||||
if 'children' in disks_info:
|
||||
for volume_info in disks_info['children']:
|
||||
if isinstance(volume_info['logicalname'], dict):
|
||||
volume_name = volume_info['logicalname'][0]
|
||||
mount_point = volume_info['logicalname'][1]
|
||||
size = round(volume_info['size'] / 1073741824)
|
||||
size = str(size) + 'Gb'
|
||||
fs = volume_info['configuration']['mount.fstype']
|
||||
state = volume_info['configuration']['state']
|
||||
disks[volume_name] = {'mount_point': mount_point,
|
||||
'size': size,
|
||||
'fs': fs,
|
||||
'state': state}
|
||||
for z, n in s.items():
|
||||
if isinstance(n, list):
|
||||
for y in n:
|
||||
if y['class'] == 'network':
|
||||
try:
|
||||
for q in y['children']:
|
||||
try:
|
||||
ip = q['configuration']['ip']
|
||||
except Exception:
|
||||
ip = ''
|
||||
network[q['logicalname']] = {
|
||||
'description': q['description'],
|
||||
'mac': q['serial'],
|
||||
'ip': ip}
|
||||
except Exception:
|
||||
try:
|
||||
network[y['logicalname']] = {
|
||||
'description': y['description'],
|
||||
'mac': y['serial'],
|
||||
'ip': y['configuration']['ip']}
|
||||
except Exception:
|
||||
pass
|
||||
if y['class'] == 'disk':
|
||||
try:
|
||||
for q in y['children']:
|
||||
try:
|
||||
if isinstance(q['logicalname'], list):
|
||||
volume_name = q['logicalname'][0]
|
||||
mount_point = q['logicalname'][1]
|
||||
size = round(q['capacity'] / 1073741824)
|
||||
size = str(size) + 'Gb'
|
||||
fs = q['configuration']['mount.fstype']
|
||||
state = q['configuration']['state']
|
||||
disks[volume_name] = {'mount_point': mount_point,
|
||||
'size': size,
|
||||
'fs': fs,
|
||||
'state': state}
|
||||
except Exception as e:
|
||||
print(e)
|
||||
except Exception:
|
||||
pass
|
||||
if y['class'] == 'storage' or y['class'] == 'generic':
|
||||
try:
|
||||
for q in y['children']:
|
||||
for o in q['children']:
|
||||
for w in o['children']:
|
||||
try:
|
||||
if isinstance(w['logicalname'], list):
|
||||
volume_name = w['logicalname'][0]
|
||||
mount_point = w['logicalname'][1]
|
||||
size = round(w['size'] / 1073741824)
|
||||
size = str(size) + 'Gb'
|
||||
fs = w['configuration']['mount.fstype']
|
||||
state = w['configuration']['state']
|
||||
disks[volume_name] = {
|
||||
'mount_point': mount_point,
|
||||
'size': size,
|
||||
'fs': fs,
|
||||
'state': state}
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
for q, qval in y.items():
|
||||
if isinstance(qval, list):
|
||||
for o in qval:
|
||||
for w in o['children']:
|
||||
if isinstance(w['logicalname'], list):
|
||||
volume_name = w['logicalname'][0]
|
||||
mount_point = w['logicalname'][1]
|
||||
size = round(w['size'] / 1073741824)
|
||||
size = str(size) + 'Gb'
|
||||
fs = w['configuration']['mount.fstype']
|
||||
state = w['configuration']['state']
|
||||
disks[volume_name] = {
|
||||
'mount_point': mount_point,
|
||||
'size': size,
|
||||
'fs': fs,
|
||||
'state': state}
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if sql.insert_system_info(server_id, os_info, sys_info, cpu, ram, network, disks):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def string_to_dict(dict_string):
|
||||
from ast import literal_eval
|
||||
return literal_eval(dict_string)
|
||||
|
|
108
app/options.py
108
app/options.py
|
@ -372,8 +372,6 @@ if form.getvalue('sessions_select_show') is not None:
|
|||
cmd = 'echo "show sess %s" |nc %s %s' % (sess_id, serv, haproxy_sock_port)
|
||||
output, stderr = funct.subprocess_execute(cmd)
|
||||
|
||||
output, stderr = funct.subprocess_execute(cmd)
|
||||
|
||||
if stderr:
|
||||
print('error: ' + stderr[0])
|
||||
else:
|
||||
|
@ -476,6 +474,7 @@ if act == "overviewHapserverBackends":
|
|||
env = Environment(loader=FileSystemLoader('templates/ajax'), autoescape=True)
|
||||
template = env.get_template('haproxyservers_backends.html')
|
||||
service = form.getvalue('service')
|
||||
format_file = 'cfg'
|
||||
|
||||
if service == 'haproxy':
|
||||
configs_dir = funct.get_config_var('configs', 'haproxy_save_configs_dir')
|
||||
|
@ -1411,6 +1410,7 @@ if form.getvalue('haproxy_exp_install'):
|
|||
|
||||
if form.getvalue('nginx_exp_install'):
|
||||
serv = form.getvalue('nginx_exp_install')
|
||||
ver = form.getvalue('exporter_v')
|
||||
script = "install_nginx_exporter.sh"
|
||||
stats_user = sql.get_setting('nginx_stats_user')
|
||||
stats_password = sql.get_setting('nginx_stats_password')
|
||||
|
@ -2026,6 +2026,11 @@ if form.getvalue('newserver') is not None:
|
|||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
funct.get_system_info(ip)
|
||||
except Exception as e:
|
||||
funct.logging('Cannot get information from ' + hostname, str(e), haproxywi=1, login=1)
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
env = Environment(loader=FileSystemLoader('templates/'), autoescape=True)
|
||||
|
@ -2038,7 +2043,6 @@ if form.getvalue('newserver') is not None:
|
|||
page=page,
|
||||
adding=1)
|
||||
print(template)
|
||||
funct.logging('a new server ' + hostname, ' has been created ', haproxywi=1, login=1)
|
||||
funct.logging(ip, 'A new server ' + hostname + ' has been created', haproxywi=1, login=1,
|
||||
keep_history=1, service='server')
|
||||
|
||||
|
@ -2092,8 +2096,9 @@ if form.getvalue('serverdel') is not None:
|
|||
sql.delete_port_scanner_settings(server_id)
|
||||
sql.delete_waf_rules(server_ip)
|
||||
sql.delete_action_history(server_id)
|
||||
sql.delete_system_info(server_id)
|
||||
print("Ok")
|
||||
funct.logging(hostname, ' has been deleted server with ', haproxywi=1, login=1)
|
||||
funct.logging(server_ip, 'The server ' + hostname + ' has been deleted', haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('newgroup') is not None:
|
||||
newgroup = form.getvalue('groupname')
|
||||
|
@ -2109,7 +2114,7 @@ if form.getvalue('newgroup') is not None:
|
|||
|
||||
output_from_parsed_template = template.render(groups=sql.select_groups(group=newgroup))
|
||||
print(output_from_parsed_template)
|
||||
funct.logging('a new group ' + newgroup, ' has been created ', haproxywi=1, login=1)
|
||||
funct.logging('localhost','A new group ' + newgroup + ' has been created', haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('groupdel') is not None:
|
||||
groupdel = form.getvalue('groupdel')
|
||||
|
@ -2118,7 +2123,7 @@ if form.getvalue('groupdel') is not None:
|
|||
groupname = g.name
|
||||
if sql.delete_group(groupdel):
|
||||
print("Ok")
|
||||
funct.logging(groupname, ' has been deleted group ', haproxywi=1, login=1)
|
||||
funct.logging('localhost', 'The ' + groupname + ' has been deleted', haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('updategroup') is not None:
|
||||
name = form.getvalue('updategroup')
|
||||
|
@ -2129,7 +2134,7 @@ if form.getvalue('updategroup') is not None:
|
|||
else:
|
||||
try:
|
||||
sql.update_group(name, descript, group_id)
|
||||
funct.logging('the group ' + groupname, ' has been updated ', haproxywi=1, login=1)
|
||||
funct.logging('localhost', 'The ' + name + ' has been updated', haproxywi=1, login=1)
|
||||
except Exception as e:
|
||||
print('error: ' + str(e))
|
||||
|
||||
|
@ -2155,7 +2160,7 @@ if form.getvalue('new_ssh'):
|
|||
output_from_parsed_template = template.render(groups=sql.select_groups(), sshs=sql.select_ssh(name=name),
|
||||
page=page)
|
||||
print(output_from_parsed_template)
|
||||
funct.logging(name, ' has created a new SSH credentials ', haproxywi=1, login=1)
|
||||
funct.logging('localhost', 'A new SSH credentials ' + name +' has created', haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('sshdel') is not None:
|
||||
fullpath = funct.get_config_var('main', 'fullpath')
|
||||
|
@ -2174,7 +2179,7 @@ if form.getvalue('sshdel') is not None:
|
|||
pass
|
||||
if sql.delete_ssh(sshdel):
|
||||
print("Ok")
|
||||
funct.logging(name, ' has deleted the SSH credentials ', haproxywi=1, login=1)
|
||||
funct.logging('localhost', 'The SSH credentials ' + name + ' has deleted', haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('updatessh'):
|
||||
ssh_id = form.getvalue('id')
|
||||
|
@ -2203,7 +2208,7 @@ if form.getvalue('updatessh'):
|
|||
except Exception:
|
||||
pass
|
||||
sql.update_ssh(ssh_id, name, enable, group, username, password)
|
||||
funct.logging('the SSH ' + name, ' has updated credentials ', haproxywi=1, login=1)
|
||||
funct.logging('localhost', 'The SSH credentials ' + name + ' has been updated ', haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('ssh_cert'):
|
||||
import paramiko
|
||||
|
@ -2245,7 +2250,7 @@ if form.getvalue('ssh_cert'):
|
|||
except IOError as e:
|
||||
funct.logging('localhost', e.args[0], haproxywi=1)
|
||||
|
||||
funct.logging("localhost", " has been uploaded a new SSH cert %s" % ssh_keys, haproxywi=1, login=1)
|
||||
funct.logging("localhost", "A new SSH cert has been uploaded %s" % ssh_keys, haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('newtelegram'):
|
||||
token = form.getvalue('newtelegram')
|
||||
|
@ -2265,7 +2270,7 @@ if form.getvalue('newtelegram'):
|
|||
output_from_parsed_template = template.render(groups=sql.select_groups(),
|
||||
telegrams=sql.select_telegram(token=token), page=page)
|
||||
print(output_from_parsed_template)
|
||||
funct.logging(channel, ' a new Telegram channel has been created ', haproxywi=1, login=1)
|
||||
funct.logging('localhost', 'A new Telegram channel ' + channel + ' has been created ', haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('newslack'):
|
||||
token = form.getvalue('newslack')
|
||||
|
@ -2285,25 +2290,27 @@ if form.getvalue('newslack'):
|
|||
output_from_parsed_template = template.render(groups=sql.select_groups(),
|
||||
slacks=sql.select_slack(token=token), page=page)
|
||||
print(output_from_parsed_template)
|
||||
funct.logging(channel, ' has created a new Slack channel ', haproxywi=1, login=1)
|
||||
funct.logging('localhost', 'A new Slack channel ' + channel + ' has been created ', haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('telegramdel') is not None:
|
||||
telegramdel = form.getvalue('telegramdel')
|
||||
telegram = sql.select_telegram(id=telegramdel)
|
||||
telegram_name = ''
|
||||
for t in telegram:
|
||||
telegram_name = t.token
|
||||
if sql.delete_telegram(telegramdel):
|
||||
print("Ok")
|
||||
funct.logging(telegram_name, ' has deleted the Telegram channel ', haproxywi=1, login=1)
|
||||
funct.logging('localhost', 'The Telegram channel ' + telegram_name + ' has been deleted ', haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('slackdel') is not None:
|
||||
slackdel = form.getvalue('slackdel')
|
||||
slack = sql.select_slack(id=slackdel)
|
||||
slack_name = ''
|
||||
for t in slack:
|
||||
slack_name = t[1]
|
||||
if sql.delete_slack(slackdel):
|
||||
print("Ok")
|
||||
funct.logging(slack_name, ' has deleted the Slack channel ', haproxywi=1, login=1)
|
||||
funct.logging('localhost', 'The Slack channel ' + slack_name + ' has been deleted ', haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('updatetoken') is not None:
|
||||
token = form.getvalue('updatetoken')
|
||||
|
@ -2314,7 +2321,7 @@ if form.getvalue('updatetoken') is not None:
|
|||
print(error_mess)
|
||||
else:
|
||||
sql.update_telegram(token, channel, group, user_id)
|
||||
funct.logging('group ' + group, ' Telegram token has updated channel: ' + channel, haproxywi=1, login=1)
|
||||
funct.logging('group ' + group, 'The Telegram token has been updated for channel: ' + channel, haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('update_slack_token') is not None:
|
||||
token = form.getvalue('update_slack_token')
|
||||
|
@ -2325,13 +2332,13 @@ if form.getvalue('update_slack_token') is not None:
|
|||
print(error_mess)
|
||||
else:
|
||||
sql.update_slack(token, channel, group, user_id)
|
||||
funct.logging('group ' + group, ' Slack token has updated channel: ' + channel, haproxywi=1, login=1)
|
||||
funct.logging('group ' + group, 'The Slack token has been updated for channel: ' + channel, haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('updatesettings') is not None:
|
||||
settings = form.getvalue('updatesettings')
|
||||
val = form.getvalue('val')
|
||||
if sql.update_setting(settings, val):
|
||||
funct.logging('value ' + val, ' changed settings ' + settings, haproxywi=1, login=1)
|
||||
funct.logging('localhost', 'The ' + settings +' setting has been changed to: ' + val, haproxywi=1, login=1)
|
||||
print("Ok")
|
||||
|
||||
if form.getvalue('getuserservices'):
|
||||
|
@ -2370,7 +2377,7 @@ if form.getvalue('changeUserGroupId') is not None:
|
|||
continue
|
||||
sql.update_user_groups(groups=group[0], user_group_id=group_id)
|
||||
|
||||
funct.logging('localhost', ' has been updated groups for user: ' + user, haproxywi=1, login=1)
|
||||
funct.logging('localhost', 'Groups has been updated for user: ' + user, haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('changeUserServicesId') is not None:
|
||||
user_id = form.getvalue('changeUserServicesId')
|
||||
|
@ -2378,7 +2385,7 @@ if form.getvalue('changeUserServicesId') is not None:
|
|||
user = form.getvalue('changeUserServicesUser')
|
||||
|
||||
if sql.update_user_services(services=services, user_id=user_id):
|
||||
funct.logging('localhost', ' has been updated services for user: ' + user, haproxywi=1, login=1)
|
||||
funct.logging('localhost', 'Access to the services has been updated for user: ' + user, haproxywi=1, login=1)
|
||||
|
||||
if form.getvalue('changeUserCurrentGroupId') is not None:
|
||||
group_id = form.getvalue('changeUserCurrentGroupId')
|
||||
|
@ -2588,6 +2595,7 @@ if form.getvalue('lets_domain'):
|
|||
ssl_path = sql.get_setting('cert_path')
|
||||
haproxy_dir = sql.get_setting('haproxy_dir')
|
||||
script = "letsencrypt.sh"
|
||||
ssh_port = "22"
|
||||
ssh_enable, ssh_user_name, ssh_user_password, ssh_key_name = funct.return_ssh_keys_path(serv)
|
||||
|
||||
if ssh_enable == 0:
|
||||
|
@ -2690,6 +2698,7 @@ if form.getvalue('actionvpn') is not None:
|
|||
if form.getvalue('scan_ports') is not None:
|
||||
serv_id = form.getvalue('scan_ports')
|
||||
server = sql.select_servers(id=serv_id)
|
||||
ip = ''
|
||||
|
||||
for s in server:
|
||||
ip = s[2]
|
||||
|
@ -2751,6 +2760,7 @@ if form.getvalue('geoip_install'):
|
|||
maxmind_key = sql.get_setting('maxmind_key')
|
||||
haproxy_dir = sql.get_setting('haproxy_dir')
|
||||
script = 'install_geoip.sh'
|
||||
ssh_port = '22'
|
||||
ssh_enable, ssh_user_name, ssh_user_password, ssh_key_name = funct.return_ssh_keys_path(serv)
|
||||
|
||||
if ssh_enable == 0:
|
||||
|
@ -2784,6 +2794,7 @@ if form.getvalue('nettools_icmp_server_from'):
|
|||
server_to = funct.is_ip_or_dns(server_to)
|
||||
action = form.getvalue('nettools_action')
|
||||
stderr = ''
|
||||
action_for_sending = ''
|
||||
|
||||
if server_to == '':
|
||||
print('warning: enter a correct IP or DNS name')
|
||||
|
@ -3885,4 +3896,59 @@ if act == 'showListOfVersion':
|
|||
for_delver=for_delver,
|
||||
configs=configs,
|
||||
style=style)
|
||||
print(template)
|
||||
print(template)
|
||||
|
||||
if act == 'getSystemInfo':
|
||||
server_ip = form.getvalue('server_ip')
|
||||
server_ip = funct.is_ip_or_dns(server_ip)
|
||||
server_id = form.getvalue('server_id')
|
||||
|
||||
if server_ip == '':
|
||||
print('error: IP or DNS name is not valid')
|
||||
sys.exit()
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
env = Environment(loader=FileSystemLoader('templates/'), autoescape=True,
|
||||
extensions=["jinja2.ext.loopcontrols", "jinja2.ext.do"])
|
||||
env.globals['string_to_dict'] = funct.string_to_dict
|
||||
template = env.get_template('ajax/show_system_info.html')
|
||||
if sql.is_system_info(server_id):
|
||||
if funct.get_system_info(server_ip):
|
||||
system_info = sql.select_one_system_info(server_id)
|
||||
|
||||
template = template.render(system_info=system_info, server_ip=server_ip, server_id=server_id)
|
||||
print(template)
|
||||
else:
|
||||
print('error: Cannot update server info')
|
||||
else:
|
||||
system_info = sql.select_one_system_info(server_id)
|
||||
|
||||
template = template.render(system_info=system_info, server_ip=server_ip, server_id=server_id)
|
||||
print(template)
|
||||
|
||||
|
||||
if act == 'updateSystemInfo':
|
||||
server_ip = form.getvalue('server_ip')
|
||||
server_ip = funct.is_ip_or_dns(server_ip)
|
||||
server_id = form.getvalue('server_id')
|
||||
|
||||
if server_ip == '':
|
||||
print('error: IP or DNS name is not valid')
|
||||
sys.exit()
|
||||
|
||||
sql.delete_system_info(server_id)
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
env = Environment(loader=FileSystemLoader('templates/'), autoescape=True,
|
||||
extensions=["jinja2.ext.loopcontrols", "jinja2.ext.do"])
|
||||
env.globals['string_to_dict'] = funct.string_to_dict
|
||||
template = env.get_template('ajax/show_system_info.html')
|
||||
|
||||
if funct.get_system_info(server_ip):
|
||||
system_info = sql.select_one_system_info(server_id)
|
||||
|
||||
template = template.render(system_info=system_info, server_ip=server_ip, server_id=server_id)
|
||||
print(template)
|
||||
else:
|
||||
print('error: Cannot update server info')
|
||||
|
|
53
app/sql.py
53
app/sql.py
|
@ -2941,3 +2941,56 @@ def delete_config_version(service: str, local_path: str):
|
|||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def insert_system_info(server_id: int, os_info: str, sys_info: str, cpu: str, ram: str, network: str, disks: str) -> bool:
|
||||
try:
|
||||
SystemInfo.insert(server_id=server_id, os_info=os_info, sys_info=sys_info, cpu=cpu, ram=ram,
|
||||
network=network, disks=disks).on_conflict('replace').execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def delete_system_info(server_id: int):
|
||||
query = SystemInfo.delete().where(SystemInfo.server_id == server_id)
|
||||
try:
|
||||
query.execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
|
||||
|
||||
def select_one_system_info(server_id: int):
|
||||
query = SystemInfo.select().where(SystemInfo.server_id == server_id)
|
||||
try:
|
||||
query_res = query.execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
return
|
||||
else:
|
||||
return query_res
|
||||
|
||||
|
||||
def select_system_info():
|
||||
query = SystemInfo.select()
|
||||
try:
|
||||
query_res = query.execute()
|
||||
except Exception as e:
|
||||
out_error(e)
|
||||
return
|
||||
else:
|
||||
return query_res
|
||||
|
||||
|
||||
def is_system_info(server_id):
|
||||
try:
|
||||
query_res = SystemInfo.get(SystemInfo.server_id == server_id).server_id
|
||||
except Exception:
|
||||
return True
|
||||
else:
|
||||
if query_res != '':
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
{% if not system_info %}
|
||||
<td style="padding-top: 20px;" colspan="16">
|
||||
<a onclick="updateServerInfo('{{server_ip}}', '{{server_id}}')" title="Refresh" style="float: right; margin-bottom: 10px;">
|
||||
<span class="service-reload"></span>
|
||||
</a>
|
||||
</td>
|
||||
{% else %}
|
||||
{% for s_i in system_info %}
|
||||
<td style="padding-top: 20px;" colspan="16">
|
||||
<table class="overview-wi">
|
||||
<tr class="overviewHead">
|
||||
<td class="padding10 first-collumn-wi" colspan=2>
|
||||
Base info
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td class="padding10 first-collumn-wi">Linux</td>
|
||||
<td>{{s_i.os_info}}</td>
|
||||
</tr>
|
||||
{% set base_info = string_to_dict(s_i.sys_info) %}
|
||||
<tr class="even">
|
||||
<td class="padding10 first-collumn-wi" style="width: 20%;">
|
||||
Hostname
|
||||
</td>
|
||||
<td>{{base_info.hostname}}</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td class="padding10 first-collumn-wi">
|
||||
Family
|
||||
</td>
|
||||
<td>{{base_info.family}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="overview-wi">
|
||||
<tr class="overviewHead" colspan=2>
|
||||
<td class="padding10 first-collumn-wi">
|
||||
RAM
|
||||
</td>
|
||||
<td>
|
||||
<a onclick="updateServerInfo('{{server_ip}}', '{{server_id}}')" title="Update System info" style="float: right; margin-right: 15px;">
|
||||
<span class="service-reload"></span>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% set ram_info = string_to_dict(s_i.ram) %}
|
||||
<tr class="odd">
|
||||
<td class="padding10 first-collumn-wi" style="width: 20%;">
|
||||
Slots
|
||||
</td>
|
||||
<td>{{ram_info.slots}}</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td class="padding10 first-collumn-wi">
|
||||
Size
|
||||
</td>
|
||||
<td>{{ram_info.size}}Gb</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="overview-wi">
|
||||
<tr class="overviewHead">
|
||||
<td class="padding10 first-collumn-wi" colspan=2>
|
||||
CPU
|
||||
</td>
|
||||
</tr>
|
||||
{% set cpu_info = string_to_dict(s_i.cpu) %}
|
||||
<tr class="odd">
|
||||
<td class="padding10 first-collumn-wi">Model</td>
|
||||
<td>{{cpu_info.cpu_model}}</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td class="padding10 first-collumn-wi" style="width: 20%;">
|
||||
Cores
|
||||
</td>
|
||||
<td>{{cpu_info.cpu_core}}</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td class="padding10 first-collumn-wi">
|
||||
Threads
|
||||
</td>
|
||||
<td>{{cpu_info.cpu_thread}}</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td class="padding10 first-collumn-wi">
|
||||
Frequency
|
||||
</td>
|
||||
<td>{{cpu_info.hz}}Hz</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
{% set disks_info = string_to_dict(s_i.disks) %}
|
||||
{% for v,d in disks_info.items() %}
|
||||
<table class="overview-wi">
|
||||
<tr class="overviewHead" colspan=2>
|
||||
<td class="padding10 first-collumn-wi" colspan=2>
|
||||
{{v}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td class="padding10 first-collumn-wi" style="width: 20%;">
|
||||
Mount point
|
||||
</td>
|
||||
<td>{{d.mount_point}}</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td class="padding10 first-collumn-wi">
|
||||
Size
|
||||
</td>
|
||||
<td>{{d.size}}</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td class="padding10 first-collumn-wi" style="width: 20%;">
|
||||
File system
|
||||
</td>
|
||||
<td>{{d.fs}}</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td class="padding10 first-collumn-wi">
|
||||
State
|
||||
</td>
|
||||
<td>{{d.state}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endfor %}
|
||||
{% set network_info = string_to_dict(s_i.network) %}
|
||||
{% for v,d in network_info.items() %}
|
||||
<table class="overview-wi">
|
||||
<tr class="overviewHead" colspan=2>
|
||||
<td class="padding10 first-collumn-wi" colspan=2>
|
||||
{{v}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td class="padding10 first-collumn-wi" style="width: 20%;">
|
||||
IP
|
||||
</td>
|
||||
<td>{{d.ip}}</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td class="padding10 first-collumn-wi">
|
||||
MAC
|
||||
</td>
|
||||
<td>{{d.mac}}</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td class="padding10 first-collumn-wi" style="width: 20%;">
|
||||
Description
|
||||
</td>
|
||||
<td>{{d.description}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endfor %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
{% endif %}
|
|
@ -3,7 +3,7 @@
|
|||
<table class="overview" id="ajax-servers">
|
||||
<thead>
|
||||
<tr class="overviewHead">
|
||||
<th class="padding10 first-collumn">Hostname</th>
|
||||
<th class="padding10 first-collumn">Name</th>
|
||||
<th class="ip-field" style="width: 10%">IP</th>
|
||||
<th class="checkbox-head" style="width: 5%" class="help_cursor"><span title="SSH port">Port</span></th>
|
||||
{% if page != "servers.py" %}
|
||||
|
@ -26,6 +26,7 @@
|
|||
</th>
|
||||
<th class="cred-field">Credentials</th>
|
||||
<th style="width: 100%">Description</th>
|
||||
<th style="min-width: 17px;"></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
@ -150,6 +151,9 @@
|
|||
{{ input(id, size='20') }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style="min-width: 17px;">
|
||||
<a class="info" onclick="showServerInfo('{{server.0}}', '{{server.2}}')" id="server_info_link-{{server.0}}" title="Show server info" style="cursor: pointer; color: var(--green-color)"></a>
|
||||
</td>
|
||||
<td>
|
||||
<a class="add" onclick="cloneServer({{server.0}})" id="clone-{{server.0}}" title="Clone {{server.1}}" style="cursor: pointer;"></a>
|
||||
</td>
|
||||
|
@ -157,6 +161,7 @@
|
|||
<a class="delete" onclick="confirmDeleteServer({{server.0}})" title="Delete server {{server.1}}" style="cursor: pointer;"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="server_info-{{server.0}}" style="display: none"></tr>
|
||||
{% endfor %}
|
||||
{% if not adding %}
|
||||
</tbody>
|
||||
|
|
|
@ -19,7 +19,6 @@ try:
|
|||
settings = sql.get_setting('', all=1)
|
||||
ldap_enable = sql.get_setting('ldap_enable')
|
||||
grafana, stderr = funct.subprocess_execute("systemctl is-active grafana-server")
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
|
56
inc/users.js
56
inc/users.js
|
@ -182,7 +182,6 @@ $( function() {
|
|||
toastr.clear();
|
||||
toastr.success(data);
|
||||
$('#cur_haproxy_exp_ver').text('HAProxy exporter is installed');
|
||||
$('#haproxy_exp_install').text('Update');
|
||||
$("#haproxy_exp_addserv").trigger( "selectmenuchange" );
|
||||
} else if (data.indexOf('Info') != '-1' ){
|
||||
toastr.clear();
|
||||
|
@ -213,7 +212,6 @@ $( function() {
|
|||
toastr.clear();
|
||||
toastr.success(data);
|
||||
$('#cur_nginx_exp_ver').text('Nginx exporter is installed');
|
||||
$('#nginx_exp_install').text('Update');
|
||||
$("#nginx_exp_addserv").trigger( "selectmenuchange" );
|
||||
} else if (data.indexOf('Info') != '-1' ){
|
||||
toastr.clear();
|
||||
|
@ -244,7 +242,6 @@ $( function() {
|
|||
toastr.clear();
|
||||
toastr.success(data);
|
||||
$('#cur_node_exp_ver').text('Node exporter is installed');
|
||||
$('#node_exp_install').text('Update');
|
||||
$("#node_exp_addserv").trigger( "selectmenuchange" );
|
||||
} else if (data.indexOf('Info') != '-1' ){
|
||||
toastr.clear();
|
||||
|
@ -270,6 +267,7 @@ $( function() {
|
|||
if(data != '') {
|
||||
data = data+'-1';
|
||||
$('#cur_hap_ver').text(data);
|
||||
$('#cur_hap_ver').css('font-weight', 'bold');
|
||||
$('#install').text('Update');
|
||||
$('#install').attr('title', 'Update HAProxy');
|
||||
} else {
|
||||
|
@ -297,6 +295,7 @@ $( function() {
|
|||
$('#nginx_install').attr('title', 'Install Nginx');
|
||||
} else {
|
||||
$('#cur_nginx_ver').text(data);
|
||||
$('#cur_nginx_ver').css('font-weight', 'bold');
|
||||
$('#nginx_install').text('Update');
|
||||
$('#nginx_install').attr('title', 'Update Nginx');
|
||||
}
|
||||
|
@ -2424,3 +2423,54 @@ function checkSlack(slack_id) {
|
|||
}
|
||||
} );
|
||||
}
|
||||
function updateServerInfo(ip, id) {
|
||||
$.ajax({
|
||||
url: "options.py",
|
||||
data: {
|
||||
act: 'updateSystemInfo',
|
||||
server_ip: ip,
|
||||
server_id: id,
|
||||
token: $('#token').val()
|
||||
},
|
||||
type: "POST",
|
||||
success: function (data) {
|
||||
data = data.replace(/\s+/g, ' ');
|
||||
if (data.indexOf('error:') != '-1' || data.indexOf('error_code') != '-1') {
|
||||
toastr.error(data);
|
||||
} else {
|
||||
$("#server_info-"+id).html(data);
|
||||
$('#server_info-'+id).show();
|
||||
$('#server_info_link-'+id).attr('title', 'Hide System info');
|
||||
$.getScript(awesome);
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
function showServerInfo(id, ip) {
|
||||
if ($('#server_info-'+id).css('display') == 'none') {
|
||||
$.ajax({
|
||||
url: "options.py",
|
||||
data: {
|
||||
act: 'getSystemInfo',
|
||||
server_ip: ip,
|
||||
server_id: id,
|
||||
token: $('#token').val()
|
||||
},
|
||||
type: "POST",
|
||||
success: function (data) {
|
||||
data = data.replace(/\s+/g, ' ');
|
||||
if (data.indexOf('error:') != '-1' || data.indexOf('error_code') != '-1') {
|
||||
toastr.error(data);
|
||||
} else {
|
||||
$("#server_info-"+id).html(data);
|
||||
$('#server_info-'+id).show();
|
||||
$('#server_info_link-'+id).attr('title', 'Hide System info');
|
||||
$.getScript(awesome);
|
||||
}
|
||||
}
|
||||
} );
|
||||
} else {
|
||||
$('#server_info-'+id).hide();
|
||||
$('#server_info_link-'+id).attr('title', 'Show System info');
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue