From 177f8c6cded4db2e76bc55e7999fd43ff7f646ff Mon Sep 17 00:00:00 2001 From: Simone Mainardi Date: Mon, 4 May 2020 11:20:57 +0200 Subject: [PATCH] Implements notification endpoint edit and documentation --- scripts/lua/test_notification_endpoints.lua | 25 +++- .../modules/notification_endpoint_configs.lua | 130 +++++++++++++++--- 2 files changed, 135 insertions(+), 20 deletions(-) diff --git a/scripts/lua/test_notification_endpoints.lua b/scripts/lua/test_notification_endpoints.lua index c682a2080e..0e485a2ce6 100644 --- a/scripts/lua/test_notification_endpoints.lua +++ b/scripts/lua/test_notification_endpoints.lua @@ -95,13 +95,36 @@ assert(res["status"] == "OK") assert(res["endpoint_key"] == "email") assert(res["endpoint_conf_name"] == "ntop_email") assert(res["endpoint_conf"]) -assert(not res["endpoint_conf"]["trash"]) +assert(not res["endpoint_conf"]["garbage"]) for k, v in pairs(res["endpoint_conf"]) do assert(conf_params[k]) assert(conf_params[k] == v) end +-- Edit the config +conf_params["smtp_server_name"] = "mail2.ntop.org" +res = notification_endpoint_configs.edit_endpoint_config_params("ntop_email", conf_params) +assert(res["status"] == "OK") + +res = notification_endpoint_configs.get_endpoint_config("ntop_email") +assert(res["status"] == "OK") +assert(res["endpoint_key"] == "email") +assert(res["endpoint_conf_name"] == "ntop_email") +assert(res["endpoint_conf"]) +assert(res["endpoint_conf"]["smtp_server_name"] == "mail2.ntop.org") + +-- Add another endpoint +conf_params = { + smtp_server_name = "mail.google.com", + sender = "tester@google.com", + username = "googleuser", + password = "googlepassword" +} + +res = notification_endpoint_configs.add_endpoint_config("email", "google_email", conf_params) +assert(res["status"] == "OK") + ------------------------------ -- TEST ENDPOINT RECIPIENTS -- ------------------------------ diff --git a/scripts/plugins/notification_endpoints/modules/notification_endpoint_configs.lua b/scripts/plugins/notification_endpoints/modules/notification_endpoint_configs.lua index faa74a1bc7..c021f33bac 100644 --- a/scripts/plugins/notification_endpoints/modules/notification_endpoint_configs.lua +++ b/scripts/plugins/notification_endpoints/modules/notification_endpoint_configs.lua @@ -37,6 +37,9 @@ local notification_endpoint_configs = {} -- ################################################################# +-- @brief Check if an endpoint configuration with name `endpoint_conf_name` exists +-- @param endpoint_conf_name A string with the configuration name +-- @return true if the configuration exists, false otherwise local function is_endpoint_config_existing(endpoint_conf_name) if not endpoint_conf_name or endpoint_conf_name == "" then return false @@ -53,6 +56,24 @@ end -- ################################################################# +-- @brief Set a configuration along with its params. Configuration name and params must be already sanitized +-- @param endpoint_key A string with the notification endpoint key +-- @param endpoint_conf_name A string with the configuration name +-- @param safe_params A table with endpoint configuration params already sanitized +-- @return nil +local function set_endpoint_config_params(endpoint_key, endpoint_conf_name, safe_params) + -- Write the endpoint conf_name and its key in a hash + ntop.setHashCache(ENDPOINT_CONFIG_TO_ENDPOINT_KEY, endpoint_conf_name, endpoint_key) + -- Write the endpoint config in another hash + local k = string.format(ENDPOINT_CONFIGS_KEY, endpoint_key) + ntop.setHashCache(k, endpoint_conf_name, json.encode(safe_params)) +end + +-- ################################################################# + +-- @brief Read the configuration parameters of an existing configuration +-- @param endpoint_conf_name A string with the configuration name +-- @return A table with two keys: endpoint_key and conf_params or nil if the configuration isn't found local function read_endpoint_config_raw(endpoint_conf_name) local endpoint_key = ntop.getHashCache(ENDPOINT_CONFIG_TO_ENDPOINT_KEY, endpoint_conf_name) @@ -66,6 +87,9 @@ end -- ################################################################# +-- @brief Sanity checks for the endpoint key +-- @param endpoint_key A string with the notification endpoint key +-- @return true if the sanity checks are ok, false otherwise local function check_endpoint_key(endpoint_key) if not notification_endpoint_consts.endpoint_types[endpoint_key] then return false, {status = "failed", error = {type = "endpoint_not_existing"}} @@ -76,6 +100,9 @@ end -- ################################################################# +-- @brief Sanity checks for the endpoint configuration name +-- @param endpoint_conf_name A string with the configuration name +-- @return true if the sanity checks are ok, false otherwise local function check_endpoint_conf_name(endpoint_conf_name) if not endpoint_conf_name or endpoint_conf_name == "" then return false, {status = "failed", error = {type = "invalid_endpoint_conf_name"}} @@ -86,6 +113,40 @@ end -- ################################################################# +-- @brief Sanity checks for the endpoint configuration parameters +-- @param endpoint_key A string with the notification endpoint key +-- @param conf_params A table with endpoint configuration params that will be possibly sanitized +-- @return false with a description of the error, or true, with a table containing sanitized configuration params. +local function check_endpoint_params(endpoint_key, conf_params) + if not conf_params or not type(conf_params) == "table" then + return false, {status = "failed", error = {type = "invalid_conf_params"}} + end + + -- Create a safe_params table with only expected params + local safe_params = {} + -- So iterate across all expected params of the current endpoint + for _, param in ipairs(notification_endpoint_consts.endpoint_types[endpoint_key].conf_params) do + -- param is a lua table so we access its elements + local param_name = param["param_name"] + local optional = param["optional"] + + if conf_params and conf_params[param_name] and not safe_params[param_name] then + safe_params[param_name] = conf_params[param_name] + elseif not optional then + return false, {status = "failed", error = {type = "missing_mandatory_param", missing_param = param_name}} + end + end + + return true, {status = "OK", safe_params = safe_params} +end + +-- ################################################################# + +-- @brief Add a new configuration endpoint +-- @param endpoint_key A string with the notification endpoint key +-- @param endpoint_conf_name A string with the configuration name +-- @param conf_params A table with endpoint configuration params that will be possibly sanitized +-- @return A table with a key status which is either "OK" or "failed". When "failed", the table contains another key "error" with an indication of the issue function notification_endpoint_configs.add_endpoint_config(endpoint_key, endpoint_conf_name, conf_params) local ok, status = check_endpoint_key(endpoint_key) if not ok then @@ -102,35 +163,59 @@ function notification_endpoint_configs.add_endpoint_config(endpoint_key, endpoin return {status = "failed", error = {type = "endpoint_config_already_existing", endpoint_conf_name = endpoint_conf_name}} end - if not conf_params or not type(conf_params) == "table" then - return {status = "failed", error = {type = "invalid_conf_params"}} + -- Are the submitted params those expected by the endpoint? + ok, status = check_endpoint_params(endpoint_key, conf_params) + + if not ok then + return status end - -- Create a safe_params table with only expected params - local safe_params = {} - -- So iterate across all expected params of the current endpoint - for _, param in ipairs(notification_endpoint_consts.endpoint_types[endpoint_key].conf_params) do - -- param is a lua table so we access its elements - local param_name = param["param_name"] - local optional = param["optional"] - - if conf_params and conf_params[param_name] and not safe_params[param_name] then - safe_params[param_name] = conf_params[param_name] - elseif not optional then - return {status = "failed", error = {type = "missing_mandatory_param", missing_param = param_name}} - end - end + local safe_params = status["safe_params"] -- Set the config - ntop.setHashCache(ENDPOINT_CONFIG_TO_ENDPOINT_KEY, endpoint_conf_name, endpoint_key) - local k = string.format(ENDPOINT_CONFIGS_KEY, endpoint_key) - ntop.setHashCache(k, endpoint_conf_name, json.encode(safe_params)) + set_endpoint_config_params(endpoint_key, endpoint_conf_name, safe_params) return {status = "OK"} end -- ################################################################# +-- @brief Edit the configuration parameters of an existing endpoint +-- @param endpoint_conf_name A string with the configuration name +-- @param conf_params A table with endpoint configuration params that will be possibly sanitized +-- @return A table with a key status which is either "OK" or "failed". When "failed", the table contains another key "error" with an indication of the issue +function notification_endpoint_configs.edit_endpoint_config_params(endpoint_conf_name, conf_params) + local ok, status = check_endpoint_conf_name(endpoint_conf_name) + if not ok then + return status + end + + -- Is the config already existing? + local ec = read_endpoint_config_raw(endpoint_conf_name) + if not ec then + return {status = "failed", error = {type = "endpoint_config_not_existing", endpoint_conf_name = endpoint_conf_name}} + end + + -- Are the submitted params those expected by the endpoint? + ok, status = check_endpoint_params(ec["endpoint_key"], conf_params) + + if not ok then + return status + end + + local safe_params = status["safe_params"] + + -- Overwrite the config + set_endpoint_config_params(ec["endpoint_key"], endpoint_conf_name, safe_params) + + return {status = "OK"} +end + +-- ################################################################# + +-- @brief Delete the configuration parameters of an existing endpoint configuration +-- @param endpoint_conf_name A string with the configuration name +-- @return A table with a key status which is either "OK" or "failed". When "failed", the table contains another key "error" with an indication of the issue function notification_endpoint_configs.delete_endpoint_config(endpoint_conf_name) local ok, status = check_endpoint_conf_name(endpoint_conf_name) if not ok then @@ -152,6 +237,11 @@ end -- ################################################################# +-- @brief Retrieve the configuration parameters of an existing endpoint configuration +-- @param endpoint_conf_name A string with the configuration name +-- @return A table with a key status which is either "OK" or "failed". +-- When "failed", the table contains another key "error" with an indication of the issue. +-- When "OK", the table contains "endpoint_conf_name", "endpoint_key", and "endpoint_conf" with the results function notification_endpoint_configs.get_endpoint_config(endpoint_conf_name) local ok, status = check_endpoint_conf_name(endpoint_conf_name) if not ok then @@ -174,6 +264,8 @@ end -- ################################################################# +-- @brief Clear all the existing endpoint configurations +-- @return Always return a table {status = "OK"} function notification_endpoint_configs.reset_endpoint_configs() local notification_endpoint_recipients = plugins_utils.loadModule("notification_endpoints", "notification_endpoint_recipients")