EVOLUTION-MANAGER
Edit File: shell.lua
-- -- (C) 2021 - ntop.org -- require "lua_utils" local sys_utils = require "sys_utils" local json = require "dkjson" local alerts_api = require "alerts_api" local alert_consts = require "alert_consts" local other_alert_keys = require "other_alert_keys" local alert_utils = require "alert_utils" local endpoint_key = "shell" local shell = { name = "Shell Script", endpoint_params = {{ param_name = "shell_script" }}, endpoint_template = { script_key = endpoint_key, template_name = "shell_endpoint.template" }, recipient_params = {{ param_name = "shell_script_options" }, { param_name = "shell_script_execution" }}, recipient_template = { script_key = endpoint_key, template_name = "shell_recipient.template" }, -- This is not a script that is supposed to run on Windows windows_exclude = true } shell.EXPORT_FREQUENCY = 5 -- ############################################## -- @brief Returns the desided formatted output for recipient params function shell.format_recipient_params(recipient_params) return string.format("(%s)", shell.name) end -- ############################################## local function recipient2sendMessageSettings(recipient) local settings = { path = recipient.endpoint_conf.shell_script, options = recipient.recipient_params.shell_script_options, execution_period = recipient.recipient_params.shell_script_execution } return settings end -- ############################################## function shell.setup() local is_enabled = true global_state = {} return (is_enabled) end -- ############################################## function shell.runScript(alerts, settings) local where = {"/usr/share/ntopng/scripts/shell/", dirs.installdir .. "/scripts/shell/"} local fullpath = nil local do_debug = false local options = settings.options for _, p in ipairs(where) do local path = p .. settings.path if (do_debug) then tprint("Checking " .. path) end if (ntop.exists(path)) then fullpath = path break end end if (fullpath == nil) then if (do_debug) then tprint("Not found: " .. settings.path .. " (" .. dirs.installdir .. ")") end return (false) end for key, alert in ipairs(alerts) do -- Trigger the script for the stored alert -- Trigger the script just one time in case of engaged/released alerts if not alert.action or settings.execution_period == "always" or alert.action == settings.execution_period then -- Executing the script local exec_script = fullpath -- Mask output local cmd = exec_script .. " " .. options .. " > /dev/null" -- Running script with the alert (json) as input (stdin) sys_utils.execShellCmd(cmd, json.encode(alert)) if (alert.alert_id ~= other_alert_keys.alert_shell_script_executed) then -- Trigger alert (exclude those for the shell script execution itself to avoid loops) -- Storing an alert-notice in regard of the shell script execution -- for security reasons local entity_info = alerts_api.systemEntity(ntop.getInfo().product) local type_info = alert_consts.alert_types.alert_shell_script_executed.new(exec_script, alert_consts.alertTypeLabel(alert["alert_id"], true)) type_info:set_score_notice() type_info:store(entity_info) end end end -- for return true end -- ############################################## function shell.dequeueRecipientAlerts(recipient, budget) local settings = recipient2sendMessageSettings(recipient) local start_time = os.time() local sent = 0 local more_available = true local budget_used = 0 local MAX_ALERTS_PER_REQUEST = 1 local return_msg = {} -- Dequeue alerts up to budget x MAX_ALERTS_PER_REQUEST -- Note: in this case budget is the number of script messages to send while budget_used <= budget and more_available do local diff = os.time() - start_time if diff >= shell.EXPORT_FREQUENCY then break end -- Dequeue MAX_ALERTS_PER_REQUEST notifications local notifications = {} local i = 0 while i < MAX_ALERTS_PER_REQUEST do local notification = ntop.recipient_dequeue(recipient.recipient_id) if notification then if alert_utils.filter_notification(notification, recipient.recipient_id) then notifications[#notifications + 1] = notification.alert i = i + 1 end else break end end if not notifications or #notifications == 0 then more_available = false break end local alerts = {} for _, json_message in ipairs(notifications) do local alert = json.decode(json_message) table.insert(alerts, alert) end if (shell.runScript(alerts, settings) == false) then return { success = false, error_message = "- unable to execute the script" } end -- Remove the processed messages from the queue budget_used = budget_used + #notifications sent = sent + 1 end return { success = true, more_available = more_available } end -- ############################################## function shell.runTest(recipient) local message_info local settings = recipient2sendMessageSettings(recipient) local success = shell.runScript({}, settings) if not success then message_info = i18n("shell_alert_endpoint.shell_send_error") end return success, message_info end -- ############################################## return shell