mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
FQDN, Dig refactor, docs #1065
This commit is contained in:
@@ -153,7 +153,7 @@ def main ():
|
||||
|
||||
# Resolve devices names
|
||||
mylog('debug','[Main] Resolve devices names')
|
||||
update_devices_names(db)
|
||||
update_devices_names(db)
|
||||
|
||||
# Check if new devices found
|
||||
sql.execute (sql_new_devices)
|
||||
|
||||
@@ -60,6 +60,7 @@ sql_devices_all = """
|
||||
IFNULL(devSyncHubNode, '') AS devSyncHubNode,
|
||||
IFNULL(devSourcePlugin, '') AS devSourcePlugin,
|
||||
IFNULL(devCustomProps, '') AS devCustomProps,
|
||||
IFNULL(devFQDN, '') AS devFQDN,
|
||||
CASE
|
||||
WHEN devIsNew = 1 THEN 'New'
|
||||
WHEN devPresentLastScan = 1 THEN 'On-line'
|
||||
|
||||
@@ -80,370 +80,10 @@ class DB():
|
||||
"""
|
||||
Check the current tables in the DB and upgrade them if neccessary
|
||||
"""
|
||||
|
||||
self.sql.execute("""
|
||||
CREATE TABLE IF NOT EXISTS "Online_History" (
|
||||
"Index" INTEGER,
|
||||
"Scan_Date" TEXT,
|
||||
"Online_Devices" INTEGER,
|
||||
"Down_Devices" INTEGER,
|
||||
"All_Devices" INTEGER,
|
||||
"Archived_Devices" INTEGER,
|
||||
"Offline_Devices" INTEGER,
|
||||
PRIMARY KEY("Index" AUTOINCREMENT)
|
||||
);
|
||||
""")
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# DevicesNew - cleanup after 6/6/2025 - need to update also DB in the source code!
|
||||
|
||||
# check if migration already done based on devMac
|
||||
devMac_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='devMac'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if devMac_missing:
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Alter Devices table
|
||||
# -------------------------------------------------------------------------
|
||||
# dev_Network_Node_MAC_ADDR column
|
||||
dev_Network_Node_MAC_ADDR_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Network_Node_MAC_ADDR'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_Network_Node_MAC_ADDR_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_Network_Node_MAC_ADDR to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_Network_Node_MAC_ADDR" TEXT
|
||||
""")
|
||||
|
||||
# dev_Network_Node_port column
|
||||
dev_Network_Node_port_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Network_Node_port'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_Network_Node_port_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_Network_Node_port to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_Network_Node_port" INTEGER
|
||||
""")
|
||||
|
||||
# dev_Icon column
|
||||
dev_Icon_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Icon'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_Icon_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_Icon to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_Icon" TEXT
|
||||
""")
|
||||
|
||||
# dev_GUID column
|
||||
dev_GUID_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_GUID'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_GUID_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_GUID to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_GUID" TEXT
|
||||
""")
|
||||
|
||||
# dev_NetworkSite column
|
||||
dev_NetworkSite_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_NetworkSite'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_NetworkSite_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_NetworkSite to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_NetworkSite" TEXT
|
||||
""")
|
||||
|
||||
# dev_SSID column
|
||||
dev_SSID_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SSID'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_SSID_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_SSID to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_SSID" TEXT
|
||||
""")
|
||||
|
||||
# SQL query to update missing dev_GUID
|
||||
self.sql.execute(f'''
|
||||
UPDATE Devices
|
||||
SET dev_GUID = {sql_generateGuid}
|
||||
WHERE dev_GUID IS NULL
|
||||
''')
|
||||
|
||||
# dev_SyncHubNodeName column
|
||||
dev_SyncHubNodeName_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SyncHubNodeName'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_SyncHubNodeName_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_SyncHubNodeName to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_SyncHubNodeName" TEXT
|
||||
""")
|
||||
|
||||
# dev_SourcePlugin column
|
||||
dev_SourcePlugin_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SourcePlugin'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_SourcePlugin_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_SourcePlugin to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_SourcePlugin" TEXT
|
||||
""")
|
||||
|
||||
# SQL to create Devices table with indexes
|
||||
sql_create_devices_new_tmp = """
|
||||
CREATE TABLE IF NOT EXISTS Devices_tmp (
|
||||
devMac STRING (50) PRIMARY KEY NOT NULL COLLATE NOCASE,
|
||||
devName STRING (50) NOT NULL DEFAULT "(unknown)",
|
||||
devOwner STRING (30) DEFAULT "(unknown)" NOT NULL,
|
||||
devType STRING (30),
|
||||
devVendor STRING (250),
|
||||
devFavorite BOOLEAN CHECK (devFavorite IN (0, 1)) DEFAULT (0) NOT NULL,
|
||||
devGroup STRING (10),
|
||||
devComments TEXT,
|
||||
devFirstConnection DATETIME NOT NULL,
|
||||
devLastConnection DATETIME NOT NULL,
|
||||
devLastIP STRING (50) NOT NULL COLLATE NOCASE,
|
||||
devStaticIP BOOLEAN DEFAULT (0) NOT NULL CHECK (devStaticIP IN (0, 1)),
|
||||
devScan INTEGER DEFAULT (1) NOT NULL,
|
||||
devLogEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devLogEvents IN (0, 1)),
|
||||
devAlertEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devAlertEvents IN (0, 1)),
|
||||
devAlertDown BOOLEAN NOT NULL DEFAULT (0) CHECK (devAlertDown IN (0, 1)),
|
||||
devSkipRepeated INTEGER DEFAULT 0 NOT NULL,
|
||||
devLastNotification DATETIME,
|
||||
devPresentLastScan BOOLEAN NOT NULL DEFAULT (0) CHECK (devPresentLastScan IN (0, 1)),
|
||||
devIsNew BOOLEAN NOT NULL DEFAULT (1) CHECK (devIsNew IN (0, 1)),
|
||||
devLocation STRING (250) COLLATE NOCASE,
|
||||
devIsArchived BOOLEAN NOT NULL DEFAULT (0) CHECK (devIsArchived IN (0, 1)),
|
||||
devParentMAC TEXT,
|
||||
devParentPort INTEGER,
|
||||
devIcon TEXT,
|
||||
devGUID TEXT,
|
||||
devSite TEXT,
|
||||
devSSID TEXT,
|
||||
devSyncHubNode TEXT,
|
||||
devSourcePlugin TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_PresentLastScan ON Devices_tmp (devPresentLastScan);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_FirstConnection ON Devices_tmp (devFirstConnection);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_AlertDeviceDown ON Devices_tmp (devAlertDown);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_StaticIP ON Devices_tmp (devStaticIP);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_ScanCycle ON Devices_tmp (devScan);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_Favorite ON Devices_tmp (devFavorite);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_LastIP ON Devices_tmp (devLastIP);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_NewDevice ON Devices_tmp (devIsNew);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_Archived ON Devices_tmp (devIsArchived);
|
||||
"""
|
||||
|
||||
# Execute the creation of the Devices table and indexes
|
||||
self.sql.executescript(sql_create_devices_new_tmp)
|
||||
|
||||
|
||||
# copy over data
|
||||
sql_copy_from_devices = """
|
||||
INSERT OR IGNORE INTO Devices_tmp (
|
||||
devMac,
|
||||
devName,
|
||||
devOwner,
|
||||
devType,
|
||||
devVendor,
|
||||
devFavorite,
|
||||
devGroup,
|
||||
devComments,
|
||||
devFirstConnection,
|
||||
devLastConnection,
|
||||
devLastIP,
|
||||
devStaticIP,
|
||||
devScan,
|
||||
devLogEvents,
|
||||
devAlertEvents,
|
||||
devAlertDown,
|
||||
devSkipRepeated,
|
||||
devLastNotification,
|
||||
devPresentLastScan,
|
||||
devIsNew,
|
||||
devLocation,
|
||||
devIsArchived,
|
||||
devParentMAC,
|
||||
devParentPort,
|
||||
devIcon,
|
||||
devGUID,
|
||||
devSite,
|
||||
devSSID,
|
||||
devSyncHubNode,
|
||||
devSourcePlugin
|
||||
)
|
||||
SELECT
|
||||
dev_MAC AS devMac,
|
||||
dev_Name AS devName,
|
||||
dev_Owner AS devOwner,
|
||||
dev_DeviceType AS devType,
|
||||
dev_Vendor AS devVendor,
|
||||
dev_Favorite AS devFavorite,
|
||||
dev_Group AS devGroup,
|
||||
dev_Comments AS devComments,
|
||||
dev_FirstConnection AS devFirstConnection,
|
||||
dev_LastConnection AS devLastConnection,
|
||||
dev_LastIP AS devLastIP,
|
||||
dev_StaticIP AS devStaticIP,
|
||||
dev_ScanCycle AS devScan,
|
||||
dev_LogEvents AS devLogEvents,
|
||||
dev_AlertEvents AS devAlertEvents,
|
||||
dev_AlertDeviceDown AS devAlertDown,
|
||||
dev_SkipRepeated AS devSkipRepeated,
|
||||
dev_LastNotification AS devLastNotification,
|
||||
dev_PresentLastScan AS devPresentLastScan,
|
||||
dev_NewDevice AS devIsNew,
|
||||
dev_Location AS devLocation,
|
||||
dev_Archived AS devIsArchived,
|
||||
dev_Network_Node_MAC_ADDR AS devParentMAC,
|
||||
dev_Network_Node_port AS devParentPort,
|
||||
dev_Icon AS devIcon,
|
||||
dev_GUID AS devGUID,
|
||||
dev_NetworkSite AS devSite,
|
||||
dev_SSID AS devSSID,
|
||||
dev_SyncHubNodeName AS devSyncHubNode,
|
||||
dev_SourcePlugin AS devSourcePlugin
|
||||
FROM Devices;
|
||||
"""
|
||||
|
||||
self.sql.execute(sql_copy_from_devices)
|
||||
|
||||
|
||||
self.sql.execute(""" DROP TABLE Devices;""")
|
||||
# SQL to create Devices table with indexes
|
||||
sql_create_devices_new = """
|
||||
CREATE TABLE IF NOT EXISTS Devices (
|
||||
devMac STRING (50) PRIMARY KEY NOT NULL COLLATE NOCASE,
|
||||
devName STRING (50) NOT NULL DEFAULT "(unknown)",
|
||||
devOwner STRING (30) DEFAULT "(unknown)" NOT NULL,
|
||||
devType STRING (30),
|
||||
devVendor STRING (250),
|
||||
devFavorite BOOLEAN CHECK (devFavorite IN (0, 1)) DEFAULT (0) NOT NULL,
|
||||
devGroup STRING (10),
|
||||
devComments TEXT,
|
||||
devFirstConnection DATETIME NOT NULL,
|
||||
devLastConnection DATETIME NOT NULL,
|
||||
devLastIP STRING (50) NOT NULL COLLATE NOCASE,
|
||||
devStaticIP BOOLEAN DEFAULT (0) NOT NULL CHECK (devStaticIP IN (0, 1)),
|
||||
devScan INTEGER DEFAULT (1) NOT NULL,
|
||||
devLogEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devLogEvents IN (0, 1)),
|
||||
devAlertEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devAlertEvents IN (0, 1)),
|
||||
devAlertDown BOOLEAN NOT NULL DEFAULT (0) CHECK (devAlertDown IN (0, 1)),
|
||||
devSkipRepeated INTEGER DEFAULT 0 NOT NULL,
|
||||
devLastNotification DATETIME,
|
||||
devPresentLastScan BOOLEAN NOT NULL DEFAULT (0) CHECK (devPresentLastScan IN (0, 1)),
|
||||
devIsNew BOOLEAN NOT NULL DEFAULT (1) CHECK (devIsNew IN (0, 1)),
|
||||
devLocation STRING (250) COLLATE NOCASE,
|
||||
devIsArchived BOOLEAN NOT NULL DEFAULT (0) CHECK (devIsArchived IN (0, 1)),
|
||||
devParentMAC TEXT,
|
||||
devParentPort INTEGER,
|
||||
devIcon TEXT,
|
||||
devGUID TEXT,
|
||||
devSite TEXT,
|
||||
devSSID TEXT,
|
||||
devSyncHubNode TEXT,
|
||||
devSourcePlugin TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_PresentLastScan ON Devices (devPresentLastScan);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_FirstConnection ON Devices (devFirstConnection);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_AlertDeviceDown ON Devices (devAlertDown);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_StaticIP ON Devices (devStaticIP);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_ScanCycle ON Devices (devScan);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_Favorite ON Devices (devFavorite);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_LastIP ON Devices (devLastIP);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_NewDevice ON Devices (devIsNew);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_Archived ON Devices (devIsArchived);
|
||||
"""
|
||||
|
||||
# Execute the creation of the Devices table and indexes
|
||||
self.sql.executescript(sql_create_devices_new)
|
||||
|
||||
# copy over data
|
||||
sql_copy_from_devices_tmp = """
|
||||
INSERT OR IGNORE INTO Devices (
|
||||
devMac,
|
||||
devName,
|
||||
devOwner,
|
||||
devType,
|
||||
devVendor,
|
||||
devFavorite,
|
||||
devGroup,
|
||||
devComments,
|
||||
devFirstConnection,
|
||||
devLastConnection,
|
||||
devLastIP,
|
||||
devStaticIP,
|
||||
devScan,
|
||||
devLogEvents,
|
||||
devAlertEvents,
|
||||
devAlertDown,
|
||||
devSkipRepeated,
|
||||
devLastNotification,
|
||||
devPresentLastScan,
|
||||
devIsNew,
|
||||
devLocation,
|
||||
devIsArchived,
|
||||
devParentMAC,
|
||||
devParentPort,
|
||||
devIcon,
|
||||
devGUID,
|
||||
devSite,
|
||||
devSSID,
|
||||
devSyncHubNode,
|
||||
devSourcePlugin
|
||||
)
|
||||
SELECT
|
||||
devMac,
|
||||
devName,
|
||||
devOwner,
|
||||
devType,
|
||||
devVendor,
|
||||
devFavorite,
|
||||
devGroup,
|
||||
devComments,
|
||||
devFirstConnection,
|
||||
devLastConnection,
|
||||
devLastIP,
|
||||
devStaticIP,
|
||||
devScan,
|
||||
devLogEvents,
|
||||
devAlertEvents,
|
||||
devAlertDown,
|
||||
devSkipRepeated,
|
||||
devLastNotification,
|
||||
devPresentLastScan,
|
||||
devIsNew,
|
||||
devLocation,
|
||||
devIsArchived,
|
||||
devParentMAC,
|
||||
devParentPort,
|
||||
devIcon,
|
||||
devGUID,
|
||||
devSite,
|
||||
devSSID,
|
||||
devSyncHubNode,
|
||||
devSourcePlugin
|
||||
FROM Devices_tmp;
|
||||
"""
|
||||
|
||||
self.sql.execute(sql_copy_from_devices_tmp)
|
||||
self.sql.execute(""" DROP TABLE Devices_tmp;""")
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Alter Devices table
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# VIEWS
|
||||
|
||||
@@ -477,17 +117,19 @@ class DB():
|
||||
|
||||
|
||||
# add fields if missing
|
||||
|
||||
# devCustomProps column
|
||||
devCustomProps_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='devCustomProps'
|
||||
|
||||
# devFQDN missing?
|
||||
devFQDN_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='devFQDN'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if devFQDN_missing:
|
||||
|
||||
if devCustomProps_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding devCustomProps to the Devices table"])
|
||||
mylog('verbose', ["[upgradeDB] Adding devFQDN to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "devCustomProps" TEXT
|
||||
ALTER TABLE "Devices" ADD "devFQDN" TEXT
|
||||
""")
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Settings table setup
|
||||
@@ -564,48 +206,6 @@ class DB():
|
||||
); """
|
||||
self.sql.execute(sql_Plugins_Objects)
|
||||
|
||||
# -----------------------------------------
|
||||
# REMOVE after 6/6/2025 - START
|
||||
# -----------------------------------------
|
||||
# syncHubNodeName column
|
||||
plug_SyncHubNodeName_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Objects') WHERE name='SyncHubNodeName'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if plug_SyncHubNodeName_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding SyncHubNodeName to the Plugins_Objects table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Plugins_Objects" ADD "SyncHubNodeName" TEXT
|
||||
""")
|
||||
|
||||
# helper columns HelpVal1-4
|
||||
plug_HelpValues_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Objects') WHERE name='HelpVal1'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if plug_HelpValues_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding HelpVal1-4 to the Plugins_Objects table"])
|
||||
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal1" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal2" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal3" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal4" TEXT')
|
||||
|
||||
# plug_ObjectGUID_missing column
|
||||
plug_ObjectGUID_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Objects') WHERE name='ObjectGUID'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if plug_ObjectGUID_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding ObjectGUID to the Plugins_Objects table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Plugins_Objects" ADD "ObjectGUID" TEXT
|
||||
""")
|
||||
|
||||
|
||||
# -----------------------------------------
|
||||
# REMOVE after 6/6/2025 - END
|
||||
# -----------------------------------------
|
||||
|
||||
# Plugin execution results
|
||||
sql_Plugins_Events = """ CREATE TABLE IF NOT EXISTS Plugins_Events(
|
||||
"Index" INTEGER,
|
||||
@@ -631,49 +231,6 @@ class DB():
|
||||
); """
|
||||
self.sql.execute(sql_Plugins_Events)
|
||||
|
||||
# -----------------------------------------
|
||||
# REMOVE after 6/6/2025 - START
|
||||
# -----------------------------------------
|
||||
|
||||
# syncHubNodeName column
|
||||
plug_SyncHubNodeName_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Events') WHERE name='SyncHubNodeName'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if plug_SyncHubNodeName_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding SyncHubNodeName to the Plugins_Events table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Plugins_Events" ADD "SyncHubNodeName" TEXT
|
||||
""")
|
||||
|
||||
# helper columns HelpVal1-4
|
||||
plug_HelpValues_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Events') WHERE name='HelpVal1'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if plug_HelpValues_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding HelpVal1-4 to the Plugins_Events table"])
|
||||
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal1" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal2" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal3" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal4" TEXT')
|
||||
|
||||
# plug_ObjectGUID_missing column
|
||||
plug_ObjectGUID_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Events') WHERE name='ObjectGUID'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if plug_ObjectGUID_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding ObjectGUID to the Plugins_Events table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Plugins_Events" ADD "ObjectGUID" TEXT
|
||||
""")
|
||||
|
||||
# -----------------------------------------
|
||||
# REMOVE after 6/6/2025 - END
|
||||
# -----------------------------------------
|
||||
|
||||
|
||||
# Plugin execution history
|
||||
sql_Plugins_History = """ CREATE TABLE IF NOT EXISTS Plugins_History(
|
||||
"Index" INTEGER,
|
||||
@@ -699,48 +256,6 @@ class DB():
|
||||
); """
|
||||
self.sql.execute(sql_Plugins_History)
|
||||
|
||||
# -----------------------------------------
|
||||
# REMOVE after 6/6/2025 - START
|
||||
# -----------------------------------------
|
||||
|
||||
# syncHubNodeName column
|
||||
plug_SyncHubNodeName_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_History') WHERE name='SyncHubNodeName'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if plug_SyncHubNodeName_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding SyncHubNodeName to the Plugins_History table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Plugins_History" ADD "SyncHubNodeName" TEXT
|
||||
""")
|
||||
|
||||
# helper columns HelpVal1-4
|
||||
plug_HelpValues_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_History') WHERE name='HelpVal1'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if plug_HelpValues_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding HelpVal1-4 to the Plugins_History table"])
|
||||
self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal1" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal2" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal3" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal4" TEXT')
|
||||
|
||||
|
||||
# plug_ObjectGUID_missing column
|
||||
plug_ObjectGUID_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_History') WHERE name='ObjectGUID'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if plug_ObjectGUID_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding ObjectGUID to the Plugins_History table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Plugins_History" ADD "ObjectGUID" TEXT
|
||||
""")
|
||||
|
||||
# -----------------------------------------
|
||||
# REMOVE after 6/6/2025 - END
|
||||
# -----------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Plugins_Language_Strings table setup
|
||||
@@ -845,21 +360,6 @@ class DB():
|
||||
# Init the AppEvent database table
|
||||
AppEvent_obj(self)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# DELETING OBSOLETE TABLES - to remove with updated db file after 9/9/2024
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# Deletes obsolete ScanCycles
|
||||
self.sql.execute(""" DROP TABLE IF EXISTS ScanCycles;""")
|
||||
self.sql.execute(""" DROP TABLE IF EXISTS DHCP_Leases;""")
|
||||
self.sql.execute(""" DROP TABLE IF EXISTS PiHole_Network;""")
|
||||
|
||||
self.commitDB()
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# DELETING OBSOLETE TABLES - to remove with updated db file after 9/9/2024
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def get_table_as_json(self, sqlQuery):
|
||||
|
||||
@@ -73,6 +73,7 @@ class Device(ObjectType):
|
||||
devParentChildrenCount = Int()
|
||||
devIpLong = Int()
|
||||
devFilterStatus = String()
|
||||
devFQDN = String()
|
||||
|
||||
|
||||
class DeviceResult(ObjectType):
|
||||
@@ -180,7 +181,7 @@ class Query(ObjectType):
|
||||
searchable_fields = [
|
||||
"devName", "devMac", "devOwner", "devType", "devVendor", "devLastIP",
|
||||
"devGroup", "devComments", "devLocation", "devStatus",
|
||||
"devSSID", "devSite", "devSourcePlugin", "devSyncHubNode"
|
||||
"devSSID", "devSite", "devSourcePlugin", "devSyncHubNode", "devFQDN"
|
||||
]
|
||||
|
||||
search_term = options.search.lower()
|
||||
|
||||
206
server/helper.py
206
server/helper.py
@@ -18,6 +18,7 @@ import hashlib
|
||||
import random
|
||||
import string
|
||||
import ipaddress
|
||||
import dns.resolver
|
||||
|
||||
import conf
|
||||
from const import *
|
||||
@@ -427,211 +428,6 @@ def check_IP_format (pIP):
|
||||
# Return IP
|
||||
return IP.group(0)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def get_device_name_mdns(db, pMAC, pIP):
|
||||
|
||||
nameNotFound = "(name not found)"
|
||||
|
||||
sql = db.sql
|
||||
|
||||
name = nameNotFound
|
||||
|
||||
# get names from the AVAHISCAN plugin entries vased on MAC
|
||||
sql.execute(
|
||||
f"""
|
||||
SELECT Watched_Value2 FROM Plugins_Objects
|
||||
WHERE
|
||||
Plugin = 'AVAHISCAN' AND
|
||||
Object_PrimaryID = '{pMAC}'
|
||||
"""
|
||||
)
|
||||
nameEntry = sql.fetchall()
|
||||
db.commitDB()
|
||||
|
||||
if len(nameEntry) != 0:
|
||||
name = cleanDeviceName(nameEntry[0][0], False)
|
||||
|
||||
return name
|
||||
|
||||
# get names from the AVAHISCAN plugin entries based on IP
|
||||
sql.execute(
|
||||
f"""
|
||||
SELECT Watched_Value2 FROM Plugins_Objects
|
||||
WHERE
|
||||
Plugin = 'AVAHISCAN' AND
|
||||
Object_SecondaryID = '{pIP}'
|
||||
"""
|
||||
)
|
||||
nameEntry = sql.fetchall()
|
||||
db.commitDB()
|
||||
|
||||
if len(nameEntry) != 0:
|
||||
name = cleanDeviceName(nameEntry[0][0], True)
|
||||
|
||||
return name
|
||||
|
||||
return name
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def get_device_name_nslookup(db, pMAC, pIP):
|
||||
|
||||
nameNotFound = "(name not found)"
|
||||
|
||||
sql = db.sql
|
||||
|
||||
name = nameNotFound
|
||||
|
||||
# get names from the NSLOOKUP plugin entries vased on MAC
|
||||
sql.execute(
|
||||
f"""
|
||||
SELECT Watched_Value2 FROM Plugins_Objects
|
||||
WHERE
|
||||
Plugin = 'NSLOOKUP' AND
|
||||
Object_PrimaryID = '{pMAC}'
|
||||
"""
|
||||
)
|
||||
nameEntry = sql.fetchall()
|
||||
db.commitDB()
|
||||
|
||||
if len(nameEntry) != 0:
|
||||
name = cleanDeviceName(nameEntry[0][0], False)
|
||||
|
||||
return name
|
||||
|
||||
# get names from the NSLOOKUP plugin entries based on IP
|
||||
sql.execute(
|
||||
f"""
|
||||
SELECT Watched_Value2 FROM Plugins_Objects
|
||||
WHERE
|
||||
Plugin = 'NSLOOKUP' AND
|
||||
Object_SecondaryID = '{pIP}'
|
||||
"""
|
||||
)
|
||||
nameEntry = sql.fetchall()
|
||||
db.commitDB()
|
||||
|
||||
if len(nameEntry) != 0:
|
||||
name = cleanDeviceName(nameEntry[0][0], True)
|
||||
|
||||
return name
|
||||
|
||||
return name
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def get_device_name_nbtlookup(db, pMAC, pIP):
|
||||
|
||||
nameNotFound = "(name not found)"
|
||||
|
||||
sql = db.sql
|
||||
|
||||
name = nameNotFound
|
||||
|
||||
# get names from the NBTSCAN plugin entries vased on MAC
|
||||
sql.execute(
|
||||
f"""
|
||||
SELECT Watched_Value2 FROM Plugins_Objects
|
||||
WHERE
|
||||
Plugin = 'NBTSCAN' AND
|
||||
Object_PrimaryID = '{pMAC}'
|
||||
"""
|
||||
)
|
||||
nameEntry = sql.fetchall()
|
||||
db.commitDB()
|
||||
|
||||
if len(nameEntry) != 0:
|
||||
name = cleanDeviceName(nameEntry[0][0], False)
|
||||
|
||||
return name
|
||||
|
||||
# get names from the NSLOOKUP plugin entries based on IP
|
||||
sql.execute(
|
||||
f"""
|
||||
SELECT Watched_Value2 FROM Plugins_Objects
|
||||
WHERE
|
||||
Plugin = 'NBTSCAN' AND
|
||||
Object_SecondaryID = '{pIP}'
|
||||
"""
|
||||
)
|
||||
nameEntry = sql.fetchall()
|
||||
db.commitDB()
|
||||
|
||||
if len(nameEntry) != 0:
|
||||
name = cleanDeviceName(nameEntry[0][0], True)
|
||||
|
||||
return name
|
||||
|
||||
return name
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def resolve_device_name_dig (pMAC, pIP):
|
||||
|
||||
nameNotFound = "(name not found)"
|
||||
|
||||
dig_args = ['dig', '+short', '-x', pIP]
|
||||
|
||||
# Execute command
|
||||
try:
|
||||
# try runnning a subprocess
|
||||
newName = subprocess.check_output (dig_args, universal_newlines=True)
|
||||
|
||||
# Check returns
|
||||
newName = newName.strip()
|
||||
|
||||
if len(newName) == 0 :
|
||||
return nameNotFound
|
||||
|
||||
# Cleanup
|
||||
newName = cleanDeviceName(newName, True)
|
||||
|
||||
if newName == "" or len(newName) == 0 or newName == '-1' or newName == -1 or "communications error" in newName or 'malformed message packet' in newName :
|
||||
return nameNotFound
|
||||
|
||||
# all checks passed
|
||||
mylog('debug', [f'[resolve_device_name_dig] Found a new name: "{newName}"'])
|
||||
|
||||
return newName
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
# An error occured, handle it
|
||||
mylog('none', ['[resolve_device_name_dig] ⚠ ERROR: ', e.output])
|
||||
# newName = "Error - check logs"
|
||||
return nameNotFound
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# DNS record (Name resolution) cleanup methods
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
import dns.resolver
|
||||
|
||||
def cleanDeviceName(str, match_IP):
|
||||
|
||||
mylog('debug', ["[cleanDeviceName] input: " + str])
|
||||
|
||||
# add matching info
|
||||
if match_IP:
|
||||
str = str + " (IP match)"
|
||||
|
||||
# Applying cleanup REGEXEs
|
||||
mylog('debug', ["[Name cleanup] Using old cleanDeviceName(" + str + ")"])
|
||||
|
||||
regexes = get_setting_value('NEWDEV_NAME_CLEANUP_REGEX')
|
||||
|
||||
for rgx in regexes:
|
||||
mylog('trace', ["[cleanDeviceName] applying regex : " + rgx])
|
||||
mylog('trace', ["[cleanDeviceName] name before regex : " + str])
|
||||
str = re.sub(rgx, "", str)
|
||||
mylog('trace', ["[cleanDeviceName] name after regex : " + str])
|
||||
|
||||
# str = re.sub(r'\.\b', '', str) # trailing dot after words
|
||||
str = re.sub(r'\.$', '', str) # trailing dot at the end of the string
|
||||
str = str.replace(". (IP match)", " (IP match)") # Remove dot if (IP match) is added
|
||||
|
||||
mylog('debug', ["[cleanDeviceName] output: " + str])
|
||||
|
||||
return str
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# String manipulation methods
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@@ -168,6 +168,7 @@ def importConfigs (db, all_plugins):
|
||||
conf.HRS_TO_KEEP_NEWDEV = ccd('HRS_TO_KEEP_NEWDEV', 0 , c_d, 'Keep new devices for', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
|
||||
conf.HRS_TO_KEEP_OFFDEV = ccd('HRS_TO_KEEP_OFFDEV', 0 , c_d, 'Keep offline devices for', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
|
||||
conf.CLEAR_NEW_FLAG = ccd('CLEAR_NEW_FLAG', 0 , c_d, 'Clear new flag', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
|
||||
conf.REFRESH_FQDN = ccd('REFRESH_FQDN', False , c_d, 'Refresh FQDN', """{"dataType": "boolean","elements": [{"elementType": "input","elementOptions": [{ "type": "checkbox" }],"transformers": []}]}""", '[]', 'General')
|
||||
conf.API_CUSTOM_SQL = ccd('API_CUSTOM_SQL', 'SELECT * FROM Devices WHERE devPresentLastScan = 0' , c_d, 'Custom endpoint', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}', '[]', 'General')
|
||||
conf.VERSION = ccd('VERSION', '' , c_d, 'Version', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{ "readonly": "true" }] ,"transformers": []}]}', '', 'General')
|
||||
conf.NETWORK_DEVICE_TYPES = ccd('NETWORK_DEVICE_TYPES', ['AP', 'Gateway', 'Firewall', 'Hypervisor', 'Powerline', 'Switch', 'WLAN', 'PLC', 'Router','USB LAN Adapter', 'USB WIFI Adapter', 'Internet'] , c_d, 'Network device types', '{"dataType":"array","elements":[{"elementType":"input","elementOptions":[{"placeholder":"Enter value"},{"suffix":"_in"},{"cssClasses":"col-sm-10"},{"prefillValue":"null"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":["_in"]},{"separator":""},{"cssClasses":"col-xs-12"},{"onClick":"addList(this,false)"},{"getStringKey":"Gen_Add"}],"transformers":[]},{"elementType":"select", "elementHasInputValue":1,"elementOptions":[{"multiple":"true"},{"readonly":"true"},{"editable":"true"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":[]},{"separator":""},{"cssClasses":"col-xs-6"},{"onClick":"removeAllOptions(this)"},{"getStringKey":"Gen_Remove_All"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":[]},{"separator":""},{"cssClasses":"col-xs-6"},{"onClick":"removeFromList(this)"},{"getStringKey":"Gen_Remove_Last"}],"transformers":[]}]}', '[]', 'General')
|
||||
@@ -445,46 +446,6 @@ replacements = {
|
||||
r'\bREPORT_TO\b': 'SMTP_REPORT_TO',
|
||||
r'\bSYNC_api_token\b': 'API_TOKEN',
|
||||
r'\bAPI_TOKEN=\'\'': f'API_TOKEN=\'t_{generate_random_string(20)}\'',
|
||||
r'\bREPORT_FROM\b': 'SMTP_REPORT_FROM',
|
||||
r'\bPIALERT_WEB_PROTECTION\b': 'SETPWD_enable_password',
|
||||
r'\bPIALERT_WEB_PASSWORD\b': 'SETPWD_password',
|
||||
r'REPORT_MAIL=True': "SMTP_RUN='on_notification'",
|
||||
r'REPORT_APPRISE=True': "APPRISE_RUN='on_notification'",
|
||||
r'REPORT_NTFY=True': "NTFY_RUN='on_notification'",
|
||||
r'REPORT_WEBHOOK=True': "WEBHOOK_RUN='on_notification'",
|
||||
r'REPORT_PUSHSAFER=True': "PUSHSAFER_RUN='on_notification'",
|
||||
r'REPORT_MQTT=True': "MQTT_RUN='on_notification'",
|
||||
# r'PIHOLE_CMD=': 'PIHOLE_CMD_OLD=',
|
||||
r'\bINCLUDED_SECTIONS\b': 'NTFPRCS_INCLUDED_SECTIONS',
|
||||
r'\bDIG_GET_IP_ARG\b': 'INTRNT_DIG_GET_IP_ARG',
|
||||
r'dev_MAC': 'devMac',
|
||||
r'dev_Name': 'devName',
|
||||
r'dev_Favorite': 'devFavorite',
|
||||
r'dev_Group': 'devGroup',
|
||||
r'dev_Comments': 'devComments',
|
||||
r'dev_FirstConnection': 'devFirstConnection',
|
||||
r'dev_LastConnection': 'devLastConnection',
|
||||
r'dev_LastIP': 'devLastIP',
|
||||
r'dev_StaticIP': 'devStaticIP',
|
||||
r'dev_ScanCycle': 'devScan',
|
||||
r'dev_LogEvents': 'devLogEvents',
|
||||
r'dev_AlertEvents': 'devAlertEvents',
|
||||
r'dev_AlertDeviceDown': 'devAlertDown',
|
||||
r'dev_SkipRepeated': 'devSkipRepeated',
|
||||
r'dev_LastNotification': 'devLastNotification',
|
||||
r'dev_PresentLastScan': 'devPresentLastScan',
|
||||
r'dev_NewDevice': 'devIsNew',
|
||||
r'dev_Location': 'devLocation',
|
||||
r'dev_Archived': 'devIsArchived',
|
||||
r'dev_Network_Node_MAC_ADDR': 'devParentMAC',
|
||||
r'dev_Network_Node_port': 'devParentPort',
|
||||
r'dev_Icon': 'devIcon',
|
||||
r'dev_GUID': 'devGUID',
|
||||
r'dev_NetworkSite': 'devSite',
|
||||
r'dev_SSID': 'devSSID',
|
||||
r'dev_SyncHubNodeName': 'devSyncHubNode',
|
||||
r'dev_SourcePlugin': 'devSourcePlugin',
|
||||
r'/home/pi/pialert\b': '/app'
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,10 +8,11 @@ import subprocess
|
||||
import conf
|
||||
import os
|
||||
import re
|
||||
from helper import timeNowTZ, get_setting, get_setting_value, list_to_where, resolve_device_name_dig, get_device_name_nbtlookup, get_device_name_nslookup, get_device_name_mdns, check_IP_format, sanitize_SQL_input
|
||||
from helper import timeNowTZ, get_setting, get_setting_value, list_to_where, check_IP_format, sanitize_SQL_input
|
||||
from logger import mylog
|
||||
from const import vendorsPath, vendorsPathNewest, sql_generateGuid
|
||||
from models.device_instance import DeviceInstance
|
||||
from scan.name_resolution import NameResolver
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Removing devices from the CurrentScan DB table which the user chose to ignore by MAC or IP
|
||||
@@ -481,88 +482,109 @@ def update_devices_data_from_scan (db):
|
||||
mylog('debug','[Update Devices] Update devices end')
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def update_devices_names (db):
|
||||
sql = db.sql #TO-DO
|
||||
# Initialize variables
|
||||
recordsToUpdate = []
|
||||
recordsNotFound = []
|
||||
def update_devices_names(db):
|
||||
sql = db.sql
|
||||
resolver = NameResolver(db)
|
||||
device_handler = DeviceInstance(db)
|
||||
|
||||
nameNotFound = "(name not found)"
|
||||
|
||||
ignored = 0
|
||||
notFound = 0
|
||||
# Define resolution strategies in priority order
|
||||
strategies = [
|
||||
(resolver.resolve_dig, 'dig'),
|
||||
(resolver.resolve_mdns, 'mdns'),
|
||||
(resolver.resolve_nslookup, 'nslookup'),
|
||||
(resolver.resolve_nbtlookup, 'nbtlookup')
|
||||
]
|
||||
|
||||
foundDig = 0
|
||||
foundmDNSLookup = 0
|
||||
foundNsLookup = 0
|
||||
foundNbtLookup = 0
|
||||
def resolve_devices(devices, resolve_both_name_and_fqdn=True):
|
||||
"""
|
||||
Attempts to resolve device names and/or FQDNs using available strategies.
|
||||
|
||||
Parameters:
|
||||
devices (list): List of devices to resolve.
|
||||
resolve_both_name_and_fqdn (bool): If True, resolves both name and FQDN.
|
||||
If False, resolves only FQDN.
|
||||
|
||||
Returns:
|
||||
recordsToUpdate (list): List of [newName, newFQDN, devMac] or [newFQDN, devMac] for DB update.
|
||||
recordsNotFound (list): List of [nameNotFound, devMac] for DB update.
|
||||
foundStats (dict): Number of successes per strategy.
|
||||
notFound (int): Number of devices not resolved.
|
||||
"""
|
||||
recordsToUpdate = []
|
||||
recordsNotFound = []
|
||||
foundStats = {label: 0 for _, label in strategies}
|
||||
notFound = 0
|
||||
|
||||
# Gen unknown devices
|
||||
device_handler = DeviceInstance(db)
|
||||
# Retrieve devices
|
||||
for device in devices:
|
||||
newName = nameNotFound
|
||||
newFQDN = ''
|
||||
|
||||
# Attempt each resolution strategy in order
|
||||
for resolve_fn, label in strategies:
|
||||
resolved = resolve_fn(device['devMac'], device['devLastIP'])
|
||||
|
||||
# Only use name if resolving both name and FQDN
|
||||
newName = resolved.cleaned if resolve_both_name_and_fqdn else None
|
||||
newFQDN = resolved.raw
|
||||
|
||||
# If a valid result is found, record it and stop further attempts
|
||||
if newFQDN not in [nameNotFound, '', 'localhost.'] and ' communications error to ' not in newFQDN:
|
||||
foundStats[label] += 1
|
||||
|
||||
if resolve_both_name_and_fqdn:
|
||||
recordsToUpdate.append([newName, newFQDN, device['devMac']])
|
||||
else:
|
||||
recordsToUpdate.append([newFQDN, device['devMac']])
|
||||
break
|
||||
|
||||
# If no name was resolved, queue device for "(name not found)" update
|
||||
if resolve_both_name_and_fqdn and newName == nameNotFound:
|
||||
notFound += 1
|
||||
if device['devName'] != nameNotFound:
|
||||
recordsNotFound.append([nameNotFound, device['devMac']])
|
||||
|
||||
return recordsToUpdate, recordsNotFound, foundStats, notFound
|
||||
|
||||
# --- Step 1: Update device names for unknown devices ---
|
||||
unknownDevices = device_handler.getUnknown()
|
||||
if unknownDevices:
|
||||
mylog('verbose', f'[Update Device Name] Trying to resolve devices without name. Unknown devices count: {len(unknownDevices)}')
|
||||
|
||||
# skip checks if no unknown devices
|
||||
if len(unknownDevices) == 0:
|
||||
return
|
||||
# Try resolving both name and FQDN
|
||||
recordsToUpdate, recordsNotFound, foundStats, notFound = resolve_devices(unknownDevices)
|
||||
|
||||
# Devices without name
|
||||
mylog('verbose', f'[Update Device Name] Trying to resolve devices without name. Unknown devices count: {len(unknownDevices)}')
|
||||
# Log summary
|
||||
mylog('verbose', f"[Update Device Name] Names Found (DiG/mDNS/NSLOOKUP/NBTSCAN): {len(recordsToUpdate)} ({foundStats['dig']}/{foundStats['mdns']}/{foundStats['nslookup']}/{foundStats['nbtlookup']})")
|
||||
mylog('verbose', f'[Update Device Name] Names Not Found : {notFound}')
|
||||
|
||||
for device in unknownDevices:
|
||||
newName = nameNotFound
|
||||
|
||||
# Resolve device name with DiG
|
||||
newName = resolve_device_name_dig (device['devMac'], device['devLastIP'])
|
||||
|
||||
# count
|
||||
if newName != nameNotFound:
|
||||
foundDig += 1
|
||||
|
||||
# Resolve device name with AVAHISCAN plugin data
|
||||
if newName == nameNotFound:
|
||||
newName = get_device_name_mdns(db, device['devMac'], device['devLastIP'])
|
||||
# Apply updates to database
|
||||
sql.executemany("UPDATE Devices SET devName = ? WHERE devMac = ?", recordsNotFound)
|
||||
sql.executemany("UPDATE Devices SET devName = ?, devFQDN = ? WHERE devMac = ?", recordsToUpdate)
|
||||
|
||||
if newName != nameNotFound:
|
||||
foundmDNSLookup += 1
|
||||
# --- Step 2: Optionally refresh FQDN for all devices ---
|
||||
if get_setting_value("REFRESH_FQDN"):
|
||||
allDevices = device_handler.getAll()
|
||||
if allDevices:
|
||||
mylog('verbose', f'[Update FQDN] Trying to resolve FQDN. Devices count: {len(allDevices)}')
|
||||
|
||||
# Resolve device name with NSLOOKUP plugin data
|
||||
if newName == nameNotFound:
|
||||
newName = get_device_name_nslookup(db, device['devMac'], device['devLastIP'])
|
||||
# Try resolving only FQDN
|
||||
recordsToUpdate, _, foundStats, notFound = resolve_devices(allDevices, resolve_both_name_and_fqdn=False)
|
||||
|
||||
if newName != nameNotFound:
|
||||
foundNsLookup += 1
|
||||
|
||||
# Resolve device name with NBTLOOKUP plugin data
|
||||
if newName == nameNotFound:
|
||||
newName = get_device_name_nbtlookup(db, device['devMac'], device['devLastIP'])
|
||||
# Log summary
|
||||
mylog('verbose', f"[Update FQDN] Names Found (DiG/mDNS/NSLOOKUP/NBTSCAN): {len(recordsToUpdate)} ({foundStats['dig']}/{foundStats['mdns']}/{foundStats['nslookup']}/{foundStats['nbtlookup']})")
|
||||
mylog('verbose', f'[Update FQDN] Names Not Found : {notFound}')
|
||||
|
||||
if newName != nameNotFound:
|
||||
foundNbtLookup += 1
|
||||
|
||||
# if still not found update name so we can distinguish the devices where we tried already
|
||||
if newName == nameNotFound :
|
||||
# Apply FQDN-only updates
|
||||
sql.executemany("UPDATE Devices SET devFQDN = ? WHERE devMac = ?", recordsToUpdate)
|
||||
|
||||
notFound += 1
|
||||
|
||||
# if devName is the same as what we will change it to, take no action
|
||||
# this mitigates a race condition which would overwrite a users edits that occured since the select earlier
|
||||
if device['devName'] != nameNotFound:
|
||||
recordsNotFound.append (["(name not found)", device['devMac']])
|
||||
else:
|
||||
# name was found
|
||||
recordsToUpdate.append ([newName, device['devMac']])
|
||||
|
||||
# Print log
|
||||
mylog('verbose', [f'[Update Device Name] Names Found (DiG/mDNS/NSLOOKUP/NBTSCAN): {len(recordsToUpdate)} ({foundDig}/{foundmDNSLookup}/{foundNsLookup}/{foundNbtLookup})'] )
|
||||
mylog('verbose', [f'[Update Device Name] Names Not Found : {notFound}'] )
|
||||
|
||||
# update not found devices with (name not found)
|
||||
sql.executemany ("UPDATE Devices SET devName = ? WHERE devMac = ? ", recordsNotFound )
|
||||
# update names of devices which we were bale to resolve
|
||||
sql.executemany ("UPDATE Devices SET devName = ? WHERE devMac = ? ", recordsToUpdate )
|
||||
# Commit all database changes
|
||||
db.commitDB()
|
||||
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Check if the variable contains a valid MAC address or "Internet"
|
||||
def check_mac_or_internet(input_str):
|
||||
|
||||
83
server/scan/name_resolution.py
Executable file
83
server/scan/name_resolution.py
Executable file
@@ -0,0 +1,83 @@
|
||||
import sys
|
||||
import re
|
||||
import subprocess
|
||||
import socket
|
||||
import dns.resolver
|
||||
|
||||
# Register NetAlertX directories
|
||||
INSTALL_PATH = "/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/server"])
|
||||
|
||||
import conf
|
||||
from const import *
|
||||
from logger import mylog
|
||||
from helper import get_setting_value
|
||||
|
||||
class ResolvedName:
|
||||
def __init__(self, raw: str = "(name not found)", cleaned: str = "(name not found)"):
|
||||
self.raw = raw
|
||||
self.cleaned = cleaned
|
||||
|
||||
def __str__(self):
|
||||
return self.cleaned
|
||||
|
||||
class NameResolver:
|
||||
def __init__(self, db):
|
||||
self.db = db
|
||||
|
||||
def resolve_from_plugin(self, plugin: str, pMAC: str, pIP: str) -> ResolvedName:
|
||||
sql = self.db.sql
|
||||
nameNotFound = ResolvedName()
|
||||
|
||||
# Check by MAC
|
||||
sql.execute(f"""
|
||||
SELECT Watched_Value2 FROM Plugins_Objects
|
||||
WHERE Plugin = '{plugin}' AND Object_PrimaryID = '{pMAC}'
|
||||
""")
|
||||
result = sql.fetchall()
|
||||
self.db.commitDB()
|
||||
if result:
|
||||
raw = result[0][0]
|
||||
return ResolvedName(raw, self.clean_device_name(raw, False))
|
||||
|
||||
# Check by IP
|
||||
sql.execute(f"""
|
||||
SELECT Watched_Value2 FROM Plugins_Objects
|
||||
WHERE Plugin = '{plugin}' AND Object_SecondaryID = '{pIP}'
|
||||
""")
|
||||
result = sql.fetchall()
|
||||
self.db.commitDB()
|
||||
if result:
|
||||
raw = result[0][0]
|
||||
return ResolvedName(raw, self.clean_device_name(raw, True))
|
||||
|
||||
return nameNotFound
|
||||
|
||||
def resolve_mdns(self, pMAC, pIP) -> ResolvedName:
|
||||
return self.resolve_from_plugin("AVAHISCAN", pMAC, pIP)
|
||||
|
||||
def resolve_nslookup(self, pMAC, pIP) -> ResolvedName:
|
||||
return self.resolve_from_plugin("NSLOOKUP", pMAC, pIP)
|
||||
|
||||
def resolve_nbtlookup(self, pMAC, pIP) -> ResolvedName:
|
||||
return self.resolve_from_plugin("NBTSCAN", pMAC, pIP)
|
||||
|
||||
def resolve_dig(self, pMAC, pIP) -> ResolvedName:
|
||||
return self.resolve_from_plugin("DIGSCAN", pMAC, pIP)
|
||||
|
||||
def clean_device_name(self, name: str, match_ip: bool) -> str:
|
||||
mylog('debug', [f"[cleanDeviceName] input: {name}"])
|
||||
|
||||
if match_ip:
|
||||
name += " (IP match)"
|
||||
|
||||
regexes = get_setting_value('NEWDEV_NAME_CLEANUP_REGEX') or []
|
||||
for rgx in regexes:
|
||||
mylog('trace', [f"[cleanDeviceName] applying regex: {rgx}"])
|
||||
name = re.sub(rgx, "", name)
|
||||
|
||||
name = re.sub(r'\.$', '', name)
|
||||
name = name.replace(". (IP match)", " (IP match)")
|
||||
|
||||
mylog('debug', [f"[cleanDeviceName] output: {name}"])
|
||||
return name
|
||||
@@ -170,7 +170,7 @@ class AppEvent_obj:
|
||||
END;
|
||||
"""
|
||||
|
||||
mylog("verbose", [query])
|
||||
# mylog("verbose", [query])
|
||||
|
||||
self.db.sql.execute(query)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user