diff --git a/userspace/engine/falco_engine.cpp b/userspace/engine/falco_engine.cpp index 023d2bde..7843385b 100644 --- a/userspace/engine/falco_engine.cpp +++ b/userspace/engine/falco_engine.cpp @@ -342,18 +342,30 @@ void falco_engine::populate_rule_result(unique_ptr &res, gen if(lua_isfunction(m_ls, -1)) { lua_pushnumber(m_ls, ev->get_check_id()); - - if(lua_pcall(m_ls, 1, 4, 0) != 0) + + if(lua_pcall(m_ls, 1, 5, 0) != 0) { const char* lerr = lua_tostring(m_ls, -1); string err = "Error invoking function output: " + string(lerr); throw falco_exception(err); } - const char *p = lua_tostring(m_ls, -4); + const char *p = lua_tostring(m_ls, -5); res->rule = p; res->evt = ev; - res->priority_num = (falco_common::priority_type) lua_tonumber(m_ls, -3); - res->format = lua_tostring(m_ls, -2); + res->priority_num = (falco_common::priority_type) lua_tonumber(m_ls, -4); + res->format = lua_tostring(m_ls, -3); + + // Tags are passed back as a table, and is on the top of the stack + lua_pushnil(m_ls); /* first key */ + while (lua_next(m_ls, -2) != 0) { + // key is at index -2, value is at index + // -1. We want the value. + res->tags.insert(luaL_checkstring(m_ls, -1)); + + // Remove value, keep key for next iteration + lua_pop(m_ls, 1); + } + lua_pop(m_ls, 1); // Clean table leftover // Exception fields are passed back as a table lua_pushnil(m_ls); /* first key */ diff --git a/userspace/engine/falco_engine.h b/userspace/engine/falco_engine.h index a5459a66..d975b59f 100644 --- a/userspace/engine/falco_engine.h +++ b/userspace/engine/falco_engine.h @@ -161,6 +161,7 @@ public: falco_common::priority_type priority_num; std::string format; std::set exception_fields; + std::set tags; }; // diff --git a/userspace/engine/lua/rule_loader.lua b/userspace/engine/lua/rule_loader.lua index bf6c669a..6d24ba40 100644 --- a/userspace/engine/lua/rule_loader.lua +++ b/userspace/engine/lua/rule_loader.lua @@ -1156,7 +1156,7 @@ function on_event(rule_id) error ("rule_loader.on_event(): could not find rule by name: ", rule.rule) end - return rule.rule, rule.priority_num, output, combined_rule.exception_fields + return rule.rule, rule.priority_num, output, combined_rule.exception_fields, rule.tags end function print_stats() diff --git a/userspace/falco/falco.cpp b/userspace/falco/falco.cpp index 59d37457..802f8dfe 100644 --- a/userspace/falco/falco.cpp +++ b/userspace/falco/falco.cpp @@ -374,7 +374,7 @@ uint64_t do_inspect(falco_engine *engine, unique_ptr res = engine->process_sinsp_event(ev); if(res) { - outputs->handle_event(res->evt, res->rule, res->source, res->priority_num, res->format); + outputs->handle_event(res->evt, res->rule, res->source, res->priority_num, res->format, res->tags); } num_evts++; diff --git a/userspace/falco/falco_outputs.cpp b/userspace/falco/falco_outputs.cpp index dcb98cd0..a148927d 100644 --- a/userspace/falco/falco_outputs.cpp +++ b/userspace/falco/falco_outputs.cpp @@ -142,7 +142,7 @@ void falco_outputs::add_output(falco::outputs::config oc) } void falco_outputs::handle_event(gen_event *evt, string &rule, string &source, - falco_common::priority_type priority, string &format) + falco_common::priority_type priority, string &format, std::set tags) { if(!m_notifications_tb.claim()) { @@ -192,6 +192,7 @@ void falco_outputs::handle_event(gen_event *evt, string &rule, string &source, cmsg.msg = falco_formats::format_event(evt, rule, source, falco_common::priority_names[priority], sformat); cmsg.fields = falco_formats::resolve_tokens(evt, source, sformat); + cmsg.tags.insert(tags.begin(), tags.end()); cmsg.type = ctrl_msg_type::CTRL_MSG_OUTPUT; m_queue.push(cmsg); diff --git a/userspace/falco/falco_outputs.h b/userspace/falco/falco_outputs.h index 12daed4f..56065b47 100644 --- a/userspace/falco/falco_outputs.h +++ b/userspace/falco/falco_outputs.h @@ -48,7 +48,7 @@ public: // Format then send the event to all configured outputs (`evt` is an event that has matched some rule). void handle_event(gen_event *evt, std::string &rule, std::string &source, - falco_common::priority_type priority, std::string &format); + falco_common::priority_type priority, std::string &format, std::set tags); // Format then send a generic message to all outputs. Not necessarily associated with any event. void handle_msg(uint64_t now, diff --git a/userspace/falco/outputs.h b/userspace/falco/outputs.h index d089a08d..937d1ae0 100644 --- a/userspace/falco/outputs.h +++ b/userspace/falco/outputs.h @@ -50,6 +50,7 @@ struct message std::string rule; std::string source; map fields; + std::set tags; }; // diff --git a/userspace/falco/outputs.proto b/userspace/falco/outputs.proto index 43d16ef2..663168af 100644 --- a/userspace/falco/outputs.proto +++ b/userspace/falco/outputs.proto @@ -50,6 +50,5 @@ message response { string output = 5; map output_fields = 6; string hostname = 7; - // TODO(leodido,fntlnz): tags not supported yet, keeping it for reference. - // repeated string tags = 8; + repeated string tags = 8; } \ No newline at end of file diff --git a/userspace/falco/outputs_grpc.cpp b/userspace/falco/outputs_grpc.cpp index a2479810..ed024223 100644 --- a/userspace/falco/outputs_grpc.cpp +++ b/userspace/falco/outputs_grpc.cpp @@ -64,5 +64,9 @@ void falco::outputs::output_grpc::output(const message *msg) auto host = grpc_res.mutable_hostname(); *host = m_hostname; + // tags + auto tags = grpc_res.mutable_tags(); + *tags = {msg->tags.begin(), msg->tags.end()}; + falco::grpc::queue::get().push(grpc_res); } \ No newline at end of file diff --git a/userspace/falco/webserver.cpp b/userspace/falco/webserver.cpp index 5aeb13a8..bd9c6e49 100644 --- a/userspace/falco/webserver.cpp +++ b/userspace/falco/webserver.cpp @@ -102,7 +102,7 @@ bool k8s_audit_handler::accept_data(falco_engine *engine, { outputs->handle_event(res->evt, res->rule, res->source, res->priority_num, - res->format); + res->format, res->tags); } catch(falco_exception &e) {