Add support bundle (#517)

* Expose required_engine_version when loading rules

When loading a rules file, have alternate methods that return the
required_engine_version. The existing methods remain unchanged and just
call the new methods with a dummy placeholder.

* Add --support argument to print support bundle

Add an argument --support that can be used as a single way to collect
necessary support information, including the falco version, config,
commandline, and all rules files.

There might be a big of extra structure to the rules files, as they
actually support an array of "variants", but we're thinking ahead to
cases where there might be a comprehensive library of rules files and
choices, so we're adding the extra structure.
This commit is contained in:
Mark Stemm
2019-02-06 16:36:33 -08:00
committed by GitHub
parent bd4c3ffa39
commit 5e9bbd139c
6 changed files with 102 additions and 7 deletions

View File

@@ -143,6 +143,13 @@ void falco_engine::list_fields(bool names_only)
}
void falco_engine::load_rules(const string &rules_content, bool verbose, bool all_events)
{
uint64_t dummy;
return load_rules(rules_content, verbose, all_events, dummy);
}
void falco_engine::load_rules(const string &rules_content, bool verbose, bool all_events, uint64_t &required_engine_version)
{
// The engine must have been given an inspector by now.
if(! m_inspector)
@@ -171,10 +178,17 @@ void falco_engine::load_rules(const string &rules_content, bool verbose, bool al
bool json_include_output_property = false;
falco_formats::init(m_inspector, this, m_ls, json_output, json_include_output_property);
m_rules->load_rules(rules_content, verbose, all_events, m_extra, m_replace_container_info, m_min_priority);
m_rules->load_rules(rules_content, verbose, all_events, m_extra, m_replace_container_info, m_min_priority, required_engine_version);
}
void falco_engine::load_rules_file(const string &rules_filename, bool verbose, bool all_events)
{
uint64_t dummy;
return load_rules_file(rules_filename, verbose, all_events, dummy);
}
void falco_engine::load_rules_file(const string &rules_filename, bool verbose, bool all_events, uint64_t &required_engine_version)
{
ifstream is;
@@ -189,7 +203,7 @@ void falco_engine::load_rules_file(const string &rules_filename, bool verbose, b
string rules_content((istreambuf_iterator<char>(is)),
istreambuf_iterator<char>());
load_rules(rules_content, verbose, all_events);
load_rules(rules_content, verbose, all_events, required_engine_version);
}
void falco_engine::enable_rule(const string &pattern, bool enabled, const string &ruleset)

View File

@@ -68,6 +68,13 @@ public:
void load_rules_file(const std::string &rules_filename, bool verbose, bool all_events);
void load_rules(const std::string &rules_content, bool verbose, bool all_events);
//
// Identical to above, but also returns the required engine version for the file/content.
// (If no required engine version is specified, returns 0).
//
void load_rules_file(const std::string &rules_filename, bool verbose, bool all_events, uint64_t &required_engine_version);
void load_rules(const std::string &rules_content, bool verbose, bool all_events, uint64_t &required_engine_version);
//
// Enable/Disable any rules matching the provided pattern
// (regex). When provided, enable/disable these rules in the

View File

@@ -195,10 +195,11 @@ function load_rules(sinsp_lua_parser,
min_priority)
local rules = yaml.load(rules_content)
local required_engine_version = 0
if rules == nil then
-- An empty rules file is acceptable
return
return required_engine_version
end
if type(rules) ~= "table" then
@@ -216,6 +217,7 @@ function load_rules(sinsp_lua_parser,
end
if (v['required_engine_version']) then
required_engine_version = v['required_engine_version']
if falco_rules.engine_version(rules_mgr) < v['required_engine_version'] then
error("Rules require engine version "..v['required_engine_version']..", but engine version is "..falco_rules.engine_version(rules_mgr))
end
@@ -549,6 +551,8 @@ function load_rules(sinsp_lua_parser,
end
io.flush()
return required_engine_version
end
local rule_fmt = "%-50s %s"

View File

@@ -223,7 +223,8 @@ int falco_rules::engine_version(lua_State *ls)
void falco_rules::load_rules(const string &rules_content,
bool verbose, bool all_events,
string &extra, bool replace_container_info,
falco_common::priority_type min_priority)
falco_common::priority_type min_priority,
uint64_t &required_engine_version)
{
lua_getglobal(m_ls, m_lua_load_rules.c_str());
if(lua_isfunction(m_ls, -1))
@@ -398,12 +399,15 @@ void falco_rules::load_rules(const string &rules_content,
lua_pushstring(m_ls, extra.c_str());
lua_pushboolean(m_ls, (replace_container_info ? 1 : 0));
lua_pushnumber(m_ls, min_priority);
if(lua_pcall(m_ls, 9, 0, 0) != 0)
if(lua_pcall(m_ls, 9, 1, 0) != 0)
{
const char* lerr = lua_tostring(m_ls, -1);
string err = "Error loading rules: " + string(lerr);
throw falco_exception(err);
}
required_engine_version = lua_tonumber(m_ls, -1);
lua_pop(m_ls, 1);
} else {
throw falco_exception("No function " + m_lua_load_rules + " found in lua rule module");
}

View File

@@ -41,7 +41,8 @@ class falco_rules
~falco_rules();
void load_rules(const string &rules_content, bool verbose, bool all_events,
std::string &extra, bool replace_container_info,
falco_common::priority_type min_priority);
falco_common::priority_type min_priority,
uint64_t &required_engine_version);
void describe_rule(string *rule);
static void init(lua_State *ls);