vendor_update plugin

This commit is contained in:
Jokob-sk
2023-09-18 14:29:44 +10:00
parent 0ab5ca32a6
commit 12b89f7e24
5 changed files with 503 additions and 348 deletions

View File

@@ -458,7 +458,7 @@
"Plugins_Out_of" : "out of", "Plugins_Out_of" : "out of",
"Plugins_no_control" : "No form control was found to render this value.", "Plugins_no_control" : "No form control was found to render this value.",
"Settings_Metadata_Toggle" : "Show/hide metadata for the given setting.", "Settings_Metadata_Toggle" : "Show/hide metadata for the given setting.",
"settings_missing" : "Not all settings loaded, refresh the page! This is probably caused by a high load on the database.", "settings_missing" : "Not all settings loaded, refresh the page! This is probably caused by a high load on the database or app startup sequence.",
"settings_missing_block" : "You can not save your settings without specifying all setting keys. Refresh the page. This is probably caused by a high load on the database.", "settings_missing_block" : "You can not save your settings without specifying all setting keys. Refresh the page. This is probably caused by a high load on the database.",
"settings_old" : "Importing settings and re-initializing...", "settings_old" : "Importing settings and re-initializing...",
"settings_saved" : "<br/>Settings saved to the <code>pialert.conf</code> file.<br/><br/>A time-stamped backup of the previous file created. <br/><br/> Reloading...<br/>", "settings_saved" : "<br/>Settings saved to the <code>pialert.conf</code> file.<br/><br/>A time-stamped backup of the previous file created. <br/><br/> Reloading...<br/>",

View File

@@ -4,8 +4,11 @@
"enabled": true, "enabled": true,
"data_source": "script", "data_source": "script",
"show_ui": true, "show_ui": true,
"localized": ["display_name", "description", "icon"], "localized": [
"display_name",
"description",
"icon"
],
"display_name": [ "display_name": [
{ {
"language_code": "en_us", "language_code": "en_us",
@@ -24,17 +27,24 @@
"string": "A plugin to schedule vendor database updates for mac based vendor resolution." "string": "A plugin to schedule vendor database updates for mac based vendor resolution."
} }
], ],
"params" : [ "params": [],
],
"settings": [ "settings": [
{ {
"function": "RUN", "function": "RUN",
"type": "text.select", "type": "text.select",
"default_value": "schedule", "default_value": "schedule",
"options": ["disabled", "once", "schedule", "always_after_scan"], "options": [
"localized": ["name", "description"], "disabled",
"name" :[{ "once",
"schedule",
"always_after_scan"
],
"localized": [
"name",
"description"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "When to run" "string": "When to run"
}, },
@@ -45,18 +55,24 @@
{ {
"language_code": "de_de", "language_code": "de_de",
"string": "Wann laufen" "string": "Wann laufen"
}], }
"description": [{ ],
"description": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "When the cleanup should be performed. An overnight weekly <code>SCHEDULE</code> is recommended." "string": "When the cleanup should be performed. An overnight weekly <code>SCHEDULE</code> is recommended."
}] }
]
}, },
{ {
"function": "CMD", "function": "CMD",
"type": "readonly", "type": "readonly",
"default_value": "python3 /home/pi/pialert/front/plugins/vendor_update/script.py", "default_value": "python3 /home/pi/pialert/front/plugins/vendor_update/script.py",
"options": [], "options": [],
"localized": ["name", "description"], "localized": [
"name",
"description"
],
"name": [ "name": [
{ {
"language_code": "en_us", "language_code": "en_us",
@@ -91,8 +107,12 @@
"type": "text", "type": "text",
"default_value": "0 4 * * *", "default_value": "0 4 * * *",
"options": [], "options": [],
"localized": ["name", "description"], "localized": [
"name" : [{ "name",
"description"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "Schedule" "string": "Schedule"
}, },
@@ -103,8 +123,10 @@
{ {
"language_code": "de_de", "language_code": "de_de",
"string": "Schedule" "string": "Schedule"
}], }
"description": [{ ],
"description": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "Only enabled if you select <code>schedule</code> in the <a href=\"#VNDRPDT_RUN\"><code>VNDRPDT_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes." "string": "Only enabled if you select <code>schedule</code> in the <a href=\"#VNDRPDT_RUN\"><code>VNDRPDT_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes."
}, },
@@ -115,14 +137,18 @@
{ {
"language_code": "de_de", "language_code": "de_de",
"string": "Nur aktiviert, wenn Sie <code>schedule</code> in der <a href=\"#VNDRPDT_RUN\"><code>VNDRPDT_RUN</code>-Einstellung</a> auswählen. Stellen Sie sicher, dass Sie den Zeitplan im richtigen Cron-ähnlichen Format eingeben (z. B. validieren unter <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Wenn Sie beispielsweise <code>0 4 * * *</code> eingeben, wird der Scan nach 4 Uhr morgens in der <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</ ausgeführt. Code> den Sie oben festgelegt haben</a>. Wird das NÄCHSTE Mal ausgeführt, wenn die Zeit vergeht." "string": "Nur aktiviert, wenn Sie <code>schedule</code> in der <a href=\"#VNDRPDT_RUN\"><code>VNDRPDT_RUN</code>-Einstellung</a> auswählen. Stellen Sie sicher, dass Sie den Zeitplan im richtigen Cron-ähnlichen Format eingeben (z. B. validieren unter <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Wenn Sie beispielsweise <code>0 4 * * *</code> eingeben, wird der Scan nach 4 Uhr morgens in der <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</ ausgeführt. Code> den Sie oben festgelegt haben</a>. Wird das NÄCHSTE Mal ausgeführt, wenn die Zeit vergeht."
}] }
]
}, },
{ {
"function": "RUN_TIMEOUT", "function": "RUN_TIMEOUT",
"type": "integer", "type": "integer",
"default_value": 300, "default_value": 600,
"options": [], "options": [],
"localized": ["name", "description"], "localized": [
"name",
"description"
],
"name": [ "name": [
{ {
"language_code": "en_us", "language_code": "en_us",
@@ -151,11 +177,84 @@
"string": "Maximale Zeit in Sekunden, die auf den Abschluss des Skripts gewartet werden soll. Bei Überschreitung dieser Zeit wird das Skript abgebrochen." "string": "Maximale Zeit in Sekunden, die auf den Abschluss des Skripts gewartet werden soll. Bei Überschreitung dieser Zeit wird das Skript abgebrochen."
} }
] ]
},
{
"function": "WATCH",
"type": "text.multiselect",
"default_value": [
"Watched_Value1"
],
"options": [
"Watched_Value1",
"Watched_Value2",
"Watched_Value3",
"Watched_Value4"
],
"localized": [
"name",
"description"
],
"name": [
{
"language_code": "en_us",
"string": "Watched"
},
{
"language_code": "es_es",
"string": "Visto"
} }
], ],
"description": [
"database_column_definitions": {
[ "language_code": "en_us",
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is response status code (e.g.: 200, 404)</li><li><code>Watched_Value2</code> is Latency (not recommended)</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> unused </li></ul>"
},
{
"language_code": "es_es",
"string": "Envíe una notificación si los valores seleccionados cambian. Use <code>CTRL + Click</code> para seleccionar/deseleccionar. <ul> <li><code>Watched_Value1</code> es un código de estado de respuesta (por ejemplo: 200, 404) </li><li><code>Valor_observado2</code> es Latencia (no recomendado)</li><li><code>Valor_observado3</code> no utilizado </li><li><code>Valor_observado4 </ code> sin usar </li></ul>"
}
]
},
{
"function": "REPORT_ON",
"type": "text.multiselect",
"default_value": [
"new",
"watched-changed"
],
"options": [
"new",
"watched-changed",
"watched-not-changed",
"missing-in-last-scan"
],
"localized": [
"name",
"description"
],
"name": [
{
"language_code": "en_us",
"string": "Report on"
},
{
"language_code": "es_es",
"string": "Informar sobre"
}
],
"description": [
{
"language_code": "en_us",
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
},
{
"language_code": "es_es",
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que seleccionó <code>Watched_ValueN Las columnas </code> cambiaron."
}
]
}
],
"database_column_definitions": [
{ {
"column": "Index", "column": "Index",
"css_classes": "col-sm-2", "css_classes": "col-sm-2",
@@ -163,15 +262,19 @@
"type": "label", "type": "label",
"default_value": "", "default_value": "",
"options": [], "options": [],
"localized": ["name"], "localized": [
"name":[{ "name"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "N/A" "string": "N/A"
}, },
{ {
"language_code": "es_es", "language_code": "es_es",
"string": "N/A" "string": "N/A"
}] }
]
}, },
{ {
"column": "Plugin", "column": "Plugin",
@@ -180,15 +283,19 @@
"type": "label", "type": "label",
"default_value": "", "default_value": "",
"options": [], "options": [],
"localized": ["name"], "localized": [
"name":[{ "name"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "N/A" "string": "N/A"
}, },
{ {
"language_code": "es_es", "language_code": "es_es",
"string": "N/A" "string": "N/A"
}] }
]
}, },
{ {
"column": "Object_PrimaryID", "column": "Object_PrimaryID",
@@ -198,15 +305,19 @@
"type": "device_mac", "type": "device_mac",
"default_value": "", "default_value": "",
"options": [], "options": [],
"localized": ["name"], "localized": [
"name":[{ "name"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "MAC address" "string": "MAC address"
}, },
{ {
"language_code": "es_es", "language_code": "es_es",
"string": "Dirección MAC" "string": "Dirección MAC"
}] }
]
}, },
{ {
"column": "Object_SecondaryID", "column": "Object_SecondaryID",
@@ -216,15 +327,19 @@
"type": "device_ip", "type": "device_ip",
"default_value": "", "default_value": "",
"options": [], "options": [],
"localized": ["name"], "localized": [
"name":[{ "name"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "IP" "string": "IP"
}, },
{ {
"language_code": "es_es", "language_code": "es_es",
"string": "IP" "string": "IP"
}] }
]
}, },
{ {
"column": "DateTimeCreated", "column": "DateTimeCreated",
@@ -233,15 +348,19 @@
"type": "label", "type": "label",
"default_value": "", "default_value": "",
"options": [], "options": [],
"localized": ["name"], "localized": [
"name":[{ "name"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "Created" "string": "Created"
}, },
{ {
"language_code": "es_es", "language_code": "es_es",
"string": "Creado" "string": "Creado"
}] }
]
}, },
{ {
"column": "DateTimeChanged", "column": "DateTimeChanged",
@@ -251,15 +370,19 @@
"type": "label", "type": "label",
"default_value": "", "default_value": "",
"options": [], "options": [],
"localized": ["name"], "localized": [
"name":[{ "name"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "Changed" "string": "Changed"
}, },
{ {
"language_code": "es_es", "language_code": "es_es",
"string": "Cambiado" "string": "Cambiado"
}] }
]
}, },
{ {
"column": "Dummy", "column": "Dummy",
@@ -272,15 +395,19 @@
"type": "label", "type": "label",
"default_value": "", "default_value": "",
"options": [], "options": [],
"localized": ["name"], "localized": [
"name":[{ "name"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "Scan method" "string": "Scan method"
}, },
{ {
"language_code": "es_es", "language_code": "es_es",
"string": "Método de escaneo" "string": "Método de escaneo"
}] }
]
}, },
{ {
"column": "Watched_Value1", "column": "Watched_Value1",
@@ -290,11 +417,15 @@
"type": "label", "type": "label",
"default_value": "", "default_value": "",
"options": [], "options": [],
"localized": ["name"], "localized": [
"name":[{ "name"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "Vendor" "string": "Vendor"
}] }
]
}, },
{ {
"column": "Watched_Value2", "column": "Watched_Value2",
@@ -304,15 +435,19 @@
"type": "label", "type": "label",
"default_value": "", "default_value": "",
"options": [], "options": [],
"localized": ["name"], "localized": [
"name":[{ "name"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "Hostname" "string": "Hostname"
}, },
{ {
"language_code": "es_es", "language_code": "es_es",
"string": "Nombre de host" "string": "Nombre de host"
}] }
]
}, },
{ {
"column": "Watched_Value3", "column": "Watched_Value3",
@@ -321,11 +456,15 @@
"type": "label", "type": "label",
"default_value": "", "default_value": "",
"options": [], "options": [],
"localized": ["name"], "localized": [
"name":[{ "name"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "N/A" "string": "N/A"
}] }
]
}, },
{ {
"column": "Watched_Value4", "column": "Watched_Value4",
@@ -334,11 +473,15 @@
"type": "label", "type": "label",
"default_value": "", "default_value": "",
"options": [], "options": [],
"localized": ["name"], "localized": [
"name":[{ "name"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "N/A" "string": "N/A"
}] }
]
}, },
{ {
"column": "UserData", "column": "UserData",
@@ -347,15 +490,19 @@
"type": "textbox_save", "type": "textbox_save",
"default_value": "", "default_value": "",
"options": [], "options": [],
"localized": ["name"], "localized": [
"name":[{ "name"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "Comments" "string": "Comments"
}, },
{ {
"language_code": "es_es", "language_code": "es_es",
"string": "Comentarios" "string": "Comentarios"
}] }
]
}, },
{ {
"column": "Extra", "column": "Extra",
@@ -364,11 +511,15 @@
"type": "label", "type": "label",
"default_value": "", "default_value": "",
"options": [], "options": [],
"localized": ["name"], "localized": [
"name":[{ "name"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "N/A" "string": "N/A"
}] }
]
}, },
{ {
"column": "Status", "column": "Status",
@@ -394,15 +545,19 @@
"replacement": "<div style='text-align:center'><i class='fa-solid fa-question'></i></div>" "replacement": "<div style='text-align:center'><i class='fa-solid fa-question'></i></div>"
} }
], ],
"localized": ["name"], "localized": [
"name":[{ "name"
],
"name": [
{
"language_code": "en_us", "language_code": "en_us",
"string": "Status" "string": "Status"
}, },
{ {
"language_code": "es_es", "language_code": "es_es",
"string": "Estado" "string": "Estado"
}] }
]
} }
] ]
} }

View File

@@ -32,7 +32,7 @@ def main():
mylog('verbose', ['[VNDRPDT] In script']) mylog('verbose', ['[VNDRPDT] In script'])
# Get newest DB # Get newest DB
update_vendor_database() # update_vendor_database() TODOz
# Resolve missing vendors # Resolve missing vendors
plugin_objects = Plugin_Objects(RESULT_FILE) plugin_objects = Plugin_Objects(RESULT_FILE)
@@ -63,52 +63,65 @@ def update_vendor_database():
mylog('none', [' FAILED: Updating vendors DB, set LOG_LEVEL=debug for more info']) mylog('none', [' FAILED: Updating vendors DB, set LOG_LEVEL=debug for more info'])
mylog('none', [e.output]) mylog('none', [e.output])
# ------------------------------------------------------------------------------
# resolve missing vendors # resolve missing vendors
def update_vendors (dbPath, plugin_objects): def update_vendors (dbPath, plugin_objects):
# Connect to the PiAlert SQLite database # Connect to the PiAlert SQLite database
conn = sqlite3.connect(dbPath) conn = sqlite3.connect(dbPath)
cursor = conn.cursor() sql = conn.cursor()
# Initialize variables # Initialize variables
recordsToUpdate = [] recordsToUpdate = []
ignored = 0 ignored = 0
notFound = 0 notFound = 0
# All devices loop
mylog('verbose', [' Searching devices vendor']) mylog('verbose', [' Searching devices vendor'])
for device in cursor.execute ("""SELECT * FROM Devices # Get devices without a vendor
sql.execute ("""SELECT
dev_MAC,
dev_LastIP,
dev_Name,
dev_Vendor
FROM Devices
WHERE dev_Vendor = '(unknown)' WHERE dev_Vendor = '(unknown)'
OR dev_Vendor = '' OR dev_Vendor = ''
OR dev_Vendor IS NULL""") : OR dev_Vendor IS NULL
""")
devices = sql.fetchall()
conn.commit()
# Close the database connection
conn.close()
# All devices loop
for device in devices:
# Search vendor in HW Vendors DB # Search vendor in HW Vendors DB
vendor = query_MAC_vendor (device['dev_MAC']) vendor = query_MAC_vendor (device[0])
if vendor == -1 : if vendor == -1 :
notFound += 1 notFound += 1
elif vendor == -2 : elif vendor == -2 :
ignored += 1 ignored += 1
else : else :
plugin_objects.add_object( plugin_objects.add_object(
primaryId = device['dev_MAC'], # MAC (Device Name) primaryId = device[0], # MAC (Device Name)
secondaryId = device['dev_LastIP'], # IP Address (always 0.0.0.0) secondaryId = device[1], # IP Address (always 0.0.0.0)
watched1 = vendor, watched1 = vendor,
watched2 = device['dev_Name'], watched2 = device[2],
watched3 = "", watched3 = "",
watched4 = "", watched4 = "",
extra = "", extra = "",
foreignKey = device['dev_MAC'] foreignKey = device[0]
) )
# Print log # Print log
mylog('verbose', [" Devices Ignored : ", ignored]) mylog('verbose', [" Devices Ignored : ", ignored])
mylog('verbose', [" Devices with missing vendor : ", len(devices)])
mylog('verbose', [" Vendors Not Found : ", notFound]) mylog('verbose', [" Vendors Not Found : ", notFound])
mylog('verbose', [" Vendors updated : ", len(plugin_objects) ]) mylog('verbose', [" Vendors updated : ", len(plugin_objects) ])
conn.commit()
# Close the database connection
conn.close()
return plugin_objects return plugin_objects

View File

@@ -15,10 +15,7 @@ logPath = pialertPath + '/front/log'
apiPath = pialertPath + '/front/api/' apiPath = pialertPath + '/front/api/'
fullConfPath = pialertPath + confPath fullConfPath = pialertPath + confPath
fullDbPath = pialertPath + dbPath fullDbPath = pialertPath + dbPath
vendorsPath = '/usr/share/arp-scan/ieee-oui.txt'
vendorsDB = '/usr/share/arp-scan/ieee-oui.txt'

View File

@@ -6,7 +6,7 @@ import re
from helper import timeNowTZ, get_setting, get_setting_value,resolve_device_name_dig, resolve_device_name_pholus from helper import timeNowTZ, get_setting, get_setting_value,resolve_device_name_dig, resolve_device_name_pholus
from scanners.internet import check_IP_format, get_internet_IP from scanners.internet import check_IP_format, get_internet_IP
from logger import mylog, print_log from logger import mylog, print_log
from const import vendorsDB from const import vendorsPath
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
@@ -319,37 +319,27 @@ def check_mac_or_internet(input_str):
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
def query_MAC_vendor (pMAC): def query_MAC_vendor (pMAC):
try :
# BUGFIX #6 - Fix pMAC parameter as numbers
pMACstr = str(pMAC) pMACstr = str(pMAC)
# Check MAC parameter # Check MAC parameter
mac = pMACstr.replace (':','') mac = pMACstr.replace (':','')
if len(pMACstr) != 17 or len(mac) != 12 : if len(pMACstr) != 17 or len(mac) != 12 :
return -2 return -2 # return -2 if ignored MAC
# Search vendor in HW Vendors DB # Search vendor in HW Vendors DB
mac = mac[0:6] mac_start_string = mac[0:6]
grep_args = ['grep', '-i', mac, vendorsDB]
# Execute command
if conf.LOG_LEVEL == 'debug':
# try runnning a subprocess
grep_output = subprocess.check_output (grep_args)
else:
try: try:
# try runnning a subprocess with open(vendorsPath, 'r') as f:
grep_output = subprocess.check_output (grep_args) for line in f:
except subprocess.CalledProcessError as e: if line.startswith(mac_start_string):
# An error occured, handle it vendor = line.split(' ', 1)[1].strip()
mylog('none', ["[Mac Vendor Check] Error: ", e.output]) mylog('debug', [f"[Vendor Check] Found '{vendor}' for '{pMAC}'"])
grep_output = " There was an error, check logs for details"
# Return Vendor
vendor = grep_output[7:]
vendor = vendor.rstrip()
return vendor return vendor
# not Found return -1 # MAC address not found in the database
except subprocess.CalledProcessError : except FileNotFoundError:
mylog('none', [f"[Vendor Check] Error: Vendors file {vendorsPath} not found."])
return -1 return -1