From 2ef631a44024969b41fea852ed12278b8437ea8d Mon Sep 17 00:00:00 2001 From: Jokob-sk Date: Sun, 19 Feb 2023 13:08:41 +1100 Subject: [PATCH] Plugins 0.2 - Reports working + Report status setting --- back/pialert.py | 72 ++++-- back/report_template.html | 11 +- back/report_template_new_version.html | 11 +- docker-compose.yml | 3 + front/plugins.php | 25 +- front/plugins/README.md | 268 ++++++++++++++++------ front/plugins/website_monitor/config.json | 233 ++++++++++++++----- 7 files changed, 462 insertions(+), 161 deletions(-) diff --git a/back/pialert.py b/back/pialert.py index 64bd27d3..b2f74a9d 100755 --- a/back/pialert.py +++ b/back/pialert.py @@ -2347,7 +2347,7 @@ def send_notifications (): if 'plugins' in INCLUDED_SECTIONS: # Compose Plugins Section - sqlQuery = """SELECT * from Plugins_Events where Status == 'new'""" + sqlQuery = """SELECT Plugin, Object_PrimaryId, Object_SecondaryId, DateTimeChanged, Watched_Value1, Watched_Value2, Watched_Value3, Watched_Value4, Status from Plugins_Events""" notiStruc = construct_notifications(sqlQuery, "Plugins") @@ -2357,6 +2357,9 @@ def send_notifications (): mail_text = mail_text.replace ('', notiStruc.text + '\n') mail_html = mail_html.replace ('', notiStruc.html) + # check if we need to report something + plugins_report = plugin_check_smth_to_report(json_plugins) + json_final = { "internet": json_internet, @@ -2373,11 +2376,12 @@ def send_notifications (): mail_html = generate_mac_links (mail_html, deviceUrl) # Write output emails for debug + write_file (logPath + '/report_output.json', json.dumps(json_final)) write_file (logPath + '/report_output.txt', mail_text) write_file (logPath + '/report_output.html', mail_html) # Send Mail - if json_internet != [] or json_new_devices != [] or json_down_devices != [] or json_events != [] or json_ports != [] or debug_force_notification: + if json_internet != [] or json_new_devices != [] or json_down_devices != [] or json_events != [] or json_ports != [] or debug_force_notification or plugins_report: update_api(True) @@ -2430,6 +2434,9 @@ def send_notifications (): """, (datetime.datetime.now(),) ) sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0 WHERE eve_PendingAlertEmail = 1""") + + # clear plugin events + sql.execute ("DELETE FROM Plugins_Events") changedPorts_json_struc = None @@ -2457,22 +2464,22 @@ def construct_notifications(sqlQuery, tableTitle, skipText = False, suppliedJson else: json_struc = suppliedJsonStruct - json = json_struc.json + jsn = json_struc.json html = "" text = "" - if json["data"] != []: + if len(jsn["data"]) > 0: text = tableTitle + "\n---------\n" - html = convert(json, build_direction=build_direction, table_attributes=table_attributes) - + html = convert(jsn, build_direction=build_direction, table_attributes=table_attributes) html = format_table(html, "data", headerProps, tableTitle).replace('
    ','
      ') headers = json_struc.columnNames # prepare text-only message if skipText == False: - for device in json["data"]: + + for device in jsn["data"]: for header in headers: padding = "" if len(header) < 4: @@ -2484,7 +2491,7 @@ def construct_notifications(sqlQuery, tableTitle, skipText = False, suppliedJson for header in headers: html = format_table(html, header, thProps) - return noti_struc(json, text, html) + return noti_struc(jsn, text, html) #------------------------------------------------------------------------------- class noti_struc: @@ -3295,19 +3302,20 @@ def get_table_as_json(sqlQuery): result = {"data":[]} for row in rows: - tmp = fill_row(columnNames, row) - + tmp = row_to_json(columnNames, row) result["data"].append(tmp) return json_struc(result, columnNames) #------------------------------------------------------------------------------- class json_struc: - def __init__(self, json, columnNames): - self.json = json + def __init__(self, jsn, columnNames): + # mylog('verbose', [' [] tmp: ', str(json.dumps(jsn))]) + self.json = jsn self.columnNames = columnNames #------------------------------------------------------------------------------- -def fill_row(names, row): +# Creates a JSON object from a DB row +def row_to_json(names, row): rowEntry = {} @@ -3577,6 +3585,21 @@ def handle_test(testType): mylog('info', ['[', timeNow(), '] END Test: ', testType]) +#------------------------------------------------------------------------------- +# Return setting value +def get_setting_value(key): + + set = get_setting(key) + + if get_setting(key) is not None: + + setVal = set[6] # setting value + setTyp = set[3] # setting type + + return setVal + + return '' + #------------------------------------------------------------------------------- # Return whole setting touple def get_setting(key): @@ -3813,6 +3836,8 @@ def execute_plugin(plugin): # Check if watched values changed for the given plugin def process_plugin_events(plugin): + global pluginObjects, pluginEvents + pluginPref = plugin["unique_prefix"] plugObjectsArr = get_sql_array ("SELECT * FROM Plugins_Objects where Plugin = '" + str(pluginPref)+"'") @@ -3983,6 +4008,27 @@ def resolve_wildcards(command, params): return command +#------------------------------------------------------------------------------- +# Check if there are events which need to be reported on based on settings +def plugin_check_smth_to_report(notifs): + + for notJsn in notifs: + + pref = notJsn['Plugin'] #"Plugin" column + stat = notJsn['Status'] #"Status" column + + val = get_setting_value(pref + '_REPORT_ON') + + if set is not None: + + # report if there is at least one value in teh events to be reported on + # future improvement - selectively remove events based on this + if stat in val: + return True + + return False + + #------------------------------------------------------------------------------- # Flattens a setting to make it passable to a script def plugin_param_from_glob_set(globalSetting): diff --git a/back/report_template.html b/back/report_template.html index 87beb6d8..08d8aad3 100755 --- a/back/report_template.html +++ b/back/report_template.html @@ -34,14 +34,11 @@ - - - - - - - + + + + diff --git a/back/report_template_new_version.html b/back/report_template_new_version.html index 2c19e881..a2267ef8 100755 --- a/back/report_template_new_version.html +++ b/back/report_template_new_version.html @@ -38,15 +38,10 @@ - - - - - - - + + + - diff --git a/docker-compose.yml b/docker-compose.yml index 6345993e..5821bf50 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,6 +14,9 @@ services: - ${LOGS_LOCATION}:/home/pi/pialert/front/log # DELETE START anyone trying to use this file: comment out / delete BELOW lines, they are only for development purposes - ${DEV_LOCATION}/back/pialert.py:/home/pi/pialert/back/pialert.py + - ${DEV_LOCATION}/back/report_template.html:/home/pi/pialert/back/report_template.html + - ${DEV_LOCATION}/back/report_template_new_version.html:/home/pi/pialert/back/report_template_new_version.html + - ${DEV_LOCATION}/back/report_template.txt:/home/pi/pialert/back/report_template.txt - ${DEV_LOCATION}/pholus:/home/pi/pialert/pholus - ${DEV_LOCATION}/dockerfiles:/home/pi/pialert/dockerfiles - ${APP_DATA_LOCATION}/pialert/php.ini:/etc/php/7.4/fpm/php.ini diff --git a/front/plugins.php b/front/plugins.php index 356cb36b..aa3b8f82 100755 --- a/front/plugins.php +++ b/front/plugins.php @@ -119,17 +119,22 @@ function generateTabs() $.each(pluginDefinitions, function(index, obj) { headersHtml = "" - headers = [] + // headers = [] + colDefinitions = [] evRows = "" obRows = "" // Generate the header - $.each(obj["database_column_aliases"]["localized"], function(index, locItem){ - headers.push(locItem) - headersHtml += `${localize(obj["database_column_aliases"], locItem )}` - + $.each(obj["database_column_definitions"], function(index, colDef){ + if(colDef.show == true) + { + colDefinitions.push(colDef) + headersHtml += `${localize(colDef, "name" )}` + } }); + + // Generate the event rows for(i=0;i' + clm += ''+ pluginUnprocessedEvents[i][colDefinitions[j].column] +'' } evRows += '' + clm + '' } } + + // Generate the object rows for(i=0;i' + clm += ''+ pluginObjects[i][colDefinitions[j].column] +'' } obRows += '' + clm + '' } diff --git a/front/plugins/README.md b/front/plugins/README.md index 07171e03..b6025bda 100755 --- a/front/plugins/README.md +++ b/front/plugins/README.md @@ -159,34 +159,23 @@ Example: } ``` -##### database_column_aliases +##### database_column_definitions -- Only columns specified in the `"localized"` parameter and also with at least an english translation will be shown in the UI. +- Only columns with `"show": true` and also with at least an english translation will be shown in the UI. ```json -{ - "localized": ["Index", "Object_PrimaryID", "DateTime", "Watched_Value1", "Watched_Value2"], - "Index":[{ - "language_code":"en_us", - "string" : "Index" - }], - "Object_PrimaryID":[{ - "language_code":"en_us", - "string" : "Monitored URL" - }], - "DateTime":[{ - "language_code":"en_us", - "string" : "Checked on" - }], - "Watched_Value1":[{ - "language_code":"en_us", - "string" : "Status code" - }], - "Watched_Value2":[{ - "language_code":"en_us", - "string" : "Latency" - }] - } +{ + "column": "Index", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "N/A" + }] + } ``` ## Full Example @@ -223,29 +212,165 @@ Example: "type" : "setting", "value" : "WEBMON_SQL_internet_ip" }], - "database_column_aliases":{ - "localized": ["Index", "Object_PrimaryID", "DateTime", "Watched_Value1", "Watched_Value2"], - "Index":[{ - "language_code":"en_us", - "string" : "Index" - }], - "Object_PrimaryID":[{ - "language_code":"en_us", - "string" : "Monitored URL" - }], - "DateTime":[{ - "language_code":"en_us", - "string" : "Checked on" - }], - "Watched_Value1":[{ - "language_code":"en_us", - "string" : "Status code" - }], - "Watched_Value2":[{ - "language_code":"en_us", - "string" : "Latency" - }] - }, + "database_column_definitions": + [ + { + "column": "Index", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "N/A" + }] + } , + { + "column": "Plugin", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "N/A" + }] + }, + { + "column": "Object_PrimaryID", + "show": true, + "type": "text", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Monitored URL" + }] + }, + { + "column": "Object_SecondaryD", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "N/A" + }] + } , + { + "column": "DateTimeCreated", + "show": true, + "type": "text", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Created" + }] + }, + { + "column": "DateTimeChanged", + "show": true, + "type": "text", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Changed" + }] + }, + { + "column": "Watched_Value1", + "show": true, + "type": "text", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Status code" + }] + }, + { + "column": "Watched_Value2", + "show": true, + "type": "text", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Latency" + }] + }, + { + "column": "Watched_Value3", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "N/A" + }] + } , + { + "column": "Watched_Value4", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "N/A" + }] + } , + { + "column": "UserData", + "show": true, + "type": "text", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Comments" + }] + }, + { + "column": "Status", + "show": true, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Status" + }] + }, + { + "column": "Extra", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Extra" + }] + } + ], "settings":[ { "function": "RUN", @@ -274,29 +399,9 @@ Example: }], "description": [{ "language_code":"en_us", - "string" : "Comamnd to run" + "string" : "Command to run" }] }, - { - "function": "FORCE_REPORT", - "type": "boolean", - "default_value": false, - "options": [], - "localized": ["name", "description"], - "name" : [{ - "language_code":"en_us", - "string" : "Force report" - }, - { - "language_code":"de_de", - "string" : "Zwing Bericht" - }], - "description": [{ - "language_code":"en_us", - "string" : "Force a notification message even if there are no changes detected." - }] - - }, { "function": "RUN_SCHD", "type": "text", @@ -336,6 +441,10 @@ Example: "name" : [{ "language_code":"en_us", "string" : "Run timeout" + }, + { + "language_code":"de_de", + "string" : "Wartezeit" }], "description": [{ "language_code":"en_us", @@ -350,13 +459,28 @@ Example: "localized": ["name", "description"], "name" :[{ "language_code":"en_us", - "string" : "Notify on" + "string" : "Watched" }] , "description":[{ "language_code":"en_us", "string" : "Send a notification if selected values change. Use CTRL + Click to select/deselect.
      • Watched_Value1 is response status code (e.g.: 200, 404)
      • Watched_Value2 is Latency (not recommended)
      • Watched_Value3 unused
      • Watched_Value4 unused
      " }] }, + { + "function": "REPORT_ON", + "type": "multiselect", + "default_value":["new","watched-changed"], + "options": ["new","watched-changed","watched-not-changed"], + "localized": ["name", "description"], + "name" :[{ + "language_code":"en_us", + "string" : "Report on" + }] , + "description":[{ + "language_code":"en_us", + "string" : "Send a notification only on these statuses. new means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. watched-changed means that selected Watched_ValueN columns changed." + }] + }, { "function": "urls_to_check", "type": "list", @@ -384,7 +508,7 @@ Example: }], "description": [{ "language_code":"en_us", - "string" : "Getting the IP address of the Router / Internet" + "string" : "Unused setting - for demonstration only. Getting the IP address of the Router / Internet. " }] } @@ -393,4 +517,6 @@ Example: + + ``` diff --git a/front/plugins/website_monitor/config.json b/front/plugins/website_monitor/config.json index 76b69cf1..e2c45d22 100755 --- a/front/plugins/website_monitor/config.json +++ b/front/plugins/website_monitor/config.json @@ -29,37 +29,165 @@ "type" : "setting", "value" : "WEBMON_SQL_internet_ip" }], - "database_column_aliases":{ - "localized": ["Object_PrimaryID", "DateTimeCreated", "DateTimeChanged", "Watched_Value1", "Watched_Value2", "UserData", "Status"], - "Object_PrimaryID":[{ - "language_code":"en_us", - "string" : "Monitored URL" - }], - "DateTimeCreated":[{ - "language_code":"en_us", - "string" : "Created" - }], - "DateTimeChanged":[{ - "language_code":"en_us", - "string" : "Changed" - }], - "Watched_Value1":[{ - "language_code":"en_us", - "string" : "Status code" - }], - "Watched_Value2":[{ - "language_code":"en_us", - "string" : "Latency" - }], - "UserData":[{ - "language_code":"en_us", - "string" : "Comments" - }], - "Status":[{ - "language_code":"en_us", - "string" : "Status" - }] - }, + "database_column_definitions": + [ + { + "column": "Index", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "N/A" + }] + } , + { + "column": "Plugin", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "N/A" + }] + }, + { + "column": "Object_PrimaryID", + "show": true, + "type": "text", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Monitored URL" + }] + }, + { + "column": "Object_SecondaryD", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "N/A" + }] + } , + { + "column": "DateTimeCreated", + "show": true, + "type": "text", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Created" + }] + }, + { + "column": "DateTimeChanged", + "show": true, + "type": "text", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Changed" + }] + }, + { + "column": "Watched_Value1", + "show": true, + "type": "text", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Status code" + }] + }, + { + "column": "Watched_Value2", + "show": true, + "type": "text", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Latency" + }] + }, + { + "column": "Watched_Value3", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "N/A" + }] + } , + { + "column": "Watched_Value4", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "N/A" + }] + } , + { + "column": "UserData", + "show": true, + "type": "text", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Comments" + }] + }, + { + "column": "Status", + "show": true, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Status" + }] + }, + { + "column": "Extra", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Extra" + }] + } + ], "settings":[ { "function": "RUN", @@ -91,26 +219,6 @@ "string" : "Command to run" }] }, - { - "function": "FORCE_REPORT", - "type": "boolean", - "default_value": false, - "options": [], - "localized": ["name", "description"], - "name" : [{ - "language_code":"en_us", - "string" : "Force report" - }, - { - "language_code":"de_de", - "string" : "Zwing Bericht" - }], - "description": [{ - "language_code":"en_us", - "string" : "Force a notification message even if there are no changes detected." - }] - - }, { "function": "RUN_SCHD", "type": "text", @@ -150,6 +258,10 @@ "name" : [{ "language_code":"en_us", "string" : "Run timeout" + }, + { + "language_code":"de_de", + "string" : "Wartezeit" }], "description": [{ "language_code":"en_us", @@ -164,13 +276,28 @@ "localized": ["name", "description"], "name" :[{ "language_code":"en_us", - "string" : "Notify on" + "string" : "Watched" }] , "description":[{ "language_code":"en_us", "string" : "Send a notification if selected values change. Use CTRL + Click to select/deselect.
      • Watched_Value1 is response status code (e.g.: 200, 404)
      • Watched_Value2 is Latency (not recommended)
      • Watched_Value3 unused
      • Watched_Value4 unused
      " }] }, + { + "function": "REPORT_ON", + "type": "multiselect", + "default_value":["new","watched-changed"], + "options": ["new","watched-changed","watched-not-changed"], + "localized": ["name", "description"], + "name" :[{ + "language_code":"en_us", + "string" : "Report on" + }] , + "description":[{ + "language_code":"en_us", + "string" : "Send a notification only on these statuses. new means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. watched-changed means that selected Watched_ValueN columns changed." + }] + }, { "function": "urls_to_check", "type": "list", @@ -198,7 +325,7 @@ }], "description": [{ "language_code":"en_us", - "string" : "Getting the IP address of the Router / Internet" + "string" : "Unused setting - for demonstration only. Getting the IP address of the Router / Internet. " }] }