update(userspace/engine): avoid solving macros AST at each cycle when getting details of all rules

Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
This commit is contained in:
Lorenzo Susini
2023-05-13 09:48:49 +00:00
committed by poiana
parent c1623771d8
commit 727aed0c03
4 changed files with 31 additions and 21 deletions

View File

@@ -462,13 +462,26 @@ void falco_engine::describe_rule(std::string *rule, bool json) const
Json::FastWriter writer;
std::string json_str;
filter_details details;
for(const auto &m : m_rule_collector.macros())
{
// Assumption: no exception because rules have already been loaded.
auto cond_ast = libsinsp::filter::parser(m.cond).parse();
std::shared_ptr<libsinsp::filter::ast::expr> cond_ast_ptr = std::move(cond_ast);
details.known_macros[m.name] = cond_ast_ptr;
}
for(const auto &l : m_rule_collector.lists())
{
details.known_lists.insert(l.name);
}
if(!rule)
{
Json::Value output_array = Json::arrayValue;
for(const auto& r : m_rules)
{
auto json_details = get_json_rule_details(r);
auto json_details = get_json_rule_details(r, details);
output_array.append(json_details);
}
@@ -482,14 +495,14 @@ void falco_engine::describe_rule(std::string *rule, bool json) const
throw falco_exception("Rule \"" + *rule + "\" is not loaded");
}
auto json_details = get_json_rule_details(*r);
auto json_details = get_json_rule_details(*r, details);
json_str = writer.write(json_details);
}
fprintf(stdout, "%s", json_str.c_str());
}
Json::Value falco_engine::get_json_rule_details(const falco_rule& r) const
Json::Value falco_engine::get_json_rule_details(const falco_rule& r, filter_details& details) const
{
// Parse rule condition and build the AST
// Assumption: the parsing will not throw an exception because
@@ -497,24 +510,8 @@ Json::Value falco_engine::get_json_rule_details(const falco_rule& r) const
auto rule_info = m_rule_collector.rules().at(r.name);
auto ast = libsinsp::filter::parser(rule_info->cond).parse();
// Prepare known macros and lists for the details resolver
filter_details_resolver resolver;
filter_details details;
for(const auto &m : m_rule_collector.macros())
{
// Assumption: same as above.
auto cond_ast = libsinsp::filter::parser(m.cond).parse();
std::shared_ptr<libsinsp::filter::ast::expr> cond_ast_ptr = std::move(cond_ast);
details.known_macros[m.name] = cond_ast_ptr;
}
for(const auto &l : m_rule_collector.lists())
{
details.known_lists.insert(l.name);
}
// Resolve the AST details
filter_details_resolver resolver;
resolver.run(ast.get(), details);
// Get fields from output string
@@ -573,6 +570,8 @@ Json::Value falco_engine::get_json_rule_details(const falco_rule& r) const
}
output["lists"] = lists;
details.reset();
return output;
}

View File

@@ -37,6 +37,7 @@ limitations under the License.
#include "falco_common.h"
#include "falco_source.h"
#include "falco_load_result.h"
#include "filter_details_resolver.h"
//
// This class acts as the primary interface between a program and the
@@ -299,7 +300,7 @@ private:
inline bool should_drop_evt() const;
// Retrieve details of a rule in json format
Json::Value get_json_rule_details(const falco_rule& r) const;
Json::Value get_json_rule_details(const falco_rule& r, filter_details& details) const;
rule_loader::collector m_rule_collector;
indexed_vector<falco_rule> m_rules;

View File

@@ -18,6 +18,14 @@ limitations under the License.
using namespace libsinsp::filter;
void filter_details::reset()
{
fields.clear();
macros.clear();
operators.clear();
lists.clear();
}
void filter_details_resolver::run(ast::expr* filter, filter_details& details)
{
visitor v(details);

View File

@@ -32,6 +32,8 @@ struct filter_details
std::unordered_set<std::string> macros;
std::unordered_set<std::string> operators;
std::unordered_set<std::string> lists;
void reset();
};
/*!