💠down_reconnected support v0.5 #611

This commit is contained in:
jokob-sk
2024-05-25 23:28:48 +10:00
parent 2f4423481d
commit 3102b8a76e
11 changed files with 84 additions and 17 deletions

View File

@@ -33,6 +33,7 @@ services:
- ${DEV_LOCATION}/back/update_vendors.sh:/app/back/update_vendors.sh - ${DEV_LOCATION}/back/update_vendors.sh:/app/back/update_vendors.sh
- ${DEV_LOCATION}/front/lib:/app/front/lib - ${DEV_LOCATION}/front/lib:/app/front/lib
- ${DEV_LOCATION}/front/js:/app/front/js - ${DEV_LOCATION}/front/js:/app/front/js
- ${DEV_LOCATION}/front/report_templates:/front/report_templates
- ${DEV_LOCATION}/install/start.debian.sh:/app/install/start.debian.sh - ${DEV_LOCATION}/install/start.debian.sh:/app/install/start.debian.sh
- ${DEV_LOCATION}/install/user-mapping.debian.sh:/app/install/user-mapping.debian.sh - ${DEV_LOCATION}/install/user-mapping.debian.sh:/app/install/user-mapping.debian.sh
- ${DEV_LOCATION}/install/install.debian.sh:/app/install/install.debian.sh - ${DEV_LOCATION}/install/install.debian.sh:/app/install/install.debian.sh

View File

@@ -742,7 +742,7 @@ height: 50px;
{ {
font-size: 20px; font-size: 20px;
padding-top: 7px; padding-top: 7px;
padding-bottom: 9px; padding-bottom: 9px;
} }
.overview-section .small-box .icon .overview-section .small-box .icon
@@ -753,12 +753,12 @@ height: 50px;
.overview-section .overview-section
{ {
border: solid; /* border-top: solid;
border-width: medium; border-width: medium;
border-width: medium; border-width: medium;
border-width: 1px; border-width: 1px;
border-radius: 15px; border-radius: 15px;
margin-bottom: 3px; margin-bottom: 3px; */
} }
@@ -771,6 +771,7 @@ height: 50px;
font-size: 20px; font-size: 20px;
padding-top: 7px; padding-top: 7px;
padding-bottom: 9px; padding-bottom: 9px;
margin-left: -20px;
} }

View File

@@ -332,7 +332,7 @@
"HelpFAQ_Cat_Presence_401_head": "A device is displayed as present although it is \"Offline\".", "HelpFAQ_Cat_Presence_401_head": "A device is displayed as present although it is \"Offline\".",
"HelpFAQ_Cat_Presence_401_text": "If this happens, you have the possibility to delete the events for the device in question (details view). Another possibility would be to switch on the device and wait until NetAlertX recognizes the device as \"online\" with the next scan and then simply switch the device off again. Now NetAlertX should properly note the state of the device in the database with the next scan.", "HelpFAQ_Cat_Presence_401_text": "If this happens, you have the possibility to delete the events for the device in question (details view). Another possibility would be to switch on the device and wait until NetAlertX recognizes the device as \"online\" with the next scan and then simply switch the device off again. Now NetAlertX should properly note the state of the device in the database with the next scan.",
"HelpFAQ_Title": "Help / FAQ", "HelpFAQ_Title": "Help / FAQ",
"LOADED_PLUGINS_description": "Which Plugins to load. Adding plugins might slow the application. Read more about which plugins need to be enabled, types, or scanning options in the <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins docs</a>. Unloaded plugins will lose your settings. Only <code>disabled</code> plugins can be unloaded.", "LOADED_PLUGINS_description": "Which Plugins to load. Adding plugins might slow the application. Read more about which plugins need to be enabled, types, or scanning options in the <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme\">plugins docs</a>. Unloaded plugins will lose your settings. Only <code>disabled</code> plugins can be unloaded.",
"LOADED_PLUGINS_name": "Loaded plugins", "LOADED_PLUGINS_name": "Loaded plugins",
"LOG_LEVEL_description": "This setting will enable more verbose logging. Useful for debugging events writing into the database.", "LOG_LEVEL_description": "This setting will enable more verbose logging. Useful for debugging events writing into the database.",
"LOG_LEVEL_name": "Print additional logging", "LOG_LEVEL_name": "Print additional logging",

View File

@@ -51,7 +51,7 @@ def main():
# perform the new IP lookup N times specified by the INTRNT_TRIES setting # perform the new IP lookup N times specified by the INTRNT_TRIES setting
new_internet_IP = "" new_internet_IP = ""
INTRNT_RETRIES = get_setting_value("INTRNT_RETRIES") INTRNT_RETRIES = get_setting_value("INTRNT_RETRIES")
tries_needed = 0 retries_needed = 0
for i in range(INTRNT_RETRIES + 1): for i in range(INTRNT_RETRIES + 1):
@@ -60,7 +60,7 @@ def main():
if new_internet_IP == no_internet_ip: if new_internet_IP == no_internet_ip:
time.sleep(1*i) # Exponential backoff strategy time.sleep(1*i) # Exponential backoff strategy
else: else:
tries_needed = i retries_needed = i
break break
plugin_objects = Plugin_Objects(RESULT_FILE) plugin_objects = Plugin_Objects(RESULT_FILE)
@@ -70,7 +70,7 @@ def main():
secondaryId = new_internet_IP, # IP Address secondaryId = new_internet_IP, # IP Address
watched1 = f'Previous IP: {PREV_IP}', watched1 = f'Previous IP: {PREV_IP}',
watched2 = cmd_output.replace('\n',''), watched2 = cmd_output.replace('\n',''),
watched3 = tries_needed, watched3 = retries_needed,
watched4 = '', watched4 = '',
extra = f'Previous IP: {PREV_IP}', extra = f'Previous IP: {PREV_IP}',
foreignKey = 'Internet') foreignKey = 'Internet')

View File

@@ -32,7 +32,7 @@
"function": "INCLUDED_SECTIONS", "function": "INCLUDED_SECTIONS",
"type": "text.multiselect", "type": "text.multiselect",
"default_value": ["new_devices", "down_devices", "events"], "default_value": ["new_devices", "down_devices", "events"],
"options": ["new_devices", "down_devices", "events", "plugins"], "options": ["new_devices", "down_devices", "down_reconnected", "events", "plugins"],
"localized": ["name", "description"], "localized": ["name", "description"],
"name": [ "name": [
{ {

View File

@@ -48,7 +48,8 @@
<NEW_DEVICES_TABLE> <NEW_DEVICES_TABLE>
<DOWN_DEVICES_TABLE> <DOWN_DEVICES_TABLE>
<DOWN_RECONNECTED_TABLE>
<EVENTS_TABLE> <EVENTS_TABLE>
<PLUGINS_TABLE> <PLUGINS_TABLE>

View File

@@ -3,5 +3,6 @@ Server: <SERVER_NAME>
<NEW_DEVICES_TABLE> <NEW_DEVICES_TABLE>
<DOWN_DEVICES_TABLE> <DOWN_DEVICES_TABLE>
<DOWN_RECONNECTED_TABLE>
<EVENTS_TABLE> <EVENTS_TABLE>
<PLUGINS_TABLE> <PLUGINS_TABLE>

View File

@@ -53,6 +53,7 @@
<NEW_DEVICES_TABLE> <NEW_DEVICES_TABLE>
<DOWN_DEVICES_TABLE> <DOWN_DEVICES_TABLE>
<DOWN_RECONNECTED_TABLE>
<EVENTS_TABLE> <EVENTS_TABLE>
<PLUGINS_TABLE> <PLUGINS_TABLE>

View File

@@ -137,7 +137,7 @@ def importConfigs (db, all_plugins):
conf.TIMEZONE = ccd('TIMEZONE', 'Europe/Berlin' , c_d, 'Time zone', 'text', '', 'General') conf.TIMEZONE = ccd('TIMEZONE', 'Europe/Berlin' , c_d, 'Time zone', 'text', '', 'General')
conf.PLUGINS_KEEP_HIST = ccd('PLUGINS_KEEP_HIST', 250 , c_d, 'Keep history entries', 'integer', '', 'General') conf.PLUGINS_KEEP_HIST = ccd('PLUGINS_KEEP_HIST', 250 , c_d, 'Keep history entries', 'integer', '', 'General')
conf.REPORT_DASHBOARD_URL = ccd('REPORT_DASHBOARD_URL', 'http://netalertx/' , c_d, 'NetAlertX URL', 'text', '', 'General') conf.REPORT_DASHBOARD_URL = ccd('REPORT_DASHBOARD_URL', 'http://netalertx/' , c_d, 'NetAlertX URL', 'text', '', 'General')
conf.UI_LANG = ccd('UI_LANG', 'English' , c_d, 'Language Interface', 'text.select', "['English', 'French', 'German', 'Norwegian', 'Russian', 'Spanish' ]", 'General') conf.UI_LANG = ccd('UI_LANG', 'English' , c_d, 'Language Interface', 'text.select', "['English', 'French', 'German', 'Norwegian', 'Russian', 'Spanish', 'Italian', 'Portuguese (Brazil)', 'Polish', 'Chinese (zh_cn)' ]", 'General')
conf.UI_PRESENCE = ccd('UI_PRESENCE', ['online', 'offline', 'archived'] , c_d, 'Include in presence', 'text.multiselect', "['online', 'offline', 'archived']", 'General') conf.UI_PRESENCE = ccd('UI_PRESENCE', ['online', 'offline', 'archived'] , c_d, 'Include in presence', 'text.multiselect', "['online', 'offline', 'archived']", 'General')
conf.UI_DEV_SECTIONS = ccd('UI_DEV_SECTIONS', [] , c_d, 'Show sections', 'text.multiselect', "['Tile Cards', 'Device Presence']", 'General') conf.UI_DEV_SECTIONS = ccd('UI_DEV_SECTIONS', [] , c_d, 'Show sections', 'text.multiselect', "['Tile Cards', 'Device Presence']", 'General')
conf.UI_MY_DEVICES = ccd('UI_MY_DEVICES', ['online', 'offline', 'archived', 'new', 'down'] , c_d, 'Include in My Devices', 'text.multiselect', "['online', 'offline', 'archived', 'new', 'down']", 'General') conf.UI_MY_DEVICES = ccd('UI_MY_DEVICES', ['online', 'offline', 'archived', 'new', 'down'] , c_d, 'Include in My Devices', 'text.multiselect', "['online', 'offline', 'archived', 'new', 'down']", 'General')

View File

@@ -51,7 +51,7 @@ class Notification_obj:
write_file (logPath + '/report_output.json', json.dumps(JSON)) write_file (logPath + '/report_output.json', json.dumps(JSON))
# Check if nothing to report, end # Check if nothing to report, end
if JSON["new_devices"] == [] and JSON["down_devices"] == [] and JSON["events"] == [] and JSON["plugins"] == []: if JSON["new_devices"] == [] and JSON["down_devices"] == [] and JSON["events"] == [] and JSON["plugins"] == [] and JSON["down_reconnected"] == []:
self.HasNotifications = False self.HasNotifications = False
else: else:
self.HasNotifications = True self.HasNotifications = True
@@ -119,19 +119,35 @@ class Notification_obj:
mail_html = mail_html.replace ('<BUILD_DATE>', BUILDFILE) mail_html = mail_html.replace ('<BUILD_DATE>', BUILDFILE)
# Start generating the TEXT & HTML notification messages # Start generating the TEXT & HTML notification messages
# new_devices
# ---
html, text = construct_notifications(self.JSON, "new_devices") html, text = construct_notifications(self.JSON, "new_devices")
mail_text = mail_text.replace ('<NEW_DEVICES_TABLE>', text + '\n') mail_text = mail_text.replace ('<NEW_DEVICES_TABLE>', text + '\n')
mail_html = mail_html.replace ('<NEW_DEVICES_TABLE>', html) mail_html = mail_html.replace ('<NEW_DEVICES_TABLE>', html)
mylog('verbose', ['[Notification] New Devices sections done.']) mylog('verbose', ['[Notification] New Devices sections done.'])
# down_devices
# ---
html, text = construct_notifications(self.JSON, "down_devices") html, text = construct_notifications(self.JSON, "down_devices")
mail_text = mail_text.replace ('<DOWN_DEVICES_TABLE>', text + '\n') mail_text = mail_text.replace ('<DOWN_DEVICES_TABLE>', text + '\n')
mail_html = mail_html.replace ('<DOWN_DEVICES_TABLE>', html) mail_html = mail_html.replace ('<DOWN_DEVICES_TABLE>', html)
mylog('verbose', ['[Notification] Down Devices sections done.']) mylog('verbose', ['[Notification] Down Devices sections done.'])
# down_reconnected
# ---
html, text = construct_notifications(self.JSON, "down_reconnected")
mail_text = mail_text.replace ('<DOWN_RECONNECTED_TABLE>', text + '\n')
mail_html = mail_html.replace ('<DOWN_RECONNECTED_TABLE>', html)
mylog('verbose', ['[Notification] Reconnected Down Devices sections done.'])
# events
# ---
html, text = construct_notifications(self.JSON, "events") html, text = construct_notifications(self.JSON, "events")
@@ -140,6 +156,8 @@ class Notification_obj:
mylog('verbose', ['[Notification] Events sections done.']) mylog('verbose', ['[Notification] Events sections done.'])
# plugins
# ---
html, text = construct_notifications(self.JSON, "plugins") html, text = construct_notifications(self.JSON, "plugins")
mail_text = mail_text.replace ('<PLUGINS_TABLE>', text + '\n') mail_text = mail_text.replace ('<PLUGINS_TABLE>', text + '\n')
@@ -237,6 +255,21 @@ class Notification_obj:
AND eve_DateTime < datetime('now', '-{get_setting_value('NTFPRCS_alert_down_time')} minutes', '{get_timezone_offset()}') AND eve_DateTime < datetime('now', '-{get_setting_value('NTFPRCS_alert_down_time')} minutes', '{get_timezone_offset()}')
""") """)
# Clear the pending email flag for reconnected devices
self.db.sql.execute(f"""UPDATE Events_Devices
SET eve_PendingAlertEmail = 0
WHERE eve_MAC IN (
SELECT down_events.eve_MAC
FROM Events_Devices AS down_events
INNER JOIN Events AS connected_events
ON connected_events.eve_MAC = down_events.eve_MAC
WHERE down_events.eve_EventType = 'Device Down'
AND connected_events.eve_EventType = 'Connected'
AND connected_events.eve_DateTime > down_events.eve_DateTime
)
AND eve_EventType = 'Device Down'
""")
# clear plugin events # clear plugin events
self.db.sql.execute ("DELETE FROM Plugins_Events") self.db.sql.execute ("DELETE FROM Plugins_Events")

View File

@@ -37,6 +37,8 @@ def get_notifications (db):
json_new_devices_meta = {} json_new_devices_meta = {}
json_down_devices = [] json_down_devices = []
json_down_devices_meta = {} json_down_devices_meta = {}
json_down_reconnected = []
json_down_reconnected_meta = {}
json_events = [] json_events = []
json_events_meta = {} json_events_meta = {}
json_plugins = [] json_plugins = []
@@ -72,7 +74,7 @@ def get_notifications (db):
json_obj = db.get_table_as_json(sqlQuery) json_obj = db.get_table_as_json(sqlQuery)
json_new_devices_meta = { json_new_devices_meta = {
"title": "New devices", "title": "🆕New devices",
"columnNames": json_obj.columnNames "columnNames": json_obj.columnNames
} }
@@ -100,11 +102,36 @@ def get_notifications (db):
# Get the events as JSON # Get the events as JSON
json_obj = db.get_table_as_json(sqlQuery) json_obj = db.get_table_as_json(sqlQuery)
json_down_devices_meta = { json_down_devices_meta = {
"title": "Down devices", "title": "Down devices",
"columnNames": json_obj.columnNames "columnNames": json_obj.columnNames
} }
json_down_devices = json_obj.json["data"] json_down_devices = json_obj.json["data"]
if 'down_reconnected' in sections:
# Compose Reconnected Down Section
# - select only Devices, that were previously down and now are Connected
sqlQuery = f"""
SELECT down_events.dev_Name, down_events.eve_MAC, down_events.dev_Vendor, down_events.eve_IP,
down_events.eve_DateTime AS DownTime, connected_events.eve_DateTime AS ConnectedTime
FROM Events_Devices AS down_events
INNER JOIN Events AS connected_events
ON connected_events.eve_MAC = down_events.eve_MAC
WHERE down_events.eve_EventType = 'Device Down'
AND connected_events.eve_EventType = 'Connected'
AND connected_events.eve_DateTime > down_events.eve_DateTime
AND down_events.eve_PendingAlertEmail = 1
ORDER BY down_events.eve_DateTime;
"""
# Get the events as JSON
json_obj = db.get_table_as_json(sqlQuery)
json_down_reconnected_meta = {
"title": "🔁 Reconnected down devices",
"columnNames": json_obj.columnNames
}
json_down_reconnected = json_obj.json["data"]
if 'events' in sections: if 'events' in sections:
# Compose Events Section # Compose Events Section
@@ -121,7 +148,7 @@ def get_notifications (db):
json_obj = db.get_table_as_json(sqlQuery) json_obj = db.get_table_as_json(sqlQuery)
json_events_meta = { json_events_meta = {
"title": "Events", "title": "Events",
"columnNames": json_obj.columnNames "columnNames": json_obj.columnNames
} }
json_events = json_obj.json["data"] json_events = json_obj.json["data"]
@@ -134,7 +161,7 @@ def get_notifications (db):
json_obj = db.get_table_as_json(sqlQuery) json_obj = db.get_table_as_json(sqlQuery)
json_plugins_meta = { json_plugins_meta = {
"title": "Plugins", "title": "🔌 Plugins",
"columnNames": json_obj.columnNames "columnNames": json_obj.columnNames
} }
json_plugins = json_obj.json["data"] json_plugins = json_obj.json["data"]
@@ -145,6 +172,8 @@ def get_notifications (db):
"new_devices_meta": json_new_devices_meta, "new_devices_meta": json_new_devices_meta,
"down_devices": json_down_devices, "down_devices": json_down_devices,
"down_devices_meta": json_down_devices_meta, "down_devices_meta": json_down_devices_meta,
"down_reconnected": json_down_reconnected,
"down_reconnected_meta": json_down_reconnected_meta,
"events": json_events, "events": json_events,
"events_meta": json_events_meta, "events_meta": json_events_meta,
"plugins": json_plugins, "plugins": json_plugins,