2022-11-17 07:34:58 +00:00
|
|
|
import os
|
2022-11-17 09:49:30 +00:00
|
|
|
import http.cookies
|
2022-11-17 07:34:58 +00:00
|
|
|
|
|
|
|
import modules.db.sql as sql
|
2022-12-07 09:27:46 +00:00
|
|
|
import modules.server.ssh as mod_ssh
|
2022-11-17 07:34:58 +00:00
|
|
|
import modules.common.common as common
|
|
|
|
import modules.server.server as server_mod
|
2023-03-03 20:03:41 +00:00
|
|
|
import modules.roxywi.common as roxywi_common
|
2022-12-07 09:27:46 +00:00
|
|
|
import modules.roxy_wi_tools as roxy_wi_tools
|
|
|
|
|
2022-12-07 09:59:39 +00:00
|
|
|
time_zone = sql.get_setting('time_zone')
|
|
|
|
get_date = roxy_wi_tools.GetDate(time_zone)
|
2022-12-07 09:27:46 +00:00
|
|
|
get_config = roxy_wi_tools.GetConfigVar()
|
2022-11-17 07:34:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
def check_haproxy_version(server_ip):
|
|
|
|
hap_sock_p = sql.get_setting('haproxy_sock_port')
|
|
|
|
ver = ""
|
|
|
|
cmd = f"echo 'show info' |nc {server_ip} {hap_sock_p} |grep Version |awk '{{print $2}}'"
|
2022-11-17 15:27:26 +00:00
|
|
|
output, stderr = server_mod.subprocess_execute(cmd)
|
2022-11-17 07:34:58 +00:00
|
|
|
for line in output:
|
|
|
|
ver = line
|
|
|
|
|
|
|
|
return ver
|
|
|
|
|
|
|
|
|
|
|
|
def is_restarted(server_ip: str, action: str) -> None:
|
|
|
|
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
|
|
|
|
user_uuid = cookie.get('uuid')
|
2023-03-03 20:03:41 +00:00
|
|
|
group_id = cookie.get('group')
|
|
|
|
group_id = int(group_id.value)
|
|
|
|
user_role = sql.get_user_role_by_uuid(user_uuid.value, group_id)
|
2022-11-17 07:34:58 +00:00
|
|
|
|
|
|
|
if sql.is_serv_protected(server_ip) and int(user_role) > 2:
|
|
|
|
print(f'error: This server is protected. You cannot {action} it')
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def is_not_allowed_to_restart(server_id: int, service: str) -> None:
|
2022-12-06 19:37:45 +00:00
|
|
|
if service != 'waf':
|
|
|
|
is_restart = sql.select_service_setting(server_id, service, 'restart')
|
|
|
|
else:
|
|
|
|
is_restart = 0
|
2022-11-17 07:34:58 +00:00
|
|
|
|
2022-12-29 11:11:51 +00:00
|
|
|
try:
|
|
|
|
if int(is_restart) == 1:
|
|
|
|
print('warning: this service is not allowed to be restarted')
|
|
|
|
return
|
|
|
|
except Exception:
|
|
|
|
pass
|
2022-11-17 07:34:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_exp_version(server_ip: str, service_name: str) -> str:
|
|
|
|
server_ip = common.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}'"]
|
|
|
|
elif service_name == 'apache_exporter':
|
|
|
|
commands = ["/opt/prometheus/exporters/apache_exporter --version 2>&1 |head -1|awk '{print $3}'"]
|
2023-01-18 07:37:23 +00:00
|
|
|
elif service_name == 'keepalived_exporter':
|
|
|
|
commands = ["systemctl list-units --full -all |grep keepalived_exporter"]
|
2022-11-17 07:34:58 +00:00
|
|
|
|
|
|
|
ver = server_mod.ssh_command(server_ip, commands)
|
|
|
|
|
|
|
|
if ver != '':
|
|
|
|
return ver
|
|
|
|
else:
|
|
|
|
return 'no'
|
|
|
|
|
|
|
|
|
|
|
|
def get_correct_apache_service_name(server_ip=None, server_id=0) -> str:
|
|
|
|
if server_id is None:
|
|
|
|
server_id = sql.select_server_id_by_ip(server_ip)
|
|
|
|
|
|
|
|
try:
|
|
|
|
os_info = sql.select_os_info(server_id)
|
2022-12-06 19:37:45 +00:00
|
|
|
except Exception as e:
|
|
|
|
raise Exception(f'error: cannot get server info: {e}')
|
2022-11-17 07:34:58 +00:00
|
|
|
|
|
|
|
if "CentOS" in os_info or "Redhat" in os_info:
|
|
|
|
return 'httpd'
|
|
|
|
else:
|
|
|
|
return 'apache2'
|
|
|
|
|
|
|
|
|
|
|
|
def server_status(stdout):
|
|
|
|
proc_count = ""
|
|
|
|
|
|
|
|
for line in stdout:
|
|
|
|
if "Ncat: " not in line:
|
|
|
|
for k in line:
|
|
|
|
try:
|
|
|
|
proc_count = k.split(":")[1]
|
|
|
|
except Exception:
|
|
|
|
proc_count = 1
|
|
|
|
else:
|
|
|
|
proc_count = 0
|
|
|
|
return proc_count
|
|
|
|
|
|
|
|
|
|
|
|
def check_haproxy_config(server_ip):
|
|
|
|
server_id = sql.select_server_id_by_ip(server_ip=server_ip)
|
|
|
|
is_dockerized = sql.select_service_setting(server_id, 'haproxy', 'dockerized')
|
|
|
|
config_path = sql.get_setting('haproxy_config_path')
|
|
|
|
|
|
|
|
if is_dockerized == '1':
|
|
|
|
container_name = sql.get_setting('haproxy_container_name')
|
|
|
|
commands = [f"sudo docker exec -it {container_name} haproxy -q -c -f {config_path}"]
|
|
|
|
else:
|
|
|
|
commands = [f"haproxy -q -c -f {config_path}"]
|
|
|
|
|
2022-12-07 09:27:46 +00:00
|
|
|
with mod_ssh.ssh_connect(server_ip) as ssh:
|
2022-11-17 07:34:58 +00:00
|
|
|
for command in commands:
|
|
|
|
stdin, stdout, stderr = ssh.run_command(command)
|
|
|
|
if not stderr.read():
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def check_nginx_config(server_ip):
|
|
|
|
commands = [f"nginx -q -t -p {sql.get_setting('nginx_dir')}"]
|
|
|
|
|
2022-12-07 09:27:46 +00:00
|
|
|
with mod_ssh.ssh_connect(server_ip) as ssh:
|
2022-11-17 07:34:58 +00:00
|
|
|
for command in commands:
|
|
|
|
stdin, stdout, stderr = ssh.run_command(command)
|
|
|
|
if not stderr.read():
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
return False
|
2022-12-07 09:27:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
def overview_backends(server_ip: str, service: str) -> None:
|
|
|
|
from jinja2 import Environment, FileSystemLoader
|
|
|
|
|
2022-12-07 10:21:55 +00:00
|
|
|
import modules.config.config as config_mod
|
2022-12-07 09:27:46 +00:00
|
|
|
import modules.config.section as section_mod
|
|
|
|
import modules.roxywi.common as roxywi_common
|
|
|
|
|
2023-03-03 20:03:41 +00:00
|
|
|
env = Environment(loader=FileSystemLoader('templates/'), autoescape=True)
|
|
|
|
template = env.get_template('ajax/haproxyservers_backends.html')
|
2022-12-07 09:27:46 +00:00
|
|
|
format_file = 'cfg'
|
|
|
|
|
|
|
|
if service == 'haproxy':
|
|
|
|
configs_dir = get_config.get_config_var('configs', 'haproxy_save_configs_dir')
|
|
|
|
format_file = 'cfg'
|
|
|
|
elif service == 'keepalived':
|
|
|
|
configs_dir = get_config.get_config_var('configs', 'kp_save_configs_dir')
|
|
|
|
format_file = 'conf'
|
|
|
|
|
|
|
|
if service != 'nginx' and service != 'apache':
|
|
|
|
try:
|
|
|
|
sections = section_mod.get_sections(configs_dir + roxywi_common.get_files(configs_dir, format_file)[0],
|
|
|
|
service=service)
|
|
|
|
except Exception as e:
|
|
|
|
roxywi_common.logging('Roxy-WI server', str(e), roxywi=1)
|
|
|
|
|
|
|
|
try:
|
|
|
|
cfg = f"{configs_dir}{server_ip}-{get_date.return_date('config')}.{format_file}"
|
|
|
|
except Exception as e:
|
|
|
|
roxywi_common.logging('Roxy-WI server', f' Cannot generate a cfg path {e}', roxywi=1)
|
|
|
|
try:
|
|
|
|
if service == 'keepalived':
|
|
|
|
config_mod.get_config(server_ip, cfg, keepalived=1)
|
|
|
|
else:
|
|
|
|
config_mod.get_config(server_ip, cfg)
|
|
|
|
except Exception as e:
|
|
|
|
roxywi_common.logging('Roxy-WI server', f' Cannot download a config {e}', roxywi=1)
|
|
|
|
try:
|
|
|
|
sections = section_mod.get_sections(cfg, service=service)
|
|
|
|
except Exception as e:
|
|
|
|
roxywi_common.logging('Roxy-WI server', f' Cannot get sections from config file {e}', roxywi=1)
|
|
|
|
sections = 'Cannot get backends'
|
|
|
|
else:
|
|
|
|
sections = section_mod.get_remote_sections(server_ip, service)
|
|
|
|
|
|
|
|
template = template.render(backends=sections, serv=server_ip, service=service)
|
|
|
|
print(template)
|
|
|
|
|
|
|
|
|
|
|
|
def get_overview_last_edit(server_ip: str, service: str) -> None:
|
|
|
|
if service == 'nginx':
|
|
|
|
config_path = sql.get_setting('nginx_config_path')
|
|
|
|
elif service == 'keepalived':
|
|
|
|
config_path = sql.get_setting('keepalived_config_path')
|
|
|
|
else:
|
|
|
|
config_path = sql.get_setting('haproxy_config_path')
|
|
|
|
commands = ["ls -l %s |awk '{ print $6\" \"$7\" \"$8}'" % config_path]
|
|
|
|
try:
|
|
|
|
print(server_mod.ssh_command(server_ip, commands))
|
|
|
|
except Exception as e:
|
2022-12-07 09:59:39 +00:00
|
|
|
print(f'error: Cannot get last date {e} for server {server_ip}')
|
2022-12-07 09:27:46 +00:00
|
|
|
|
|
|
|
|
2022-12-07 09:59:39 +00:00
|
|
|
def overview_service(server_ip: str, server_id: int, name: str, service: str) -> None:
|
2022-12-07 09:27:46 +00:00
|
|
|
import asyncio
|
|
|
|
from jinja2 import Environment, FileSystemLoader
|
|
|
|
|
2023-03-03 20:03:41 +00:00
|
|
|
user_params = roxywi_common.get_users_params()
|
|
|
|
|
2022-12-07 09:27:46 +00:00
|
|
|
async def async_get_overviewServers(serv1, serv2, service):
|
|
|
|
if service == 'haproxy':
|
|
|
|
cmd = 'echo "show info" |nc %s %s -w 1|grep -e "node\|Nbproc\|Maxco\|MB\|Nbthread"' % (
|
|
|
|
serv2, sql.get_setting('haproxy_sock_port'))
|
|
|
|
out = server_mod.subprocess_execute(cmd)
|
|
|
|
return_out = ""
|
|
|
|
|
|
|
|
for k in out:
|
|
|
|
if "Ncat:" not in k:
|
|
|
|
for r in k:
|
|
|
|
return_out += r
|
|
|
|
return_out += "<br />"
|
|
|
|
else:
|
|
|
|
return_out = "Cannot connect to HAProxy"
|
|
|
|
else:
|
|
|
|
return_out = ''
|
|
|
|
|
|
|
|
server_status = (serv1, serv2, return_out)
|
|
|
|
return server_status
|
|
|
|
|
|
|
|
async def get_runner_overviewServers(**kwargs):
|
2023-03-03 20:03:41 +00:00
|
|
|
env = Environment(loader=FileSystemLoader('templates/'), extensions=['jinja2.ext.loopcontrols', 'jinja2.ext.do'])
|
|
|
|
template = env.get_template('ajax/overviewServers.html')
|
2022-12-07 09:27:46 +00:00
|
|
|
|
|
|
|
servers = []
|
|
|
|
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
|
|
|
|
user_id = cookie.get('uuid')
|
2023-03-03 20:03:41 +00:00
|
|
|
group_id = cookie.get('group')
|
|
|
|
group_id = int(group_id.value)
|
|
|
|
role = sql.get_user_role_by_uuid(user_id.value, group_id)
|
2022-12-07 09:27:46 +00:00
|
|
|
futures = [async_get_overviewServers(kwargs.get('server1'), kwargs.get('server2'), kwargs.get('service'))]
|
|
|
|
|
|
|
|
for i, future in enumerate(asyncio.as_completed(futures)):
|
|
|
|
result = await future
|
|
|
|
servers.append(result)
|
|
|
|
servers_sorted = sorted(servers, key=common.get_key)
|
2023-03-03 20:03:41 +00:00
|
|
|
template = template.render(service_status=servers_sorted, role=role, id=kwargs.get('id'), service_page=service, lang=user_params['lang'])
|
2022-12-07 09:27:46 +00:00
|
|
|
print(template)
|
|
|
|
|
|
|
|
ioloop = asyncio.get_event_loop()
|
2022-12-07 09:59:39 +00:00
|
|
|
ioloop.run_until_complete(get_runner_overviewServers(server1=name, server2=server_ip, id=server_id, service=service))
|
2022-12-07 09:27:46 +00:00
|
|
|
ioloop.close()
|
2022-12-07 09:59:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_stat_page(server_ip: str, service: str) -> None:
|
|
|
|
import requests
|
|
|
|
from jinja2 import Environment, FileSystemLoader
|
|
|
|
|
|
|
|
if service in ('nginx', 'apache'):
|
|
|
|
stats_user = sql.get_setting(f'{service}_stats_user')
|
|
|
|
stats_pass = sql.get_setting(f'{service}_stats_password')
|
|
|
|
stats_port = sql.get_setting(f'{service}_stats_port')
|
|
|
|
stats_page = sql.get_setting(f'{service}_stats_page')
|
|
|
|
else:
|
|
|
|
stats_user = sql.get_setting('stats_user')
|
|
|
|
stats_pass = sql.get_setting('stats_password')
|
|
|
|
stats_port = sql.get_setting('stats_port')
|
|
|
|
stats_page = sql.get_setting('stats_page')
|
|
|
|
try:
|
|
|
|
response = requests.get(f'http://{server_ip}:{stats_port}/{stats_page}', auth=(stats_user, stats_pass))
|
|
|
|
except requests.exceptions.ConnectTimeout:
|
|
|
|
print('error: Oops. Connection timeout occurred!')
|
|
|
|
except requests.exceptions.ReadTimeout:
|
|
|
|
print('error: Oops. Read timeout occurred')
|
|
|
|
except requests.exceptions.HTTPError as errh:
|
|
|
|
print("error: Http Error:", errh)
|
|
|
|
except requests.exceptions.ConnectionError as errc:
|
|
|
|
print('error: Error Connecting: %s' % errc)
|
|
|
|
except requests.exceptions.Timeout as errt:
|
|
|
|
print("error: Timeout Error:", errt)
|
|
|
|
except requests.exceptions.RequestException as err:
|
|
|
|
print("error: OOps: Something Else", err)
|
|
|
|
|
|
|
|
data = response.content
|
|
|
|
if service == 'nginx':
|
2023-03-25 09:01:26 +00:00
|
|
|
lang = roxywi_common.get_user_lang()
|
2022-12-07 09:59:39 +00:00
|
|
|
env = Environment(loader=FileSystemLoader('templates/'), autoescape=True)
|
|
|
|
template = env.get_template('ajax/nginx_stats.html')
|
|
|
|
|
|
|
|
servers_with_status = list()
|
|
|
|
h = ()
|
|
|
|
out1 = []
|
|
|
|
for k in data.decode('utf-8').split():
|
|
|
|
out1.append(k)
|
|
|
|
h = (out1,)
|
|
|
|
servers_with_status.append(h)
|
|
|
|
|
2023-03-25 09:01:26 +00:00
|
|
|
template = template.render(out=servers_with_status, lang=lang)
|
2022-12-07 09:59:39 +00:00
|
|
|
print(template)
|
|
|
|
else:
|
|
|
|
print(data.decode('utf-8'))
|
2023-01-02 20:01:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
def show_service_version(server_ip: str, service: str) -> None:
|
|
|
|
if service not in ('nginx', 'apache', 'haproxy'):
|
|
|
|
print('warning: wrong service')
|
|
|
|
return None
|
|
|
|
|
|
|
|
if service == 'haproxy':
|
|
|
|
print(check_haproxy_version(server_ip))
|
|
|
|
return None
|
|
|
|
|
|
|
|
server_id = sql.select_server_id_by_ip(server_ip)
|
|
|
|
service_name = service
|
|
|
|
is_dockerized = sql.select_service_setting(server_id, service, 'dockerized')
|
|
|
|
|
|
|
|
if service == 'apache':
|
|
|
|
service_name = get_correct_apache_service_name(None, server_id)
|
|
|
|
|
|
|
|
if is_dockerized == '1':
|
|
|
|
container_name = sql.get_setting(f'{service}_container_name')
|
|
|
|
if service == 'apache':
|
|
|
|
cmd = [f'docker exec -it {container_name} /usr/local/apache2/bin/httpd -v 2>&1|head -1|awk -F":" \'{{print $2}}\'']
|
|
|
|
else:
|
|
|
|
cmd = [f'docker exec -it {container_name} /usr/sbin/{service_name} -v 2>&1|head -1|awk -F":" \'{{print $2}}\'']
|
|
|
|
else:
|
|
|
|
cmd = [f'sudo /usr/sbin/{service_name} -v|head -1|awk -F":" \'{{print $2}}\'']
|
|
|
|
print(server_mod.ssh_command(server_ip, cmd))
|