From f981819505f7a1673835d6ef9522acf517f4d03f Mon Sep 17 00:00:00 2001 From: Aidaho Date: Fri, 16 Feb 2024 09:50:27 +0300 Subject: [PATCH] v7.2.0.0 Changelog: https://roxy-wi.org/changelog#7.2.0 --- app/create_db.py | 59 +- app/login.py | 2 +- app/middleware.py | 2 +- app/modules/db/db_model.py | 22 +- app/modules/db/smon.py | 639 +++++++++++++++ app/modules/db/sql.py | 736 +----------------- app/modules/server/server.py | 36 +- app/modules/service/installation.py | 4 + app/modules/tools/smon.py | 171 +++- app/modules/tools/smon_agent.py | 210 +++++ app/routes/add/routes.py | 4 + app/routes/logs/routes.py | 3 +- app/routes/smon/__init__.py | 1 + app/routes/smon/agent_routes.py | 169 ++++ app/routes/smon/routes.py | 248 +++--- app/static/css/smon.css | 3 + app/static/css/style-6.3.9.css | 36 +- app/templates/ajax/show_services_ovw.html | 2 +- app/templates/ajax/smon/agent.html | 51 ++ app/templates/ajax/smon/check.html | 111 +++ app/templates/ajax/smon/show_new_smon.html | 16 - app/templates/ajax/smon/smon_dashboard.html | 137 +--- app/templates/include/admin_settings.html | 10 +- app/templates/include/main_menu.html | 6 +- app/templates/include/smon/add_form.html | 162 ++++ .../include/smon/smon_dns_server.html | 105 --- app/templates/include/smon/smon_history.html | 14 +- .../include/smon/smon_http_server.html | 101 --- .../include/smon/smon_ping_server.html | 92 --- .../include/smon/smon_tcp_server.html | 92 --- app/templates/languages/en.html | 22 +- app/templates/languages/fr.html | 22 +- app/templates/languages/pt-br.html | 22 +- app/templates/languages/ru.html | 22 +- app/templates/logs_internal.html | 6 +- app/templates/smon/add.html | 294 ------- app/templates/smon/agent.html | 79 ++ app/templates/smon/dashboard.html | 16 +- inc/admin_settings.js | 3 + inc/script.js | 14 +- inc/smon.js | 680 +++++++++++----- inc/users.js | 8 +- 42 files changed, 2420 insertions(+), 2012 deletions(-) create mode 100644 app/modules/db/smon.py create mode 100644 app/modules/tools/smon_agent.py create mode 100644 app/routes/smon/agent_routes.py create mode 100644 app/templates/ajax/smon/agent.html create mode 100644 app/templates/ajax/smon/check.html delete mode 100644 app/templates/ajax/smon/show_new_smon.html create mode 100644 app/templates/include/smon/add_form.html delete mode 100644 app/templates/include/smon/smon_dns_server.html delete mode 100644 app/templates/include/smon/smon_http_server.html delete mode 100644 app/templates/include/smon/smon_ping_server.html delete mode 100644 app/templates/include/smon/smon_tcp_server.html delete mode 100644 app/templates/smon/add.html create mode 100644 app/templates/smon/agent.html diff --git a/app/create_db.py b/app/create_db.py index fcb1c60a..747cefcb 100644 --- a/app/create_db.py +++ b/app/create_db.py @@ -54,16 +54,18 @@ def default_values(): {'param': 'ldap_user_attribute', 'value': 'userPrincipalName', 'section': 'ldap', 'desc': 'Attribute to search users by', 'group': '1'}, {'param': 'ldap_search_field', 'value': 'mail', 'section': 'ldap', 'desc': 'User\'s email address', 'group': '1'}, {'param': 'ldap_type', 'value': '0', 'section': 'ldap', 'desc': 'Use LDAPS', 'group': '1'}, - {'param': 'smon_check_interval', 'value': '1', 'section': 'monitoring', 'desc': 'Check interval for SMON (in minutes)', 'group': '1'}, {'param': 'port_scan_interval', 'value': '5', 'section': 'monitoring', 'desc': 'Check interval for Port scanner (in minutes)', 'group': '1'}, {'param': 'portscanner_keep_history_range', 'value': '14', 'section': 'monitoring', 'desc': 'Retention period for Port scanner history', 'group': '1'}, - {'param': 'smon_keep_history_range', 'value': '14', 'section': 'monitoring', 'desc': 'Retention period for SMON history', 'group': '1'}, + {'param': 'smon_keep_history_range', 'value': '14', 'section': 'smon', 'desc': 'Retention period for SMON history', 'group': '1'}, {'param': 'checker_keep_history_range', 'value': '14', 'section': 'monitoring', 'desc': 'Retention period for Checker history', 'group': '1'}, {'param': 'action_keep_history_range', 'value': '30', 'section': 'monitoring', 'desc': 'Retention period for Action history', 'group': '1'}, {'param': 'checker_maxconn_threshold', 'value': '90', 'section': 'monitoring', 'desc': 'Threshold value for alerting, in %', 'group': '1'}, {'param': 'checker_check_interval', 'value': '1', 'section': 'monitoring', 'desc': 'Check interval for Checker (in minutes)', 'group': '1'}, - {'param': 'smon_ssl_expire_warning_alert', 'value': '14', 'section': 'monitoring', 'desc': 'Warning alert about a SSL certificate expiration (in days)', 'group': '1'}, - {'param': 'smon_ssl_expire_critical_alert', 'value': '7', 'section': 'monitoring', 'desc': 'Critical alert about a SSL certificate expiration (in days)', 'group': '1'}, + {'param': 'smon_ssl_expire_warning_alert', 'value': '14', 'section': 'smon', 'desc': 'Warning alert about a SSL certificate expiration (in days)', 'group': '1'}, + {'param': 'smon_ssl_expire_critical_alert', 'value': '7', 'section': 'smon', 'desc': 'Critical alert about a SSL certificate expiration (in days)', 'group': '1'}, + {'param': 'master_ip', 'value': '', 'section': 'smon', 'desc': '', 'group': '1'}, + {'param': 'master_port', 'value': '5100', 'section': 'smon', 'desc': '', 'group': '1'}, + {'param': 'agent_port', 'value': '5101', 'section': 'smon', 'desc': '', 'group': '1'}, {'param': 'rabbitmq_host', 'value': '127.0.0.1', 'section': 'rabbitmq', 'desc': 'RabbitMQ-server host', 'group': '1'}, {'param': 'rabbitmq_port', 'value': '5672', 'section': 'rabbitmq', 'desc': 'RabbitMQ-server port', 'group': '1'}, {'param': 'rabbitmq_port', 'value': '5672', 'section': 'rabbitmq', 'desc': 'RabbitMQ-server port', 'group': '1'}, @@ -682,9 +684,54 @@ def update_db_v_7_1_2_1(): print("An error occurred:", e) +def update_db_v_7_2_0(): + try: + if mysql_enable: + migrate( + migrator.add_column('smon_ping_check', 'interval', IntegerField(default=120)), + migrator.add_column('smon_http_check', 'interval', IntegerField(default=120)), + migrator.add_column('smon_tcp_check', 'interval', IntegerField(default=120)), + migrator.add_column('smon_dns_check', 'interval', IntegerField(default=120)), + migrator.add_column('smon_ping_check', 'agent_id', IntegerField(default=1)), + migrator.add_column('smon_http_check', 'agent_id', IntegerField(default=1)), + migrator.add_column('smon_tcp_check', 'agent_id', IntegerField(default=1)), + migrator.add_column('smon_dns_check', 'agent_id', IntegerField(default=1)) + ) + else: + migrate( + migrator.add_column('smon_ping_check', 'interval', IntegerField(constraints=[SQL('DEFAULT 120')])), + migrator.add_column('smon_http_check', 'interval', IntegerField(constraints=[SQL('DEFAULT 120')])), + migrator.add_column('smon_tcp_check', 'interval', IntegerField(constraints=[SQL('DEFAULT 120')])), + migrator.add_column('smon_dns_check', 'interval', IntegerField(constraints=[SQL('DEFAULT 120')])), + migrator.add_column('smon_ping_check', 'agent_id', IntegerField(constraints=[SQL('DEFAULT 1')])), + migrator.add_column('smon_http_check', 'agent_id', IntegerField(constraints=[SQL('DEFAULT 1')])), + migrator.add_column('smon_tcp_check', 'agent_id', IntegerField(constraints=[SQL('DEFAULT 1')])), + migrator.add_column('smon_dns_check', 'agent_id', IntegerField(constraints=[SQL('DEFAULT 1')])) + ) + except Exception as e: + if e.args[0] == 'duplicate column name: agent_id' or str(e) == '(1060, "Duplicate column name \'agent_id\'")': + print('Updating... DB has been updated to version 7.2.0') + elif e.args[0] == 'duplicate column name: interval' or str(e) == '(1060, "Duplicate column name \'interval\'")': + print('Updating... DB has been updated to version 7.2.0') + else: + print("An error occurred:", e) + + +def update_db_v_7_2_0_1(): + try: + Setting.delete().where(Setting.param == 'smon_check_interval').execute() + Setting.delete().where((Setting.param == 'smon_keep_history_range') & (Setting.section == 'monitoring')).execute() + Setting.delete().where((Setting.param == 'smon_ssl_expire_warning_alert') & (Setting.section == 'monitoring')).execute() + Setting.delete().where((Setting.param == 'smon_ssl_expire_critical_alert') & (Setting.section == 'monitoring')).execute() + except Exception as e: + print("An error occurred:", e) + else: + print("Updating... DB has been updated to version 7.2.0-1") + + def update_ver(): try: - Version.update(version='7.1.2.0').execute() + Version.update(version='7.2.0.0').execute() except Exception: print('Cannot update version') @@ -718,6 +765,8 @@ def update_all(): update_db_v_6_3_18() update_db_v_7_1_2() update_db_v_7_1_2_1() + update_db_v_7_2_0() + update_db_v_7_2_0_1() update_ver() diff --git a/app/login.py b/app/login.py index 61e6c272..26803a69 100644 --- a/app/login.py +++ b/app/login.py @@ -13,7 +13,7 @@ import app.modules.roxy_wi_tools as roxy_wi_tools def check_login(): if request.endpoint not in ( 'login_page', 'static', 'main.show_roxywi_version', 'service.check_service', 'smon.show_smon_status_page', - 'smon.smon_history_statuses' + 'smon.smon_history_statuses', 'smon.agent_get_checks', 'smon.get_check_status' ): try: user_params = roxywi_common.get_users_params() diff --git a/app/middleware.py b/app/middleware.py index b9d170db..35fbff50 100644 --- a/app/middleware.py +++ b/app/middleware.py @@ -10,7 +10,7 @@ def check_services(fn): @wraps(fn) def decorated_view(*args, **kwargs): service = kwargs['service'] - if service not in ('haproxy', 'nginx', 'apache', 'keepalived', 'cluster'): + if service not in ('haproxy', 'nginx', 'apache', 'keepalived', 'cluster', 'waf'): abort(405, 'Wrong service') if not roxywi_auth.is_access_permit_to_service(service): abort(403, f'You do not have needed permissions to access to {service.title()} service') diff --git a/app/modules/db/db_model.py b/app/modules/db/db_model.py index 7e09e17d..6acfec95 100644 --- a/app/modules/db/db_model.py +++ b/app/modules/db/db_model.py @@ -573,10 +573,24 @@ class SmonHistory(BaseModel): primary_key = False +class SmonAgent(BaseModel): + id = AutoField() + server_id = ForeignKeyField(Server, on_delete='Cascade') + name = CharField() + uuid = CharField() + enabled = IntegerField(constraints=[SQL('DEFAULT 1')]) + desc = CharField() + + class Meta: + table_name = 'smon_agents' + + class SmonTcpCheck(BaseModel): smon_id = ForeignKeyField(SMON, on_delete='Cascade', unique=True) ip = CharField() port = IntegerField() + interval = IntegerField(constraints=[SQL('DEFAULT 120')]) + agent_id = IntegerField(constraints=[SQL('DEFAULT 1')]) class Meta: table_name = 'smon_tcp_check' @@ -589,6 +603,8 @@ class SmonHttpCheck(BaseModel): method = CharField(constraints=[SQL('DEFAULT "get"')]) accepted_status_codes = CharField(constraints=[SQL('DEFAULT "200"')]) body = CharField(null=True) + interval = IntegerField(constraints=[SQL('DEFAULT 120')]) + agent_id = IntegerField(constraints=[SQL('DEFAULT 1')]) class Meta: table_name = 'smon_http_check' @@ -599,6 +615,8 @@ class SmonPingCheck(BaseModel): smon_id = ForeignKeyField(SMON, on_delete='Cascade', unique=True) ip = CharField() packet_size = IntegerField(constraints=[SQL('DEFAULT 56')]) + interval = IntegerField(constraints=[SQL('DEFAULT 120')]) + agent_id = IntegerField(constraints=[SQL('DEFAULT 1')]) class Meta: table_name = 'smon_ping_check' @@ -611,6 +629,8 @@ class SmonDnsCheck(BaseModel): port = IntegerField(constraints=[SQL('DEFAULT 53')]) resolver = CharField() record_type = CharField() + interval = IntegerField(constraints=[SQL('DEFAULT 120')]) + agent_id = IntegerField(constraints=[SQL('DEFAULT 1')]) class Meta: table_name = 'smon_dns_check' @@ -724,7 +744,7 @@ def create_tables(): Cred, Backup, Metrics, WafMetrics, Version, Option, SavedServer, Waf, ActionHistory, PortScannerSettings, PortScannerPorts, PortScannerHistory, ServiceSetting, MetricsHttpStatus, SMON, WafRules, Alerts, GeoipCodes, NginxMetrics, SystemInfo, Services, UserName, GitSetting, CheckerSetting, ApacheMetrics, WafNginx, ServiceStatus, - KeepaliveRestart, PD, SmonHistory, SmonTcpCheck, SmonHttpCheck, SmonPingCheck, SmonDnsCheck, S3Backup, RoxyTool, + KeepaliveRestart, PD, SmonHistory, SmonAgent, SmonTcpCheck, SmonHttpCheck, SmonPingCheck, SmonDnsCheck, S3Backup, RoxyTool, SmonStatusPage, SmonStatusPageCheck, HaCluster, HaClusterSlave, HaClusterVip, HaClusterVirt, HaClusterService, HaClusterRouter] ) diff --git a/app/modules/db/smon.py b/app/modules/db/smon.py new file mode 100644 index 00000000..ba2d9cd9 --- /dev/null +++ b/app/modules/db/smon.py @@ -0,0 +1,639 @@ +import logging +import uuid + +from peewee import fn + +from app.modules.db.db_model import SmonAgent, Server, SMON, SmonTcpCheck, SmonHttpCheck, SmonDnsCheck, SmonPingCheck, SmonHistory, SmonStatusPageCheck, SmonStatusPage +from app.modules.db.sql import out_error, get_setting +import modules.roxy_wi_tools as roxy_wi_tools + +time_zone = get_setting('time_zone') +get_date = roxy_wi_tools.GetDate(time_zone) + + +def get_agents(group_id: int): + try: + return SmonAgent.select(SmonAgent, Server).join(Server).where(Server.groups == group_id).objects().execute() + except Exception as e: + out_error(e) + + +def get_free_servers_for_agent(group_id: int): + try: + query = Server.select().where( + (Server.type_ip == 0) & + (Server.server_id.not_in(SmonAgent.select(SmonAgent.server_id))) & + (Server.groups == group_id) + ) + return query.execute() + except Exception as e: + out_error(e) + + +def get_agent(agent_id: int): + try: + return SmonAgent.select(SmonAgent, Server).join(Server).where(SmonAgent.id == agent_id).objects().execute() + except Exception as e: + out_error(e) + + +def get_agent_id_by_check_id(check_id: int): + check_type = SMON.get(SMON.id == check_id).check_type + if check_type == 'tcp': + query = SmonTcpCheck.get(SmonTcpCheck.smon_id == check_id).agent_id + elif check_type == 'http': + query = SmonHttpCheck.get(SmonHttpCheck.smon_id == check_id).agent_id + elif check_type == 'dns': + query = SmonDnsCheck.get(SmonDnsCheck.smon_id == check_id).agent_id + else: + query = SmonPingCheck.get(SmonPingCheck.smon_id == check_id).agent_id + return query + + +def add_agent(name: str, server_id: int, desc: str, enabled: int, agent_uuid: str) -> int: + try: + last_id = SmonAgent.insert(name=name, server_id=server_id, desc=desc, enabled=enabled, uuid=agent_uuid).execute() + return last_id + except Exception as e: + out_error(e) + + +def delete_agent(agent_id: int): + try: + SmonAgent.delete().where(SmonAgent.id == agent_id).execute() + except Exception as e: + out_error(e) + + +def update_agent(agent_id: int, name: str, desc: str, enabled: int): + try: + SmonAgent.update(name=name, desc=desc, enabled=enabled).where(SmonAgent.id == agent_id).execute() + except Exception as e: + out_error(e) + + +def get_agent_uuid(agent_id: int) -> uuid: + try: + return SmonAgent.get(SmonAgent.id == agent_id).uuid + except SmonAgent.DoesNotExist: + raise Exception('agent not found') + except Exception as e: + out_error(e) + + +def get_agent_ip_by_id(agent_id: int): + try: + query = SmonAgent.select(SmonAgent, Server).join(Server).where(SmonAgent.id == agent_id) + query_res = query.objects().execute() + except Exception as e: + out_error(e) + else: + for r in query_res: + return r.ip + + +def get_agent_id_by_uuid(agent_uuid: int) -> int: + try: + return SmonAgent.get(SmonAgent.uuid == agent_uuid).id + except Exception as e: + out_error(e) + + +def get_agent_id_by_ip(agent_ip) -> int: + try: + return SmonAgent.get(SmonAgent.server_id == Server.get(Server.ip == agent_ip).server_id).id + except Exception as e: + out_error(e) + + +def select_server_ip_by_agent_id(agent_id: int) -> str: + try: + return Server.get(Server.server_id == SmonAgent.get(SmonAgent.id == agent_id).server_id).ip + except Exception as e: + out_error(e) + + +def select_en_smon_tcp(agent_id) -> object: + try: + return SmonTcpCheck.select(SmonTcpCheck, SMON).join_from(SmonTcpCheck, SMON).where((SMON.en == '1') & (SmonTcpCheck.agent_id == agent_id)).execute() + except Exception as e: + out_error(e) + + +def select_en_smon_ping(agent_id) -> object: + query = SmonPingCheck.select(SmonPingCheck, SMON).join_from(SmonPingCheck, SMON).where((SMON.en == '1') & (SmonPingCheck.agent_id == agent_id)) + try: + query_res = query.execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def select_en_smon_dns(agent_id) -> object: + query = SmonDnsCheck.select(SmonDnsCheck, SMON).join_from(SmonDnsCheck, SMON).where((SMON.en == '1') & (SmonDnsCheck.agent_id == agent_id)) + try: + query_res = query.execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def select_en_smon_http(agent_id) -> object: + query = SmonHttpCheck.select(SmonHttpCheck, SMON).join_from(SmonHttpCheck, SMON).where((SMON.en == '1') & (SmonHttpCheck.agent_id == agent_id)) + try: + query_res = query.execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def select_status(smon_id): + try: + query_res = SMON.get(SMON.id == smon_id).status + except Exception as e: + out_error(e) + else: + return int(query_res) + + +def change_status(status, smon_id): + query = SMON.update(status=status).where(SMON.id == smon_id) + try: + query.execute() + except Exception as e: + out_error(e) + return False + else: + return True + + +def response_time(time, smon_id): + query = SMON.update(response_time=time).where(SMON.id == smon_id) + try: + query.execute() + except Exception as e: + out_error(e) + return False + else: + return True + + +def add_sec_to_state_time(time, smon_id): + query = SMON.update(time_state=time).where(SMON.id == smon_id) + try: + query.execute() + except Exception as e: + out_error(e) + + +def insert_smon_history(smon_id: int, resp_time: float, status: int, check_id: int, mes='') -> None: + cur_date = get_date.return_date('regular') + try: + SmonHistory.insert(smon_id=smon_id, response_time=resp_time, status=status, date=cur_date, check_id=check_id, mes=mes).execute() + except Exception as e: + out_error(e) + + +def select_one_smon(smon_id: int, check_id: int) -> tuple: + if check_id == 1: + query = SmonTcpCheck.select(SmonTcpCheck, SMON).join_from(SmonTcpCheck, SMON).where(SMON.id == smon_id) + elif check_id == 2: + query = SmonHttpCheck.select(SmonHttpCheck, SMON).join_from(SmonHttpCheck, SMON).where(SMON.id == smon_id) + elif check_id == 5: + query = SmonDnsCheck.select(SmonDnsCheck, SMON).join_from(SmonDnsCheck, SMON).where(SMON.id == smon_id) + else: + query = SmonPingCheck.select(SmonPingCheck, SMON).join_from(SmonPingCheck, SMON).where(SMON.id == smon_id) + + try: + query_res = query.execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def insert_smon(name, enable, group, desc, telegram, slack, pd, user_group, check_type): + try: + last_id = SMON.insert( + name=name, en=enable, desc=desc, group=group, telegram_channel_id=telegram, slack_channel_id=slack, + pd_channel_id=pd, user_group=user_group, status='3', check_type=check_type + ).execute() + except Exception as e: + out_error(e) + return False + else: + return last_id + + +def insert_smon_ping(smon_id, hostname, packet_size, interval, agent_id): + try: + SmonPingCheck.insert(smon_id=smon_id, ip=hostname, packet_size=packet_size, interval=interval, agent_id=agent_id).execute() + except Exception as e: + out_error(e) + + +def insert_smon_tcp(smon_id, hostname, port, interval, agent_id): + try: + SmonTcpCheck.insert(smon_id=smon_id, ip=hostname, port=port, interval=interval, agent_id=agent_id).execute() + except Exception as e: + out_error(e) + + +def insert_smon_dns(smon_id: int, hostname: str, port: int, resolver: str, record_type: str, interval: int, agent_id: int) -> None: + try: + SmonDnsCheck.insert(smon_id=smon_id, ip=hostname, port=port, resolver=resolver, record_type=record_type, interval=interval, agent_id=agent_id).execute() + except Exception as e: + out_error(e) + + +def insert_smon_http(smon_id, url, body, http_method, interval, agent_id): + try: + SmonHttpCheck.insert(smon_id=smon_id, url=url, body=body, method=http_method, interval=interval, agent_id=agent_id).execute() + except Exception as e: + out_error(e) + + +def select_smon_ping(): + try: + query_res = SmonPingCheck.select().execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def select_smon_tcp(): + try: + query_res = SmonTcpCheck.select().execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def select_smon_http(): + try: + query_res = SmonHttpCheck.select().execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def select_smon_dns(): + try: + query_res = SmonDnsCheck.select().execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def select_smon_by_id(last_id): + query = SMON.select().where(SMON.id == last_id) + try: + query_res = query.execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def select_smon_check_by_id(last_id, check_type): + if check_type == 'ping': + query = SmonPingCheck.select().where(SmonPingCheck.smon_id == last_id) + elif check_type == 'tcp': + query = SmonTcpCheck.select().where(SmonTcpCheck.smon_id == last_id) + elif check_type == 'dns': + query = SmonDnsCheck.select().where(SmonDnsCheck.smon_id == last_id) + else: + query = SmonHttpCheck.select().where(SmonHttpCheck.smon_id == last_id) + try: + query_res = query.execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def delete_smon(smon_id, user_group): + query = SMON.delete().where((SMON.id == smon_id) & (SMON.user_group == user_group)) + try: + query.execute() + except Exception as e: + out_error(e) + return False + else: + return True + + +def smon_list(user_group): + if user_group == 1: + query = (SMON.select().order_by(SMON.group)) + else: + query = (SMON.select().where(SMON.user_group == user_group).order_by(SMON.group)) + + try: + query_res = query.execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def add_status_page(name: str, slug: str, desc: str, group_id: int, checks: list) -> int: + try: + last_id = SmonStatusPage.insert(name=name, slug=slug, group_id=group_id, desc=desc).execute() + except Exception as e: + if 'Duplicate entry' in str(e): + raise Exception('error: The Slug is already taken, please enter another one') + else: + out_error(e) + else: + add_status_page_checks(last_id, checks) + return last_id + + +def edit_status_page(page_id: int, name: str, slug: str, desc: str) -> None: + try: + SmonStatusPage.update(name=name, slug=slug, desc=desc).where(SmonStatusPage.id == page_id).execute() + except Exception as e: + out_error(e) + + +def add_status_page_checks(page_id: int, checks: list) -> None: + for check in checks: + try: + SmonStatusPageCheck.insert(page_id=page_id, check_id=int(check)).execute() + except Exception as e: + out_error(e) + + +def delete_status_page_checks(page_id: int) -> None: + try: + SmonStatusPageCheck.delete().where(SmonStatusPageCheck.page_id == page_id).execute() + except Exception as e: + out_error(e) + + +def select_status_pages(group_id: int): + try: + query_res = SmonStatusPage.select().where(SmonStatusPage.group_id == group_id).execute() + except Exception as e: + return out_error(e) + else: + return query_res + + +def select_status_page_by_id(page_id: int): + try: + query_res = SmonStatusPage.select().where(SmonStatusPage.id == page_id).execute() + except Exception as e: + return out_error(e) + else: + return query_res + + +def select_status_page(slug: str): + try: + query_res = SmonStatusPage.select().where(SmonStatusPage.slug == slug).execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def select_status_page_checks(page_id: int): + try: + query_res = SmonStatusPageCheck.select().where(SmonStatusPageCheck.page_id == page_id).execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def delete_status_page(page_id): + try: + SmonStatusPage.delete().where(SmonStatusPage.id == page_id).execute() + except Exception as e: + out_error(e) + + +def get_last_smon_status_by_check(smon_id: int) -> object: + query = SmonHistory.select().where( + SmonHistory.smon_id == smon_id + ).limit(1).order_by(SmonHistory.date.desc()) + try: + query_res = query.execute() + except Exception as e: + out_error(e) + else: + try: + for i in query_res: + return i.status + except Exception: + return '' + + +def get_last_smon_res_time_by_check(smon_id: int, check_id: int) -> int: + query = SmonHistory.select().where( + (SmonHistory.smon_id == smon_id) & + (SmonHistory.check_id == check_id) + ).limit(1).order_by(SmonHistory.date.desc()) + try: + query_res = query.execute() + except Exception as e: + out_error(e) + else: + try: + for i in query_res: + return i.response_time + except Exception: + return '' + + +def get_smon_history_count_checks(smon_id: int) -> dict: + count_checks = {} + query = SmonHistory.select(fn.Count(SmonHistory.status)).where( + SmonHistory.smon_id == smon_id + ) + try: + query_res = query.execute() + except Exception as e: + out_error(e) + else: + try: + for i in query_res: + count_checks['total'] = i.status + except Exception as e: + raise Exception(f'error: {e}') + + query = SmonHistory.select(fn.Count(SmonHistory.status)).where( + (SmonHistory.smon_id == smon_id) & + (SmonHistory.status == 1) + ) + try: + query_res = query.execute() + except Exception as e: + out_error(e) + else: + try: + for i in query_res: + count_checks['up'] = i.status + except Exception as e: + raise Exception(f'error: {e}') + + return count_checks + + +def get_smon_service_name_by_id(smon_id: int) -> str: + query = SMON.select().join(SmonHistory, on=(SmonHistory.smon_id == SMON.id)).where(SmonHistory.smon_id == smon_id) + try: + query_res = query.execute() + except Exception as e: + out_error(e) + else: + try: + for i in query_res: + return f'{i.name}' + except Exception: + return '' + + +def select_smon_history(smon_id: int) -> object: + query = SmonHistory.select().where( + SmonHistory.smon_id == smon_id + ).limit(40).order_by(SmonHistory.date.desc()) + try: + query_res = query.execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def update_smon(smon_id, name, telegram, slack, pd, group, desc, en): + query = (SMON.update( + name=name, telegram_channel_id=telegram, slack_channel_id=slack, pd_channel_id=pd, group=group, desc=desc, en=en + ).where(SMON.id == smon_id)) + try: + query.execute() + return True + except Exception as e: + out_error(e) + return False + + +def update_smonHttp(smon_id, url, body, method, interval, agent_id): + try: + SmonHttpCheck.update(url=url, body=body, method=method, interval=interval, agent_id=agent_id).where(SmonHttpCheck.smon_id == smon_id).execute() + return True + except Exception as e: + out_error(e) + return False + + +def update_smonTcp(smon_id, ip, port, interval, agent_id): + try: + SmonTcpCheck.update(ip=ip, port=port, interval=interval, agent_id=agent_id).where(SmonTcpCheck.smon_id == smon_id).execute() + return True + except Exception as e: + out_error(e) + return False + + +def update_smonPing(smon_id, ip, packet_size, interval, agent_id): + try: + SmonPingCheck.update(ip=ip, packet_size=packet_size, interval=interval, agent_id=agent_id).where(SmonPingCheck.smon_id == smon_id).execute() + return True + except Exception as e: + out_error(e) + return False + + +def update_smonDns(smon_id: int, ip: str, port: int, resolver: str, record_type: str, interval: int, agent_id: int): + try: + SmonDnsCheck.update(ip=ip, port=port, resolver=resolver, record_type=record_type, interval=interval, + agent_id=agent_id).where(SmonDnsCheck.smon_id == smon_id).execute() + return True + except Exception as e: + out_error(e) + return False + + +def select_smon(user_group): + if user_group == 1: + query = SMON.select() + else: + query = SMON.select().where(SMON.user_group == user_group) + try: + query_res = query.execute() + except Exception as e: + out_error(e) + else: + return query_res + + +def get_avg_resp_time(smon_id: int, check_id: int) -> int: + try: + query_res = SmonHistory.select(fn.AVG(SmonHistory.response_time)).where( + (SmonHistory.smon_id == smon_id) & + (SmonHistory.check_id == check_id) + ).scalar() + except Exception as e: + out_error(e) + else: + return query_res + + +def update_smon_ssl_expire_date(smon_id: str, expire_date: str) -> None: + try: + SMON.update(ssl_expire_date=expire_date).where(SMON.id == smon_id).execute() + except Exception as e: + out_error(e) + + +def update_smon_alert_status(smon_id: str, alert_value: int, alert: str) -> None: + if alert == 'ssl_expire_warning_alert': + query = SMON.update(ssl_expire_warning_alert=alert_value).where(SMON.id == smon_id) + else: + query = SMON.update(ssl_expire_critical_alert=alert_value).where(SMON.id == smon_id) + try: + query.execute() + except Exception as e: + out_error(e) + + +def get_smon_alert_status(smon_id: str, alert: str) -> int: + try: + if alert == 'ssl_expire_warning_alert': + alert_value = SMON.get(SMON.id == smon_id).ssl_expire_warning_alert + else: + alert_value = SMON.get(SMON.id == smon_id).ssl_expire_critical_alert + except Exception as e: + out_error(e) + else: + return alert_value + + +def change_body_status(status, smon_id): + query = SMON.update(body_status=status).where(SMON.id == smon_id) + try: + query.execute() + except Exception as e: + out_error(e) + return False + else: + return True + + +def select_body_status(smon_id): + try: + query_res = SMON.get(SMON.id == smon_id).body_status + except Exception as e: + out_error(e) + else: + return query_res diff --git a/app/modules/db/sql.py b/app/modules/db/sql.py index 937a54b6..630efbbb 100755 --- a/app/modules/db/sql.py +++ b/app/modules/db/sql.py @@ -50,10 +50,9 @@ def get_setting(param, **kwargs): for setting in query_res: if param in ( 'nginx_stats_port', 'session_ttl', 'token_ttl', 'haproxy_stats_port', 'haproxy_sock_port', 'ldap_type', - 'ldap_port', 'ldap_enable', 'log_time_storage', 'syslog_server_enable', 'smon_check_interval', - 'checker_check_interval', 'port_scan_interval', 'smon_keep_history_range', 'checker_keep_history_range', - 'portscanner_keep_history_range', 'checker_maxconn_threshold', 'apache_stats_port', 'smon_ssl_expire_warning_alert', - 'smon_ssl_expire_critical_alert', 'action_keep_history_range' + 'ldap_port', 'ldap_enable', 'log_time_storage', 'syslog_server_enable', 'checker_check_interval', 'port_scan_interval', + 'smon_keep_history_range', 'checker_keep_history_range', 'portscanner_keep_history_range', 'checker_maxconn_threshold', + 'apache_stats_port', 'smon_ssl_expire_warning_alert', 'smon_ssl_expire_critical_alert', 'action_keep_history_range' ): return int(setting.value) else: @@ -498,15 +497,6 @@ def get_group_id_by_name(group_name): return group_id.group_id -# def get_group_id_by_server_ip(server_ip): -# try: -# group_id = Server.get(Server.ip == server_ip) -# except Exception as e: -# out_error(e) -# else: -# return group_id.groups - - def get_cred_id_by_server_ip(server_ip): try: cred = Server.get(Server.ip == server_ip) @@ -521,7 +511,6 @@ def get_hostname_by_server_ip(server_ip): hostname = Server.get(Server.ip == server_ip) except Exception as e: return out_error(e) - # pass else: return hostname.hostname @@ -544,24 +533,6 @@ def select_server_id_by_ip(server_ip): return server_id -# def select_server_name_by_ip(server_ip): -# try: -# server_name = Server.get(Server.ip == server_ip).hostname -# except Exception: -# return None -# else: -# return server_name -# -# -# def select_server_group_by_ip(server_ip): -# try: -# groups = Server.get(Server.ip == server_ip).groups -# except Exception as e: -# return out_error(e) -# else: -# return groups - - def select_server_ip_by_id(server_id: int) -> str: try: server_ip = Server.get(Server.server_id == server_id).ip @@ -575,7 +546,6 @@ def select_servers(**kwargs): cursor = conn.cursor() if mysql_enable == '1': - sql = """select * from `servers` where `enable` = 1 ORDER BY servers.groups """ if kwargs.get("server") is not None: @@ -710,13 +680,13 @@ def get_token(uuid): except Exception: return '' - -def delete_uuid(uuid): - try: - query = UUID.delete().where(UUID.uuid == uuid) - query.execute() - except Exception: - pass +# +# def delete_uuid(uuid): +# try: +# query = UUID.delete().where(UUID.uuid == uuid) +# query.execute() +# except Exception: +# pass def delete_old_uuid(): @@ -2561,241 +2531,6 @@ def update_server_pos(pos, server_id) -> str: return 'not_ok' -# def check_token_exists(token): -# try: -# import http.cookies -# import os -# cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) -# user_id = cookie.get('uuid') -# if get_token(user_id.value) == token: -# return True -# else: -# return False -# except Exception: -# return False - - -def insert_smon(name, enable, group, desc, telegram, slack, pd, user_group, check_type): - try: - last_id = SMON.insert( - name=name, en=enable, desc=desc, group=group, telegram_channel_id=telegram, slack_channel_id=slack, - pd_channel_id=pd, user_group=user_group, status='3', check_type=check_type - ).execute() - except Exception as e: - out_error(e) - return False - else: - return last_id - - -def insert_smon_ping(smon_id, hostname, packet_size): - try: - SmonPingCheck.insert(smon_id=smon_id, ip=hostname, packet_size=packet_size).execute() - except Exception as e: - out_error(e) - - -def insert_smon_tcp(smon_id, hostname, port): - try: - SmonTcpCheck.insert(smon_id=smon_id, ip=hostname, port=port).execute() - except Exception as e: - out_error(e) - - -def insert_smon_dns(smon_id: int, hostname: str, port: int, resolver: str, record_type: str) -> None: - try: - SmonDnsCheck.insert(smon_id=smon_id, ip=hostname, port=port, resolver=resolver, record_type=record_type).execute() - except Exception as e: - out_error(e) - - -def insert_smon_http(smon_id, url, body, http_method): - try: - SmonHttpCheck.insert(smon_id=smon_id, url=url, body=body, method=http_method).execute() - except Exception as e: - out_error(e) - - -def select_smon(user_group): - if user_group == 1: - query = SMON.select() - else: - query = SMON.select().where(SMON.user_group == user_group) - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def select_smon_ping(): - try: - query_res = SmonPingCheck.select().execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def select_en_smon_ping() -> object: - query = SmonPingCheck.select(SmonPingCheck, SMON).join_from(SmonPingCheck, SMON).where(SMON.en == '1') - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def select_en_smon_tcp() -> object: - query = SmonTcpCheck.select(SmonTcpCheck, SMON).join_from(SmonTcpCheck, SMON).where(SMON.en == '1') - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def select_en_smon_http() -> object: - query = SmonHttpCheck.select(SmonHttpCheck, SMON).join_from(SmonHttpCheck, SMON).where(SMON.en == '1') - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def select_en_smon_dns() -> object: - query = SmonDnsCheck.select(SmonDnsCheck, SMON).join_from(SmonDnsCheck, SMON).where(SMON.en == '1') - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def select_smon_tcp(): - try: - query_res = SmonTcpCheck.select().execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def select_smon_http(): - try: - query_res = SmonHttpCheck.select().execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def select_smon_dns(): - try: - query_res = SmonDnsCheck.select().execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def select_smon_by_id(last_id): - query = SMON.select().where(SMON.id == last_id) - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def select_smon_check_by_id(last_id, check_type): - if check_type == 'ping': - query = SmonPingCheck.select().where(SmonPingCheck.smon_id == last_id) - elif check_type == 'tcp': - query = SmonTcpCheck.select().where(SmonTcpCheck.smon_id == last_id) - elif check_type == 'dns': - query = SmonDnsCheck.select().where(SmonDnsCheck.smon_id == last_id) - else: - query = SmonHttpCheck.select().where(SmonHttpCheck.smon_id == last_id) - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def delete_smon(smon_id, user_group): - query = SMON.delete().where((SMON.id == smon_id) & (SMON.user_group == user_group)) - try: - query.execute() - except Exception as e: - out_error(e) - return False - else: - return True - - -def update_smonHttp(smon_id, url, body, method): - query = (SmonHttpCheck.update(url=url, body=body, method=method).where(SmonHttpCheck.smon_id == smon_id)) - try: - query.execute() - return True - except Exception as e: - out_error(e) - return False - - -def update_smonTcp(smon_id, ip, port): - query = (SmonTcpCheck.update(ip=ip, port=port).where(SmonTcpCheck.smon_id == smon_id)) - try: - query.execute() - return True - except Exception as e: - out_error(e) - return False - - -def update_smonPing(smon_id, ip, packet_size): - query = (SmonPingCheck.update(ip=ip, packet_size=packet_size).where(SmonPingCheck.smon_id == smon_id)) - try: - query.execute() - return True - except Exception as e: - out_error(e) - return False - - -def update_smonDns(smon_id: int, ip: str, port: int, resolver: str, record_type: str): - query = (SmonDnsCheck.update(ip=ip, port=port, resolver=resolver, record_type=record_type) - .where(SmonDnsCheck.smon_id == smon_id)) - try: - query.execute() - return True - except Exception as e: - out_error(e) - return False - - -def update_smon(smon_id, name, telegram, slack, pd, group, desc, en): - query = (SMON.update( - name=name, telegram_channel_id=telegram, slack_channel_id=slack, pd_channel_id=pd, group=group, desc=desc, en=en - ).where(SMON.id == smon_id)) - try: - query.execute() - return True - except Exception as e: - out_error(e) - return False - - def alerts_history(service, user_group, **kwargs): cursor = conn.cursor() and_host = '' @@ -2822,305 +2557,6 @@ def alerts_history(service, user_group, **kwargs): return cursor.fetchall() -def select_status(smon_id): - try: - query_res = SMON.get(SMON.id == smon_id).status - except Exception as e: - out_error(e) - else: - return query_res - finally: - if type(conn) is not str: - if not conn.is_closed(): - conn.close() - - -def select_http_status(smon_id): - try: - query_res = SMON.get(SMON.id == smon_id).http_status - except Exception as e: - out_error(e) - else: - return query_res - finally: - if type(conn) is not str: - if not conn.is_closed(): - conn.close() - - -def select_body_status(smon_id): - try: - query_res = SMON.get(SMON.id == smon_id).body_status - except Exception as e: - out_error(e) - else: - return query_res - finally: - if type(conn) is not str: - if not conn.is_closed(): - conn.close() - - -def select_script(smon_id): - try: - query_res = SMON.get(SMON.id == smon_id).script - except Exception as e: - out_error(e) - else: - return query_res - - -def select_http(smon_id): - try: - query_res = SMON.get(SMON.id == smon_id).http - except Exception as e: - out_error(e) - else: - return query_res - finally: - if type(conn) is not str: - if not conn.is_closed(): - conn.close() - - -def select_body(smon_id): - try: - query_res = SMON.get(SMON.id == smon_id).body - except Exception as e: - out_error(e) - else: - return query_res - finally: - if type(conn) is not str: - if not conn.is_closed(): - conn.close() - - -def change_status(status, smon_id): - query = SMON.update(status=status).where(SMON.id == smon_id) - try: - query.execute() - except Exception as e: - out_error(e) - return False - else: - return True - finally: - if type(conn) is not str: - if not conn.is_closed(): - conn.close() - - -def change_body_status(status, smon_id): - query = SMON.update(body_status=status).where(SMON.id == smon_id) - try: - query.execute() - except Exception as e: - out_error(e) - return False - else: - return True - finally: - if type(conn) is not str: - if not conn.is_closed(): - conn.close() - - -def add_sec_to_state_time(time, smon_id): - query = SMON.update(time_state=time).where(SMON.id == smon_id) - try: - query.execute() - except Exception as e: - out_error(e) - return False - else: - return True - finally: - if type(conn) is not str: - if not conn.is_closed(): - conn.close() - - -def set_to_zero_time_state(smon_id): - query = SMON.update(time_state=0).where(SMON.id == smon_id) - try: - query.execute() - except Exception as e: - out_error(e) - return False - else: - return True - finally: - if type(conn) is not str: - if not conn.is_closed(): - conn.close() - - -def response_time(time, smon_id): - query = SMON.update(response_time=time).where(SMON.id == smon_id) - try: - query.execute() - except Exception as e: - out_error(e) - return False - else: - return True - finally: - if type(conn) is not str: - if not conn.is_closed(): - conn.close() - - -def smon_list(user_group): - if user_group == 1: - query = (SMON.select().order_by(SMON.group)) - else: - query = (SMON.select().where(SMON.user_group == user_group).order_by(SMON.group)) - - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def select_one_smon(smon_id: int, check_id: int) -> tuple: - if check_id == 1: - query = SmonTcpCheck.select(SmonTcpCheck, SMON).join_from(SmonTcpCheck, SMON).where(SMON.id == smon_id) - elif check_id == 2: - query = SmonHttpCheck.select(SmonHttpCheck, SMON).join_from(SmonHttpCheck, SMON).where(SMON.id == smon_id) - elif check_id == 5: - query = SmonDnsCheck.select(SmonDnsCheck, SMON).join_from(SmonDnsCheck, SMON).where(SMON.id == smon_id) - else: - query = SmonPingCheck.select(SmonPingCheck, SMON).join_from(SmonPingCheck, SMON).where(SMON.id == smon_id) - - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def insert_smon_history(smon_id: int, resp_time: float, status: int, check_id: int, mes='') -> None: - cur_date = get_date.return_date('regular') - try: - SmonHistory.insert(smon_id=smon_id, response_time=resp_time, status=status, date=cur_date, - check_id=check_id, mes=mes).execute() - except Exception as e: - out_error(e) - finally: - if type(conn) is not str: - if not conn.is_closed(): - conn.close() - - -def select_smon_history(smon_id: int) -> object: - query = SmonHistory.select().where( - SmonHistory.smon_id == smon_id - ).limit(40).order_by(SmonHistory.date.desc()) - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def get_last_smon_status_by_check(smon_id: int) -> object: - query = SmonHistory.select().where( - SmonHistory.smon_id == smon_id - ).limit(1).order_by(SmonHistory.date.desc()) - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - try: - for i in query_res: - return i.status - except Exception: - return '' - - -def get_last_smon_res_time_by_check(smon_id: int, check_id: int) -> int: - query = SmonHistory.select().where( - (SmonHistory.smon_id == smon_id) & - (SmonHistory.check_id == check_id) - ).limit(1).order_by(SmonHistory.date.desc()) - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - try: - for i in query_res: - return i.response_time - except Exception: - return '' - - -def get_smon_history_count_checks(smon_id: int) -> dict: - count_checks = {} - query = SmonHistory.select(fn.Count(SmonHistory.status)).where( - SmonHistory.smon_id == smon_id - ) - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - try: - for i in query_res: - count_checks['total'] = i.status - except Exception as e: - raise Exception(f'error: {e}') - - query = SmonHistory.select(fn.Count(SmonHistory.status)).where( - (SmonHistory.smon_id == smon_id) & - (SmonHistory.status == 1) - ) - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - try: - for i in query_res: - count_checks['up'] = i.status - except Exception as e: - raise Exception(f'error: {e}') - - return count_checks - - -def get_smon_service_name_by_id(smon_id: int) -> str: - query = SMON.select().join(SmonHistory, on=(SmonHistory.smon_id == SMON.id)).where(SmonHistory.smon_id == smon_id) - try: - query_res = query.execute() - except Exception as e: - out_error(e) - else: - try: - for i in query_res: - return f'{i.name}' - except Exception: - return '' - - -def get_avg_resp_time(smon_id: int, check_id: int) -> int: - try: - query_res = SmonHistory.select(fn.AVG(SmonHistory.response_time)).where( - (SmonHistory.smon_id == smon_id) & - (SmonHistory.check_id == check_id) - ).scalar() - except Exception as e: - out_error(e) - else: - return query_res - - def insert_alerts(user_group, level, ip, port, message, service): cur_date = get_date.return_date('regular') try: @@ -3138,23 +2574,6 @@ def insert_alerts(user_group, level, ip, port, message, service): conn.close() -# def select_alerts(user_group): -# cursor = conn.cursor() -# if mysql_enable == '1': -# sql = """ select level, message, `date` from alerts where user_group = '%s' and `date` <= (now()+ INTERVAL 10 second) """ % ( -# user_group) -# else: -# sql = """ select level, message, `date` from alerts where user_group = '%s' and `date` >= datetime('now', '-20 second', 'localtime') -# and `date` <= datetime('now', 'localtime') ; """ % ( -# user_group) -# try: -# cursor.execute(sql) -# except Exception as e: -# out_error(e) -# else: -# return cursor.fetchall() - - def select_all_alerts_for_all(): cursor = conn.cursor() if mysql_enable == '1': @@ -3637,17 +3056,6 @@ def select_one_system_info(server_id: int): 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 @@ -3760,14 +3168,14 @@ def select_user_status(): else: return query_res - -def check_user_status(): - try: - UserName.get().Status - except Exception as e: - raise Exception(str(e)) - else: - return True +# +# def check_user_status(): +# try: +# UserName.get().Status +# except Exception as e: +# raise Exception(str(e)) +# else: +# return True def select_user_plan(): @@ -3993,36 +3401,6 @@ def inset_or_update_service_status(server_id: int, service_id: int, service_chec out_error(e) -def update_smon_ssl_expire_date(smon_id: str, expire_date: str) -> None: - try: - SMON.update(ssl_expire_date=expire_date).where(SMON.id == smon_id) - except Exception as e: - out_error(e) - - -def update_smon_alert_status(smon_id: str, alert_value: int, alert: str) -> None: - if alert == 'ssl_expire_warning_alert': - query = SMON.update(ssl_expire_warning_alert=alert_value).where(SMON.id == smon_id) - else: - query = SMON.update(ssl_expire_critical_alert=alert_value).where(SMON.id == smon_id) - try: - query.execute() - except Exception as e: - out_error(e) - - -def get_smon_alert_status(smon_id: str, alert: str) -> int: - try: - if alert == 'ssl_expire_warning_alert': - alert_value = SMON.get(SMON.id == smon_id).ssl_expire_warning_alert - else: - alert_value = SMON.get(SMON.id == smon_id).ssl_expire_critical_alert - except Exception as e: - out_error(e) - else: - return alert_value - - def update_user_role(user_id: int, group_id: int, role_id: int) -> None: try: UserGroups.insert(user_id=user_id, user_group_id=group_id, user_role_id=role_id).on_conflict('replace').execute() @@ -4102,84 +3480,6 @@ def get_tool_cur_version(tool_name: str): return query -def add_status_page(name: str, slug: str, desc: str, group_id: int, checks: list) -> int: - try: - last_id = SmonStatusPage.insert(name=name, slug=slug, group_id=group_id, desc=desc).execute() - except Exception as e: - if 'Duplicate entry' in str(e): - raise Exception('error: The Slug is already taken, please enter another one') - else: - out_error(e) - else: - add_status_page_checks(last_id, checks) - return last_id - - -def edit_status_page(page_id: int, name: str, slug: str, desc: str) -> None: - try: - SmonStatusPage.update(name=name, slug=slug, desc=desc).where(SmonStatusPage.id == page_id).execute() - except Exception as e: - out_error(e) - - -def add_status_page_checks(page_id: int, checks: list) -> None: - for check in checks: - try: - SmonStatusPageCheck.insert(page_id=page_id, check_id=int(check)).execute() - except Exception as e: - out_error(e) - - -def delete_status_page_checks(page_id: int) -> None: - try: - SmonStatusPageCheck.delete().where(SmonStatusPageCheck.page_id == page_id).execute() - except Exception as e: - out_error(e) - - -def select_status_pages(group_id: int): - try: - query_res = SmonStatusPage.select().where(SmonStatusPage.group_id == group_id).execute() - except Exception as e: - return out_error(e) - else: - return query_res - - -def select_status_page_by_id(page_id: int): - try: - query_res = SmonStatusPage.select().where(SmonStatusPage.id == page_id).execute() - except Exception as e: - return out_error(e) - else: - return query_res - - -def select_status_page(slug: str): - try: - query_res = SmonStatusPage.select().where(SmonStatusPage.slug == slug).execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def select_status_page_checks(page_id: int): - try: - query_res = SmonStatusPageCheck.select().where(SmonStatusPageCheck.page_id == page_id).execute() - except Exception as e: - out_error(e) - else: - return query_res - - -def delete_status_page(page_id): - try: - SmonStatusPage.delete().where(SmonStatusPage.id == page_id).execute() - except Exception as e: - out_error(e) - - def select_clusters(group_id: int): try: return HaCluster.select().where(HaCluster.group_id == group_id).execute() diff --git a/app/modules/server/server.py b/app/modules/server/server.py index 95de20a2..646970b5 100644 --- a/app/modules/server/server.py +++ b/app/modules/server/server.py @@ -21,32 +21,26 @@ def ssh_command(server_ip: str, commands: list, **kwargs): for command in commands: try: stdin, stdout, stderr = ssh.run_command(command, timeout=timeout) + stdin.close() except Exception as e: - roxywi_common.logging('Roxy-WI server', f' Something wrong with SSH connection. Probably sudo with password {e}', roxywi=1) - raise Exception(f'error: Something wrong with SSH connection. Probably sudo with password: {e}') + roxywi_common.handle_exceptions(e, server_ip, f'Something wrong with SSH connection. Probably sudo with password', roxywi=1) if stderr: for line in stderr.readlines(): if line: - roxywi_common.logging('Roxy-WI server', f' {line}', roxywi=1) - raise Exception(f'error: there is an error: {line}') + roxywi_common.handle_exceptions(e, server_ip, line, roxywi=1) - try: - if kwargs.get('raw'): - return stdout.readlines() - elif kwargs.get("show_log") == "1": - import modules.roxywi.logs as roxywi_logs - return roxywi_logs.show_log(stdout, grep=kwargs.get("grep")) - elif kwargs.get('return_err') == 1: - return stderr.read().decode(encoding='UTF-8') - else: - return stdout.read().decode(encoding='UTF-8') - except Exception as e: - roxywi_common.logging('Roxy-WI server', f' Something wrong with SSH connection. Probably sudo with password {e}', roxywi=1) - raise Exception(f'error: Cannot run SSH: {e}') + if kwargs.get('raw'): + return stdout.readlines() + elif kwargs.get("show_log") == "1": + import modules.roxywi.logs as roxywi_logs + return roxywi_logs.show_log(stdout, grep=kwargs.get("grep")) + elif kwargs.get('return_err') == 1: + return stderr.read().decode(encoding='UTF-8') + else: + return stdout.read().decode(encoding='UTF-8') except Exception as e: - roxywi_common.logging('Roxy-WI server', f' Something wrong with SSH connection: {e}', roxywi=1) - raise Exception(f'error: Cannot run SSH: {e}') + roxywi_common.handle_exceptions(e, server_ip, f'Something wrong with SSH connection. Probably sudo with password', roxywi=1) def subprocess_execute(cmd): @@ -240,14 +234,14 @@ def get_system_info(server_ip: str) -> str: 'description': q['description'], 'mac': q['serial'], 'ip': ip, - 'up': q['configuration']['link']} + 'up': q['configuration']['link']} except Exception: try: network[y['logicalname']] = { 'description': y['description'], 'mac': y['serial'], 'ip': y['configuration']['ip'], - 'up': y['configuration']['link']} + 'up': y['configuration']['link']} except Exception: pass if y['class'] == 'disk': diff --git a/app/modules/service/installation.py b/app/modules/service/installation.py index c1307910..b7f6a725 100644 --- a/app/modules/service/installation.py +++ b/app/modules/service/installation.py @@ -404,6 +404,10 @@ def run_ansible(inv: dict, server_ips: str, ansible_role: str) -> object: roxywi_common.logging('Roxy-WI server', f'error: Cannot stop SSH agent {e}', roxywi=1) os.remove(inventory) + + if result.rc != 0: + raise Exception('Something wrong with installation, check Apache logs for details') + return result.stats diff --git a/app/modules/tools/smon.py b/app/modules/tools/smon.py index f51b19f0..48f3121c 100644 --- a/app/modules/tools/smon.py +++ b/app/modules/tools/smon.py @@ -1,12 +1,34 @@ from flask import render_template, abort -import modules.db.sql as sql -import modules.roxywi.common as roxywi_common +import app.modules.db.smon as smon_sql +import app.modules.common.common as common +import app.modules.tools.smon_agent as smon_agent +import app.modules.roxywi.common as roxywi_common -def create_smon(name: str, hostname: str, port: int, enable: int, url: str, body: str, group: int, desc: str, telegram: int, - slack: int, pd: int, packet_size: int, check_type: int, resolver: str, record_type: str, user_group: int, - http_method: str, show_new=1) -> bool: +def create_smon(json_data, user_group, show_new=1) -> bool: + name = common.checkAjaxInput(json_data['name']) + hostname = common.checkAjaxInput(json_data['ip']) + port = common.checkAjaxInput(json_data['port']) + enable = common.checkAjaxInput(json_data['enabled']) + url = common.checkAjaxInput(json_data['url']) + body = common.checkAjaxInput(json_data['body']) + group = common.checkAjaxInput(json_data['group']) + desc = common.checkAjaxInput(json_data['desc']) + telegram = common.checkAjaxInput(json_data['tg']) + slack = common.checkAjaxInput(json_data['slack']) + pd = common.checkAjaxInput(json_data['pd']) + resolver = common.checkAjaxInput(json_data['resolver']) + record_type = common.checkAjaxInput(json_data['record_type']) + packet_size = common.checkAjaxInput(json_data['packet_size']) + http_method = common.checkAjaxInput(json_data['http_method']) + interval = common.checkAjaxInput(json_data['interval']) + agent_id = common.checkAjaxInput(json_data['agent_id']) + check_type = common.checkAjaxInput(json_data['check_type']) + + if agent_id == '': + raise Exception('warning: Select an Agent first') + if check_type == 'tcp': try: port = int(port) @@ -19,30 +41,58 @@ def create_smon(name: str, hostname: str, port: int, enable: int, url: str, body if int(packet_size) < 16: raise Exception('SMON error: a packet size cannot be less than 16') - last_id = sql.insert_smon(name, enable, group, desc, telegram, slack, pd, user_group, check_type) + last_id = smon_sql.insert_smon(name, enable, group, desc, telegram, slack, pd, user_group, check_type) if check_type == 'ping': - sql.insert_smon_ping(last_id, hostname, packet_size) + smon_sql.insert_smon_ping(last_id, hostname, packet_size, interval, agent_id) elif check_type == 'tcp': - sql.insert_smon_tcp(last_id, hostname, port) + smon_sql.insert_smon_tcp(last_id, hostname, port, interval, agent_id) elif check_type == 'http': - sql.insert_smon_http(last_id, url, body, http_method) + smon_sql.insert_smon_http(last_id, url, body, http_method, interval, agent_id) elif check_type == 'dns': - sql.insert_smon_dns(last_id, hostname, port, resolver, record_type) + smon_sql.insert_smon_dns(last_id, hostname, port, resolver, record_type, interval, agent_id) if last_id: roxywi_common.logging('SMON', f' A new server {name} to SMON has been add ', roxywi=1, login=1) + try: + api_path = f'check/{last_id}' + check_json = create_check_json(json_data) + server_ip = smon_sql.select_server_ip_by_agent_id(agent_id) + smon_agent.send_post_request_to_agent(agent_id, server_ip, api_path, check_json) + except Exception as e: + roxywi_common.logging('SMON', f'Cannot add check to the agent {server_ip}: {e}', roxywi=1, login=1) + if last_id and show_new: return last_id else: return False -def update_smon(smon_id, name, ip, port, en, url, body, telegram, slack, pd, group, desc, check_type, - resolver, record_type, packet_size, http_method) -> str: +def update_smon(smon_id, json_data) -> str: + name = common.checkAjaxInput(json_data['name']) + hostname = common.checkAjaxInput(json_data['ip']) + port = common.checkAjaxInput(json_data['port']) + enabled = common.checkAjaxInput(json_data['enabled']) + url = common.checkAjaxInput(json_data['url']) + body = common.checkAjaxInput(json_data['body']) + group = common.checkAjaxInput(json_data['group']) + desc = common.checkAjaxInput(json_data['desc']) + telegram = common.checkAjaxInput(json_data['tg']) + slack = common.checkAjaxInput(json_data['slack']) + pd = common.checkAjaxInput(json_data['pd']) + resolver = common.checkAjaxInput(json_data['resolver']) + record_type = common.checkAjaxInput(json_data['record_type']) + packet_size = common.checkAjaxInput(json_data['packet_size']) + http_method = common.checkAjaxInput(json_data['http_method']) + interval = common.checkAjaxInput(json_data['interval']) + agent_id = common.checkAjaxInput(json_data['agent_id']) + check_type = common.checkAjaxInput(json_data['check_type']) is_edited = False + if agent_id == '': + raise Exception('warning: Select an Agent first') + if check_type == 'tcp': try: port = int(port) @@ -56,33 +106,78 @@ def update_smon(smon_id, name, ip, port, en, url, body, telegram, slack, pd, gro raise Exception('SMON error: a packet size cannot be less than 16') try: - if sql.update_smon(smon_id, name, telegram, slack, pd, group, desc, en): + agent_id_old = smon_sql.get_agent_id_by_check_id(smon_id) + agent_ip = smon_sql.get_agent_ip_by_id(agent_id_old) + smon_agent.delete_check(agent_id_old, agent_ip, smon_id) + except Exception as e: + return f'{e}' + + try: + if smon_sql.update_smon(smon_id, name, telegram, slack, pd, group, desc, enabled): if check_type == 'http': - is_edited = sql.update_smonHttp(smon_id, url, body, http_method) + is_edited = smon_sql.update_smonHttp(smon_id, url, body, http_method, interval, agent_id) elif check_type == 'tcp': - is_edited = sql.update_smonTcp(smon_id, ip, port) + is_edited = smon_sql.update_smonTcp(smon_id, hostname, port, interval, agent_id) elif check_type == 'ping': - is_edited = sql.update_smonPing(smon_id, ip, packet_size) + is_edited = smon_sql.update_smonPing(smon_id, hostname, packet_size, interval, agent_id) elif check_type == 'dns': - is_edited = sql.update_smonDns(smon_id, ip, port, resolver, record_type) + is_edited = smon_sql.update_smonDns(smon_id, hostname, port, resolver, record_type, interval, agent_id) if is_edited: roxywi_common.logging('SMON', f' The SMON server {name} has been update ', roxywi=1, login=1) + try: + api_path = f'check/{smon_id}' + check_json = create_check_json(json_data) + server_ip = smon_sql.select_server_ip_by_agent_id(agent_id) + smon_agent.send_post_request_to_agent(agent_id, server_ip, api_path, check_json) + except Exception as e: + roxywi_common.logging('SMON', f'error: Cannot add check to the agent {agent_ip}: {e}', roxywi=1, login=1) + return "Ok" except Exception as e: raise Exception(f'error: Cannot update the server: {e}') +def create_check_json(json_data: dict) -> dict: + check_type = json_data['check_type'] + check_json = { + 'check_type': check_type, + 'name': json_data['name'], + 'server_ip': json_data['ip'], + 'interval': json_data['interval'], + } + if check_type == 'ping': + check_json.setdefault('packet_size', json_data['packet_size']) + elif check_type == 'tcp': + check_json.setdefault('port', json_data['port']) + elif check_type == 'http': + check_json.setdefault('url', json_data['url']) + check_json.setdefault('body', json_data['body']) + check_json.setdefault('http_method', json_data['http_method']) + elif check_type == 'dns': + check_json.setdefault('port', json_data['port']) + check_json.setdefault('resolver', json_data['resolver']) + check_json.setdefault('record_type', json_data['record_type']) + + return check_json + + def show_smon(sort: str) -> str: user_group = roxywi_common.get_user_group(id=1) lang = roxywi_common.get_user_lang_for_flask() - return render_template('ajax/smon/smon_dashboard.html', smon=sql.smon_list(user_group), sort=sort, lang=lang, update=1) + return render_template('ajax/smon/smon_dashboard.html', smon=smon_sql.smon_list(user_group), sort=sort, lang=lang, update=1) def delete_smon(smon_id, user_group) -> str: try: - if sql.delete_smon(smon_id, user_group): + agent_id = smon_sql.get_agent_id_by_check_id(smon_id) + server_ip = smon_sql.get_agent_ip_by_id(agent_id) + smon_agent.delete_check(agent_id, server_ip, smon_id) + except Exception as e: + roxywi_common.handle_exceptions(e, 'Roxy-WI server', f'error: Cannot delete check: {e}', roxywi=1, login=1) + try: + if smon_sql.delete_smon(smon_id, user_group): roxywi_common.logging('SMON', ' The server from SMON has been delete ', roxywi=1, login=1) return 'Ok' except Exception as e: @@ -90,7 +185,7 @@ def delete_smon(smon_id, user_group) -> str: def history_metrics(server_id: int) -> dict: - metric = sql.select_smon_history(server_id) + metric = smon_sql.select_smon_history(server_id) metrics = {'chartData': {}} metrics['chartData']['labels'] = {} @@ -107,21 +202,21 @@ def history_metrics(server_id: int) -> dict: return metrics -def history_statuses(dashboard_id: int) -> None: - smon_statuses = sql.select_smon_history(dashboard_id) +def history_statuses(dashboard_id: int) -> str: + smon_statuses = smon_sql.select_smon_history(dashboard_id) return render_template('ajax/smon/history_status.html', smon_statuses=smon_statuses) -def history_cur_status(dashboard_id: int, check_id: int) -> None: - cur_status = sql.get_last_smon_status_by_check(dashboard_id) - smon = sql.select_one_smon(dashboard_id, check_id) +def history_cur_status(dashboard_id: int, check_id: int) -> str: + cur_status = smon_sql.get_last_smon_status_by_check(dashboard_id) + smon = smon_sql.select_one_smon(dashboard_id, check_id) return render_template('ajax/smon/cur_status.html', cur_status=cur_status, smon=smon) -def check_uptime(smon_id: str) -> int: - count_checks = sql.get_smon_history_count_checks(smon_id) +def check_uptime(smon_id: int) -> int: + count_checks = smon_sql.get_smon_history_count_checks(smon_id) try: uptime = round(count_checks['up'] * 100 / count_checks['total'], 2) @@ -135,31 +230,31 @@ def create_status_page(name: str, slug: str, desc: str, checks: list) -> str: group_id = roxywi_common.get_user_group(id=1) try: - page_id = sql.add_status_page(name, slug, desc, group_id, checks) + page_id = smon_sql.add_status_page(name, slug, desc, group_id, checks) except Exception as e: raise Exception(f'{e}') - pages = sql.select_status_page_by_id(page_id) + pages = smon_sql.select_status_page_by_id(page_id) return render_template('ajax/smon/status_pages.html', pages=pages) def edit_status_page(page_id: int, name: str, slug: str, desc: str, checks: list) -> str: - sql.delete_status_page_checks(page_id) + smon_sql.delete_status_page_checks(page_id) try: - sql.add_status_page_checks(page_id, checks) - sql.edit_status_page(page_id, name, slug, desc) + smon_sql.add_status_page_checks(page_id, checks) + smon_sql.edit_status_page(page_id, name, slug, desc) except Exception as e: return f'error: Cannot update update status page: {e}' - pages = sql.select_status_page_by_id(page_id) + pages = smon_sql.select_status_page_by_id(page_id) return render_template('ajax/smon/status_pages.html', pages=pages) def show_status_page(slug: str) -> str: - page = sql.select_status_page(slug) + page = smon_sql.select_status_page(slug) checks_status = {} if not page: abort(404, 'Not found status page') @@ -167,7 +262,7 @@ def show_status_page(slug: str) -> str: for p in page: page_id = p.id - checks = sql.select_status_page_checks(page_id) + checks = smon_sql.select_status_page_checks(page_id) for check in checks: name = '' @@ -175,7 +270,7 @@ def show_status_page(slug: str) -> str: group = '' check_type = '' check_id = str(check.check_id) - smon = sql.select_smon_by_id(check_id) + smon = smon_sql.select_smon_by_id(check_id) uptime = check_uptime(check_id) en = '' for s in smon: @@ -192,11 +287,11 @@ def show_status_page(slug: str) -> str: def avg_status_page_status(page_id: int) -> str: page_id = int(page_id) - checks = sql.select_status_page_checks(page_id) + checks = smon_sql.select_status_page_checks(page_id) for check in checks: check_id = str(check.check_id) - if not sql.get_last_smon_status_by_check(check_id): + if not smon_sql.get_last_smon_status_by_check(check_id): return '0' return '1' diff --git a/app/modules/tools/smon_agent.py b/app/modules/tools/smon_agent.py new file mode 100644 index 00000000..59fc7de2 --- /dev/null +++ b/app/modules/tools/smon_agent.py @@ -0,0 +1,210 @@ +import uuid + +import requests +import app.modules.db.sql as sql +import app.modules.db.smon as smon_sql +import app.modules.common.common as common +import app.modules.roxywi.common as common_roxywi +from app.modules.service.installation import run_ansible + + +def generate_agent_inc(server_ip: str, action: str, agent_uuid: uuid) -> object: + agent_port = sql.get_setting('agent_port') + master_port = sql.get_setting('master_port') + master_ip = sql.get_setting('master_ip') + if not master_ip: raise Exception('error: Master IP cannot be empty') + if master_port == '': raise Exception('error: Master port cannot be empty') + if agent_port == '': raise Exception('error: Agent port cannot be empty') + inv = {"server": {"hosts": {}}} + server_ips = [server_ip] + inv['server']['hosts'][server_ip] = { + 'action': action, + 'agent_port': agent_port, + 'agent_uuid': agent_uuid, + 'master_ip': master_ip, + 'master_port': master_port + } + + return inv, server_ips + + +def add_agent(data) -> int: + name = common.checkAjaxInput(data.get("name")) + server_id = int(data.get("server_id")) + server_ip = sql.select_server_ip_by_id(server_id) + desc = common.checkAjaxInput(data.get("desc")) + enabled = int(data.get("enabled")) + agent_uuid = str(uuid.uuid4()) + + try: + inv, server_ips = generate_agent_inc(server_ip, 'install', agent_uuid) + run_ansible(inv, server_ips, f'smon_agent') + except Exception as e: + common_roxywi.handle_exceptions(e, server_ip, 'Cannot install SMON agent', roxywi=1, login=1) + + try: + last_id = smon_sql.add_agent(name, server_id, desc, enabled, agent_uuid) + common_roxywi.logging(server_ip, 'A new SMON agent has been created', roxywi=1, login=1, keep_history=1, service='SMON') + return last_id + except Exception as e: + common_roxywi.handle_exceptions(e, 'Roxy-WI server', 'error: Cannot create Agent', roxywi=1, login=1) + + +def delete_agent(agent_id: int): + server_ip = smon_sql.get_agent_ip_by_id(agent_id) + agent_uuid = '' + try: + inv, server_ips = generate_agent_inc(server_ip, 'uninstall', agent_uuid) + run_ansible(inv, server_ips, f'smon_agent') + except Exception as e: + common_roxywi.handle_exceptions(e, server_ip, 'error: Cannot uninstall SMON agent', roxywi=1, login=1) + + +def update_agent(json_data): + agent_id = int(json_data.get("agent_id")) + name = common.checkAjaxInput(json_data.get("name")) + desc = common.checkAjaxInput(json_data.get("desc")) + enabled = int(json_data.get("enabled")) + + try: + smon_sql.update_agent(agent_id, name, desc, enabled) + except Exception as e: + common_roxywi.handle_exceptions(e, 'Roxy-WI server', f'error: Cannot update SMON agent: {agent_id}', roxywi=1, login=1) + + +def get_agent_headers(agent_id: int) -> dict: + try: + agent_uuid = smon_sql.get_agent_uuid(agent_id) + except Exception as e: + if str(e).find("agent not found") != -1: + agent_uuid = None + else: + raise Exception(e) + return {'Agent-UUID': str(agent_uuid)} + + +def send_get_request_to_agent(agent_id: int, server_ip: str, api_path: str) -> bytes: + headers = get_agent_headers(agent_id) + agent_port = sql.get_setting('agent_port') + try: + req = requests.get(f'http://{server_ip}:{agent_port}/{api_path}', headers=headers) + return req.content + except Exception as e: + raise Exception(f'error: Cannot get agent status: {e}') + + +def send_post_request_to_agent(agent_id: int, server_ip: str, api_path: str, json_data: object) -> bytes: + headers = get_agent_headers(agent_id) + agent_port = sql.get_setting('agent_port') + try: + req = requests.post(f'http://{server_ip}:{agent_port}/{api_path}', headers=headers, json=json_data) + return req.content + except Exception as e: + raise Exception(f'error: Cannot get agent status: {e}') + + +def delete_check(agent_id: int, server_ip: str, check_id: int) -> bytes: + headers = get_agent_headers(agent_id) + agent_port = sql.get_setting('agent_port') + try: + req = requests.delete(f'http://{server_ip}:{agent_port}/check/{check_id}', headers=headers) + return req.content + except requests.exceptions.HTTPError as e: + common_roxywi.logging(server_ip, f'error: Cannot delete check from agent: http error {e}', roxywi=1, login=1) + except requests.exceptions.ConnectTimeout: + common_roxywi.logging(server_ip, 'error: Cannot delete check from agent: connection timeout', roxywi=1, login=1) + except requests.exceptions.ConnectionError: + common_roxywi.logging(server_ip, 'error: Cannot delete check from agent: connection error', roxywi=1, login=1) + except Exception as e: + raise Exception(f'error: Cannot delete check from Agent {server_ip}: {e}') + + +def send_tcp_checks(agent_id: int, server_ip: str) -> None: + checks = smon_sql.select_en_smon_tcp(agent_id) + for check in checks: + json_data = { + 'check_type': 'tcp', + 'name': check.smon_id.name, + 'server_ip': check.ip, + 'port': check.port, + 'interval': check.interval + } + api_path = f'check/{check.smon_id}' + try: + send_post_request_to_agent(agent_id, server_ip, api_path, json_data) + except Exception as e: + raise Exception(f'{e}') + + +def send_ping_checks(agent_id: int, server_ip: str) -> None: + checks = smon_sql.select_en_smon_ping(agent_id) + for check in checks: + json_data = { + 'check_type': 'ping', + 'name': check.smon_id.name, + 'server_ip': check.ip, + 'packet_size': check.packet_size, + 'interval': check.interval + } + api_path = f'check/{check.smon_id}' + try: + send_post_request_to_agent(agent_id, server_ip, api_path, json_data) + except Exception as e: + raise Exception(f'{e}') + + +def send_dns_checks(agent_id: int, server_ip: str) -> None: + checks = smon_sql.select_en_smon_dns(agent_id) + for check in checks: + json_data = { + 'check_type': 'dns', + 'name': check.smon_id.name, + 'server_ip': check.ip, + 'port': check.port, + 'record_type': check.record_type, + 'resolver': check.resolver, + 'interval': check.interval + } + api_path = f'check/{check.smon_id}' + try: + send_post_request_to_agent(agent_id, server_ip, api_path, json_data) + except Exception as e: + raise Exception(f'{e}') + + +def send_http_checks(agent_id: int, server_ip: str) -> None: + checks = smon_sql.select_en_smon_http(agent_id) + for check in checks: + json_data = { + 'check_type': 'http', + 'name': check.smon_id.name, + 'url': check.url, + 'http_method': check.method, + 'body': check.body, + 'interval': check.interval + } + api_path = f'check/{check.smon_id}' + try: + send_post_request_to_agent(agent_id, server_ip, api_path, json_data) + except Exception as e: + raise Exception(f'{e}') + + +def send_checks(agent_id: int) -> None: + server_ip = smon_sql.select_server_ip_by_agent_id(agent_id) + try: + send_tcp_checks(agent_id, server_ip) + except Exception as e: + raise Exception(f'{e}') + try: + send_ping_checks(agent_id, server_ip) + except Exception as e: + raise Exception(f'{e}') + try: + send_dns_checks(agent_id, server_ip) + except Exception as e: + raise Exception(f'{e}') + try: + send_http_checks(agent_id, server_ip) + except Exception as e: + raise Exception(f'{e}') diff --git a/app/routes/add/routes.py b/app/routes/add/routes.py index aee064f9..45271106 100644 --- a/app/routes/add/routes.py +++ b/app/routes/add/routes.py @@ -119,9 +119,11 @@ def add_haproxy(): elif new_frontend is not None: name = f"frontend {new_frontend}" end_name = new_frontend + server_ip = request.form.get('serv2') elif new_backend is not None: name = f"backend {new_backend}" end_name = new_backend + server_ip = request.form.get('serv3') else: return 'error: The name cannot be empty' @@ -333,6 +335,8 @@ def add_haproxy(): try: port_check_val = port_check[i] + if port_check_val == '': + port_check_val = server_port[i] except Exception: port_check_val = server_port[i] diff --git a/app/routes/logs/routes.py b/app/routes/logs/routes.py index 9317d6c0..a4dd4e48 100644 --- a/app/routes/logs/routes.py +++ b/app/routes/logs/routes.py @@ -25,6 +25,7 @@ def before_request(): @get_user_params() def logs_internal(): log_type = request.args.get('type') + log_file = request.args.get('log_file') log_path = get_config.get_config_var('main', 'log_path') selects = roxywi_common.get_files(log_path, file_format="log") @@ -41,7 +42,7 @@ def logs_internal(): kwargs = { 'autorefresh': 1, 'selects': selects, - 'serv': 'viewlogs', + 'serv': log_file, 'lang': g.user_params['lang'] } return render_template('logs_internal.html', **kwargs) diff --git a/app/routes/smon/__init__.py b/app/routes/smon/__init__.py index 446c971a..bb3e0559 100644 --- a/app/routes/smon/__init__.py +++ b/app/routes/smon/__init__.py @@ -3,3 +3,4 @@ from flask import Blueprint bp = Blueprint('smon', __name__) from app.routes.smon import routes +from app.routes.smon import agent_routes diff --git a/app/routes/smon/agent_routes.py b/app/routes/smon/agent_routes.py new file mode 100644 index 00000000..df130e39 --- /dev/null +++ b/app/routes/smon/agent_routes.py @@ -0,0 +1,169 @@ +from flask import render_template, request, jsonify, g +from flask_login import login_required + +from app.routes.smon import bp + +from middleware import get_user_params +import app.modules.db.smon as smon_sql +import app.modules.common.common as common +import app.modules.tools.smon_agent as smon_agent +import app.modules.tools.common as tools_common +import app.modules.roxywi.common as roxywi_common +import app.modules.server.server as server_mod + + +@bp.route('/agent', methods=['GET', 'POST', 'PUT', 'DELETE']) +@login_required +@get_user_params() +def agent(): + if request.method == 'GET': + group_id = g.user_params['group_id'] + kwargs = { + 'agents': smon_sql.get_agents(group_id), + 'lang': roxywi_common.get_user_lang_for_flask(), + 'smon_status': tools_common.is_tool_active('roxy-wi-smon'), + 'user_subscription': roxywi_common.return_user_subscription(), + } + + return render_template('smon/agent.html', **kwargs) + elif request.method == 'POST': + data = request.get_json() + try: + last_id = smon_agent.add_agent(data) + return str(last_id) + except Exception as e: + return f'{e}' + elif request.method == "PUT": + json_data = request.get_json() + try: + smon_agent.update_agent(json_data) + except Exception as e: + return f'{e}' + return 'ok', 201 + elif request.method == 'DELETE': + agent_id = int(request.form.get('agent_id')) + try: + smon_agent.delete_agent(agent_id) + smon_sql.delete_agent(agent_id) + except Exception as e: + return f'{e}' + return 'ok' + + +@bp.post('/agent/hello') +def agent_get_checks(): + json_data = request.json + agent_id = smon_sql.get_agent_id_by_uuid(json_data['uuid']) + try: + smon_agent.send_checks(agent_id) + except Exception as e: + return f'{e}' + return 'ok' + + +@bp.get('/agent/free') +@login_required +@get_user_params() +def get_free_agents(): + group_id = g.user_params['group_id'] + free_servers = smon_sql.get_free_servers_for_agent(group_id) + servers = {} + for s in free_servers: + servers.setdefault(s.server_id, s.hostname) + + return jsonify(servers) + + +@bp.get('/agent/') +@login_required +@get_user_params() +def get_agent(agent_id): + try: + agent_data = smon_sql.get_agent(agent_id) + except Exception as e: + return f'{e}' + + return render_template('ajax/smon/agent.html', agents=agent_data, lang=roxywi_common.get_user_lang_for_flask()) + + +@bp.get('/agent/settings/') +@login_required +def get_agent_settings(agent_id): + settings = {} + try: + agent_data = smon_sql.get_agent(agent_id) + except Exception as e: + return f'{e}' + + for a in agent_data: + settings.setdefault('name', a.name) + settings.setdefault('server_id', str(a.server_id)) + settings.setdefault('hostname', a.hostname) + settings.setdefault('desc', a.desc) + settings.setdefault('enabled', str(a.enabled)) + + return jsonify(settings) + + +@bp.get('/agent/version/') +@login_required +def get_agent_version(server_ip): + agent_id = int(request.args.get('agent_id')) + + try: + req = smon_agent.send_get_request_to_agent(agent_id, server_ip, 'version') + return req + except Exception as e: + return f'{e}' + + +@bp.get('/agent/uptime/') +@login_required +def get_agent_uptime(server_ip): + agent_id = int(request.args.get('agent_id')) + + try: + req = smon_agent.send_get_request_to_agent(agent_id, server_ip, 'uptime') + return req + except Exception as e: + return f'{e}' + + +@bp.get('/agent/status/') +@login_required +def get_agent_status(server_ip): + agent_id = int(request.args.get('agent_id')) + + try: + req = smon_agent.send_get_request_to_agent(agent_id, server_ip, 'scheduler') + return req + except Exception as e: + return f'{e}' + + +@bp.get('/agent/checks/') +@login_required +def get_agent_checks(server_ip): + agent_id = int(request.args.get('agent_id')) + + try: + req = smon_agent.send_get_request_to_agent(agent_id, server_ip, 'checks') + return req + except Exception as e: + return f'{e}' + + +@bp.post('/agent/action/') +@login_required +def agent_action(action): + server_ip = common.is_ip_or_dns(request.form.get('server_ip')) + + if action not in ('start', 'stop', 'restart'): + return 'error: Wrong action' + + try: + command = [f'sudo systemctl {action} roxy-wi-smon-agent'] + server_mod.ssh_command(server_ip, command) + except Exception as e: + return f'{e}' + return 'ok' diff --git a/app/routes/smon/routes.py b/app/routes/smon/routes.py index 3a938509..0c54956c 100644 --- a/app/routes/smon/routes.py +++ b/app/routes/smon/routes.py @@ -5,18 +5,25 @@ from datetime import datetime from app.routes.smon import bp from middleware import get_user_params +from app.modules.db.db_model import conn import app.modules.db.sql as sql +import app.modules.db.smon as smon_sql import app.modules.common.common as common -import app.modules.roxywi.auth as roxywi_auth import app.modules.roxywi.common as roxywi_common import app.modules.tools.smon as smon_mod import app.modules.tools.common as tools_common +@bp.teardown_request +def _db_close(exc): + if not conn.is_closed(): + conn.close() + + @bp.route('/dashboard') @login_required @get_user_params() -def smon(): +def smon_main_dashboard(): """ Dashboard route for the smon tool. @@ -24,14 +31,19 @@ def smon(): :rtype: flask.Response """ roxywi_common.check_user_group_for_flask() + group_id = g.user_params['group_id'] kwargs = { 'autorefresh': 1, 'lang': g.user_params['lang'], - 'smon': sql.smon_list(g.user_params['group_id']), - 'group': g.user_params['group_id'], + 'smon': smon_sql.smon_list(group_id), + 'agents': smon_sql.get_agents(group_id), + 'group': group_id, 'smon_status': tools_common.is_tool_active('roxy-wi-smon'), 'user_subscription': roxywi_common.return_user_subscription(), + 'telegrams': sql.get_user_telegram_by_group(group_id), + 'slacks': sql.get_user_pd_by_group(group_id), + 'pds': sql.get_user_slack_by_group(group_id), } return render_template('smon/dashboard.html', **kwargs) @@ -68,16 +80,16 @@ def smon_dashboard(smon_id, check_id): 9. Renders the SMON history template ('include/smon/smon_history.html') using the `render_template` function from Flask, passing the `kwargs` dictionary as keyword arguments. """ roxywi_common.check_user_group_for_flask() - smon = sql.select_one_smon(smon_id, check_id) + smon = smon_sql.select_one_smon(smon_id, check_id) present = common.get_present_time() cert_day_diff = 'N/A' try: - avg_res_time = round(sql.get_avg_resp_time(smon_id, check_id), 2) + avg_res_time = round(smon_sql.get_avg_resp_time(smon_id, check_id), 2) except Exception: avg_res_time = 0 try: - last_resp_time = round(sql.get_last_smon_res_time_by_check(smon_id, check_id), 2) + last_resp_time = round(smon_sql.get_last_smon_res_time_by_check(smon_id, check_id), 2) except Exception: last_resp_time = 0 @@ -92,19 +104,113 @@ def smon_dashboard(smon_id, check_id): 'smon': smon, 'group': g.user_params['group_id'], 'user_subscription': roxywi_common.return_user_subscription(), - 'check_interval': sql.get_setting('smon_check_interval'), 'uptime': smon_mod.check_uptime(smon_id), 'avg_res_time': avg_res_time, - 'smon_name': sql.get_smon_service_name_by_id(smon_id), + 'smon_name': smon_sql.get_smon_service_name_by_id(smon_id), 'cert_day_diff': cert_day_diff, 'check_id': check_id, 'dashboard_id': smon_id, - 'last_resp_time': last_resp_time + 'last_resp_time': last_resp_time, + 'agents': smon_sql.get_agents(g.user_params['group_id']) } return render_template('include/smon/smon_history.html', **kwargs) +@bp.route('/check', methods=['POST', 'PUT', 'DELETE']) +@login_required +def smon_add(): + json_data = request.get_json() + if request.method == "POST": + user_group = roxywi_common.get_user_group(id=1) + + try: + last_id = smon_mod.create_smon(json_data, user_group) + except Exception as e: + return str(e), 200 + return str(last_id) + elif request.method == "PUT": + check_id = json_data['check_id'] + + if roxywi_common.check_user_group_for_flask(): + try: + status = smon_mod.update_smon(check_id, json_data) + except Exception as e: + return f'{e}', 200 + else: + return status, 201 + elif request.method == "DELETE": + user_group = roxywi_common.get_user_group(id=1) + check_id = json_data['check_id'] + + if roxywi_common.check_user_group_for_flask(): + try: + status = smon_mod.delete_smon(check_id, user_group) + except Exception as e: + return f'{e}', 200 + else: + return status + + +@bp.route('/check/settings//') +@login_required +def check(smon_id, check_type_id): + smon = smon_sql.select_one_smon(smon_id, check_type_id) + settings = {} + for s in smon: + settings = { + 'id': s.smon_id.id, + 'name': s.smon_id.name, + 'interval': str(s.interval), + 'agent_id': str(s.agent_id), + 'enabled': s.smon_id.en, + 'status': s.smon_id.status, + 'http': s.smon_id.http, + 'desc': s.smon_id.desc, + 'tg': s.smon_id.telegram_channel_id, + 'slack': s.smon_id.slack_channel_id, + 'pd': s.smon_id.pd_channel_id, + 'check_type': s.smon_id.check_type, + 'group': s.smon_id.group, + } + if check_type_id in (1, 5): + settings.setdefault('port', s.port) + + if check_type_id != 2: + settings.setdefault('server_ip', str(s.ip)) + if check_type_id == 2: + settings.setdefault('url', s.url) + settings.setdefault('method', s.method) + settings.setdefault('body', s.body) + elif check_type_id == 4: + settings.setdefault('packet_size', s.packet_size) + elif check_type_id == 5: + settings.setdefault('resolver', s.resolver) + settings.setdefault('record_type', s.record_type) + + return jsonify(settings) + + +@bp.route('/check//') +@login_required +@get_user_params() +def get_check(smon_id, check_type_id): + """ + Get the check for the given SMON ID and check type ID. + + Parameters: + - smon_id (int): The ID of the SMON. + - check_type_id (int): The ID of the check type. + + Returns: + - flask.Response: The rendered template for the check page. + """ + smon = smon_sql.select_one_smon(smon_id, check_type_id) + lang = roxywi_common.get_user_lang_for_flask() + agents = smon_sql.get_agents(g.user_params['group_id']) + return render_template('ajax/smon/check.html', smon=smon, lang=lang, check_type_id=check_type_id, agents=agents) + + @bp.route('/status-page', methods=['GET', 'POST', 'DELETE', 'PUT']) @login_required @get_user_params() @@ -146,8 +252,8 @@ def status_page(): if request.method == 'GET': kwargs = { 'lang': g.user_params['lang'], - 'smon': sql.smon_list(g.user_params['group_id']), - 'pages': sql.select_status_pages(g.user_params['group_id']), + 'smon': smon_sql.smon_list(g.user_params['group_id']), + 'pages': smon_sql.select_status_pages(g.user_params['group_id']), 'smon_status': tools_common.is_tool_active('roxy-wi-smon'), 'user_subscription': roxywi_common.return_user_subscription() } @@ -183,7 +289,7 @@ def status_page(): elif request.method == 'DELETE': page_id = int(request.form.get('page_id')) try: - sql.delete_status_page(page_id) + smon_sql.delete_status_page(page_id) except Exception as e: return f'{e}' else: @@ -200,7 +306,7 @@ def get_checks(page_id): """ returned_check = [] try: - checks = sql.select_status_page_checks(page_id) + checks = smon_sql.select_status_page_checks(page_id) except Exception as e: return f'error: Cannot get checks: {e}' @@ -275,120 +381,6 @@ def smon_history_cur_status(dashboard_id, check_id): return smon_mod.history_cur_status(dashboard_id, check_id) -@bp.route('/admin') -@login_required -@get_user_params() -def smon_admin(): - roxywi_auth.page_for_admin(level=3) - user_group = g.user_params['group_id'] - kwargs = { - 'lang': g.user_params['lang'], - 'smon': sql.select_smon(user_group), - 'smon_status': tools_common.is_tool_active('roxy-wi-smon'), - 'user_subscription': roxywi_common.return_user_subscription(), - 'telegrams': sql.get_user_telegram_by_group(user_group), - 'slacks': sql.get_user_slack_by_group(user_group), - 'pds': sql.get_user_pd_by_group(user_group), - 'smon_tcp': sql.select_smon_tcp(), - 'smon_ping': sql.select_smon_ping(), - 'smon_http': sql.select_smon_http(), - 'smon_dns': sql.select_smon_dns() - } - - return render_template('smon/add.html', **kwargs) - - -@bp.post('/add') -@login_required -def smon_add(): - user_group = roxywi_common.get_user_group(id=1) - name = common.checkAjaxInput(request.form.get('newsmonname')) - hostname = common.checkAjaxInput(request.form.get('newsmon')) - port = common.checkAjaxInput(request.form.get('newsmonport')) - enable = common.checkAjaxInput(request.form.get('newsmonenable')) - url = common.checkAjaxInput(request.form.get('newsmonurl')) - body = common.checkAjaxInput(request.form.get('newsmonbody')) - group = common.checkAjaxInput(request.form.get('newsmongroup')) - desc = common.checkAjaxInput(request.form.get('newsmondescription')) - telegram = common.checkAjaxInput(request.form.get('newsmontelegram')) - slack = common.checkAjaxInput(request.form.get('newsmonslack')) - pd = common.checkAjaxInput(request.form.get('newsmonpd')) - check_type = common.checkAjaxInput(request.form.get('newsmonchecktype')) - resolver = common.checkAjaxInput(request.form.get('newsmonresserver')) - record_type = common.checkAjaxInput(request.form.get('newsmondns_record_type')) - packet_size = common.checkAjaxInput(request.form.get('newsmonpacket_size')) - http_method = common.checkAjaxInput(request.form.get('newsmon_http_method')) - lang = roxywi_common.get_user_lang_for_flask() - - try: - last_id = smon_mod.create_smon( - name, hostname, port, enable, url, body, group, desc, telegram, slack, pd, packet_size, check_type, - resolver, record_type, user_group, http_method - ) - except Exception as e: - return str(e), 200 - else: - if last_id: - kwargs = { - 'smon': sql.select_smon_by_id(last_id), - 'pds': sql.get_user_pd_by_group(user_group), - 'slacks': sql.get_user_slack_by_group(user_group), - 'telegrams': sql.get_user_telegram_by_group(user_group), - 'smon_service': sql.select_smon_check_by_id(last_id, check_type), - 'check_type': check_type, - 'lang': lang - } - - return render_template('ajax/smon/show_new_smon.html', **kwargs) - - -@bp.post('/update/') -@login_required -def smon_update(smon_id): - roxywi_common.check_user_group_for_flask() - name = common.checkAjaxInput(request.form.get('updateSmonName')) - ip = common.checkAjaxInput(request.form.get('updateSmonIp')) - port = common.checkAjaxInput(request.form.get('updateSmonPort')) - en = common.checkAjaxInput(request.form.get('updateSmonEn')) - url = common.checkAjaxInput(request.form.get('updateSmonUrl')) - body = common.checkAjaxInput(request.form.get('updateSmonBody')) - telegram = common.checkAjaxInput(request.form.get('updateSmonTelegram')) - slack = common.checkAjaxInput(request.form.get('updateSmonSlack')) - pd = common.checkAjaxInput(request.form.get('updateSmonPD')) - group = common.checkAjaxInput(request.form.get('updateSmonGroup')) - desc = common.checkAjaxInput(request.form.get('updateSmonDesc')) - check_type = common.checkAjaxInput(request.form.get('check_type')) - resolver = common.checkAjaxInput(request.form.get('updateSmonResServer')) - record_type = common.checkAjaxInput(request.form.get('updateSmonRecordType')) - packet_size = common.checkAjaxInput(request.form.get('updateSmonPacket_size')) - http_method = common.checkAjaxInput(request.form.get('updateSmon_http_method')) - - if roxywi_common.check_user_group_for_flask(): - try: - status = smon_mod.update_smon( - smon_id, name, ip, port, en, url, body, telegram, slack, pd, group, desc, check_type, - resolver, record_type, packet_size, http_method - ) - except Exception as e: - return f'{e}', 200 - else: - return status - - -@bp.route('/delete/') -@login_required -def smon_delete(smon_id): - user_group = roxywi_common.get_user_group(id=1) - - if roxywi_common.check_user_group_for_flask(): - try: - status = smon_mod.delete_smon(smon_id, user_group) - except Exception as e: - return f'{e}', 200 - else: - return status - - @bp.post('/refresh') @login_required def smon_show(): diff --git a/app/static/css/smon.css b/app/static/css/smon.css index 779214f5..3df97dd1 100644 --- a/app/static/css/smon.css +++ b/app/static/css/smon.css @@ -217,3 +217,6 @@ h4 { .tooltipTop { margin-bottom: 0; } +.add .fa-clone { + margin-bottom: 3px; +} diff --git a/app/static/css/style-6.3.9.css b/app/static/css/style-6.3.9.css index 00817076..582fef53 100644 --- a/app/static/css/style-6.3.9.css +++ b/app/static/css/style-6.3.9.css @@ -833,7 +833,10 @@ label { .div-server-head-dis { border-top: 3px solid #aaa !important; } -.div-server-head-up, .div-server-head-down, .div-server-head-dis { +.div-server-head-pause { + border-top: 3px solid orange !important; +} +.div-server-head-up, .div-server-head-down, .div-server-head-dis, .div-server-head-pause { padding-top: 7px; } .add-proxy-listen-head { @@ -980,14 +983,14 @@ label { } .group_name { font-size: 18px; - padding: 10px 20px 0px 0px; + padding: 10px 20px 0 0; } .smon_services { - width: 192px; - height: 162px; + width: 300px; + height: 185px; float: left; background-color: #fbfbfb;; - margin: 10px 10px 10px 0px; + margin: 10px 10px 10px 0; padding-left: var(--indent); padding-top: 0; border: 1px solid #A4C7F5; @@ -1020,7 +1023,7 @@ label { } .up, .down, .disable, .unknown { height: 45px; - width: 177px; + width: 281px; font-size: 30px; color: #fff; text-align: center; @@ -1034,15 +1037,11 @@ label { color: var(--red-color); background-color: #f2dede; border-color: #ebccd1; - font-size: 22px; - padding-top: 7px; - height: 38px; } .unknown { color: #856404; background-color: #fff3cd; border-color: #ffeeba; - font-size: 22px; } .disable { background-color: grey; @@ -1393,15 +1392,14 @@ label { } } .animated-background { - animation-duration: 2s; - animation-fill-mode: forwards; - animation-iteration-count: infinite; - animation-name: placeHolderShimmer; - animation-timing-function: linear; - background-color: #f6f7f8; - background: linear-gradient(to right, #eeeeee 8%, #bbbbbb 18%, #eeeeee 33%); - background-size: 800px 104px; - position: relative; + animation-duration: 2s; + animation-fill-mode: forwards; + animation-iteration-count: infinite; + animation-name: placeHolderShimmer; + animation-timing-function: linear; + background: #f6f7f8 linear-gradient(to right, #eeeeee 8%, #bbbbbb 18%, #eeeeee 33%); + background-size: 800px 104px; + position: relative; } .ping_pre { padding: 10px; diff --git a/app/templates/ajax/show_services_ovw.html b/app/templates/ajax/show_services_ovw.html index 3ed6015d..0b38fcba 100644 --- a/app/templates/ajax/show_services_ovw.html +++ b/app/templates/ajax/show_services_ovw.html @@ -125,7 +125,7 @@ {% if roxy_tools_status['roxy-wi-smon'] == 'active' %} - + SMON {% else %} diff --git a/app/templates/ajax/smon/agent.html b/app/templates/ajax/smon/agent.html new file mode 100644 index 00000000..06bbf58b --- /dev/null +++ b/app/templates/ajax/smon/agent.html @@ -0,0 +1,51 @@ +{% import 'languages/'+lang|default('en')+'.html' as lang %} +{% from 'include/input_macros.html' import input, checkbox, copy_to_clipboard %} +{% for agent in agents %} +
+
+ + {{agent.name.replace("'","")}} + {% if agent.desc != '' %} ({{agent.desc.replace("'", "")}}) {% endif %} + + + {% if g.user_params['role'] <= 3 %} + + + + + + + + + + {% endif %} + {% if g.user_params['role'] <= 2 %} + + + {% endif %} + +
+
+
+ {{ lang.words.server|title() }}: {{ copy_to_clipboard(value=agent.hostname) }} + {{ lang.words.server|title() }} IP: {{ copy_to_clipboard(value=agent.ip) }} +
+
+ {{ lang.words.version|title() }}: +
+
+ {{lang.smon_page.desc.total_checks}}: + +
+
+ {{lang.words.uptime|title()}}: +
+
+
+ +{% endfor %} diff --git a/app/templates/ajax/smon/check.html b/app/templates/ajax/smon/check.html new file mode 100644 index 00000000..5ed7c07d --- /dev/null +++ b/app/templates/ajax/smon/check.html @@ -0,0 +1,111 @@ +{% import 'languages/'+lang|default('en')+'.html' as lang %} + + +{%- for s in smon -%} + {% if s.smon_id.en == 1 %} + {% if s.smon_id.status == 1 and s.smon_id.body_status == 1 %} + {% set additional_classes = 'good div-server-head-up' %} + {% set uptime_desc = lang.words.uptime + ': ' %} + {% elif s.smon_id.status == 0 or s.smon_id.body_status == 0 %} + {% set additional_classes = 'err div-server-head-down' %} + {% set uptime_desc = lang.words.downtime + ': ' %} + {% else %} + {% set additional_classes = 'err div-server-head-down' %} + {% set uptime_desc = lang.words.uptime + ': N/A' %} + {% endif %} + {% else %} + {% set additional_classes = 'dis div-server-head-dis' %} + {% set uptime_desc = lang.words.uptime + ': N/A' %} + {% endif %} +
+
+ {{s.smon_id.name.strip("'")}} + {% set agent_exist = [] %} + {% for a in agents %} + {% if a.id|string() == s.agent_id|string() %} + {% if agent_exist.append(1) %} {% endif %} + {% endif %} + {% endfor %} + {% if agent_exist|length == 0 %} + ! + {% endif %} + + + + + + +
+
+ {% if s.smon_id.desc %} + {{s.smon_id.desc.strip("'")}} + {% else %} + {{lang.words.desc|title()}}: {{lang.words.none}} + {% endif %} +
+
+ {{uptime_desc|safe}} +
+
+ {% if s.smon_id.en == 1 %} + {% if s.smon_id.status == 1 %} + {{lang.smon_page.desc.resp_time}}: + {% else %} + {{lang.smon_page.desc.last_resp_time}}: + {% endif %} + {% if s.smon_id.response_time %} + {{s.smon_id.response_time|truncate(9)}} ms + {% else %} + N/A + {% endif %} + {% else %} + N/A + {% endif %} +
+
+ {{ lang.smon_page.desc.enabled_checks }} {{ s.smon_id.check_type|upper }} + {{lang.words.agent|title()}}: + {% for a in agents %} + {% if a.id|string() == s.agent_id|string() %} + {{ a.name }} + {% endif %} + {% endfor %} +
+ {% if s.smon_id.en == 1 and agent_exist|length > 0 %} + {% if s.smon_id.status == 1 and s.smon_id.body_status == 1 %} +
+ {{lang.smon_page.desc.UP}} +
+ {% elif s.smon_id.status == 0 and s.smon_id.check_type == 'http' %} +
+ {{lang.smon_page.desc.HTTP_FAILURE}} +
+ {% elif s.smon_id.body_status == 0 %} +
+ {{lang.smon_page.desc.BODY_FAILURE}} +
+ {% elif s.smon_id.status == 3 %} +
+ {{lang.smon_page.desc.UNKNOWN}} +
+ {% else %} +
+ {{lang.smon_page.desc.DOWN}} +
+ {% endif %} + {% elif agent_exist|length == 0 %} +
+ {{lang.smon_page.desc.UNKNOWN}} +
+ {% else %} +
+ {{lang.smon_page.desc.DISABLED}} +
+ {% endif %} + +
+{%- endfor -%} diff --git a/app/templates/ajax/smon/show_new_smon.html b/app/templates/ajax/smon/show_new_smon.html deleted file mode 100644 index 83d4b99d..00000000 --- a/app/templates/ajax/smon/show_new_smon.html +++ /dev/null @@ -1,16 +0,0 @@ -{% import 'languages/'+lang|default('en')+'.html' as lang %} -{% from 'include/input_macros.html' import input, checkbox, select %} -{% for s in smon %} - {% for s_service in smon_service %} - - {% if check_type == 'tcp' %} - {% include 'include/smon/smon_tcp_server.html' %} - {% elif check_type == 'ping' %} - {% include 'include/smon/smon_ping_server.html' %} - {% elif check_type == 'http' %} - {% include 'include/smon/smon_http_server.html' %} - {% elif check_type == 'dns' %} - {% include 'include/smon/smon_dns_server.html' %} - {% endif %} - {% endfor %} -{% endfor %} diff --git a/app/templates/ajax/smon/smon_dashboard.html b/app/templates/ajax/smon/smon_dashboard.html index ed0e77f9..e8ad767b 100644 --- a/app/templates/ajax/smon/smon_dashboard.html +++ b/app/templates/ajax/smon/smon_dashboard.html @@ -1,6 +1,7 @@ {% if update %} {% import 'languages/'+lang|default('en')+'.html' as lang %} {% endif %} +{% set checking_types = {'tcp': '1', 'http': '2', 'ping': '4', 'dns': '5'} %}
{% set down = [] %} @@ -19,130 +20,30 @@ {% endfor %} {{lang.smon_page.desc.status_summary}}: {{lang.smon_page.desc.UP}}: {{up|length}}, {{lang.smon_page.desc.DOWN}}: {{down|length}}, {{lang.words.disabled|title()}}: {{dis|length}}
- {{lang.smon_page.desc.do_not_sort}} | - {{lang.smon_page.desc.sort_status}} | - {{lang.words.refresh|title()}} + {{lang.smon_page.desc.do_not_sort}} | + {{lang.smon_page.desc.sort_status}} | + {{lang.words.refresh|title()}}
{% set group = [] %} {% set group_prev = [] %} -{%- for s in smon -%} - {% set checks = lang.smon_page.desc.enabled_checks +':
' %} - {% if s.check_type == 'tcp' %} - {% set checks = checks + lang.phrases.port_check %} - {% set check_id = 1 %} - {% endif %} - {% if s.check_type == 'http' %} - {% set checks = checks + lang.smon_page.desc.http_status_check %} - {% set check_id = 2 %} - {% if s.ssl_expire_date %} - {% set checks = checks + ',
SSL ' + lang.words.expire + ': ' + s.ssl_expire_date %} - {% endif %} - {% endif %} - {% if s.check_type == 'ping' %} - {% set check_id = 4 %} - {% set checks = lang.smon_page.desc.enabled_checks +': Ping' %} - {% endif %} - {% if s.check_type == 'dns' %} - {% set check_id = 5 %} - {% set checks = lang.smon_page.desc.enabled_checks +': DNS' %} - {% endif %} - {% if s.en == 1 %} - {% if s.status == 1 and s.body_status == 1 %} - {% set additional_classes = 'good div-server-head-up' %} - {% set uptime_desc = lang.words.uptime + ': ' %} - {% elif s.status == 0 or s.body_status == 0 %} - {% set additional_classes = 'err div-server-head-down' %} - {% set uptime_desc = lang.words.downtime + ': ' %} - {% else %} - {% set additional_classes = 'err div-server-head-down' %} - {% set uptime_desc = lang.words.uptime + ': N/A' %} - {% endif %} - {% else %} - {% set additional_classes = 'dis div-server-head-dis' %} - {% set uptime_desc = lang.words.uptime + ': N/A' %} - {% endif %} - {% set additional_style = '' %} - {% if s.name|string|length > 23 %} - {% set additional_style = 'font-size: 11px;' %} - {% elif s.name|string|length > 20 %} - {% set additional_style = 'font-size: 12px;' %} - {% elif s.name|string|length > 17 %} - {% set additional_style = 'font-size: 15px;' %} - {% endif %} - {% if s.group not in group %} -
-
- {% if s.group %} {{ s.group }} {% else %} None {% endif %} +
+ {%- for s in smon -%} + {% if s.group not in group %} +
+
+ {% if s.group %} {{ s.group }} {% else %} None {% endif %} +
-
- {% endif %} - {% if group.append(s.group) %} {% endif %} -
- -
- {% if s.desc %} - {{s.desc.strip("'")}} - {% else %} - {{lang.words.desc|title()}}: {{lang.words.none}} {% endif %} -
-
- {{uptime_desc|safe}} -
-
- {% if s.en == 1 %} - {% if s.status == 1 %} - {{lang.smon_page.desc.resp_time}}: - {% else %} - {{lang.smon_page.desc.last_resp_time}}: - {% endif %} - {% if s.response_time %} - {{s.response_time|truncate(9)}} ms - {% else %} - N/A - {% endif %} - {% else %} - N/A - {% endif %} -
- {% if s.en == 1 %} - {% if s.status == 1 and s.body_status == 1 %} -
- {{lang.smon_page.desc.UP}} -
- {% elif s.status == 0 and s.check_type == 'http' %} -
- {{lang.smon_page.desc.HTTP_FAILURE}} -
- {% elif s.body_status == 0 %} -
- {{lang.smon_page.desc.BODY_FAILURE}} -
- {% elif s.status == 3 %} -
- {{lang.smon_page.desc.UNKNOWN}} -
- {% else %} -
- {{lang.smon_page.desc.DOWN}} -
- {% endif %} - {% else %} -
- {{lang.smon_page.desc.DISABLED}} -
- {% endif %} -
-{% endfor %} + {% if group.append(s.group) %} {% endif %} +
+ {% set check_id = checking_types[s.check_type] %} + + {% endfor %} +
@@ -16,7 +17,7 @@ {% set section = namespace(section='') %} {% for set in settings %} - {% if page == "servers.py" and (set.section in ('monitoring', 'rabbitmq', 'mail')) %} + {% if page == "servers.py" and (set.section in ('monitoring', 'rabbitmq', 'mail', 'smon')) %} {% else %} {% if section.section|string() != set.section|string() %} @@ -47,10 +48,9 @@ {{ input(set.param, size='25', type='password', style='width: 210px;', placeholder='******') }} {% endif %} {% elif set.param in ('nginx_stats_port', 'session_ttl', 'token_ttl', 'haproxy_stats_port', 'haproxy_sock_port', - 'ldap_port', 'log_time_storage', 'smon_check_interval', 'checker_check_interval', 'port_scan_interval', - 'smon_keep_history_range', 'checker_keep_history_range', 'portscanner_keep_history_range', - 'checker_maxconn_threshold', 'apache_stats_port', 'mail_smtp_port', 'rabbitmq_port', 'smon_ssl_expire_warning_alert', - 'smon_ssl_expire_critical_alert', 'action_keep_history_range') %} + 'ldap_port', 'log_time_storage', 'checker_check_interval', 'port_scan_interval', 'smon_keep_history_range', + 'checker_keep_history_range', 'portscanner_keep_history_range', 'checker_maxconn_threshold', 'apache_stats_port', + 'mail_smtp_port', 'rabbitmq_port', 'smon_ssl_expire_warning_alert', 'smon_ssl_expire_critical_alert', 'action_keep_history_range') %} {{ input(set.param, value=set.value, style='width: 210px;', type='number') }} {% elif set.param == 'time_zone' %} + + {% for agent in agents %} + + {% endfor %} + + + + + + {{lang.words.checking|title()}} + * + + + {% set check_types = {'dns': 'DNS', 'ping': 'Ping', 'tcp': 'TCP/UDP', 'http': 'HTTP(s)'} %} + {{ select('check_type', values=check_types, selected='http') }} + + + + + {{lang.phrases.check_interval}} + * + + + {{ input('new-smon-interval', value='120', type='number', placeholder='120', title=lang.phrases.check_interval_title) }} + + + + + {{lang.words.Hostname}} + * + + + {{ input('new-smon-ip') }} + + + + + {{lang.smon_page.desc.packet_size}} + * + + + {{ input('new-smon-packet_size', value='56', type='number', placeholder='56') }} + + + + + Resolver {{lang.words.server}} + * + + + {{ input('new-smon-resolver-server', value='8.8.8.8') }} + + + + + {{lang.words.port|title()}} + * + + + {{ input('new-smon-port', type='number', size='4') }} + + + + + URL + * + + {{ input('new-smon-url', value='https://', title='proto://url[:port]/', placeholder='proto://url[:port]/') }} + + + {{lang.words.body|title()}} + {{ input('new-smon-body') }} + + + HTTP {{lang.words.method}} + + {% set http_methods = {'get': 'GET', 'post': 'POST', 'put': 'PUT', 'patch': 'PATCH', 'delete': 'DELETE', + 'head': 'HEAD', 'options': 'OPTIONS'} %} + {{ select('new-smon-method', values=http_methods, selected='get') }} + + + + {{lang.words.enable|title()}} + + {{ checkbox('new-smon-enable', checked='checked') }} + + + + + {{lang.phrases.resource_record_type}} + * + + + {% set check_types = {'a': 'A', 'aaa': 'AAA', 'caa': 'CAA', 'cname': 'CNAME', 'mx': 'MX', 'ns': 'NS', + 'ptr': 'PTR', 'sao': 'SAO', 'srv': 'SRV', 'txt': 'TXT'} %} + {{ select('new-smon-dns_record_type', values=check_types, selected='a') }} + + + + Telegram + + + + + + Slack + + + + + + PagerDuty + + + + + + {{lang.words.group|title()}} + {{ input('new-smon-group') }} + + + {{lang.words.desc|title()}} + {{ input('new-smon-description') }} + + + {% include 'include/del_confirm.html' %} +
\ No newline at end of file diff --git a/app/templates/include/smon/smon_dns_server.html b/app/templates/include/smon/smon_dns_server.html deleted file mode 100644 index 37a0b1ae..00000000 --- a/app/templates/include/smon/smon_dns_server.html +++ /dev/null @@ -1,105 +0,0 @@ - - {% set id = 'smon-name-' + s.id|string() %} - {{ input(id, value=s.name.strip("'"), size='20') }} - - - {% set id = 'smon-ip-' + s.id|string() %} - {{ input(id, value=s_service.ip, size='20') }} - - - {% set id = 'smon-resolver-' + s.id|string() %} - {{ input(id, value=s_service.resolver, size='20') }} - - - {% set id = 'smon-port-' + s.id|string() %} - {{ input(id, value=s_service.port, size='5') }} - - - {% set id = 'smon-record_type-' + s.id|string() %} - {% set check_types = {'a': 'A', 'aaa': 'AAA', 'caa': 'CAA', 'cname': 'CNAME', 'mx': 'MX', 'ns': 'NS', - 'ptr': 'PTR', 'sao': 'SAO', 'srv': 'SRV', 'txt': 'TXT'} %} - {{ select(id, values=check_types, selected=s_service.record_type) }} - - - {% set id = 'smon-enable-' + s.id|string() %} - {% if s.en == 1 %} - {{ checkbox(id, checked='checked') }} - {% else %} - {{ checkbox(id) }} - {% endif %} - - - - - - - - - - - - {% set id = 'smon-group-' + s.id|string() %} - {% if s.group is not none %} - {{ input(id, value=s.group, size='15') }} - {% else %} - {{ input(id, size='15') }} - {% endif %} - - - {% set id = 'smon-desc-' + s.id|string() %} - {% if s.desc is not none %} - {{ input(id, value=s.desc.strip("'"), size='20') }} - {% else %} - {{ input(id, size='20') }} - {% endif %} - - - - - - - - - diff --git a/app/templates/include/smon/smon_history.html b/app/templates/include/smon/smon_history.html index 61f9e003..ab600b47 100644 --- a/app/templates/include/smon/smon_history.html +++ b/app/templates/include/smon/smon_history.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +`{% extends "base.html" %} {% from 'include/input_macros.html' import select %} {% block title %}{{ lang.menu_links.history.title }} {{ smon_name }}{% endblock %} {% block h2 %}{{ lang.menu_links.history.title }} {{ smon_name }}{% endblock %} @@ -25,17 +25,23 @@ {{s.smon_id.name}} {% endif %} -{% endfor %}
-
{{lang.words.checking|title()}} {{lang.words.every}} {{check_interval}} {{lang.words.minutes2}}
+
+ {{lang.words.checking|title()}} {{lang.words.every}} {{s.interval}} {{lang.words.seconds2}}, + {{ lang.words.agent|title() }} + {% for a in agents %} + {% if a.id|string() == s.agent_id|string() %} + {{ a.name }} + {% endif %} + {% endfor %} +
- {% for s in smon %}

{{lang.words.checking|title()}}

({{lang.words.type|title()}})

diff --git a/app/templates/include/smon/smon_http_server.html b/app/templates/include/smon/smon_http_server.html deleted file mode 100644 index cc3931c9..00000000 --- a/app/templates/include/smon/smon_http_server.html +++ /dev/null @@ -1,101 +0,0 @@ - - {% set id = 'smon-name-' + s.id|string() %} - {{ input(id, value=s.name.strip("'"), size='20') }} - - - {% set id = 'smon-url-' + s.id|string() %} - {{ input(id, value=s_service.url, size='20') }} - - - {% set id = 'smon-enable-' + s.id|string() %} - {% if s.en == 1 %} - {{ checkbox(id, checked='checked') }} - {% else %} - {{ checkbox(id) }} - {% endif %} - - - {% set id = 'smon-body-' + s.id|string() %} - {{ input(id, value=s_service.body, size='20') }} - - - {% set id = 'smon-http_method-' + s.id|string() %} - {% set http_methods = {'get': 'GET', 'post': 'POST', 'put': 'PUT', 'patch': 'PATCH', 'delete': 'DELETE', - 'head': 'HEAD', 'options': 'OPTIONS'} %} - {{ select(id, values=http_methods, selected=s_service.method) }} - - - - - - - - - - - - {% set id = 'smon-group-' + s.id|string() %} - {% if s.group is not none %} - {{ input(id, value=s.group, size='15') }} - {% else %} - {{ input(id, size='15') }} - {% endif %} - - - {% set id = 'smon-desc-' + s.id|string() %} - {% if s.desc is not none %} - {{ input(id, value=s.desc.strip("'"), size='20') }} - {% else %} - {{ input(id, size='20') }} - {% endif %} - - - - - - - - - diff --git a/app/templates/include/smon/smon_ping_server.html b/app/templates/include/smon/smon_ping_server.html deleted file mode 100644 index a692ca95..00000000 --- a/app/templates/include/smon/smon_ping_server.html +++ /dev/null @@ -1,92 +0,0 @@ - - {% set id = 'smon-name-' + s.id|string() %} - {{ input(id, value=s.name, size='20') }} - - - {% set id = 'smon-ip-' + s.id|string() %} - {{ input(id, value=s_service.ip, size='20') }} - - - {% set id = 'smon-packet_size-' + s.id|string() %} - {{ input(id, value=s_service.packet_size, style='width: 40px;', type='number') }} - - - {% set id = 'smon-enable-' + s.id|string() %} - {% if s.en == 1 %} - {{ checkbox(id, checked='checked') }} - {% else %} - {{ checkbox(id) }} - {% endif %} - - - - - - - - - - - - {% set id = 'smon-group-' + s.id|string() %} - {% if s.group is not none %} - {{ input(id, value=s_service.group, size='15') }} - {% else %} - {{ input(id, size='15') }} - {% endif %} - - - {% set id = 'smon-desc-' + s.id|string() %} - {% if s.desc is not none %} - {{ input(id, value=s.desc.strip("'"), size='20') }} - {% else %} - {{ input(id, size='20') }} - {% endif %} - - - - - - - - - diff --git a/app/templates/include/smon/smon_tcp_server.html b/app/templates/include/smon/smon_tcp_server.html deleted file mode 100644 index e9e15dff..00000000 --- a/app/templates/include/smon/smon_tcp_server.html +++ /dev/null @@ -1,92 +0,0 @@ - - {% set id = 'smon-name-' + s.id|string() %} - {{ input(id, value=s.name.strip("'"), size='20') }} - - - {% set id = 'smon-ip-' + s.id|string() %} - {{ input(id, value=s_service.ip, size='20') }} - - - {% set id = 'smon-port-' + s.id|string() %} - {{ input(id, value=s_service.port, size='5') }} - - - {% set id = 'smon-enable-' + s.id|string() %} - {% if s.en == 1 %} - {{ checkbox(id, checked='checked') }} - {% else %} - {{ checkbox(id) }} - {% endif %} - - - - - - - - - - - - {% set id = 'smon-group-' + s.id|string() %} - {% if s.group is not none %} - {{ input(id, value=s.group, size='15') }} - {% else %} - {{ input(id, size='15') }} - {% endif %} - - - {% set id = 'smon-desc-' + s.id|string() %} - {% if s.desc is not none %} - {{ input(id, value=s.desc.strip("'"), size='20') }} - {% else %} - {{ input(id, size='20') }} - {% endif %} - - - - - - - - - diff --git a/app/templates/languages/en.html b/app/templates/languages/en.html index 45a858cf..f8c82f8b 100644 --- a/app/templates/languages/en.html +++ b/app/templates/languages/en.html @@ -99,7 +99,7 @@ "dashboard": "SMON: Dashboard", "status_page": "SMON: Status page", "history": "SMON: History", - "admin": "SMON: Admin panel", + "agent": "SMON: Agent", }, "checker_history": "Checker: History", "port_scan": "Port scanner", @@ -153,17 +153,21 @@ "nginx_container_name": "Docker container name for NGINX service", }, "monitoring": { - "smon_check_interval": "Check interval for SMON (in minutes)", "port_scan_interval": "Check interval for Port scanner (in minutes)", "portscanner_keep_history_range": "Retention period for Port scanner history", - "smon_keep_history_range": "Retention period for SMON history", "checker_keep_history_range": "Retention period for Checker history", "checker_maxconn_threshold": "Threshold value for maxconn alerting, in %", "checker_check_interval": "Check interval for Checker (in minutes)", - "smon_ssl_expire_warning_alert": "Warning alert about a SSL certificate expiration (in days)", - "smon_ssl_expire_critical_alert": "Critical alert about a SSL certificate expiration (in days)", "action_keep_history_range": "Retention period for Action history (in days)", }, + "smon": { + "master_ip": "IP or name to connect to the SMON master", + "master_port": "Port for connecting to the SMON master", + "agent_port": "Agent SMON port", + "smon_keep_history_range": "Retention period for SMON history", + "smon_ssl_expire_warning_alert": "Warning alert about a SSL certificate expiration (in days)", + "smon_ssl_expire_critical_alert": "Critical alert about a SSL certificate expiration (in days)", + }, "main": { "time_zone": "Time Zone", "proxy": "IP address and port of the proxy server. Use proto://ip:port", @@ -323,6 +327,8 @@ "create_page_status": "Create status page", "not_in_cluster": "Not in a cluster", "ssh_passphrase": "SSH key passphrase", + "check_interval": "Check interval.", + "check_interval_title": "Check interval. In seconds.", } %} {% set roles = { @@ -467,6 +473,9 @@ "PORT_DOWN": "PORT DOWN", "DISABLED": "DISABLED", "packet_size": "Packet size", + "add_agent": "Add Agent", + "total_checks": "Total checks", + "not_assign_to_agent": "The check is not assigned to any agent" } } %} @@ -722,6 +731,7 @@ "virt": "virt", "virtual": "virtual", "check": "check", + "check2": "check", "checks": "checks", "checking": "checking", "protected": "protected", @@ -909,5 +919,7 @@ "method": "method", "tools": "tools", "next": "next", + "agent": "agent", + "agent2": "agent", } %} diff --git a/app/templates/languages/fr.html b/app/templates/languages/fr.html index 264eef6c..af6834f7 100644 --- a/app/templates/languages/fr.html +++ b/app/templates/languages/fr.html @@ -99,7 +99,7 @@ "dashboard": "SMON: tableau de bord", "status_page": "SMON: Page d'état", "history": "SMON: Historique", - "admin": "SMON: Panneau administrateur", + "agent": "SMON: Agent", }, "checker_history": "Vérificateur: Historique", "port_scan": "Scanner de port", @@ -153,17 +153,21 @@ "nginx_container_name": "Nom du container Docker pour le service NGINX", }, "monitoring": { - "smon_check_interval": "Interval de vérification pour SMON (en minutes)", "port_scan_interval": "Interval de vérification pour le scanner de Port (en minutes)", "portscanner_keep_history_range": "Période de rétention pour l\'historiques le scanner de Port", - "smon_keep_history_range": "Période de rétention pour l\'historiques de SMON", "checker_keep_history_range": "Période de rétention pour l\'historiques de Checker", "checker_maxconn_threshold": "Valeur du seuil pour les alertes maxconn, en %", "checker_check_interval": "Valeur du seuil pour les alertes maxconn, en %", - "smon_ssl_expire_warning_alert": "Alerte type warning dès qu'un certificat SSL expire (en jours)", - "smon_ssl_expire_critical_alert": "Alerte tpye critical dès qu'un certificat SSL expire (en jours)", "action_keep_history_range": "Période de conservation de l'historique des actions (en jours)", }, + "smon": { + "master_ip": "IP ou nom pour se connecter au maître SMON", + "master_port": "Port de connexion au maître SMON", + "agent_port": "Port SMON de l'agent", + "smon_keep_history_range": "Période de rétention pour l\'historiques de SMON", + "smon_ssl_expire_warning_alert": "Alerte type warning dès qu'un certificat SSL expire (en jours)", + "smon_ssl_expire_critical_alert": "Alerte tpye critical dès qu'un certificat SSL expire (en jours)", + }, "main": { "time_zone": "Fuseau horaire", "proxy": "Adresse IP et port du proxy server. format proto://ip:port", @@ -323,6 +327,8 @@ "create_page_status": "Créer une page de statut", "not_in_cluster": "Pas dans un cluster", "ssh_passphrase": "Phrase secrète de la clé SSH", + "check_interval": "Vérifiez l'intervalle", + "check_interval_title": "Vérifiez l'intervalle. En secondes.", } %} {% set roles = { @@ -467,6 +473,9 @@ "PORT_DOWN": "PORT DOWN", "DISABLED": "DÉSACTIVÉ", "packet_size": "Taille du paquet", + "add_agent": "Ajouter un agent", + "total_checks": "Chèques totaux", + "not_assign_to_agent": "Le chèque n'est attribué à aucun agent" } } %} @@ -722,6 +731,7 @@ "virt": "virt", "virtual": "virtuel", "check": "contrôler", + "check2": "contrôler", "checks": "vérifications", "checking": "vérifier", "protected": "protégé", @@ -909,5 +919,7 @@ "method": "méthode", "tools": "outils", "next": "suivante", + "agent": "agent", + "agent2": "agent", } %} diff --git a/app/templates/languages/pt-br.html b/app/templates/languages/pt-br.html index 6b906e12..33b580af 100644 --- a/app/templates/languages/pt-br.html +++ b/app/templates/languages/pt-br.html @@ -99,7 +99,7 @@ "dashboard": "SMON: Painel", "history": "SMON: Histórico", "status_page": "SMON: Página de status", - "admin": "SMON: Painel de administrador" + "agent": "SMON: Agente", }, "checker_history": "Checker: Histórico", "port_scan": "Port scanner", @@ -153,17 +153,21 @@ "nginx_container_name": "Nome do container Docker de NGINX", }, "monitoring": { - "smon_check_interval": "Intervalo de verificação para o SMON (em minutos)", "port_scan_interval": "Intervalo de verificação para o Port scanner (em minutos)", "portscanner_keep_history_range": "Período de retenção de historico de Port scanner", - "smon_keep_history_range": "Período de retenção de historico de SMON", "checker_keep_history_range": "Período de retenção de historico de Checker", "checker_maxconn_threshold": "Valor limite para a notificação de maxconn, em %", "checker_check_interval": "Intervalo de verificação para o Checker (em minutos)", - "smon_ssl_expire_warning_alert": "Aviso de alerta sobre a expiração do certificado SSL (em dias)", - "smon_ssl_expire_critical_alert": "Alerta critico a expiração do certificado SSL (em dias)", "action_keep_history_range": "Período de retenção do histórico de ações (em dias)", }, + "smon": { + "master_ip": "IP ou nome para conectar ao mestre SMON", + "master_port": "Porta para conexão ao mestre SMON", + "agent_port": "Porta SMON do agente", + "smon_keep_history_range": "Período de retenção de historico de SMON", + "smon_ssl_expire_warning_alert": "Aviso de alerta sobre a expiração do certificado SSL (em dias)", + "smon_ssl_expire_critical_alert": "Alerta critico a expiração do certificado SSL (em dias)", + }, "main": { "time_zone": "Fuso horário.", "proxy": "Endereço e porta de prowy. Utiliza proto://ip:port", @@ -323,6 +327,8 @@ "create_page_status": "Criar página de status", "not_in_cluster": "Não em um cluster", "ssh_passphrase": "Senha da chave SSH", + "check_interval": "Verifique o intervalo", + "check_interval_title": "Verifique o intervalo. Em segundos.", } %} {% set roles = { @@ -467,6 +473,9 @@ "PORT_DOWN": "PORT DOWN", "DISABLED": "DESABIL.", "packet_size": "Tamanho do pacote", + "add_agent": "Adicionar agente", + "total_checks": "Cheques totais", + "not_assign_to_agent": "O cheque não é atribuído a nenhum agente" } } %} @@ -722,6 +731,7 @@ "virt": "virt", "virtual": "virtual", "check": "verificar", + "check2": "verificar", "checks": "verificações", "checking": "verificando", "protected": "protegido", @@ -909,5 +919,7 @@ "method": "método", "tools": "ferramentas", "next": "próxima", + "agent": "agente", + "agent2": "agente", } %} diff --git a/app/templates/languages/ru.html b/app/templates/languages/ru.html index 78b3d8db..6a2ebc64 100644 --- a/app/templates/languages/ru.html +++ b/app/templates/languages/ru.html @@ -99,7 +99,7 @@ "dashboard": "SMON: Дашборд", "status_page": "SMON: Страница статуса", "history": "SMON: История", - "admin": "SMON: Админка", + "agent": "SMON: Агент", }, "checker_history": "Checker: История", "port_scan": "Сканер портов", @@ -153,17 +153,21 @@ "nginx_container_name": "Имя Docker контейнера для сервиса NGINX", }, "monitoring": { - "smon_check_interval": "Интервал проверки для SMON (в минутах)", "port_scan_interval": "Интервал проверки для Port scanner (в минутах)", "portscanner_keep_history_range": "Время хранения истории Port scanner", - "smon_keep_history_range": "Время хранения истории SMON", "checker_keep_history_range": "Время хранения истории Checker", "checker_maxconn_threshold": "Порог срабатывания уведомления по maxconn, в %", "checker_check_interval": "Интервал проверки для Checker (в минутах)", - "smon_ssl_expire_warning_alert": "Предупреждение о истечении SSL-сертификата (в днях)", - "smon_ssl_expire_critical_alert": "Критическое предупреждение о истечении SSL-сертификата (в днях)", "action_keep_history_range": "Время хранения истории действий (в днях)", }, + "smon": { + "master_ip": "IP или имя для подключения к SMON мастеру", + "master_port": "Порт для подключения к SMON мастеру", + "agent_port": "Порт SMON агента", + "smon_keep_history_range": "Время хранения истории SMON", + "smon_ssl_expire_warning_alert": "Предупреждение о истечении SSL-сертификата (в днях)", + "smon_ssl_expire_critical_alert": "Критическое предупреждение о истечении SSL-сертификата (в днях)", + }, "main": { "time_zone": "Временная зона", "proxy": "IP-адрес и порт прокси сервера. Формат: proto://ip:port", @@ -323,6 +327,8 @@ "create_page_status": "Создать страницу статуса", "not_in_cluster": "Не в кластере", "ssh_passphrase": "Ключевая фраза SSH", + "check_interval": "Интервал проверки", + "check_interval_title": "Интервал проверки. В секундах.", } %} {% set roles = { @@ -467,6 +473,9 @@ "PORT_DOWN": "ПОРТ НЕ ДОСТ.", "DISABLED": "ОТКЛ.", "packet_size": "Размер пакета", + "add_agent": "Добавить Агента", + "total_checks": "Всего проверок", + "not_assign_to_agent": "Чек не назначен ни одному агенту" } } %} @@ -722,6 +731,7 @@ "virt": "вирт", "virtual": "виртуальный", "check": "проверить", + "check2": "проверку", "checks": "проверки", "checking": "проверка", "protected": "защищенный", @@ -909,5 +919,7 @@ "method": "метод", "tools": "инструменты", "next": "дальше", + "agent": "агент", + "agent2": "агента", } %} diff --git a/app/templates/logs_internal.html b/app/templates/logs_internal.html index cc9e6ab9..6665ba4b 100644 --- a/app/templates/logs_internal.html +++ b/app/templates/logs_internal.html @@ -24,7 +24,11 @@
- - {% for t in telegrams %} - - {% endfor %} - - - - - Slack - - - - - - PagerDuty - - - - - - {{lang.words.group|title()}} - {{ input('new-smon-group') }} - - - {{lang.words.desc|title()}} - {{ input('new-smon-description') }} - - - {% include 'include/del_confirm.html' %} -
-{% endif %} -{% endblock %} \ No newline at end of file diff --git a/app/templates/smon/agent.html b/app/templates/smon/agent.html new file mode 100644 index 00000000..cd27a199 --- /dev/null +++ b/app/templates/smon/agent.html @@ -0,0 +1,79 @@ +{% extends "base.html" %} +{% block title %}{{ lang.menu_links.monitoring.smon.agent }}{% endblock %} +{% block h2 %}{{ lang.menu_links.monitoring.smon.agent }}{% endblock %} +{% block content %} +{% from 'include/input_macros.html' import input, select %} + + + + + +{% if user_subscription['user_status'] == 0 %} + {% include 'include/no_sub.html' %} +{% elif smon_status in ('failed', 'inactive', 'ERROR') %} +
+
+

{{lang.smon_page.desc.smon_is_not_run}}

+ There is no server +

{{lang.smon_page.desc.run_smon}} {{lang.words.here}} {{lang.smon_page.desc.before_use}}

+
+{% else %} +{% if g.user_params['role'] <= 2 %} +
+ {{lang.smon_page.desc.add_agent}}
+{% endif %} +
+ {% for agent in agents %} +
+ {% endfor %} +
+ + +{% endif %} + +{% endblock %} diff --git a/app/templates/smon/dashboard.html b/app/templates/smon/dashboard.html index 20e145a1..a1626597 100644 --- a/app/templates/smon/dashboard.html +++ b/app/templates/smon/dashboard.html @@ -1,11 +1,15 @@ {% extends "base.html" %} {% block title %}{{ lang.menu_links.monitoring.smon.dashboard }}{% endblock %} {% block h2 %}{{ lang.menu_links.monitoring.smon.dashboard }}{% endblock %} +{% from 'include/input_macros.html' import input, checkbox, select %} {% block content %} + + + {% if user_subscription['user_status'] == 0 %} {% include 'include/no_sub.html' %} {% elif smon_status in ('failed', 'inactive', 'ERROR') %} @@ -17,15 +21,25 @@
{% elif smon|length == 0 %}
+ {% if g.user_params['role'] <= 3 %} +
+ {{lang.words.add|title()}} {{ lang.words.check2 }}
+ {% endif %}

{{lang.smon_page.desc.not_added}}

There is no server

{{lang.smon_page.desc.create_server}} {{lang.words.here}} {{lang.smon_page.desc.before_use}}


+ {% if g.user_params['role'] <= 3 %} +
+ {{lang.words.add|title()}} {{ lang.words.check2 }}
+ {% endif %} {% else %} + {% if g.user_params['role'] <= 3 %} +
+ {{lang.words.add|title()}} {{ lang.words.check2 }}
+ {% endif %}
{% include 'ajax/smon/smon_dashboard.html' %}
{% endif %} -{% endblock %} \ No newline at end of file +{% include 'include/smon/add_form.html' %} +{% endblock %} diff --git a/inc/admin_settings.js b/inc/admin_settings.js index 73043aac..f0e865c3 100644 --- a/inc/admin_settings.js +++ b/inc/admin_settings.js @@ -29,6 +29,9 @@ $( function() { $('#mail-section-head').click(function () { hideAndShowSettings('mail'); }); + $('#smon-section-head').click(function () { + hideAndShowSettings('smon'); + }); $( "#settings select" ).on('select2:select',function() { var id = $(this).attr('id'); var val = $(this).val(); diff --git a/inc/script.js b/inc/script.js index 81e59c69..519bb5b9 100644 --- a/inc/script.js +++ b/inc/script.js @@ -96,13 +96,13 @@ $( function() { show_current_page($(this)) } else if (full_uri == 'smon/dashboard' && full_uri1 == 'smon/dashboard') { show_current_page($(this)) - } else if (full_uri == 'smon/admin' && full_uri1 == 'smon/admin') { + } else if (full_uri == 'smon/agent' && full_uri1 == 'smon/agent') { show_current_page($(this)) } else if (full_uri == 'smon/history' && full_uri1 == 'smon/history') { show_current_page($(this)) } else if (full_uri == 'smon/status-page' && full_uri1 == 'smon/status-page') { show_current_page($(this)) - } else if (full_uri == 'checker/settings' && full_uri1 == 'checker/settings') { + } else if (full_uri === 'checker/settings' && full_uri1 === 'checker/settings') { show_current_page($(this)) } else if (full_uri == 'checker/history' && full_uri1 == 'checker/history') { show_current_page($(this)) @@ -133,7 +133,7 @@ jQuery.expr[':'].regex = function(elem, index, match) { var matchParams = match[3].split(','), validLabels = /^(data|css):/, attr = { - method: matchParams[0].match(validLabels) ? + method: matchParams[0].match(validLabels) ? matchParams[0].split(':')[0] : 'attr', property: matchParams.shift().replace(validLabels,'') }, @@ -149,12 +149,12 @@ window.onblur= function() { } else if (cur_url[0] == "stats") { showStats() } else if (cur_url[0] == "/") { - showOverview(); + showOverview(); } else if (cur_url[0] == "internal") { viewLogs(); } else if (cur_url[0] == "metrics") { showMetrics(); - } else if (cur_url[0] == "smon" && cur_url[1] == "dasboards") { + } else if (cur_url[0] == "smon" && cur_url[1] == "dashboard") { showSmon('refresh') } } @@ -277,7 +277,7 @@ function startSetInterval(interval) { } intervalId = setInterval('showMetrics()', interval); showMetrics(); - } else if (cur_url[0] == "smon" && cur_url[1] == "dashboards") { + } else if (cur_url[0] == "smon" && cur_url[1] == "dashboard") { intervalId = setInterval("showSmon('refresh')", interval); showSmon('refresh'); } else if (cur_url[0] == "smon" && cur_url[1] == "history") { @@ -305,7 +305,7 @@ function pauseAutoResume(){ function hideAutoRefreshDiv() { $(function() { $('.auto-refresh-div').hide("blind", "fast"); - $('#1').css("display", "none"); + $('#1').css("display", "none"); $('#0').css("display", "inline"); }); } diff --git a/inc/smon.js b/inc/smon.js index f114bfb3..f72f1452 100644 --- a/inc/smon.js +++ b/inc/smon.js @@ -1,3 +1,12 @@ +let add_word = $('#translate').attr('data-add'); +const delete_word = $('#translate').attr('data-delete'); +const cancel_word = $('#translate').attr('data-cancel'); +const check_types = {'tcp': 1, 'http': 2, 'ping': 4, 'dns': 5}; +$(function () { + $( "#check_type" ).on('selectmenuchange',function() { + check_and_clear_check_type($('#check_type').val()); + }); +}); function sort_by_status() { $('
').appendTo('.main'); $('
').appendTo('.main'); @@ -10,11 +19,10 @@ function sort_by_status() { window.history.pushState("SMON Dashboard", "SMON Dashboard", cur_url[0]+"?action=view&sort=by_status"); } function showSmon(action) { - var sort = ''; - var location = window.location.href; - var cur_url = '/app/' + location.split('/').pop(); - console.log(cur_url) - if (action == 'refresh') { + let sort = ''; + let location = window.location.href; + let cur_url = '/app/' + location.split('/').pop(); + if (action === 'refresh') { try { sort = cur_url[1].split('&')[1]; sort = sort.split('=')[1]; @@ -35,112 +43,104 @@ function showSmon(action) { } else { toastr.clear(); $("#smon_dashboard").html(data); - // if (action == 'not_sort') { - // window.history.pushState("SMON Dashboard", document.title, "/app/smon"); - // } else { - // window.history.pushState("SMON Dashboard", document.title, cur_url[0] + "?" + cur_url[1]); - // } } } }); } -function addNewSmonServer(dialog_id) { - var valid = true; - var check_type = $('#check_type').val(); - if (check_type == 'tcp') { - allFields = $([]).add($('#new-smon-ip')).add($('#new-smon-port')).add($('#new-smon-name')) +function addNewSmonServer(dialog_id, smon_id=0, edit=false) { + let valid = true; + let check_type = $('#check_type').val(); + if (check_type === 'tcp') { + allFields = $([]).add($('#new-smon-ip')).add($('#new-smon-port')).add($('#new-smon-name')).add($('#new-smon-interval')) allFields.removeClass("ui-state-error"); - valid = valid && checkLength($('#new-smon-ip'), "Hostname", 1); - valid = valid && checkLength($('#new-smon-name'), "Name", 1); valid = valid && checkLength($('#new-smon-port'), "Port", 1); + valid = valid && checkLength($('#new-smon-ip'), "Hostname", 1); } - if (check_type == 'http') { - allFields = $([]).add($('#new-smon-url')).add($('#new-smon-name')) + if (check_type === 'http') { + allFields = $([]).add($('#new-smon-url')).add($('#new-smon-name')).add($('#new-smon-interval')) allFields.removeClass("ui-state-error"); - valid = valid && checkLength($('#new-smon-name'), "Name", 1); valid = valid && checkLength($('#new-smon-url'), "URL", 1); } - if (check_type == 'ping') { - allFields = $([]).add($('#new-smon-ip')).add($('#new-smon-name')).add($('#new-smon-packet_size')) + if (check_type === 'ping') { + allFields = $([]).add($('#new-smon-ip')).add($('#new-smon-name')).add($('#new-smon-packet_size')).add($('#new-smon-interval')) allFields.removeClass("ui-state-error"); - valid = valid && checkLength($('#new-smon-name'), "Name", 1); valid = valid && checkLength($('#new-smon-ip'), "Hostname", 1); - valid = valid && checkLength($('#new-smon-packet_size'), "Packet size", 1); } - if (check_type == 'dns') { - allFields = $([]).add($('#new-smon-ip')).add($('#new-smon-port')).add($('#new-smon-name')).add($('#new-smon-resolver-server')) + if (check_type === 'dns') { + allFields = $([]).add($('#new-smon-ip')).add($('#new-smon-port')).add($('#new-smon-name')).add($('#new-smon-resolver-server')).add($('#new-smon-interval')) allFields.removeClass("ui-state-error"); - valid = valid && checkLength($('#new-smon-name'), "Name", 1); - valid = valid && checkLength($('#new-smon-ip'), "Hostname", 1); valid = valid && checkLength($('#new-smon-port'), "Port", 1); valid = valid && checkLength($('#new-smon-resolver-server'), "Resolver server", 1); + valid = valid && checkLength($('#new-smon-ip'), "Hostname", 1); } - var enable = 0; + valid = valid && checkLength($('#new-smon-name'), "Name", 1); + valid = valid && checkLength($('#new-smon-interval'), "Check interval", 1); + let enable = 0; if ($('#new-smon-enable').is(':checked')) { enable = '1'; } + let jsonData = { + 'name': $('#new-smon-name').val(), + 'ip': $('#new-smon-ip').val(), + 'port': $('#new-smon-port').val(), + 'resolver': $('#new-smon-resolver-server').val(), + 'record_type': $('#new-smon-dns_record_type').val(), + 'enabled': enable, + 'url': $('#new-smon-url').val(), + 'body': $('#new-smon-body').val(), + 'group': $('#new-smon-group').val(), + 'desc': $('#new-smon-description').val(), + 'tg': $('#new-smon-telegram').val(), + 'slack': $('#new-smon-slack').val(), + 'pd': $('#new-smon-pd').val(), + 'packet_size': $('#new-smon-packet_size').val(), + 'http_method': $('#new-smon-method').val(), + 'check_type': check_type, + 'interval': $('#new-smon-interval').val(), + 'agent_id': $('#new-smon-agent-id').val(), + 'token': $('#token').val() + } + let method = "post"; + if (edit) { + method = "put"; + jsonData['check_id'] = smon_id; + } if (valid) { $.ajax( { - url: "/app/smon/add", - data: { - newsmonname: $('#new-smon-name').val(), - newsmon: $('#new-smon-ip').val(), - newsmonport: $('#new-smon-port').val(), - newsmonresserver: $('#new-smon-resolver-server').val(), - newsmondns_record_type: $('#new-smon-dns_record_type').val(), - newsmonenable: enable, - newsmonurl: $('#new-smon-url').val(), - newsmonbody: $('#new-smon-body').val(), - newsmongroup: $('#new-smon-group').val(), - newsmondescription: $('#new-smon-description').val(), - newsmontelegram: $('#new-smon-telegram').val(), - newsmonslack: $('#new-smon-slack').val(), - newsmonpd: $('#new-smon-pd').val(), - newsmonpacket_size: $('#new-smon-packet_size').val(), - newsmon_http_method: $('#new-smon-method').val(), - newsmonchecktype: check_type, - token: $('#token').val() - }, - type: "POST", + url: '/app/smon/check', + data: JSON.stringify(jsonData), + contentType: "application/json; charset=utf-8", + type: method, success: function( data ) { data = data.replace(/\s+/g,' '); if (data.indexOf('error:') != '-1' || data.indexOf('unique') != '-1') { toastr.error(data); + } else if (data.indexOf('warning:') != '-1') { + toastr.warning(data); } else { - if (check_type == 'ping') { - table_id = 'ajax-smon-ping'; - } else if (check_type == 'tcp') { - table_id = 'ajax-smon-tcp'; - } else if (check_type == 'dns') { - table_id = 'ajax-smon-dns'; + let check_id = check_types[check_type]; + if (edit) { + getSmonCheck(smon_id, check_id, dialog_id); + } else { + getSmonCheck(data, check_id, dialog_id, true); } - else { - table_id = 'ajax-smon-http'; - } - common_ajax_action_after_success(dialog_id, 'newserver', table_id, data); - $( "input[type=submit], button" ).button(); - $( "input[type=checkbox]" ).checkboxradio(); - $( "select" ).selectmenu(); - $.getScript('/inc/users.js'); } } } ); } } -function confirmDeleteSmon(id, check_type) { - var delete_word = $('#translate').attr('data-delete'); - var cancel_word = $('#translate').attr('data-cancel'); +function confirmDeleteSmon(id) { $( "#dialog-confirm" ).dialog({ resizable: false, height: "auto", width: 400, modal: true, - title: delete_word+" " +$('#smon-ip-'+id).val() + "?", + title: delete_word+" " +$('#smon-name-'+id).text() + "?", buttons: [{ text: delete_word, click: function () { $(this).dialog("close"); - removeSmon(id, check_type); + removeSmon(id); } }, { text: cancel_word, @@ -150,149 +150,38 @@ function confirmDeleteSmon(id, check_type) { }] }); } -function removeSmon(id, check_type) { - $("#smon-"+id).css("background-color", "#f2dede"); +function removeSmon(smon_id) { + $("#smon-"+smon_id).css("background-color", "#f2dede"); + let jsonData = {'check_id': smon_id} $.ajax( { - url: "/app/smon/delete/" + id, - // data: { - // smondel: id, - // token: $('#token').val() - // }, - type: "GET", + url: "/app/smon/check", + type: "DELETE", + data: JSON.stringify(jsonData), + contentType: "application/json; charset=utf-8", success: function( data ) { data = data.replace(/\s+/g,' '); - if(data == "Ok") { - $("#smon-"+check_type+"-"+id).remove(); + if(data === "Ok") { + $("#smon-"+smon_id).remove(); } else { toastr.error(data); } } } ); } - -function updateSmon(id, check_type) { - toastr.clear(); - var enable = 0; - if ($('#smon-enable-'+id).is(':checked')) { - enable = '1'; - } - $.ajax( { - url: "/app/smon/update/"+id, - data: { - updateSmonName: $('#smon-name-'+id).val(), - updateSmonIp: $('#smon-ip-'+id).val(), - updateSmonResServer: $('#smon-resolver-'+id).val(), - updateSmonRecordType: $('#smon-record_type-'+id).val(), - updateSmonPort: $('#smon-port-'+id).val(), - updateSmonUrl: $('#smon-url-'+id).val(), - updateSmonEn: enable, - updateSmonBody: $('#smon-body-'+id).val(), - updateSmonTelegram: $('#smon-telegram-'+id).val(), - updateSmonSlack: $('#smon-slack-'+id).val(), - updateSmonPD: $('#smon-pd-'+id).val(), - updateSmonGroup: $('#smon-group-'+id).val(), - updateSmonDesc: $('#smon-desc-'+id).val(), - updateSmonPacket_size: $('#smon-packet_size-'+id).val(), - updateSmon_http_method: $('#smon-http_method-'+id).val(), - check_type: check_type, - token: $('#token').val() - }, - type: "POST", - success: function( data ) { - data = data.replace(/\s+/g,' '); - if (data.indexOf('error:') != '-1' || data.indexOf('unique') != '-1') { - toastr.error(data); - } else { - toastr.clear(); - $("#smon-"+check_type+"-"+id).addClass( "update", 1000 ); - setTimeout(function() { - $("#smon-"+check_type+"-"+id).removeClass( "update" ); - }, 2500 ); - } - } - } ); -} -function cloneSmom(id, check_type) { +function openSmonDialog(check_type, smon_id=0, edit=false) { check_and_clear_check_type(check_type); - $( "#add-smon-button-"+check_type ).trigger( "click" ); - if ($('#smon-enable-'+id).is(':checked')) { - $('#new-smon-enable').prop('checked', true) + let smon_add_tabel_title = $("#smon-add-table-overview").attr('title'); + if (edit) { + add_word = $('#translate').attr('data-edit'); + smon_add_tabel_title = $("#smon-add-table-overview").attr('data-edit'); + $('#check_type').attr('disabled', 'disabled'); + $('#check_type').selectmenu("refresh"); } else { - $('#new-smon-enable').prop('checked', false) + $('#check_type').removeAttr('disabled'); + $('#check_type').selectmenu("refresh"); + $('#new-smon-name').val(''); } - $('#new-smon-enable').checkboxradio("refresh"); - $('#new-smon-name').val($('#smon-name-'+id).val()); - $('#new-smon-ip').val($('#smon-ip-'+id).val()); - $('#new-smon-port').val($('#smon-port-'+id).val()); - $('#new-smon-resolver-server').val($('#smon-resolver-'+id).val()); - $('#new-smon-dns_record_typer').val($('#smon-record_type-'+id).val()); - $('#new-smon-url').val($('#smon-url-'+id).val()); - $('#new-smon-group').val($('#smon-group-'+id).val()); - $('#new-smon-description').val($('#smon-desc-'+id).val()) - $('#new-smon-packet_size').val($('#smon-packet_size-'+id).val()) - $('#new-smon-telegram').val($('#smon-telegram-'+id+' option:selected').val()).change() - $('#new-smon-slack').val($('#smon-slack-'+id+' option:selected').val()).change() - $('#new-smon-pd').val($('#smon-pd-'+id+' option:selected').val()).change() - $('#new-smon-telegram').selectmenu("refresh"); - $('#new-smon-slack').selectmenu("refresh"); - $('#new-smon-pd').selectmenu("refresh"); -} -$( function() { - $('#add-smon-button-http').click(function() { - addSmonServer.dialog('open'); - check_and_clear_check_type('http'); - }); - $('#add-smon-button-tcp').click(function() { - addSmonServer.dialog('open'); - check_and_clear_check_type('tcp'); - }); - $('#add-smon-button-ping').click(function() { - addSmonServer.dialog('open'); - check_and_clear_check_type('ping'); - }); - $('#add-smon-button-dns').click(function() { - addSmonServer.dialog('open'); - check_and_clear_check_type('dns'); - }); - $( "#ajax-smon-http input" ).change(function() { - var id = $(this).attr('id').split('-'); - updateSmon(id[2], 'http'); - }); - $( "#ajax-smon-http select" ).on('selectmenuchange',function() { - var id = $(this).attr('id').split('-'); - updateSmon(id[2], 'http'); - }); - $( "#ajax-smon-tcp input" ).change(function() { - var id = $(this).attr('id').split('-'); - updateSmon(id[2], 'tcp'); - }); - $( "#ajax-smon-tcp select" ).on('selectmenuchange',function() { - var id = $(this).attr('id').split('-'); - updateSmon(id[2], 'tcp'); - }); - $( "#ajax-smon-ping input" ).change(function() { - var id = $(this).attr('id').split('-'); - updateSmon(id[2], 'ping'); - }); - $( "#ajax-smon-ping select" ).on('selectmenuchange',function() { - var id = $(this).attr('id').split('-'); - updateSmon(id[2], 'ping'); - }); - $( "#ajax-smon-dns input" ).change(function() { - var id = $(this).attr('id').split('-'); - updateSmon(id[2], 'dns'); - }); - $( "#ajax-smon-dns select" ).on('selectmenuchange',function() { - var id = $(this).attr('id').split('-'); - updateSmon(id[2], 'dns'); - }); - $( "#check_type" ).on('selectmenuchange',function() { - check_and_clear_check_type($('#check_type').val()); - }); - var add_word = $('#translate').attr('data-add'); - var cancel_word = $('#translate').attr('data-cancel'); - var smon_add_tabel_title = $( "#smon-add-table-overview" ).attr('title'); - var addSmonServer = $( "#smon-add-table" ).dialog({ + let addSmonServer = $("#smon-add-table").dialog({ autoOpen: false, resizable: false, height: "auto", @@ -310,7 +199,11 @@ $( function() { buttons: [{ text: add_word, click: function () { - addNewSmonServer(this); + if (edit) { + addNewSmonServer(this, smon_id, check_type); + } else { + addNewSmonServer(this); + } } }, { text: cancel_word, @@ -320,9 +213,71 @@ $( function() { } }] }); -}); + addSmonServer.dialog('open'); +} +function getCheckSettings(smon_id, check_type) { + $.ajax( { + url: "/app/smon/check/settings/" + smon_id + "/" + check_types[check_type], + type: "get", + async: false, + dataType: "json", + success: function( data ) { + $('#new-smon-name').val(data['name']); + $('#new-smon-ip').val(data['server_ip']); + $('#new-smon-port').val(data['port']); + $('#new-smon-resolver-server').val(data['resolver']); + $('#new-smon-dns_record_typer').val(data['record_type']); + $('#new-smon-url').val(data['url']); + $('#new-smon-group').val(data['group']); + $('#new-smon-description').val(data['desc']) + $('#new-smon-packet_size').val(data['packet_size']) + $('#new-smon-interval').val(data['interval']) + $('#new-smon-body').val(data['body']) + $('#new-smon-agent-id').val(data['agent_id']).change() + $('#new-smon-telegram').val(data['tg']).change() + $('#new-smon-slack').val(data['slack']).change() + $('#new-smon-pd').val(data['pd']).change() + $('#new-smon-telegram').selectmenu("refresh"); + $('#new-smon-slack').selectmenu("refresh"); + $('#new-smon-pd').selectmenu("refresh"); + $('#new-smon-agent-id').selectmenu("refresh"); + if (data['enabled']) { + $('#new-smon-enable').prop('checked', true) + } else { + $('#new-smon-enable').prop('checked', false) + } + $('#new-smon-enable').checkboxradio("refresh"); + } + } ); +} +function editSmon(smon_id, check_type) { + check_and_clear_check_type(check_type); + openSmonDialog(check_type, smon_id, true); + getCheckSettings(smon_id, check_type); + +} +function cloneSmom(id, check_type) { + check_and_clear_check_type(check_type); + getCheckSettings(id, check_type); + openSmonDialog(check_type); +} +function getSmonCheck(smon_id, check_id, dialog_id, new_check=false) { + $.ajax({ + url: "/app/smon/check/" + smon_id + "/" + check_id, + type: "get", + success: function (data) { + if (new_check) { + $('#dashboards').prepend(data); + } else { + $('#smon-' + smon_id).replaceWith(data); + } + $(dialog_id).dialog("close"); + // $.getScript("/inc/fontawesome.min.js"); + } + }); +} function check_and_clear_check_type(check_type) { - if (check_type == 'http') { + if (check_type === 'http') { $('.new_smon_hostname').hide(); $("#check_type").val('http'); $('#check_type').selectmenu("refresh"); @@ -331,7 +286,7 @@ function check_and_clear_check_type(check_type) { $('.smon_dns_check').hide(); clear_check_vals(); $('.smon_http_check').show(); - } else if (check_type == 'tcp') { + } else if (check_type === 'tcp') { $("#check_type").val('tcp'); $('#check_type').selectmenu("refresh"); $('.new_smon_hostname').show(); @@ -340,7 +295,7 @@ function check_and_clear_check_type(check_type) { $('.smon_ping_check').hide(); clear_check_vals(); $('.smon_tcp_check').show(); - } else if (check_type == 'dns') { + } else if (check_type === 'dns') { $("#check_type").val('dns'); $('#check_type').selectmenu("refresh"); $('.smon_tcp_check').hide(); @@ -357,16 +312,17 @@ function check_and_clear_check_type(check_type) { $('.smon_dns_check').hide(); $('.smon_ping_check').show(); $("#check_type").val('ping'); - $('#check_type').selectmenu("refresh"); clear_check_vals(); + $('#new-smon-packet_size').val('56'); + $('#check_type').selectmenu("refresh"); } } function clear_check_vals() { - $('#new_smon_hostname').val(''); $('#new-smon-url').val(''); $('#new-smon-body').val(''); $('#new-smon-port').val(''); $('#new-smon-packet_size').val(''); + $('#new-smon-ip').val(''); } function show_statuses(dashboard_id, check_id, id_for_history_replace) { show_smon_history_statuses(dashboard_id, id_for_history_replace); @@ -440,8 +396,6 @@ function smon_manage_status_page_avg_status(page_id) { }); } function createStatusPageStep1(edited=false, page_id=0) { - var add_word = $('#translate').attr('data-next'); - var cancel_word = $('#translate').attr('data-cancel'); var next_word = $('#translate').attr('data-next'); var smon_add_tabel_title = $("#create-status-page-step-1-overview").attr('title'); if (edited) { @@ -499,8 +453,6 @@ function createStatusPageStep1(edited=false, page_id=0) { addSmonStatus.dialog('open'); } function createStatusPageStep2(edited, page_id) { - var add_word = $('#translate').attr('data-add'); - var cancel_word = $('#translate').attr('data-cancel'); var back_word = $('#translate').attr('data-back'); var smon_add_tabel_title = $("#create-status-page-step-2-overview").attr('title'); if (edited) { @@ -642,7 +594,6 @@ function editStatusPage(dialog_id, page_id) { } function addCheckToStatus(service_id) { var service_name = $('#add_check-' + service_id).attr('data-service_name'); - var delete_word = $('#translate').attr('data-delete'); var service_word = $('#translate').attr('data-service'); var length_tr = $('#all-checks').length; var tr_class = 'odd'; @@ -657,7 +608,6 @@ function addCheckToStatus(service_id) { } function removeCheckFromStatus(service_id) { var service_name = $('#remove_check-' + service_id).attr('data-service_name'); - var add_word = $('#translate').attr('data-add'); var service_word = $('#translate').attr('data-service'); var length_tr = $('#all_services tbody tr').length; var tr_class = 'odd'; @@ -671,8 +621,6 @@ function removeCheckFromStatus(service_id) { $("#all-checks").append(html_tag); } function confirmDeleteStatusPage(id) { - var delete_word = $('#translate').attr('data-delete'); - var cancel_word = $('#translate').attr('data-cancel'); $("#dialog-confirm").dialog({ resizable: false, height: "auto", @@ -710,3 +658,305 @@ function deleteStatusPage(page_id) { } }); } +function addAgentDialog(agent_id=0, edit=false) { + cleanAgentAddForm(); + let tabel_title = $("#add-agent-page-overview").attr('title'); + if (edit) { + add_word = $('#translate').attr('data-edit'); + tabel_title = $("#add-agent-page-overview").attr('data-edit'); + getAgentSettings(agent_id); + } else { + getFreeServers(); + } + let dialogTable = $("#add-agent-page").dialog({ + autoOpen: false, + resizable: false, + height: "auto", + width: 630, + modal: true, + title: tabel_title, + show: { + effect: "fade", + duration: 200 + }, + hide: { + effect: "fade", + duration: 200 + }, + buttons: [{ + text: add_word, + click: function () { + if (edit) { + addAgent($(this), agent_id, true); + } else { + addAgent($(this)); + } + } + }, { + text: cancel_word, + click: function () { + $(this).dialog("close"); + } + }] + }); + dialogTable.dialog('open'); +} +function addAgent(dialog_id, agent_id=0, edit=false) { + let valid = true; + allFields = $([]).add($('#new-agent-name')); + allFields.removeClass("ui-state-error"); + valid = valid && checkLength($('#new-agent-name'), "Name", 1); + let agent_name = $('#new-agent-name').val(); + let agent_server_id = $('#new-agent-server-id').val(); + let agent_desc = $('#new-agent-desc').val(); + let agent_enabled = $('#new-agent-enabled').is(':checked') ? 1 : 0; + let agent_data = { + 'name': agent_name, + 'server_id': agent_server_id, + 'desc': agent_desc, + 'enabled': agent_enabled + }; + let method = 'POST'; + if (edit) { + method = 'PUT' + agent_data['agent_id'] = agent_id; + } + if (valid) { + $.ajax({ + url: "/app/smon/agent", + type: method, + data: JSON.stringify(agent_data), + contentType: "application/json; charset=utf-8", + success: function (data) { + data = data.replace(/\s+/g, ' '); + if (data.indexOf('error:') != '-1' || data.indexOf('unique') != '-1') { + toastr.error(data); + } else { + toastr.clear(); + $(dialog_id).dialog("close"); + if (edit) { + getAgent(agent_id, false); + } else { + getAgent(data, new_agent = true); + } + } + } + }); + } +} +function getAgentSettings(agent_id) { + $.ajax({ + url: "/app/smon/agent/settings/" + agent_id, + async: false, + success: function (data) { + $('#new-agent-name').val(data['name']); + $('#new-agent-server-id').append(''); + $('#new-agent-server-id').attr('disabled', 'disabled'); + $('#new-agent-desc').val(data['desc']); + $('#new-agent-enabled').checkboxradio("refresh"); + if (data['enabled']) { + $('#new-agent-enabled').prop('checked', true) + } else { + $('#new-agent-enabled').prop('checked', false) + } + $('#new-agent-enabled').checkboxradio("refresh"); + $('#new-agent-server-id').selectmenu("refresh"); + } + }); +} +function getFreeServers() { + $.ajax({ + url: "/app/smon/agent/free", + async: false, + contentType: "application/json; charset=utf-8", + success: function (data) { + $("#new-agent-server-id option[value!='------']").remove(); + for (k in data) { + $('#new-agent-server-id').append(''); + } + $('#new-agent-server-id').selectmenu("refresh"); + } + }); +} +function cleanAgentAddForm() { + $('#new-agent-name').val(''); + $('#new-agent-server-id').val('------').change(); + $('#new-agent-desc').val(''); + $('#new-agent-enabled').prop('checked', true); + $('#new-agent-enabled').checkboxradio("refresh"); + $('#new-agent-server-id').removeAttr('disabled'); + $('#new-agent-server-id').selectmenu("refresh"); +} +function getAgent(agent_id, new_agent=false) { + $.ajax({ + url: "/app/smon/agent/" + agent_id, + success: function (data) { + data = data.replace(/^\s+|\s+$/g, ''); + if (data.indexOf('error:') != '-1') { + toastr.error(data); + } else { + if (new_agent) { + $('.up-pannel').append(data); + } else { + $('#agent-' + agent_id).replaceWith(data); + } + $.getScript("/inc/fontawesome.min.js"); + $('#agent-' + agent_id).removeClass('animated-background'); + } + } + }); +} +function getAgentVersion(server_ip, agent_id){ + $.ajax({ + url: '/app/smon/agent/version/' + server_ip, + type: 'get', + data: {agent_id: agent_id}, + success: function (data){ + try { + data = JSON.parse(data); + $('#agent-version-' + agent_id).text(data['version']) + } catch (e) { + console.log(e) + } + } + }); +} +function getAgentUptime(server_ip, agent_id){ + $.ajax({ + url: '/app/smon/agent/uptime/' + server_ip, + type: 'get', + data: {agent_id: agent_id}, + success: function (data){ + try { + data = JSON.parse(data); + $('#agent-uptime-' + agent_id).text(data['uptime']); + $('#agent-uptime-' + agent_id).attr('datetime', data['uptime']); + $("#agent-uptime-"+agent_id).timeago(); + } catch (e) { + console.log(e) + } + } + }); +} +function getAgentStatus(server_ip, agent_id){ + $.ajax({ + url: '/app/smon/agent/status/' + server_ip, + type: 'get', + data: {agent_id: agent_id}, + success: function (data){ + try { + data = JSON.parse(data); + if (data['running']) { + $('#agent-'+agent_id).addClass('div-server-head-up'); + $('#start-'+agent_id).children().addClass('disabled-button'); + $('#start-'+agent_id).children().removeAttr('onclick'); + $('#agent-'+agent_id).removeClass('div-server-head-down'); + } else { + $('#agent-'+agent_id).removeClass('div-server-head-up'); + $('#agent-'+agent_id).addClass('div-server-head-pause'); + $('#pause-'+agent_id).children().addClass('disabled-button'); + $('#pause-'+agent_id).children().removeAttr('onclick'); + } + } catch (e) { + console.log(e); + $('#agent-'+agent_id).addClass('div-server-head-down'); + $('#stop-'+agent_id).children().addClass('disabled-button'); + $('#pause-'+agent_id).children().addClass('disabled-button'); + $('#pause-'+agent_id).children().removeAttr('onclick'); + $('#stop-'+agent_id).children().removeAttr('onclick'); + } + } + }); +} +function getAgentTotalChecks(server_ip, agent_id){ + $.ajax({ + url: '/app/smon/agent/checks/' + server_ip, + type: 'get', + data: {agent_id: agent_id}, + success: function (data){ + try { + data = JSON.parse(data); + $('#agent-total-checks-'+agent_id).text(Object.keys(data).length) + } catch (e) { + console.log(e); + $('#agent-'+agent_id).addClass('div-server-head-down') + } + } + }); +} +function confirmDeleteAgent(id) { + $( "#dialog-confirm" ).dialog({ + resizable: false, + height: "auto", + width: 400, + modal: true, + title: delete_word+" " +$('#agent-name-'+id).text() + "?", + buttons: [{ + text: delete_word, + click: function () { + $(this).dialog("close"); + removeAgent(id, $(this)); + } + }, { + text: cancel_word, + click: function() { + $( this ).dialog( "close" ); + } + }] + }); +} +function removeAgent(id, dialog_id) { + $.ajax({ + url: "/app/smon/agent", + type: "delete", + data: {agent_id: id}, + success: function (data){ + data = data.replace(/\s+/g, ' '); + if (data.indexOf('error:') != '-1' || data.indexOf('unique') != '-1') { + toastr.error(data); + } else { + toastr.clear(); + $(dialog_id).dialog("close"); + $('#agent-'+id).remove(); + } + } + }); +} +function confirmAjaxAction(action, id, server_ip) { + let action_word = $('#translate').attr('data-'+action); + $( "#dialog-confirm" ).dialog({ + resizable: false, + height: "auto", + width: 400, + modal: true, + title: action_word + " " + $('#agent-name-'+id).text() + "?", + buttons: [{ + text: action_word, + click: function (){ + agentAction(action, id, server_ip, $(this)); + } + }, { + text: cancel_word, + click: function(){ + $( this ).dialog( "close" ); + } + }] + }); +} +function agentAction(action, id, server_ip, dialog_id) { + $.ajax({ + url: "/app/smon/agent/action/"+ action, + type: "post", + data: {agent_id: id, server_ip: server_ip}, + success: function (data) { + data = data.replace(/\s+/g, ' '); + if (data.indexOf('error:') != '-1' || data.indexOf('unique') != '-1') { + toastr.error(data); + } else { + toastr.clear(); + $(dialog_id).dialog("close"); + getAgent(id, false); + } + } + }); +} diff --git a/inc/users.js b/inc/users.js index 890aea21..687d21b6 100644 --- a/inc/users.js +++ b/inc/users.js @@ -1974,8 +1974,8 @@ function removeServiceFromUser(service_id) { $("#all_services tbody").append(html_tag); } function confirmAjaxServiceAction(action, service) { - var cancel_word = $('#translate').attr('data-cancel'); - var action_word = $('#translate').attr('data-'+action); + let cancel_word = $('#translate').attr('data-cancel'); + let action_word = $('#translate').attr('data-'+action); $( "#dialog-confirm-services" ).dialog({ resizable: false, height: "auto", @@ -1986,7 +1986,7 @@ function confirmAjaxServiceAction(action, service) { text: action_word, click: function () { $(this).dialog("close"); - ajaxActionServies(action, service) + ajaxActionServices(action, service); } }, { text: cancel_word, @@ -1996,7 +1996,7 @@ function confirmAjaxServiceAction(action, service) { }] }); } -function ajaxActionServies(action, service) { +function ajaxActionServices(action, service) { $.ajax( { url: "/app/admin/tools/action/" + service + "/" + action, // data: {