mirror of
https://github.com/ntop/ntopng.git
synced 2026-05-10 17:58:09 +00:00
277 lines
8.8 KiB
Lua
277 lines
8.8 KiB
Lua
--
|
|
-- (C) 2013-26 - ntop.org
|
|
--
|
|
local dirs = ntop.getDirs()
|
|
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
|
|
|
-- ####################################
|
|
|
|
require "check_redis_prefs"
|
|
require "ntop_utils"
|
|
local format_utils = require "format_utils"
|
|
local am_utils = require "am_utils"
|
|
local auth = require "auth"
|
|
|
|
local am = {}
|
|
|
|
local function isValidHostMeasurementCombination(host, measurement)
|
|
-- Strips the prefix (either http:// or https://) and a possible port
|
|
|
|
-- Extract the domain, e.g.,
|
|
-- http://user:password@www.example.com/p1/p2 becomes www.example.com
|
|
-- http://www.example.com:3000/p1/p2 becomes www.example.com
|
|
|
|
-- See if domain has user and password encoded, i.e.,
|
|
-- http://user:password@www.example.com becomes www.example.com
|
|
local domain = host:match('^%w+://[^:]+:[^@]+@([^/:]+)')
|
|
|
|
if not domain then
|
|
-- Domain has no user and password encoded, i.e.,
|
|
-- http://www.example.com:3000/p1/p2
|
|
domain = host:match('^%w+://([^/:]+)')
|
|
end
|
|
|
|
-- Take the domain (if found) or the host as-is
|
|
host = domain or host
|
|
|
|
local host_v4 = isIPv4(host)
|
|
local host_v6 = isIPv6(host)
|
|
|
|
if not host_v4 and not host_v6 then
|
|
-- Host is a domain, try to resolve it as ipv4, then ipv6
|
|
if ntop.resolveHost(host, true) then
|
|
-- Valid Host
|
|
return (true)
|
|
elseif ntop.resolveHost(host, false) then
|
|
-- Valid Host
|
|
return (true)
|
|
else
|
|
return (false)
|
|
end
|
|
end
|
|
|
|
return (true)
|
|
end
|
|
|
|
-- ################################################
|
|
|
|
-- lists active monitoring scripts definitions
|
|
function am.get_am_defs()
|
|
local rsp = {}
|
|
local measurements_info = {}
|
|
|
|
for key, info in pairs(am_utils.getMeasurementsInfo()) do
|
|
if key == "vulnerability_scan" or key == "cve_changes_detected" or key == "ports_changes_detected" then
|
|
goto continue
|
|
end
|
|
local label = i18n(info.i18n_label) or info.i18n_label
|
|
local unit = i18n(info.i18n_unit) or info.i18n_unit
|
|
|
|
measurements_info[key] = {
|
|
label = label,
|
|
granularities = am_utils.getAvailableGranularities(key),
|
|
key = key,
|
|
operator = info.operator,
|
|
unit = unit,
|
|
force_host = info.force_host,
|
|
max_threshold = info.max_threshold,
|
|
default_threshold = info.default_threshold
|
|
}
|
|
|
|
::continue::
|
|
end
|
|
|
|
for _, info in pairsByKeys(measurements_info, asc) do
|
|
rsp[#rsp + 1] = info
|
|
end
|
|
return rsp
|
|
end
|
|
|
|
-- lists am activated scripts
|
|
function am.list_am_scripts(ifid, measurement, alerted)
|
|
|
|
local res = {}
|
|
|
|
if not isEmptyString(alerted) then
|
|
alerted = alerted == '1'
|
|
end
|
|
|
|
local active_monitoring_hosts = am_utils.getHosts() or {}
|
|
|
|
for key, info in pairs(active_monitoring_hosts) do
|
|
local last_measurement = am_utils.getMeasurementInfo(info.measurement)
|
|
local is_alerted = am_utils.hasAlerts(info)
|
|
|
|
if not last_measurement then
|
|
goto continue
|
|
end
|
|
|
|
-- Filters applied
|
|
if not isEmptyString(measurement) and measurement ~= info.measurement then
|
|
goto continue
|
|
end
|
|
|
|
if not isEmptyString(alerted) and alerted ~= is_alerted then
|
|
goto continue
|
|
end
|
|
|
|
-- Format the data
|
|
local ip_address = ''
|
|
local last_measurement_time = 0
|
|
local measurement_value = ''
|
|
local last_mean = ''
|
|
local last_jitter = ''
|
|
local hourly_stats, availability = am_utils.getAvailability(info.host, info.measurement)
|
|
local last_update = am_utils.getLastAmUpdate(info.host, info.measurement)
|
|
|
|
if last_update then
|
|
ip_address = last_update.ip
|
|
measurement_value = last_update.value
|
|
last_measurement_time = last_update.when
|
|
last_mean = last_update.mean
|
|
last_jitter = last_update.jitter
|
|
|
|
if info.measurement == "speedtest" then
|
|
measurement_value = format_utils.bytesToBPS(measurement_value)
|
|
end
|
|
end
|
|
|
|
-- Clean the IP Address in case of http
|
|
if not isEmptyString(ip_address) and string.find(ip_address, '//') then
|
|
ip_address = split(ip_address, '//')[2]
|
|
if string.find(ip_address, '/') then
|
|
ip_address = split(ip_address, '/')[1]
|
|
end
|
|
end
|
|
|
|
if ip_address == info.label then
|
|
info.label = ip2label(ip_address)
|
|
end
|
|
|
|
local custom_name = getHumanReadableInterfaceName(info.ifname)
|
|
if isEmptyString(custom_name) then custom_name = nil end
|
|
|
|
res[#res + 1] = {
|
|
key = key,
|
|
ip_address = ip_address,
|
|
threshold = info.threshold,
|
|
hourly_stats = hourly_stats or {},
|
|
am_host = info.host, -- This is used by http_src/constants/metrics-consts.js
|
|
target = {
|
|
name = info.label,
|
|
host = info.host
|
|
},
|
|
last_measurement = {
|
|
measurement_type = info.measurement,
|
|
measurement_value = measurement_value,
|
|
last_measurement_time = last_measurement_time,
|
|
},
|
|
metadata = {
|
|
is_infrastructure_instance = info.is_infrastructure,
|
|
is_alerted = is_alerted,
|
|
interface_name = custom_name or info.ifname,
|
|
interface_id = getInterfaceId(info.ifname),
|
|
granularity = info.granularity,
|
|
availability = availability or "",
|
|
unit = last_measurement.i18n_unit,
|
|
timeseries = (areSystemTimeseriesEnabled() and not isEmptyString(measurement_value))
|
|
},
|
|
extra_measurements = {
|
|
mean = last_mean,
|
|
jitter = last_jitter
|
|
}
|
|
}
|
|
::continue::
|
|
end
|
|
return res
|
|
end
|
|
|
|
-- ################################################
|
|
|
|
-- Adds a new AM host if it does not already exist.
|
|
-- Returns true on success, false + error string on failure.
|
|
function am.add_am_script(host, measurement, ifname, threshold, granularity)
|
|
if isEmptyString(host) then
|
|
return false, i18n("missing_x_parameter", { param = "Host" })
|
|
end
|
|
|
|
if isEmptyString(measurement) then
|
|
return false, i18n("missing_x_parameter", { param = "Measurement" })
|
|
end
|
|
|
|
-- invalid active monitoring combination
|
|
if not isValidHostMeasurementCombination(host, measurement) then
|
|
return false, i18n('active_monitoring_stats.invalid_host')
|
|
end
|
|
|
|
if not am_utils.hasHost(host, measurement) then
|
|
am_utils.addHost(host, ifname, measurement, threshold, granularity)
|
|
end
|
|
|
|
return true, nil
|
|
end
|
|
|
|
-- ################################################
|
|
|
|
-- Edits an existing AM host entry.
|
|
-- If the key (host + measurement) has changed, deletes the old entry and creates a new one.
|
|
-- If only the settings changed, updates them in place.
|
|
-- Returns true on success, false + error string on failure.
|
|
function am.edit_am_script(host, measurement, ifname, threshold, granularity,
|
|
old_am_host, old_measurement)
|
|
if isEmptyString(host) then
|
|
return false, i18n("missing_x_parameter", { param = "Host" })
|
|
end
|
|
|
|
if isEmptyString(measurement) then
|
|
return false, i18n("missing_x_parameter", { param = "Measurement" })
|
|
end
|
|
|
|
-- invalid active monitoring combination
|
|
if not isValidHostMeasurementCombination(host, measurement) then
|
|
return false, i18n('active_monitoring_stats.invalid_host')
|
|
end
|
|
|
|
if not am_utils.getHost(old_am_host, old_measurement) then
|
|
return false, i18n("active_monitoring_stats.invalid_host")
|
|
end
|
|
|
|
if (old_am_host ~= host) or (old_measurement ~= measurement) then
|
|
-- Key has changed: replace old entry with a new one
|
|
am_utils.deleteHost(old_am_host, old_measurement)
|
|
am_utils.addHost(host, ifname, measurement, threshold, granularity)
|
|
else
|
|
-- Key unchanged: update settings in place
|
|
am_utils.editHost(host, ifname, measurement, threshold, granularity)
|
|
end
|
|
|
|
return true, nil
|
|
end
|
|
|
|
-- ################################################
|
|
function am.delete_am_script(host, measurement)
|
|
|
|
if isEmptyString(host) then
|
|
return false, i18n("missing_x_parameter", { param = 'Host' })
|
|
end
|
|
|
|
if isEmptyString(measurement) then
|
|
return false, i18n("missing_x_parameter", { param = 'Measurement' })
|
|
end
|
|
|
|
if not auth.has_capability(auth.capabilities.active_monitoring) then
|
|
return false, i18n("not_admin")
|
|
end
|
|
|
|
local existing = am_utils.hasHost(host, measurement)
|
|
|
|
if existing then
|
|
am_utils.deleteHost(host, measurement)
|
|
end
|
|
|
|
return true, nil
|
|
end
|
|
|
|
-- ################################################
|
|
|
|
return am
|