mirror of
https://github.com/ntop/ntopng.git
synced 2026-04-29 15:39:33 +00:00
351 lines
11 KiB
Lua
351 lines
11 KiB
Lua
--
|
|
-- (C) 2017-21 - ntop.org
|
|
--
|
|
-- Module to keep things in common across alert_exclusions of various type
|
|
|
|
local dirs = ntop.getDirs()
|
|
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
|
|
|
require "lua_utils"
|
|
local alert_consts = require "alert_consts"
|
|
local alert_entities = require "alert_entities"
|
|
local json = require "dkjson"
|
|
|
|
-- ##############################################
|
|
|
|
local alert_exclusions = {}
|
|
|
|
-- ##############################################
|
|
|
|
local function _get_alert_exclusions_prefix_key()
|
|
local key = string.format("ntopng.prefs.alert_exclusions")
|
|
|
|
return key
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
local function _get_alert_exclusions_lock_key()
|
|
local key = string.format("ntopng.cache.alert_exclusions.alert_exclusions_lock")
|
|
|
|
return key
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
local function _lock()
|
|
local max_lock_duration = 5 -- seconds
|
|
local max_lock_attempts = 5 -- give up after at most this number of attempts
|
|
local lock_key = _get_alert_exclusions_lock_key()
|
|
|
|
for i = 1, max_lock_attempts do
|
|
local value_set = ntop.setnxCache(lock_key, "1", max_lock_duration)
|
|
|
|
if value_set then
|
|
return true -- lock acquired
|
|
end
|
|
|
|
ntop.msleep(1000)
|
|
end
|
|
|
|
return false -- lock not acquired
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
local function _unlock()
|
|
ntop.delCache(_get_alert_exclusions_lock_key())
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
local function _check_host_ip_alert_key(host_ip, alert_key)
|
|
if not isIPv4(host_ip) and not isIPv6(host_ip) then
|
|
-- Invalid host submitted
|
|
return false
|
|
end
|
|
|
|
if not alert_consts.getAlertType(tonumber(alert_key)) then
|
|
-- Invalid alert key submitted
|
|
return false
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
local function _get_configured_alert_exclusions()
|
|
local excl_key = _get_alert_exclusions_prefix_key()
|
|
local configured_excl_str = ntop.getPref(excl_key)
|
|
local configured_excl = json.decode(configured_excl_str) or {}
|
|
|
|
return configured_excl
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
local function _set_configured_alert_exclusions(exclusions)
|
|
local excl_key = _get_alert_exclusions_prefix_key()
|
|
|
|
ntop.setPref(excl_key, json.encode(exclusions)) -- Add the preference
|
|
ntop.reloadAlertExclusions() -- Tell ntopng to reload
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
--@brief Enables or disables an alert for an `host_ip`
|
|
local function _toggle_alert(alert_entity, host_ip, alert_key, disable)
|
|
local ret = false
|
|
|
|
if not _check_host_ip_alert_key(host_ip, alert_key) then
|
|
-- Invalid params submitted
|
|
return false
|
|
end
|
|
|
|
local locked = _lock()
|
|
|
|
if locked then
|
|
-- In JSON, keys are always strings
|
|
alert_key = tostring(alert_key) -- The key of the alert
|
|
local entity_id = tostring(alert_entity.entity_id) -- The entity of the alert that is being disabled, e.g., "host", or "flow"
|
|
|
|
local do_persist = false
|
|
local exclusions = _get_configured_alert_exclusions()
|
|
|
|
-- Add an entry for the current alert entity, if currently exising exclusions don't already have it
|
|
if not exclusions[entity_id] then
|
|
exclusions[entity_id] = {}
|
|
end
|
|
|
|
-- Add an entry for the current alert key, if currently existing exclusions don't already have it
|
|
if not exclusions[entity_id][alert_key] then
|
|
exclusions[entity_id][alert_key] = {excluded_hosts = {}}
|
|
end
|
|
|
|
-- Add an entry for excluded_hosts, if the currently existing exclusions don't already have it
|
|
if not exclusions[entity_id][alert_key]["excluded_hosts"] then
|
|
exclusions[entity_id][alert_key]["excluded_hosts"] = {}
|
|
end
|
|
|
|
-- Now check if there is actually some work to do
|
|
if not disable and exclusions[entity_id][alert_key]["excluded_hosts"][host_ip] then
|
|
-- Enable an host_ip that was disabled
|
|
exclusions[entity_id][alert_key]["excluded_hosts"][host_ip] = nil
|
|
do_persist = true
|
|
elseif disable and not exclusions[entity_id][alert_key]["excluded_hosts"][host_ip] then
|
|
-- Disable an host_ip that was not already disabled
|
|
exclusions[entity_id][alert_key]["excluded_hosts"][host_ip] = { --[[ Currently empty, will possibly contain values in the future, e.g., as_cli, as_srv--]]}
|
|
do_persist = true
|
|
end
|
|
|
|
if do_persist then
|
|
_set_configured_alert_exclusions(exclusions)
|
|
end
|
|
|
|
ret = true
|
|
_unlock()
|
|
end
|
|
|
|
return ret
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
--@brief Removes all exclusions for a given entity
|
|
local function _enable_all_alerts(alert_entity, host)
|
|
local ret = false
|
|
|
|
local locked = _lock()
|
|
|
|
if locked then
|
|
-- In JSON, keys are always strings
|
|
local entity_id = tostring(alert_entity.entity_id) -- The entity of the alert that is being disabled, e.g., "host", or "flow"
|
|
|
|
local do_persist = false
|
|
local exclusions = _get_configured_alert_exclusions()
|
|
|
|
-- Add an entry for the current alert entity, if currently exising exclusions don't already have it
|
|
if isEmptyString(host) then
|
|
if exclusions[entity_id] then
|
|
exclusions[entity_id] = nil
|
|
do_persist = true
|
|
end
|
|
else
|
|
for alert_key, cur_exclusions in pairs(exclusions[entity_id] or {}) do
|
|
if cur_exclusions["excluded_hosts"] and cur_exclusions["excluded_hosts"][host] then
|
|
-- Remove the entry
|
|
cur_exclusions["excluded_hosts"][host] = nil
|
|
do_persist = true
|
|
end
|
|
end
|
|
end
|
|
|
|
if do_persist then
|
|
_set_configured_alert_exclusions(exclusions)
|
|
end
|
|
|
|
ret = true
|
|
_unlock()
|
|
end
|
|
|
|
return ret
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- @brief Returns true if `host_ip` has the alert identified with `alert_key` disabled
|
|
function _has_disabled_alert(alert_entity, host_ip, alert_key)
|
|
local exclusions = _get_configured_alert_exclusions()
|
|
alert_key = tostring(alert_key)
|
|
local entity_id = tostring(alert_entity.entity_id)
|
|
|
|
return not not (exclusions[entity_id]
|
|
and exclusions[entity_id][alert_key]
|
|
and exclusions[entity_id][alert_key]["excluded_hosts"]
|
|
and exclusions[entity_id][alert_key]["excluded_hosts"][host_ip])
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- @brief Returns true if `alert_entity` has one or more disabled alerts
|
|
function alert_exclusions.has_disabled_alerts(alert_entity)
|
|
local exclusions = _get_configured_alert_exclusions()
|
|
local entity_id = tostring(alert_entity.entity_id)
|
|
|
|
for alert_key, alert_exclusions in pairs(exclusions[entity_id] or {}) do
|
|
if alert_exclusions["excluded_hosts"] and table.len(alert_exclusions["excluded_hosts"]) > 0 then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- @brief Returns all excluded hosts for the given `alert_key` or nil if no excluded host exists
|
|
function _get_excluded_hosts(alert_entity, alert_key)
|
|
local exclusions = _get_configured_alert_exclusions()
|
|
|
|
alert_key = tostring(alert_key)
|
|
local entity_id = tostring(alert_entity.entity_id)
|
|
|
|
return exclusions[entity_id]
|
|
and exclusions[entity_id][alert_key]
|
|
and exclusions[entity_id][alert_key]["excluded_hosts"]
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
--@brief Marks a flow alert as disabled for a given `host_ip`, considered either as client or server
|
|
--@return True, if alert is disabled with success, false otherwise
|
|
function alert_exclusions.disable_flow_alert(host_ip, alert_key)
|
|
return _toggle_alert(alert_entities.flow, host_ip, alert_key, true --[[ disable --]])
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
--@brief Marks a flow alert as enabled for a given `host_ip`, considered either as client or server
|
|
--@return True, if alert is enabled with success, false otherwise
|
|
function alert_exclusions.enable_flow_alert(host_ip, alert_key)
|
|
return _toggle_alert(alert_entities.flow, host_ip, alert_key, false --[[ enable --]])
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
--@brief Enables all flow alerts possibly disabled
|
|
--@param host If a valid ip address is specified, then all alerts will be enabled only for `host`, otherwise all alerts will be enabled
|
|
--@return True, if enabled with success, false otherwise
|
|
function alert_exclusions.enable_all_flow_alerts(host)
|
|
return _enable_all_alerts(alert_entities.flow, host)
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- @brief Returns true if `host_ip` has the flow alert identified with `alert_key` disabled
|
|
function alert_exclusions.has_disabled_flow_alert(host_ip, alert_key)
|
|
return _has_disabled_alert(alert_entities.flow, host_ip, alert_key)
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
--@brief Marks a host alert as disabled for a given `host_ip`
|
|
--@return True, if alert is disabled with success, false otherwise
|
|
function alert_exclusions.disable_host_alert(host_ip, alert_key)
|
|
return _toggle_alert(alert_entities.host, host_ip, alert_key, true --[[ disable --]])
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
--@brief Marks a host alert as enabled for a given `host_ip`
|
|
--@return True, if alert is enabled with success, false otherwise
|
|
function alert_exclusions.enable_host_alert(host_ip, alert_key)
|
|
return _toggle_alert(alert_entities.host, host_ip, alert_key, false --[[ enable --]])
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
--@brief Enables all host alerts possibly disabled
|
|
--@param host If a valid ip address is specified, then all alerts will be enabled only for `host`, otherwise all alerts will be enabled
|
|
--@return True, if enabled with success, false otherwise
|
|
function alert_exclusions.enable_all_host_alerts(host)
|
|
return _enable_all_alerts(alert_entities.host, host)
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- @brief Returns true if `host_ip` has the host alert identified with `alert_key` disabled
|
|
function alert_exclusions.has_disabled_host_alert(host_ip, alert_key)
|
|
return _has_disabled_alert(alert_entities.host, host_ip, alert_key)
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- @brief Returns all the excluded hosts for the host alert identified with `alert_key`
|
|
function alert_exclusions.host_alerts_get_excluded_hosts(alert_key)
|
|
return _get_excluded_hosts(alert_entities.host, alert_key) or {}
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- @brief Returns all the excluded hosts for the flowt alert identified with `alert_key`
|
|
function alert_exclusions.flow_alerts_get_excluded_hosts(alert_key)
|
|
return _get_excluded_hosts(alert_entities.flow, alert_key) or {}
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- @brief Import a previously `export`ed exclusions configuration
|
|
function alert_exclusions.import(exclusions)
|
|
_set_configured_alert_exclusions(exclusions)
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- @brief Exports the current configuration
|
|
function alert_exclusions.export()
|
|
local exclusions = _get_configured_alert_exclusions()
|
|
|
|
return exclusions
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- @brief Delete all alert_exclusions
|
|
function alert_exclusions.cleanup()
|
|
local locked = _lock()
|
|
|
|
if locked then
|
|
local excl_key = _get_alert_exclusions_prefix_key()
|
|
|
|
ntop.delCache(excl_key)
|
|
ntop.reloadAlertExclusions() -- Tell ntopng to reload
|
|
|
|
_unlock()
|
|
end
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
return alert_exclusions
|