diff --git a/app/modules/server/server.py b/app/modules/server/server.py index 3c4d493e..cba04670 100644 --- a/app/modules/server/server.py +++ b/app/modules/server/server.py @@ -62,6 +62,19 @@ def subprocess_execute(cmd): return output, stderr +def subprocess_execute_with_rc(cmd): + import subprocess + + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, universal_newlines=True) + stdout, stderr = p.communicate() + output = stdout.splitlines() + rc = p.returncode + + return_out = {'output': output, 'error': stderr, 'rc': rc} + + return return_out + + def is_file_exists(server_ip: str, file: str) -> bool: cmd = [f'[ -f {file} ] && echo yes || echo no'] @@ -110,8 +123,8 @@ def get_system_info(server_ip: str) -> str: except Exception as e: raise e - if 'command not found' in sys_info_returned: - raise Exception(f' You should install lshw on the server {server_ip}. Update System info after installation.') + if 'not found' in sys_info_returned: + raise Exception(f'You should install lshw on the server {server_ip}. Update System info after installation.') try: os_info = ssh_command(server_ip, command1) diff --git a/app/modules/server/ssh.py b/app/modules/server/ssh.py index 4df70bea..52396cb7 100644 --- a/app/modules/server/ssh.py +++ b/app/modules/server/ssh.py @@ -95,6 +95,10 @@ def upload_ssh_key(name: str, user_group: str, key: str) -> bool: print('error: nice try') return False + if name == '': + print('error: please select credentials first') + return False + try: key = paramiko.pkey.load_private_key(key) except Exception as e: diff --git a/app/modules/service/common.py b/app/modules/service/common.py index 82e58051..ac0c1e1b 100644 --- a/app/modules/service/common.py +++ b/app/modules/service/common.py @@ -276,6 +276,7 @@ def get_stat_page(server_ip: str, service: str) -> None: data = response.content if service == 'nginx': + lang = roxywi_common.get_user_lang() env = Environment(loader=FileSystemLoader('templates/'), autoescape=True) template = env.get_template('ajax/nginx_stats.html') @@ -287,7 +288,7 @@ def get_stat_page(server_ip: str, service: str) -> None: h = (out1,) servers_with_status.append(h) - template = template.render(out=servers_with_status) + template = template.render(out=servers_with_status, lang=lang) print(template) else: print(data.decode('utf-8')) diff --git a/app/modules/service/installation.py b/app/modules/service/installation.py index 446e73f8..23991f78 100644 --- a/app/modules/service/installation.py +++ b/app/modules/service/installation.py @@ -10,21 +10,22 @@ from modules.server.ssh import return_ssh_keys_path form = common.form -def show_installation_output(error: str, output: str, service: str) -> bool: +def show_installation_output(error: str, output: str, service: str, rc=0) -> bool: if error and "WARNING" not in error: roxywi_common.logging('Roxy-WI server', error, roxywi=1) print('error: ' + error) return False else: - for line in output: - if any(s in line for s in ("Traceback", "FAILED", "error", "ERROR", "UNREACHABLE")): - try: - correct_out = line.split('=>') - print(f'error: {correct_out[1]}') - break - except Exception: - print(output) - break + if rc != 0: + for line in output: + if any(s in line for s in ("Traceback", "FAILED", "error", "ERROR", "UNREACHABLE")): + try: + correct_out = line.split('=>') + print(f'error: {correct_out[1]}') + break + except Exception: + print(output) + break else: from jinja2 import Environment, FileSystemLoader env = Environment(loader=FileSystemLoader('templates/'), autoescape=True) @@ -70,13 +71,14 @@ def install_haproxy(server_ip: str, **kwargs): f"KEY={ssh_settings['key']}" ] - output, error = server_mod.subprocess_execute(commands[0]) if server_for_installing: service = server_for_installing + ' HAProxy' else: service = ' HAProxy' - if show_installation_output(error, output, service): + return_out = server_mod.subprocess_execute_with_rc(commands[0]) + + if show_installation_output(return_out['error'], return_out['output'], service, rc=return_out['rc']): sql.update_haproxy(server_ip) if docker == '1': @@ -107,9 +109,9 @@ def waf_install(server_ip: str): f"KEY={ssh_settings['key']}" ] - output, error = server_mod.subprocess_execute(commands[0]) + return_out = server_mod.subprocess_execute_with_rc(commands[0]) - if show_installation_output(error, output, service): + if show_installation_output(return_out['error'], return_out['output'], service, rc=return_out['rc']): sql.insert_waf_metrics_enable(server_ip, "0") sql.insert_waf_rules(server_ip) @@ -134,9 +136,9 @@ def waf_nginx_install(server_ip: str): f"HOST={server_ip} USER={ssh_settings['user']} PASS='{ssh_settings['password']}' KEY={ssh_settings['key']}" ] - output, error = server_mod.subprocess_execute(commands[0]) + return_out = server_mod.subprocess_execute_with_rc(commands[0]) - if show_installation_output(error, output, service): + if show_installation_output(return_out['error'], return_out['output'], service, rc=return_out['rc']): sql.insert_nginx_waf_rules(server_ip) sql.insert_waf_nginx_server(server_ip) @@ -183,7 +185,7 @@ def install_service(server_ip: str, service: str, docker: str, **kwargs) -> None if server_for_installing: service_name = f'{server_for_installing} {service.title()}' else: - service_name = service.title + service_name = service.title() if show_installation_output(error, output, service_name): if service == 'nginx': @@ -226,10 +228,9 @@ def geoip_installation(): f"PASS={ssh_settings['password']} KEY={ssh_settings['key']}" ] - output, error = server_mod.subprocess_execute(commands[0]) - - show_installation_output(error, output, 'GeoLite2 Database') + return_out = server_mod.subprocess_execute_with_rc(commands[0]) + show_installation_output(return_out['error'], return_out['output'], 'GeoLite2 Database', rc=return_out['rc']) os.remove(script) @@ -296,9 +297,9 @@ def keepalived_master_install(): f"USER={ssh_settings['user']} PASS='{ssh_settings['password']}' KEY={ssh_settings['key']}" ] - output, error = server_mod.subprocess_execute(commands[0]) + return_out = server_mod.subprocess_execute_with_rc(commands[0]) - if show_installation_output(error, output, 'master Keepalived'): + if show_installation_output(return_out['error'], return_out['output'], 'master Keepalived', rc=return_out['rc']): sql.update_keepalived(master) if virt_server != '0': @@ -340,10 +341,9 @@ def keepalived_slave_install(): f"NGINX={nginx} HOST={slave} USER={ssh_settings['user']} PASS='{ssh_settings['password']}' KEY={ssh_settings['key']}" ] - output, error = server_mod.subprocess_execute(commands[0]) - - show_installation_output(error, output, 'slave Keepalived') + return_out = server_mod.subprocess_execute_with_rc(commands[0]) + show_installation_output(return_out['error'], return_out['output'], 'slave Keepalived', rc=return_out['rc']) os.remove(script) sql.update_server_master(master, slave) sql.update_keepalived(slave) @@ -375,9 +375,9 @@ def keepalived_masteradd(): f"PASS='{ssh_settings['password']}' KEY={ssh_settings['key']}" ] - output, error = server_mod.subprocess_execute(commands[0]) + return_out = server_mod.subprocess_execute_with_rc(commands[0]) - show_installation_output(error, output, 'master VRRP address') + show_installation_output(return_out['error'], return_out['output'], 'master VRRP address', rc=return_out['rc']) os.remove(script) @@ -405,8 +405,6 @@ def keepalived_slaveadd(): f"router_id={router_id} USER={ssh_settings['user']} PASS='{ssh_settings['password']}' KEY={ssh_settings['key']}" ] - output, error = server_mod.subprocess_execute(commands[0]) - - show_installation_output(error, output, 'slave VRRP address') - + return_out = server_mod.subprocess_execute_with_rc(commands[0]) + show_installation_output(return_out['error'], return_out['output'], 'slave VRRP address', rc=return_out['rc']) os.remove(script) diff --git a/app/scripts/ansible/roles/keepalived/templates/add_vrrp.conf.j2 b/app/scripts/ansible/roles/keepalived/templates/add_vrrp.conf.j2 index 2303a8f0..ed1905de 100644 --- a/app/scripts/ansible/roles/keepalived/templates/add_vrrp.conf.j2 +++ b/app/scripts/ansible/roles/keepalived/templates/add_vrrp.conf.j2 @@ -1,7 +1,9 @@ vrrp_instance VI_{{IP}} { state {{MASTER}} interface {% if MASTER == 'MASTER' %}{{ETH}} {% else %} {{ETH_SLAVE}} {% endif %} + virtual_router_id {{ router_id }} + priority {% if RETURN_TO_MASTER == 1 and MASTER == 'MASTER' %}152{% elif MASTER == 'MASTER' and RETURN_TO_MASTER == 0 %}102{% else %}101{%endif%} track_script { diff --git a/app/scripts/ansible/roles/keepalived_exporter/tasks/preflight.yml b/app/scripts/ansible/roles/keepalived_exporter/tasks/preflight.yml index 78e9440b..4b85aa1b 100644 --- a/app/scripts/ansible/roles/keepalived_exporter/tasks/preflight.yml +++ b/app/scripts/ansible/roles/keepalived_exporter/tasks/preflight.yml @@ -37,8 +37,6 @@ - name: Gather currently installed keepalived_exporter version (if any) command: "{{ keepalived_exporter_binary_install_dir }}/keepalived_exporter --version" - args: - warn: false changed_when: false register: __keepalived_exporter_current_version_output check_mode: false diff --git a/app/scripts/ansible/roles/node_exporter/tasks/preflight.yml b/app/scripts/ansible/roles/node_exporter/tasks/preflight.yml index aff6395d..754ebcdf 100644 --- a/app/scripts/ansible/roles/node_exporter/tasks/preflight.yml +++ b/app/scripts/ansible/roles/node_exporter/tasks/preflight.yml @@ -61,8 +61,6 @@ - name: Gather currently installed node_exporter version (if any) command: "{{ _node_exporter_binary_install_dir }}/node_exporter --version" - args: - warn: false changed_when: false register: __node_exporter_current_version_output check_mode: false diff --git a/app/scripts/ansible/roles/waf/tasks/main.yml b/app/scripts/ansible/roles/waf/tasks/main.yml index de985e25..9a753170 100644 --- a/app/scripts/ansible/roles/waf/tasks/main.yml +++ b/app/scripts/ansible/roles/waf/tasks/main.yml @@ -59,7 +59,7 @@ state: latest when: - ansible_facts['os_family'] == "RedHat" or ansible_facts['os_family'] == 'CentOS' - - ansible_facts['distribution_major_version'] == '8' + - ansible_facts['distribution_major_version'] == '9' environment: http_proxy: "{{PROXY}}" https_proxy: "{{PROXY}}" diff --git a/app/templates/ajax/nginx_stats.html b/app/templates/ajax/nginx_stats.html index 9a2faffc..e906be9c 100644 --- a/app/templates/ajax/nginx_stats.html +++ b/app/templates/ajax/nginx_stats.html @@ -1,3 +1,4 @@ +{% import 'languages/'+lang|default('en')+'.html' as lang %} {% for l in out %} - +
- NGINX status + NGINX {{lang.words.status}}
- +
{{l.0.0}} {{l.0.1}} @@ -116,7 +117,7 @@ u:hover div.tips {visibility:visible;}
-
- You can read the description about statuses here +
+ {{lang.phrases.read_desc_statuses}} {{lang.words.here}}
{% endfor %} diff --git a/app/templates/include/intro/ovw.html b/app/templates/include/intro/ovw.html index 0548acd5..c540c402 100644 --- a/app/templates/include/intro/ovw.html +++ b/app/templates/include/intro/ovw.html @@ -28,6 +28,7 @@ title: "Dashboard #3", intro: "Roxy-WI services status", }, + {% if role == 1 %} { element: document.querySelector('#overview-users'), title: "Dashboard #4", @@ -39,14 +40,30 @@ intro: "Group list", }, { - element: document.querySelector('#overview-logs'), + element: document.querySelector('#overview-roles'), title: "Dashboard #6", + intro: "Roles description", + }, + {% endif %} + {% if role < 3 %} + {% if role > 1 %} + {% set board_id = 4 %} + {% else %} + {% set board_id = 7 %} + {% endif %} + { + element: document.querySelector('#overview-logs'), + title: "Dashboard #{{ board_id }}", intro: "Last log entries", }, + {% endif %} + {% if role == 1 %} { element: document.querySelector('#overview-subs'), + title: "Dashboard #8", intro: "Subscription info", }, + {% endif %} { element: document.querySelector('#version'), intro: "Your Roxy-WI version", diff --git a/app/templates/languages/en.html b/app/templates/languages/en.html index 04754fa9..778bf255 100644 --- a/app/templates/languages/en.html +++ b/app/templates/languages/en.html @@ -298,6 +298,8 @@ "comparing_config": "Comparing config files", "select_older_config": "Select an older config", "select_newer_config": "Select a newer config", + "not_checked": "Without check", + "show_not_checked": "Show servers without checking", } %} {% set roles = { @@ -400,7 +402,7 @@ "before_install": "Before installing any exporters, first install", "been_installed": "servers have been installed", "there_are_no": "There are no Grafana and Prometheus servers", - "country_codes": "country codes", + "country_codes": "Country codes", "smon_desc": "SMON stands for Simple MONitoring", "checker_desc": "Checker is designed for monitoring HAProxy, Nginx, Apache and Keepalived services as well as HAProxy backends and maxconn", "auto_start_desc": "The Auto Start service allows to restart the HAProxy, NGINX, Apache and Keepalived services if they are down", @@ -440,6 +442,7 @@ "BODY_FAILURE": "BODY FAILURE", "UNKNOWN": "UNKNOWN", "PORT_DOWN": "PORT DOWN", + "DISABLED": "DISABLED", } } %} @@ -550,7 +553,7 @@ "role": "role", "roles": "roles", "subs": "subscription", - "show_all": "show all", + "show_all": "Show all", "plan": "plan", "pay_method": "pay method", "active": "active", @@ -828,5 +831,7 @@ "additions": "additions", "deletions": "deletions", "recent": "recent", + "already": "already", + "disable": "disable", } %} diff --git a/app/templates/languages/fr.html b/app/templates/languages/fr.html index 1f06eafe..eca1bd89 100644 --- a/app/templates/languages/fr.html +++ b/app/templates/languages/fr.html @@ -298,6 +298,8 @@ "comparing_config": "Comparer les fichiers de configuration", "select_older_config": "Sélectionnez une ancienne configuration", "select_newer_config": "Sélectionnez une configuration plus récente", + "not_checked": "Sans chèque", + "show_not_checked": "Afficher les serveurs sans vérifier", } %} {% set roles = { @@ -400,7 +402,7 @@ "before_install": "Avant d\'installer l\'Exporter, installez le d\'abord", "been_installed": "les serveurs ont été installés", "there_are_no": "Il n\'y a pas de serveurs Grafana ni Prometheus.", - "country_codes": "codes des pays", + "country_codes": "Сodes des pays", "smon_desc": "SMON stands for Simple MONitoring", "checker_desc": "Checker est conçu pour surveiller les services HAProxy, Nginx, Apache et Keepalived ainsi que les backends HAProxy et maxconn.", "auto_start_desc": "Le service Auto Start permet de redémarrer les services HAProxy, NGINX, Apache et Keepalived s\'ils sont hors service.", @@ -440,6 +442,7 @@ "BODY_FAILURE": " DÉFAILLANCE DU CORPS", "UNKNOWN": "INCONNU", "PORT_DOWN": "PORT DOWN", + "DISABLED": "DÉSACTIVÉ", } } %} @@ -550,7 +553,7 @@ "role": "rôle", "roles": "rôles", "subs": "abonnement", - "show_all": "tout afficher", + "show_all": "Tout afficher", "plan": "plan", "pay_method": "méthode de paiement", "active": "actif", @@ -828,5 +831,7 @@ "additions": "ajouts", "deletions": "suppressions", "recent": "récent", + "already": "déjà", + "disable": "désactiver", } %} diff --git a/app/templates/languages/pt-br.html b/app/templates/languages/pt-br.html index c2667dd9..855ba004 100644 --- a/app/templates/languages/pt-br.html +++ b/app/templates/languages/pt-br.html @@ -298,6 +298,8 @@ "comparing_config": "Comparando arquivos de configuração", "select_older_config": "Selecione uma configuração mais antiga", "select_newer_config": "Selecione uma configuração mais nova", + "not_checked": "Sem cheque", + "show_not_checked": "Mostrar servidores sem verificar", } %} {% set roles = { @@ -400,7 +402,7 @@ "before_install": "Antes de instalar exportadores, primeiro instale", "been_installed": "servidores instalados", "there_are_no": "Não há servidores Grafana e Prometheus", - "country_codes": "códigos de país", + "country_codes": "Códigos de país", "smon_desc": "SMON significa Simple MONitoring", "checker_desc": "O Checker foi projetado para monitorar serviços HAProxy, Nginx, Apache e Keepalived, bem como backends HAProxy e maxconn", "auto_start_desc": "O serviços Auto Start permite reiniciar os serviços HAProxy, NGINX, Apache e Keepalived se estiverem inoperantes", @@ -440,6 +442,7 @@ "BODY_FAILURE": "BODY FAILURE", "UNKNOWN": "UNKNOWN", "PORT_DOWN": "PORT DOWN", + "DISABLED": "DESABIL.", } } %} @@ -550,7 +553,7 @@ "role": "função", "roles": "funções", "subs": "inscrição", - "show_all": "mostrar tudo", + "show_all": "Mostrar tudo", "plan": "plan", "pay_method": "método de pagamento.", "active": "ativo", @@ -827,6 +830,8 @@ "send": "enviar", "additions": "adicionados", "deletions": "apagados", - "recent": "recente" + "recent": "recente", + "already": "já", + "disable": "desabilitar", } %} diff --git a/app/templates/languages/ru.html b/app/templates/languages/ru.html index 5625304b..0eb3df0e 100644 --- a/app/templates/languages/ru.html +++ b/app/templates/languages/ru.html @@ -298,6 +298,8 @@ "comparing_config": "Сравнение файлов конфигурации", "select_older_config": "Выберите более старую конфигурацию", "select_newer_config": "Выберите более новую конфигурацию", + "not_checked": "Без проверки", + "show_not_checked": "Показать сервера без проверки", } %} {% set roles = { @@ -400,7 +402,7 @@ "before_install": "Прежде чем устанавливать какие-либо экспортеры, сначала установите", "been_installed": "сервера были установлены", "there_are_no": "Нет серверов Grafana и Prometheus", - "country_codes": "коды стран", + "country_codes": "Коды стран", "smon_desc": "SMON означает Sпростой MONиторинг.", "checker_desc": "Checker предназначен для мониторинга сервисов HAProxy, Nginx, Apache и Keepalived, а также бэкендов HAProxy и maxconn.", "auto_start_desc": "Служба автозапуска позволяет перезапустить службы HAProxy, NGINX, Apache и Keepalived, если они не работают.", @@ -422,7 +424,7 @@ "smon_is_not_run": "SMON сервис не запущен.", "run_smon": "Запустить сервис SMON", "not_installed": "Вы еще не установили сервис SMON", - "not_added": "Вы еще не добавили сервера в SMON", + "not_added": "Вы еще не добавили серверы в SMON", "create_server": "Создайте Ваш первый сервер", "see_check": "чтобы посмотреть проверки, которые были добавлены", "do_not_sort": "Не сортировать", @@ -440,6 +442,7 @@ "BODY_FAILURE": "ОШИБКА ТЕЛА", "UNKNOWN": "НЕИЗВЕСТНО", "PORT_DOWN": "ПОРТ НЕ ДОСТ.", + "DISABLED": "ОТКЛ.", } } %} @@ -506,7 +509,7 @@ "users": "пользователи", "users2": "пользователями", "username": "пользователь", - "servers": "сервера", + "servers": "серверы", "servers2": "серверами", "creds": "учетные данные", "creds2": "учетными данными", @@ -550,7 +553,7 @@ "role": "роль", "roles": "роли", "subs": "подписка", - "show_all": "показать все", + "show_all": "Показать все", "plan": "план", "pay_method": "платежный метод", "active": "активный", @@ -654,7 +657,7 @@ "every": "каждых", "every2": "каждую", "every3": "каждый", - "hide": "убрать", + "hide": "скрыть", "average": "Среднее количество", "peak": "пиковые", "connect": "подключиться", @@ -828,5 +831,7 @@ "additions": "дополнения", "deletions": "удаления", "recent": "недавние", + "already": "уже", + "disable": "отключить", } %}