mirror of
https://github.com/ntop/ntopng.git
synced 2026-04-28 23:19:33 +00:00
305 lines
9.5 KiB
Lua
305 lines
9.5 KiB
Lua
--
|
|
-- (C) 2021 - ntop.org
|
|
--
|
|
|
|
-- ##############################################
|
|
|
|
local dirs = ntop.getDirs()
|
|
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
|
package.path = dirs.installdir .. "/scripts/lua/rest/v2/get/datasource/?.lua;" .. package.path
|
|
|
|
if ntop.isPro() then
|
|
-- Add Pro datasources
|
|
package.path = dirs.installdir .. "/pro/scripts/lua/rest/v2/get/datasource/?.lua;" .. package.path
|
|
end
|
|
|
|
local os_utils = require "os_utils"
|
|
require ("lua_utils")
|
|
local json = require("dkjson")
|
|
|
|
local REDIS_BASE_KEY = "ntopng.datasources"
|
|
|
|
local datasources_utils = {}
|
|
|
|
-- ##############################################
|
|
|
|
local function create_hash_source(alias, data_retention, origin)
|
|
return ntop.md5(alias .. origin .. tostring(data_retention))
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
local function is_source_valid(alias, data_retention, scope, origin)
|
|
|
|
if (isEmptyString(alias)) then return false end
|
|
if (isEmptyString(scope)) then return false end
|
|
if (isEmptyString(origin)) then return false end
|
|
|
|
if (data_retention == nil) then return false end
|
|
if (data_retention <= 0) then return false end
|
|
|
|
if (scope ~= "public" and scope ~= "private") then return false end
|
|
|
|
return true
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
local function alias_exists(alias)
|
|
|
|
local sources = ntop.getHashAllCache(REDIS_BASE_KEY)
|
|
if (sources == nil) then return false end
|
|
|
|
for key, source_json in pairs(sources) do
|
|
local source = json.decode(source_json)
|
|
if (source.alias == alias) then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- Check if the passed hash is saved inside redis.
|
|
-- @return True if the hash is contained, false otherwise
|
|
function datasources_utils.is_hash_valid(hash)
|
|
|
|
local ds_json = ntop.getHashCache(REDIS_BASE_KEY, hash)
|
|
if (isEmptyString(ds_json)) then return false end
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Create a new data source and save it to redis.
|
|
-- @param alias The human name for data source (not nil)
|
|
-- @param data_retention How many seconds the data is valid (not nil, > 0)
|
|
-- @param scope The data source scope, it can be public|private (not nil)
|
|
-- @param origin The lua script that will execute the data fetch (not nil)
|
|
-- @return The function returns `true` if the passed
|
|
-- arguments meet the precondition, otherwise `false`
|
|
-------------------------------------------------------------------------------
|
|
function datasources_utils.add_source(alias, data_retention, scope, origin, schemas)
|
|
|
|
if (not is_source_valid(alias, data_retention, scope, origin)) then
|
|
return false, "The provided arguments are not valid"
|
|
end
|
|
if (alias_exists(alias)) then
|
|
return false, "There is a data source with that alias name"
|
|
end
|
|
|
|
local ds_hash = create_hash_source(alias, data_retention, origin)
|
|
local new_datasource = {
|
|
hash = ds_hash,
|
|
alias = alias,
|
|
data_retention = data_retention,
|
|
scope = scope,
|
|
origin = origin,
|
|
schemas = schemas
|
|
}
|
|
|
|
ntop.setHashCache(REDIS_BASE_KEY, ds_hash, json.encode(new_datasource))
|
|
return true, ds_hash
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Edit the data source
|
|
-- @param hash_source the hash of the source to be edit (not nil)
|
|
-- @param alias The human name for data source (not nil)
|
|
-- @param data_retention How many seconds the data is valid (not nil, > 0)
|
|
-- @param scope The data source scope, it can be public|private (not nil)
|
|
-- @param origin The lua script that will execute the data fetch (not nil)
|
|
-- @return True if the edit was successful, false otherwise
|
|
-------------------------------------------------------------------------------
|
|
function datasources_utils.edit_source(hash_source, alias, data_retention, scope, origin, schemas)
|
|
|
|
if (isEmptyString(hash_source)) then
|
|
return false, "The has cannot be empty!"
|
|
end
|
|
if (not is_source_valid(alias, data_retention, scope, origin)) then
|
|
return false, "The sources are not valid!"
|
|
end
|
|
|
|
local json_source = ntop.getHashCache(REDIS_BASE_KEY, hash_source)
|
|
|
|
if (isEmptyString(json_source)) then
|
|
return false, "Datasource not found!"
|
|
end
|
|
|
|
local source = json.decode(json_source)
|
|
source.alias = alias
|
|
source.data_retention = data_retention
|
|
source.scope = scope
|
|
source.origin = origin
|
|
source.schemas = schemas
|
|
|
|
ntop.setHashCache(REDIS_BASE_KEY, hash_source, json.encode(source))
|
|
|
|
return true
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Delete the data source from redis
|
|
-- @param hash_source The hash of the source to be removed (not nil)
|
|
-- @return True if the delete was successful, false otherwise
|
|
-------------------------------------------------------------------------------
|
|
function datasources_utils.delete_source(hash_source)
|
|
|
|
if (isEmptyString(hash_source)) then
|
|
return false
|
|
end
|
|
|
|
if (isEmptyString(ntop.getHashCache(REDIS_BASE_KEY, hash_source))) then
|
|
return false
|
|
end
|
|
|
|
ntop.delHashCache(REDIS_BASE_KEY, hash_source)
|
|
|
|
return true
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Get a datasource stored in redis
|
|
-- @return The searched datasources stored in redis, or nil in case of error
|
|
-------------------------------------------------------------------------------
|
|
function datasources_utils.get(ds_hash)
|
|
local ds = ntop.getHashCache(REDIS_BASE_KEY, ds_hash) or "{}"
|
|
|
|
return(json.decode(ds))
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Get all datasources stored in redis
|
|
-- @return An array of datasources stored in redis, if no any sources was found
|
|
-- it returns an empty array
|
|
-------------------------------------------------------------------------------
|
|
|
|
function datasources_utils.get_all_sources()
|
|
|
|
local sources = ntop.getHashAllCache(REDIS_BASE_KEY)
|
|
if (sources == nil) then
|
|
return {}
|
|
end
|
|
|
|
local all_sources = {}
|
|
|
|
for _, json_source in pairs(sources) do
|
|
all_sources[#all_sources + 1] = json.decode(json_source)
|
|
end
|
|
|
|
return all_sources
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
function datasources_utils.prepareResponse(datasets, timestamps, unit)
|
|
local response = {}
|
|
|
|
if (datasets == nil) then return {} end
|
|
|
|
if (timestamps ~= nil) then
|
|
response.timestamps = timestamps
|
|
end
|
|
if (unit ~= nil) then
|
|
response.unit = unit
|
|
end
|
|
|
|
response.data = datasets
|
|
|
|
return response
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- A cache of all the available datasources, keyed by datasource_keys as found in datasource_keys.lua
|
|
local source_key_source_type_cache
|
|
|
|
-- ##############################################
|
|
|
|
local function cache_source_types(recache)
|
|
if source_key_source_type_cache and not recache then
|
|
-- Already cached
|
|
return
|
|
end
|
|
|
|
-- Cache available datasource types
|
|
source_key_source_type_cache = {}
|
|
|
|
local datasources_dir = {os_utils.fixPath(dirs.installdir .. "/scripts/lua/rest/v2/get/datasource/")}
|
|
|
|
if ntop.isPro() then
|
|
datasources_dir[#datasources_dir + 1] = os_utils.fixPath(dirs.installdir .. "/pro/scripts/lua/rest/v2/get/datasource/")
|
|
end
|
|
|
|
-- The base datasources directory
|
|
for _, datasource_path in ipairs(datasources_dir) do
|
|
for datasource_dir in pairs(ntop.readdir(datasource_path)) do
|
|
-- Datasource sub-directories, e.g., /interface, /host, etc
|
|
local datasource_dir_path = os_utils.fixPath(string.format("%s/%s", datasource_path, datasource_dir))
|
|
|
|
if ntop.isdir(datasource_dir_path) then
|
|
for datasource_file in pairs(ntop.readdir(datasource_dir_path)) do
|
|
-- Load all sub-classes of datasources.lua (and exclude datasources.lua itself)
|
|
|
|
if datasource_file:match("%.lua$") then
|
|
-- Do the require and return the required module, if successful
|
|
local req = string.format("%s.%s", datasource_dir, datasource_file:gsub("%.lua$", ""))
|
|
local datasource = require(req)
|
|
|
|
if datasource then
|
|
source_key_source_type_cache[req] = datasource
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- @brief Returns all the available datasource types, i.e., all possible subclasses of datasource.lua in modules/datasources
|
|
function datasources_utils.get_all_source_types()
|
|
local res = {}
|
|
|
|
-- Build the cache, if not already built
|
|
cache_source_types()
|
|
|
|
for datasource_key, datasource in pairs(source_key_source_type_cache) do
|
|
res[#res + 1] = datasource
|
|
end
|
|
|
|
return res
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- @brief Returns a datasource
|
|
-- @return The datasource that can be then instantiated with :new()
|
|
function datasources_utils.get_source_type_by_key(datasource_type)
|
|
-- Build the cache (if not already built)
|
|
cache_source_types()
|
|
|
|
-- Return the cached datasource
|
|
if datasource_type == "interface_packet_distro" then
|
|
-- TODO: remove when datasources will be identified and requested with URIs
|
|
return source_key_source_type_cache["interface.packet_distro"]
|
|
end
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
return datasources_utils
|