mirror of
https://github.com/vxcontrol/soldr-modules.git
synced 2026-07-01 12:47:17 -04:00
preserve actions list while getting them from callback data (#36)
* preserve actions list while getting them from callback data * small fixes Co-authored-by: Dmitry Ng <19asdek91@gmail.com>
This commit is contained in:
committed by
GitHub
parent
0e3500583e
commit
e26ea21191
@@ -100,7 +100,7 @@ describe('file_remover agent', function()
|
||||
"failed to send file remove action")
|
||||
-- wait for expected result to arrive (in any order)
|
||||
assert.is_true(__mock:expect("event", function(o)
|
||||
return o.event and o.event.name == "fr_object_file_removed_failed"
|
||||
return o.event and o.event.name == "fr_object_file_removed_failed"
|
||||
end))
|
||||
assert.is_true(__mock:expect("data",
|
||||
function(o) return o.data and o.data.name == "fr_remove_object_file" end))
|
||||
@@ -190,7 +190,8 @@ describe('file_remover agent', function()
|
||||
file_path = new_test_file()
|
||||
assert.is_true(file_exists(file_path), "file was not created on FS")
|
||||
end
|
||||
local expected_reason = test_case.create_file and "removed successful" or file_path .. ": No such file or directory"
|
||||
local expected_reason = test_case.create_file and "removed successful" or
|
||||
file_path .. ": No such file or directory"
|
||||
local expected_uniq = "fr_" ..
|
||||
test_case.type ..
|
||||
"_" .. test_case.subtype ..
|
||||
@@ -333,6 +334,26 @@ describe('file_remover agent', function()
|
||||
return false
|
||||
end))
|
||||
end)
|
||||
|
||||
it('actions list should be preserved in events', function()
|
||||
local test_file_path = new_test_file(__mock.rand_uuid())
|
||||
local data = { data = {}, actions = { "some_action" } }
|
||||
data.data['object.fullpath'] = test_file_path
|
||||
local action_data = cjson.encode(data)
|
||||
|
||||
assert(__mock:send_action(__mock.mock_token, __mock.module_token, action_data, "fr_remove_object_file"))
|
||||
assert.is_true(__mock:expect("event",
|
||||
function(o)
|
||||
if o.event and o.event.name == "fr_object_file_removed_successful" then
|
||||
assert.not_nil(o.event.actions)
|
||||
assert.equal(2, #o.event.actions)
|
||||
assert.equal('some_action', o.event.actions[1])
|
||||
assert.equal('file_remover.fr_remove_object_file', o.event.actions[2])
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('file removal bug fixes', function()
|
||||
@@ -355,4 +376,5 @@ describe('file_remover agent', function()
|
||||
assert.is_false(file_exists(test_file_path), "test file was not removed by a module")
|
||||
end)
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
+28
-23
@@ -84,6 +84,8 @@ cmodule.load_dependencies = function()
|
||||
local fields_schema = __config.get_fields_schema()
|
||||
local module_info = __config.get_module_info()
|
||||
|
||||
cmodule.module_config = cjson.decode(__config.get_current_config()) or {}
|
||||
|
||||
cmodule.unload_dependencies()
|
||||
|
||||
cmodule.action_engine = CActionEngine(
|
||||
@@ -102,36 +104,27 @@ cmodule.load_dependencies = function()
|
||||
cmodule.fields = create_strict_strings_set(cmodule.action_validator.fields_validators, "field")
|
||||
end
|
||||
|
||||
cmodule.push_event_for_action = function(event_name, action_name, event_data, actions)
|
||||
assert(event_name ~= nil and event_name ~= "", "event name must be defined")
|
||||
assert(action_name ~= nil and action_name ~= "", "action name must be defined")
|
||||
event_data = event_data or {}
|
||||
actions = actions or {}
|
||||
|
||||
if action_name ~= "" then
|
||||
local action_full_name = __config.ctx.name .. "." .. action_name
|
||||
if glue.indexof(action_full_name, actions) == nil then
|
||||
table.insert(actions, action_full_name)
|
||||
end
|
||||
end
|
||||
cmodule.push_event(event_name, event_data, actions)
|
||||
end
|
||||
|
||||
cmodule.push_event = function(event_name, event_data, actions)
|
||||
assert(event_name ~= nil and event_name ~= "", "event name must be defined")
|
||||
event_data = event_data or {}
|
||||
actions = actions or {}
|
||||
|
||||
local event = {
|
||||
-- This is small "hack" that fills real event data with actions list that was performed.
|
||||
-- It is needed to be filled for next modules wol will receive _action_ requests to know
|
||||
-- what actions was already in a chain and be able to do a circuit break.
|
||||
event_data.actions = actions
|
||||
|
||||
local result, next_actions_list = cmodule.event_engine:push_event({
|
||||
__module = __config.ctx.name,
|
||||
name = event_name, data = event_data,
|
||||
name = event_name,
|
||||
data = event_data,
|
||||
actions = actions,
|
||||
}
|
||||
local result, actions_list = cmodule.event_engine:push_event(event)
|
||||
})
|
||||
|
||||
-- result value defines if there are actions that need to be executed
|
||||
-- configuration of the following actions is done in "security policy".
|
||||
if result then
|
||||
for action_id, action_result in ipairs(cmodule.action_engine:exec(__aid, actions_list)) do
|
||||
for action_id, action_result in ipairs(cmodule.action_engine:exec(__aid, next_actions_list)) do
|
||||
__log.infof("action '%s' was requested and executed with result: %s", action_id, action_result)
|
||||
end
|
||||
end
|
||||
@@ -142,6 +135,8 @@ cmodule.start = function(action_handlers, background_process)
|
||||
|
||||
action = function(src, data, action_name)
|
||||
local action_data = cjson.decode(data) or {}
|
||||
-- actions is a set of full action names (module_name.acton_name) that was already performed
|
||||
local actions = action_data.actions or {}
|
||||
|
||||
action_data.__cid = action_data.__cid or make_uuid()
|
||||
|
||||
@@ -159,6 +154,7 @@ cmodule.start = function(action_handlers, background_process)
|
||||
response.status = "error"
|
||||
response.error = error
|
||||
response.reason = reason
|
||||
__log.errorf("%s: %s", error, reason)
|
||||
return __api.send_data_to(src, cjson.encode(response))
|
||||
end
|
||||
|
||||
@@ -166,10 +162,12 @@ cmodule.start = function(action_handlers, background_process)
|
||||
if action_handler == nil then
|
||||
response.status = "error"
|
||||
response.error = protocol.implementation_errors.action_handler_not_defined
|
||||
__log.errorf("%s: action handler '%s' is not defined", response.error, action_name)
|
||||
return __api.send_data_to(src, cjson.encode(response))
|
||||
end
|
||||
|
||||
local action_handler_result, event_data = action_handler.handler(action_data.data)
|
||||
-- handler can mutate actions list if it is required by the business logic
|
||||
local action_handler_result, event_data = action_handler.handler(action_data.data, actions)
|
||||
local event_name = action_handler.success
|
||||
if not action_handler_result then
|
||||
event_name = action_handler.failure
|
||||
@@ -178,15 +176,22 @@ cmodule.start = function(action_handlers, background_process)
|
||||
event_data.__cid = action_data.__cid
|
||||
event_data.uuid = action_data.uuid or make_uuid()
|
||||
|
||||
cmodule.push_event_for_action(event_name, action_name, event_data)
|
||||
-- before sending the event, take list of actions that was already performed and add current action
|
||||
local action_full_name = __config.ctx.name .. "." .. action_name
|
||||
if glue.indexof(action_full_name, actions) == nil then
|
||||
table.insert(actions, action_full_name)
|
||||
end
|
||||
-- try to send an event
|
||||
cmodule.push_event(event_name, event_data, actions)
|
||||
|
||||
response.data = event_data
|
||||
if action_handler_result then
|
||||
response.status = "success"
|
||||
else
|
||||
response.status = "error"
|
||||
response.error = protocol.implementation_errors.action_handler_error
|
||||
response.error = protocol.business_logic_errors.action_handler_error
|
||||
response.reason = event_data.reason
|
||||
__log.errorf("%s: %s", response.error, response.reason)
|
||||
end
|
||||
return __api.send_data_to(src, cjson.encode(response))
|
||||
end,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
local cjson = require("cjson.safe")
|
||||
local glue = require("glue")
|
||||
local protocol = require("protocol/protocol")
|
||||
|
||||
require("engine")
|
||||
@@ -82,22 +81,6 @@ local function get_agent_src_by_id(id, atype)
|
||||
return "", {}
|
||||
end
|
||||
|
||||
smodule.push_event_for_action = function(agent_id, event_name, action_name, event_data, actions)
|
||||
assert(agent_id ~= nil and agent_id ~= "", "agent id must be defined")
|
||||
assert(event_name ~= nil and event_name ~= "", "event name must be defined")
|
||||
assert(action_name ~= nil and action_name ~= "", "action name must be defined")
|
||||
event_data = event_data or {}
|
||||
actions = actions or {}
|
||||
|
||||
if action_name ~= "" then
|
||||
local action_full_name = __config.ctx.name .. "." .. action_name
|
||||
if glue.indexof(action_full_name, actions) == nil then
|
||||
table.insert(actions, action_full_name)
|
||||
end
|
||||
end
|
||||
smodule.push_event(agent_id, event_name, event_data, actions)
|
||||
end
|
||||
|
||||
smodule.push_event = function(agent_id, event_name, event_data, actions)
|
||||
assert(agent_id ~= nil and agent_id ~= "", "agent id must be defined")
|
||||
assert(event_name ~= nil and event_name ~= "", "event name must be defined")
|
||||
|
||||
Reference in New Issue
Block a user