import requests from flask import render_template, request import modules.db.sql as sql import modules.server.ssh as mod_ssh import modules.common.common as common import modules.server.server as server_mod import modules.roxywi.common as roxywi_common import modules.roxy_wi_tools as roxy_wi_tools import modules.config.section as section_mod time_zone = sql.get_setting('time_zone') get_date = roxy_wi_tools.GetDate(time_zone) get_config = roxy_wi_tools.GetConfigVar() 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}}'" output, stderr = server_mod.subprocess_execute(cmd) for line in output: ver = line return ver def is_restarted(server_ip: str, action: str) -> None: user_uuid = request.cookies.get('uuid') group_id = request.cookies.get('group') group_id = int(group_id) user_role = sql.get_user_role_by_uuid(user_uuid, group_id) if sql.is_serv_protected(server_ip) and int(user_role) > 2: raise Exception(f'error: This server is protected. You cannot {action} it') def is_not_allowed_to_restart(server_id: int, service: str) -> None: if service != 'waf': is_restart = sql.select_service_setting(server_id, service, 'restart') else: is_restart = 0 if int(is_restart) == 1: raise Exception('warning: This service is not allowed to be restarted') def get_exp_version(server_ip: str, service_name: str) -> str: server_ip = common.is_ip_or_dns(server_ip) if service_name == 'haproxy': commands = ["/opt/prometheus/exporters/haproxy_exporter --version 2>&1 |head -1|awk '{print $3}'"] elif service_name == 'nginx': commands = ["/opt/prometheus/exporters/nginx_exporter 2>&1 |head -1 |awk -F\"=\" '{print $2}'|awk '{print $1}'"] elif service_name == 'node': commands = ["node_exporter --version 2>&1 |head -1|awk '{print $3}'"] elif service_name == 'apache': commands = ["/opt/prometheus/exporters/apache_exporter --version 2>&1 |head -1|awk '{print $3}'"] elif service_name == 'keepalived': commands = ["keepalived_exporter --version 2>&1 |head -1|awk '{print $2}'"] 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=None) -> 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) except Exception as e: raise Exception(f'error: cannot get server info: {e}') 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}"] try: with mod_ssh.ssh_connect(server_ip) as ssh: for command in commands: stdin, stdout, stderr = ssh.run_command(command, timeout=5) if not stderr.read(): return True else: return False except Exception as e: print(f'error: {e}') def check_nginx_config(server_ip): commands = [f"nginx -q -t -p {sql.get_setting('nginx_dir')}"] with mod_ssh.ssh_connect(server_ip) as ssh: for command in commands: stdin, stdout, stderr = ssh.run_command(command) if not stderr.read(): return True else: return False def overview_backends(server_ip: str, service: str) -> None: import modules.config.config as config_mod lang = roxywi_common.get_user_lang_for_flask() 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', 'keepalived_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) return render_template('ajax/haproxyservers_backends.html', backends=sections, serv=server_ip, service=service, lang=lang) def get_overview_last_edit(server_ip: str, service: str) -> str: 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: return server_mod.ssh_command(server_ip, commands) except Exception as e: return f'error: Cannot get last date {e} for server {server_ip}' def get_stat_page(server_ip: str, service: str) -> str: 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: return 'error: Oops. Connection timeout occurred!' except requests.exceptions.ReadTimeout: return 'error: Oops. Read timeout occurred' except requests.exceptions.HTTPError as errh: return f'error: Http Error: {errh}' except requests.exceptions.ConnectionError as errc: return f'error: Error Connecting: {errc}' except requests.exceptions.Timeout as errt: return f'error: Timeout Error: {errt}' except requests.exceptions.RequestException as err: return f'error: OOps: Something Else {err}' data = response.content if service == 'nginx': lang = roxywi_common.get_user_lang_for_flask() servers_with_status = list() h = () out1 = [] for k in data.decode('utf-8').split(): out1.append(k) h = (out1,) servers_with_status.append(h) return render_template('ajax/nginx_stats.html', out=servers_with_status, lang=lang) else: return data.decode('utf-8') def show_service_version(server_ip: str, service: str) -> None: if service == 'haproxy': return check_haproxy_version(server_ip) 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}}\''] return server_mod.ssh_command(server_ip, cmd)