ntopng/scripts/lua/modules/asset_management_utils.lua
2024-11-09 12:45:15 +01:00

253 lines
8.7 KiB
Lua

--
-- (C) 2024 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "ntop_utils"
require "check_redis_prefs"
local os_utils = require "os_utils"
-- ##############################################
local asset_management_utils = {}
local table_name = "asset_management"
-- ##############################################
-- @brief insert assetkey
function asset_management_utils.insert_host(entry)
local insert_host = ""
if hasClickHouseSupport() then
insert_host = string.format(
"INSERT INTO %s " ..
"(type, key, ip, mac, vlan, network, name, device_type, manufacturer, first_seen, last_seen) " ..
"SELECT '%s','%s','%s','%s', %u, %u, %s, %u, %s, %u, %u "..
"WHERE NOT EXISTS ( SELECT 1 FROM %s WHERE key = '%s' )",
table_name,
entry["type"],
entry["key"],
entry["ip"] or "",
entry["mac"] or "",
entry["vlan"] or 0,
entry["network"] or 0,
ternary(not isEmptyString(entry["name"]),string.format("'%s'",entry["name"]),"NULL"),
entry["device_type"],
ternary(not isEmptyString(entry["manufacturer"]),string.format("'%s'",entry["manufacturer"]), "NULL"),
entry["first_seen"],
entry["last_seen"],
table_name,
entry["key"]
)
local update_host = string.format("ALTER TABLE `%s` UPDATE `last_seen` = %u WHERE `key`='%s'",
table_name,
entry["last_seen"],
entry["key"]
)
interface.alert_store_query(insert_host)
return interface.alert_store_query(update_host)
else
insert_host = string.format(
"INSERT INTO %s " ..
"(type, key, ip, mac, vlan, network, name, device_type, manufacturer, first_seen, last_seen) " ..
"VALUES ('%s','%s','%s','%s', %u, %u, %s, %u, %s, %u, %u) "..
"ON CONFLICT(key) DO UPDATE SET last_seen = %u;",
table_name,
entry["type"],
entry["key"],
entry["ip"],
entry["mac"] or "",
entry["vlan"] or 0,
entry["network"] or 0,
ternary(not isEmptyString(entry["name"]),string.format("'%s'",entry["name"]),"NULL"),
entry["device_type"],
ternary(not isEmptyString(entry["manufacturer"]),string.format("'%s'",entry["manufacturer"]), "NULL"),
entry["first_seen"],
entry["last_seen"],
entry["last_seen"]
)
-- traceError(TRACE_NORMAL, TRACE_CONSOLE, insert_host)
return interface.alert_store_query(insert_host)
end
end
function asset_management_utils.insert_mac(entry)
if hasClickHouseSupport() then
local insert_mac = string.format(
"INSERT INTO %s " ..
"(type, key, mac, manufacturer, vlan, device_type, first_seen, last_seen) " ..
"SELECT '%s','%s','%s','%s','%d', %u, %u, %u "..
"WHERE NOT EXISTS ( SELECT 1 FROM %s WHERE key = '%s' )",
table_name,
entry["type"],
entry["key"],
entry["mac"],
entry["manufacturer"],
0, -- VLAN
entry["device_type"],
entry["first_seen"],
entry["last_seen"],
table_name,
entry["mac"]
)
local update_mac = string.format("ALTER TABLE `%s` UPDATE `last_seen` = %u WHERE `key`='%s'",
table_name,
entry["last_seen"],
entry["key"]
)
--tprint(insert_mac)
interface.alert_store_query(insert_mac)
return interface.alert_store_query(update_mac)
else
local insert_mac = string.format(
"INSERT INTO %s " ..
"(type, key, mac, manufacturer, vlan, device_type, first_seen, last_seen) " ..
"VALUES ('%s','%s','%s','%s', %u, %u, %u, %u) "..
"ON CONFLICT(key) DO UPDATE SET last_seen = %u ;",
table_name,
entry["type"],
entry["key"],
entry["mac"],
entry["manufacturer"],
0,
entry["device_type"],
entry["first_seen"],
entry["last_seen"],
entry["last_seen"]
)
return interface.alert_store_query(insert_mac)
end
-- traceError(TRACE_NORMAL, TRACE_CONSOLE, insert_mac)
end
-- ##############################################
-- Return the lists of inactive hosts from the DB
function asset_management_utils.get_inactive_hosts(ifid, order, sort, start, length, filters)
if not ifid then
ifid = interface.getId()
end
if sort == "ip" and hasClickHouseSupport() then
sort = "IPv4StringToNum(ip)"
end
local where = ""
for key, value in pairs(filters or {}) do
where = where .. "AND"
if tonumber(value) then
value = tonumber(value)
else
value = string.format("'%s'", value)
end
where = string.format("%s %s=%s ", where, key, value)
end
if sort and order then
where = string.format("%s ORDER BY %s %s", where, sort, order)
end
if start and length then
where = string.format("%s LIMIT %s, %s", where, start, length)
end
local query = string.format("SELECT key, ip, mac, vlan, network, name, device_type, manufacturer, %s, %s " ..
"FROM %s WHERE type='%s' AND last_seen!=%d %s",
ternary(hasClickHouseSupport(), "toUnixTimestamp(last_seen) as last_seen", "last_seen"),
ternary(hasClickHouseSupport(), "toUnixTimestamp(first_seen) as first_seen", "first_seen"),
table_name,
"host", -- Only hosts here
0, -- 0 Because by default an host that is still in memory has a last_seen 0
where
)
local res = interface.alert_store_query(query)
return res
end
-- ##############################################
-- Return the lists of inactive hosts from the DB
function asset_management_utils.get_total_inactive_hosts(ifid, filters)
if not ifid then
ifid = interface.getId()
end
local where = ""
for key, value in pairs(filters) do
where = where .. "AND"
if tonumber(value) then
value = tonumber(value)
else
value = string.format("'%s'", value)
end
where = string.format("%s %s=%s ", where, key, value)
end
local query = string.format("SELECT COUNT(*) as count " ..
"FROM %s WHERE type='%s' %s AND last_seen!=%d",
table_name,
"host", -- Only hosts here,
where,
0 -- 0 Because by default an host that is still in memory has a last_seen 0
)
local res = interface.alert_store_query(query)
return res
end
-- ##############################################
-- Return the lists of inactive hosts from the DB
function asset_management_utils.get_filters(ifid)
if not ifid then
ifid = interface.getId()
end
local query = string.format("SELECT 'manufacturer' AS filter, manufacturer AS value, COUNT(*) AS count " ..
"FROM %s where type='host' GROUP BY manufacturer UNION ALL " ..
"SELECT 'device_type' AS filter, %s AS value, COUNT(*) AS count " ..
"FROM %s where type='host' GROUP BY device_type UNION ALL " ..
"SELECT 'vlan' AS filter, %s AS value, COUNT(*) AS count " ..
"FROM %s where type='host' GROUP BY vlan UNION ALL " ..
"SELECT 'network' AS filter, %s AS value, COUNT(*) AS count " ..
"FROM %s where type='host' GROUP BY network",
table_name,
ternary(hasClickHouseSupport(), "CAST(device_type, 'String')", "CAST(device_type AS CHAR)"),
table_name,
ternary(hasClickHouseSupport(), "CAST(vlan, 'String')", "CAST(vlan AS CHAR)"),
table_name,
ternary(hasClickHouseSupport(), "CAST(network, 'String')", "CAST(network AS CHAR)"),
table_name
)
local res = interface.alert_store_query(query)
return res
end
-- ##############################################
-- Return the lists of inactive hosts from the DB
function asset_management_utils.get_inactive_host_info(ifid, key)
if isEmptyString(key) then
return nil
end
local query = string.format("SELECT key, ip, mac, vlan, network, name, device_type, manufacturer, %s , %s FROM %s WHERE key='%s'",
ternary(hasClickHouseSupport(), "toUnixTimestamp(last_seen) as last_seen", "last_seen"),
ternary(hasClickHouseSupport(), "toUnixTimestamp(first_seen) as first_seen", "first_seen"),
table_name,
key
)
local res = interface.alert_store_query(query)
return res
end
-- ##############################################
return asset_management_utils