Pavel Loginov 2021-12-03 16:39:15 +06:00
parent 59d5a8c0b0
commit e99fc6b5ea
11 changed files with 590 additions and 45 deletions

View File

@ -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'])

View File

@ -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:

View File

@ -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:

View File

@ -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])

View File

@ -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)

View File

@ -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')

View File

@ -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

View File

@ -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 %}

View File

@ -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>

View File

@ -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

View File

@ -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');
}
}