mirror of
https://github.com/falcosecurity/falco.git
synced 2025-08-24 08:58:52 +00:00
refactor(falco/app): apply early return pattern in actions code
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
This commit is contained in:
parent
31c94df10e
commit
9e2c22804c
@ -170,14 +170,15 @@ falco::app::run_result falco::app::actions::init_falco_engine(falco::app::state&
|
|||||||
if(s.is_capture_mode()) {
|
if(s.is_capture_mode()) {
|
||||||
auto manager = s.offline_inspector->get_plugin_manager();
|
auto manager = s.offline_inspector->get_plugin_manager();
|
||||||
for(const auto& p : manager->plugins()) {
|
for(const auto& p : manager->plugins()) {
|
||||||
if(p->caps() & CAP_SOURCING && p->id() != 0) {
|
if((p->caps() & CAP_SOURCING) == 0 || p->id() == 0) {
|
||||||
bool added = false;
|
continue;
|
||||||
auto source_idx = manager->source_idx_by_plugin_id(p->id(), added);
|
}
|
||||||
auto engine_idx = s.source_infos.at(p->event_source())->engine_idx;
|
bool added = false;
|
||||||
if(!added || source_idx != engine_idx) {
|
auto source_idx = manager->source_idx_by_plugin_id(p->id(), added);
|
||||||
return run_result::fatal("Could not add event source in the engine: " +
|
auto engine_idx = s.source_infos.at(p->event_source())->engine_idx;
|
||||||
p->event_source());
|
if(!added || source_idx != engine_idx) {
|
||||||
}
|
return run_result::fatal("Could not add event source in the engine: " +
|
||||||
|
p->event_source());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,13 +147,14 @@ falco::app::run_result falco::app::actions::init_inspectors(falco::app::state& s
|
|||||||
std::string err;
|
std::string err;
|
||||||
std::unordered_set<std::string> used_plugins;
|
std::unordered_set<std::string> used_plugins;
|
||||||
const auto& all_plugins = s.offline_inspector->get_plugin_manager()->plugins();
|
const auto& all_plugins = s.offline_inspector->get_plugin_manager()->plugins();
|
||||||
|
const bool is_capture_mode = s.is_capture_mode();
|
||||||
|
|
||||||
for(const auto& src : s.loaded_sources) {
|
for(const auto& src : s.loaded_sources) {
|
||||||
auto src_info = s.source_infos.at(src);
|
auto src_info = s.source_infos.at(src);
|
||||||
|
|
||||||
// in capture mode, every event source uses the offline inspector.
|
// in capture mode, every event source uses the offline inspector.
|
||||||
// in live mode, we create a new inspector for each event source
|
// in live mode, we create a new inspector for each event source
|
||||||
if(s.is_capture_mode()) {
|
if(is_capture_mode) {
|
||||||
src_info->inspector = s.offline_inspector;
|
src_info->inspector = s.offline_inspector;
|
||||||
} else {
|
} else {
|
||||||
src_info->inspector =
|
src_info->inspector =
|
||||||
@ -174,15 +175,16 @@ falco::app::run_result falco::app::actions::init_inspectors(falco::app::state& s
|
|||||||
((p->id() != 0 && src == p->event_source()) ||
|
((p->id() != 0 && src == p->event_source()) ||
|
||||||
(p->id() == 0 && src == falco_common::syscall_source));
|
(p->id() == 0 && src == falco_common::syscall_source));
|
||||||
|
|
||||||
if(s.is_capture_mode()) {
|
if(is_capture_mode) {
|
||||||
// in capture mode, every plugin is already registered
|
// in capture mode, every plugin is already registered
|
||||||
// in the offline inspector by the load_plugins action
|
// in the offline inspector by the load_plugins action
|
||||||
plugin = p;
|
plugin = p;
|
||||||
} else {
|
} else {
|
||||||
// in live mode, for the inspector assigned to the given
|
// in live mode, for the inspector assigned to the given event source, we must
|
||||||
// event source, we must register the plugin supporting
|
// register a plugin if one of the following condition applies to it:
|
||||||
// that event source and also plugins with field extraction
|
// - it has event sourcing capability for the given event source
|
||||||
// capability that are compatible with that event source
|
// - it has one among field extraction, event parsing and async events capabilities
|
||||||
|
// and is compatible (with respect to that capability) with the given event source
|
||||||
if(is_input ||
|
if(is_input ||
|
||||||
(p->caps() & CAP_EXTRACTION &&
|
(p->caps() & CAP_EXTRACTION &&
|
||||||
sinsp_plugin::is_source_compatible(p->extract_event_sources(), src)) ||
|
sinsp_plugin::is_source_compatible(p->extract_event_sources(), src)) ||
|
||||||
@ -194,22 +196,23 @@ falco::app::run_result falco::app::actions::init_inspectors(falco::app::state& s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// init the plugin, if we registered it into an inspector
|
if(!plugin) {
|
||||||
// (in capture mode, this is true for every plugin)
|
continue;
|
||||||
if(plugin) {
|
|
||||||
// avoid initializing the same plugin twice in the same
|
|
||||||
// inspector if we're in capture mode
|
|
||||||
if(!s.is_capture_mode() || used_plugins.find(p->name()) == used_plugins.end()) {
|
|
||||||
if(!plugin->init(config->m_init_config, err)) {
|
|
||||||
return run_result::fatal(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(is_input) {
|
|
||||||
auto gen_check = src_info->inspector->new_generic_filtercheck();
|
|
||||||
src_info->filterchecks->add_filter_check(std::move(gen_check));
|
|
||||||
}
|
|
||||||
used_plugins.insert(plugin->name());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init the plugin only if we registered it into an inspector (in capture mode, this is
|
||||||
|
// true for every plugin). Avoid initializing the same plugin twice in the same
|
||||||
|
// inspector if we're in capture mode
|
||||||
|
if(!is_capture_mode || used_plugins.find(p->name()) == used_plugins.end()) {
|
||||||
|
if(!plugin->init(config->m_init_config, err)) {
|
||||||
|
return run_result::fatal(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(is_input) {
|
||||||
|
auto gen_check = src_info->inspector->new_generic_filtercheck();
|
||||||
|
src_info->filterchecks->add_filter_check(std::move(gen_check));
|
||||||
|
}
|
||||||
|
used_plugins.insert(plugin->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate filtercheck list for this inspector
|
// populate filtercheck list for this inspector
|
||||||
@ -221,20 +224,22 @@ falco::app::run_result falco::app::actions::init_inspectors(falco::app::state& s
|
|||||||
return run_result::fatal(err);
|
return run_result::fatal(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// in live mode, each inspector should have registered at most two event sources:
|
if(is_capture_mode) {
|
||||||
// the "syscall" on, loaded at default at index 0, and optionally another
|
continue;
|
||||||
// one defined by a plugin, at index 1
|
}
|
||||||
if(!s.is_capture_mode()) {
|
|
||||||
const auto& sources = src_info->inspector->event_sources();
|
// in live mode, each inspector should have registered at most two event sources: the
|
||||||
if(sources.size() == 0 || sources.size() > 2 ||
|
// "syscall" on, loaded at default at index 0, and optionally another one defined by a
|
||||||
sources[0] != falco_common::syscall_source) {
|
// plugin, at index 1
|
||||||
err.clear();
|
const auto& sources = src_info->inspector->event_sources();
|
||||||
for(const auto& source : sources) {
|
if(sources.size() == 0 || sources.size() > 2 ||
|
||||||
err += (err.empty() ? "" : ", ") + source;
|
sources[0] != falco_common::syscall_source) {
|
||||||
}
|
err.clear();
|
||||||
return run_result::fatal("Illegal sources setup in live inspector for source '" +
|
for(const auto& source : sources) {
|
||||||
src + "': " + err);
|
err += (err.empty() ? "" : ", ") + source;
|
||||||
}
|
}
|
||||||
|
return run_result::fatal("Illegal sources setup in live inspector for source '" + src +
|
||||||
|
"': " + err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,17 +21,18 @@ using namespace falco::app;
|
|||||||
using namespace falco::app::actions;
|
using namespace falco::app::actions;
|
||||||
|
|
||||||
falco::app::run_result falco::app::actions::list_fields(falco::app::state& s) {
|
falco::app::run_result falco::app::actions::list_fields(falco::app::state& s) {
|
||||||
if(s.options.list_fields) {
|
if(!s.options.list_fields) {
|
||||||
if(s.options.list_source_fields != "" &&
|
return run_result::ok();
|
||||||
!s.engine->is_source_valid(s.options.list_source_fields)) {
|
|
||||||
return run_result::fatal("Value for --list must be a valid source type");
|
|
||||||
}
|
|
||||||
s.engine->list_fields(s.options.list_source_fields,
|
|
||||||
s.options.verbose,
|
|
||||||
s.options.names_only,
|
|
||||||
s.options.markdown);
|
|
||||||
return run_result::exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return run_result::ok();
|
if(s.options.list_source_fields != "" &&
|
||||||
|
!s.engine->is_source_valid(s.options.list_source_fields)) {
|
||||||
|
return run_result::fatal("Value for --list must be a valid source type");
|
||||||
|
}
|
||||||
|
|
||||||
|
s.engine->list_fields(s.options.list_source_fields,
|
||||||
|
s.options.verbose,
|
||||||
|
s.options.names_only,
|
||||||
|
s.options.markdown);
|
||||||
|
return run_result::exit();
|
||||||
}
|
}
|
||||||
|
@ -24,20 +24,20 @@ using namespace falco::app;
|
|||||||
using namespace falco::app::actions;
|
using namespace falco::app::actions;
|
||||||
|
|
||||||
falco::app::run_result falco::app::actions::list_plugins(const falco::app::state& s) {
|
falco::app::run_result falco::app::actions::list_plugins(const falco::app::state& s) {
|
||||||
if(s.options.list_plugins) {
|
if(!s.options.list_plugins) {
|
||||||
std::ostringstream os;
|
return run_result::ok();
|
||||||
sinsp inspector;
|
|
||||||
const auto& configs = s.config->m_plugins;
|
|
||||||
for(auto& c : configs) {
|
|
||||||
// load the plugin (no need to initialize it)
|
|
||||||
auto plugin = inspector.register_plugin(c.m_library_path);
|
|
||||||
format_plugin_info(plugin, os);
|
|
||||||
os << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%lu Plugins Loaded:\n\n%s\n", configs.size(), os.str().c_str());
|
|
||||||
return run_result::exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return run_result::ok();
|
std::ostringstream os;
|
||||||
|
sinsp inspector;
|
||||||
|
const auto& configs = s.config->m_plugins;
|
||||||
|
for(auto& c : configs) {
|
||||||
|
// load the plugin (no need to initialize it)
|
||||||
|
auto plugin = inspector.register_plugin(c.m_library_path);
|
||||||
|
format_plugin_info(plugin, os);
|
||||||
|
os << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%lu Plugins Loaded:\n\n%s\n", configs.size(), os.str().c_str());
|
||||||
|
return run_result::exit();
|
||||||
}
|
}
|
||||||
|
@ -51,16 +51,18 @@ falco::app::run_result falco::app::actions::load_plugins(falco::app::state& s) {
|
|||||||
"Loading plugin '" + p.m_name + "' from file " + p.m_library_path + "\n");
|
"Loading plugin '" + p.m_name + "' from file " + p.m_library_path + "\n");
|
||||||
auto plugin = s.offline_inspector->register_plugin(p.m_library_path);
|
auto plugin = s.offline_inspector->register_plugin(p.m_library_path);
|
||||||
s.plugin_configs.insert(p, plugin->name());
|
s.plugin_configs.insert(p, plugin->name());
|
||||||
if(plugin->caps() & CAP_SOURCING && plugin->id() != 0) {
|
if((plugin->caps() & CAP_SOURCING) == 0 || plugin->id() == 0) {
|
||||||
state::source_info src_info;
|
continue;
|
||||||
src_info.filterchecks = std::make_shared<filter_check_list>();
|
}
|
||||||
auto sname = plugin->event_source();
|
// Account the plugin event source
|
||||||
s.source_infos.insert(src_info, sname);
|
state::source_info src_info;
|
||||||
// note: this avoids duplicate values
|
src_info.filterchecks = std::make_shared<filter_check_list>();
|
||||||
if(std::find(s.loaded_sources.begin(), s.loaded_sources.end(), sname) ==
|
auto src_name = plugin->event_source();
|
||||||
s.loaded_sources.end()) {
|
s.source_infos.insert(src_info, src_name);
|
||||||
s.loaded_sources.push_back(sname);
|
// note: this avoids duplicate values
|
||||||
}
|
if(std::find(s.loaded_sources.begin(), s.loaded_sources.end(), src_name) ==
|
||||||
|
s.loaded_sources.end()) {
|
||||||
|
s.loaded_sources.push_back(src_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,21 +30,23 @@ falco::app::run_result falco::app::actions::pidfile(const falco::app::state& sta
|
|||||||
return run_result::ok();
|
return run_result::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!state.options.pidfilename.empty()) {
|
if(state.options.pidfilename.empty()) {
|
||||||
int64_t self_pid = getpid();
|
return run_result::ok();
|
||||||
|
|
||||||
std::ofstream stream;
|
|
||||||
stream.open(state.options.pidfilename);
|
|
||||||
|
|
||||||
if(!stream.good()) {
|
|
||||||
falco_logger::log(
|
|
||||||
falco_logger::level::ERR,
|
|
||||||
"Could not write pid to pidfile " + state.options.pidfilename + ". Exiting.\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
stream << self_pid;
|
|
||||||
stream.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t self_pid = getpid();
|
||||||
|
|
||||||
|
std::ofstream stream;
|
||||||
|
stream.open(state.options.pidfilename);
|
||||||
|
|
||||||
|
if(!stream.good()) {
|
||||||
|
falco_logger::log(
|
||||||
|
falco_logger::level::ERR,
|
||||||
|
"Could not write pid to pidfile " + state.options.pidfilename + ". Exiting.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
stream << self_pid;
|
||||||
|
stream.close();
|
||||||
|
|
||||||
return run_result::ok();
|
return run_result::ok();
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,10 @@ using namespace falco::app;
|
|||||||
using namespace falco::app::actions;
|
using namespace falco::app::actions;
|
||||||
|
|
||||||
falco::app::run_result falco::app::actions::print_config_schema(falco::app::state &s) {
|
falco::app::run_result falco::app::actions::print_config_schema(falco::app::state &s) {
|
||||||
if(s.options.print_config_schema) {
|
if(!s.options.print_config_schema) {
|
||||||
printf("%s", s.config->m_config_schema.dump(2).c_str());
|
return run_result::ok();
|
||||||
return run_result::exit();
|
|
||||||
}
|
}
|
||||||
return run_result::ok();
|
|
||||||
|
printf("%s", s.config->m_config_schema.dump(2).c_str());
|
||||||
|
return run_result::exit();
|
||||||
}
|
}
|
||||||
|
@ -22,12 +22,13 @@ using namespace falco::app;
|
|||||||
using namespace falco::app::actions;
|
using namespace falco::app::actions;
|
||||||
|
|
||||||
falco::app::run_result falco::app::actions::print_generated_gvisor_config(falco::app::state& s) {
|
falco::app::run_result falco::app::actions::print_generated_gvisor_config(falco::app::state& s) {
|
||||||
if(!s.options.gvisor_generate_config_with_socket.empty()) {
|
if(s.options.gvisor_generate_config_with_socket.empty()) {
|
||||||
sinsp i;
|
return run_result::ok();
|
||||||
std::string gvisor_config =
|
|
||||||
i.generate_gvisor_config(s.options.gvisor_generate_config_with_socket);
|
|
||||||
printf("%s\n", gvisor_config.c_str());
|
|
||||||
return run_result::exit();
|
|
||||||
}
|
}
|
||||||
return run_result::ok();
|
|
||||||
|
sinsp i;
|
||||||
|
std::string gvisor_config =
|
||||||
|
i.generate_gvisor_config(s.options.gvisor_generate_config_with_socket);
|
||||||
|
printf("%s\n", gvisor_config.c_str());
|
||||||
|
return run_result::exit();
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,10 @@ using namespace falco::app;
|
|||||||
using namespace falco::app::actions;
|
using namespace falco::app::actions;
|
||||||
|
|
||||||
falco::app::run_result falco::app::actions::print_help(falco::app::state& s) {
|
falco::app::run_result falco::app::actions::print_help(falco::app::state& s) {
|
||||||
if(s.options.help) {
|
if(!s.options.help) {
|
||||||
printf("%s", s.options.usage().c_str());
|
return run_result::ok();
|
||||||
return run_result::exit();
|
|
||||||
}
|
}
|
||||||
return run_result::ok();
|
|
||||||
|
printf("%s", s.options.usage().c_str());
|
||||||
|
return run_result::exit();
|
||||||
}
|
}
|
||||||
|
@ -28,22 +28,25 @@ using namespace falco::app::actions;
|
|||||||
falco::app::run_result falco::app::actions::print_kernel_version(const falco::app::state& s) {
|
falco::app::run_result falco::app::actions::print_kernel_version(const falco::app::state& s) {
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
// We print this info only when a kernel driver is injected
|
// We print this info only when a kernel driver is injected
|
||||||
if(s.is_modern_ebpf() || s.is_ebpf() || s.is_kmod()) {
|
bool const is_kernel_driver_injected = s.is_modern_ebpf() || s.is_ebpf() || s.is_kmod();
|
||||||
std::ifstream input_file("/proc/version");
|
if(!is_kernel_driver_injected) {
|
||||||
if(!input_file.is_open()) {
|
return run_result::ok();
|
||||||
// We don't want to fail, we just need to log something
|
|
||||||
falco_logger::log(falco_logger::level::INFO,
|
|
||||||
"Cannot read under '/proc/version' (err_message: '" +
|
|
||||||
std::string(strerror(errno)) + "', err_code: " +
|
|
||||||
std::to_string(errno) + "). No info provided, go on.");
|
|
||||||
return run_result::ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream buffer;
|
|
||||||
buffer << input_file.rdbuf();
|
|
||||||
std::string contents(buffer.str());
|
|
||||||
falco_logger::log(falco_logger::level::INFO, "System info: " + contents);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ifstream input_file("/proc/version");
|
||||||
|
if(!input_file.is_open()) {
|
||||||
|
// We don't want to fail, we just need to log something
|
||||||
|
falco_logger::log(
|
||||||
|
falco_logger::level::INFO,
|
||||||
|
"Cannot read under '/proc/version' (err_message: '" + std::string(strerror(errno)) +
|
||||||
|
"', err_code: " + std::to_string(errno) + "). No info provided, go on.");
|
||||||
|
return run_result::ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream buffer;
|
||||||
|
buffer << input_file.rdbuf();
|
||||||
|
std::string contents(buffer.str());
|
||||||
|
falco_logger::log(falco_logger::level::INFO, "System info: " + contents);
|
||||||
#endif
|
#endif
|
||||||
return run_result::ok();
|
return run_result::ok();
|
||||||
}
|
}
|
||||||
|
@ -24,25 +24,24 @@ using namespace falco::app;
|
|||||||
using namespace falco::app::actions;
|
using namespace falco::app::actions;
|
||||||
|
|
||||||
falco::app::run_result falco::app::actions::print_page_size(const falco::app::state& s) {
|
falco::app::run_result falco::app::actions::print_page_size(const falco::app::state& s) {
|
||||||
if(s.options.print_page_size) {
|
if(!s.options.print_page_size) {
|
||||||
#ifndef _WIN32
|
return run_result::ok();
|
||||||
long page_size = getpagesize();
|
|
||||||
#else
|
|
||||||
SYSTEM_INFO sysInfo;
|
|
||||||
|
|
||||||
GetSystemInfo(&sysInfo);
|
|
||||||
|
|
||||||
long page_size = sysInfo.dwPageSize;
|
|
||||||
#endif
|
|
||||||
if(page_size <= 0) {
|
|
||||||
return run_result::fatal(
|
|
||||||
"\nUnable to get the system page size through 'getpagesize()'\n");
|
|
||||||
} else {
|
|
||||||
falco_logger::log(
|
|
||||||
falco_logger::level::INFO,
|
|
||||||
"Your system page size is: " + std::to_string(page_size) + " bytes\n");
|
|
||||||
}
|
|
||||||
return run_result::exit();
|
|
||||||
}
|
}
|
||||||
return run_result::ok();
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
long page_size = getpagesize();
|
||||||
|
#else
|
||||||
|
SYSTEM_INFO sysInfo;
|
||||||
|
|
||||||
|
GetSystemInfo(&sysInfo);
|
||||||
|
|
||||||
|
long page_size = sysInfo.dwPageSize;
|
||||||
|
#endif
|
||||||
|
if(page_size <= 0) {
|
||||||
|
return run_result::fatal("\nUnable to get the system page size through 'getpagesize()'\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
falco_logger::log(falco_logger::level::INFO,
|
||||||
|
"Your system page size is: " + std::to_string(page_size) + " bytes\n");
|
||||||
|
return run_result::exit();
|
||||||
}
|
}
|
||||||
|
@ -24,78 +24,81 @@ using namespace falco::app;
|
|||||||
using namespace falco::app::actions;
|
using namespace falco::app::actions;
|
||||||
|
|
||||||
falco::app::run_result falco::app::actions::print_plugin_info(const falco::app::state &s) {
|
falco::app::run_result falco::app::actions::print_plugin_info(const falco::app::state &s) {
|
||||||
if(!s.options.print_plugin_info.empty()) {
|
if(s.options.print_plugin_info.empty()) {
|
||||||
sinsp inspector;
|
return run_result::ok();
|
||||||
for(auto &pc : s.config->m_plugins) {
|
|
||||||
if(pc.m_name == s.options.print_plugin_info ||
|
|
||||||
pc.m_library_path == s.options.print_plugin_info) {
|
|
||||||
// load the plugin
|
|
||||||
auto p = inspector.register_plugin(pc.m_library_path);
|
|
||||||
|
|
||||||
// print plugin descriptive info
|
|
||||||
std::ostringstream os;
|
|
||||||
format_plugin_info(p, os);
|
|
||||||
os << std::endl;
|
|
||||||
printf("%s", os.str().c_str());
|
|
||||||
|
|
||||||
// print plugin init schema
|
|
||||||
os.str("");
|
|
||||||
os.clear();
|
|
||||||
ss_plugin_schema_type type;
|
|
||||||
auto schema = p->get_init_schema(type);
|
|
||||||
os << "Init config schema type: ";
|
|
||||||
switch(type) {
|
|
||||||
case SS_PLUGIN_SCHEMA_JSON:
|
|
||||||
os << "JSON" << std::endl;
|
|
||||||
break;
|
|
||||||
case SS_PLUGIN_SCHEMA_NONE:
|
|
||||||
default:
|
|
||||||
os << "Not available, plugin does not implement the init config schema "
|
|
||||||
"functionality"
|
|
||||||
<< std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
os << schema << std::endl;
|
|
||||||
os << std::endl;
|
|
||||||
printf("%s", os.str().c_str());
|
|
||||||
|
|
||||||
// init the plugin
|
|
||||||
std::string err;
|
|
||||||
if(!p->init(pc.m_init_config, err)) {
|
|
||||||
return run_result::fatal(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
// print plugin suggested open parameters
|
|
||||||
if(p->caps() & CAP_SOURCING) {
|
|
||||||
os.str("");
|
|
||||||
os.clear();
|
|
||||||
auto params = p->list_open_params();
|
|
||||||
if(params.empty()) {
|
|
||||||
os << "No suggested open params available: ";
|
|
||||||
os << "plugin has not been configured, or it does not implement the open "
|
|
||||||
"params suggestion functionality"
|
|
||||||
<< std::endl;
|
|
||||||
} else {
|
|
||||||
os << "Suggested open params:" << std::endl;
|
|
||||||
for(const auto &oparam : p->list_open_params()) {
|
|
||||||
if(oparam.desc == "") {
|
|
||||||
os << oparam.value << std::endl;
|
|
||||||
} else {
|
|
||||||
os << oparam.value << ": " << oparam.desc << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
os << std::endl;
|
|
||||||
printf("%s", os.str().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// exit
|
|
||||||
return run_result::exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return run_result::fatal("can't find plugin and print its info: " +
|
|
||||||
s.options.print_plugin_info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return run_result::ok();
|
sinsp inspector;
|
||||||
|
for(auto &pc : s.config->m_plugins) {
|
||||||
|
if(pc.m_name != s.options.print_plugin_info &&
|
||||||
|
pc.m_library_path != s.options.print_plugin_info) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// found matching plugin; load it
|
||||||
|
auto p = inspector.register_plugin(pc.m_library_path);
|
||||||
|
|
||||||
|
// print plugin descriptive info
|
||||||
|
std::ostringstream os;
|
||||||
|
format_plugin_info(p, os);
|
||||||
|
os << std::endl;
|
||||||
|
printf("%s", os.str().c_str());
|
||||||
|
|
||||||
|
// print plugin init schema
|
||||||
|
os.str("");
|
||||||
|
os.clear();
|
||||||
|
ss_plugin_schema_type type;
|
||||||
|
auto schema = p->get_init_schema(type);
|
||||||
|
os << "Init config schema type: ";
|
||||||
|
switch(type) {
|
||||||
|
case SS_PLUGIN_SCHEMA_JSON:
|
||||||
|
os << "JSON" << std::endl;
|
||||||
|
break;
|
||||||
|
case SS_PLUGIN_SCHEMA_NONE:
|
||||||
|
default:
|
||||||
|
os << "Not available, plugin does not implement the init config schema "
|
||||||
|
"functionality"
|
||||||
|
<< std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
os << schema << std::endl;
|
||||||
|
os << std::endl;
|
||||||
|
printf("%s", os.str().c_str());
|
||||||
|
|
||||||
|
// init the plugin
|
||||||
|
std::string err;
|
||||||
|
if(!p->init(pc.m_init_config, err)) {
|
||||||
|
return run_result::fatal(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// print plugin suggested open parameters
|
||||||
|
if(p->caps() & CAP_SOURCING) {
|
||||||
|
os.str("");
|
||||||
|
os.clear();
|
||||||
|
auto params = p->list_open_params();
|
||||||
|
if(params.empty()) {
|
||||||
|
os << "No suggested open params available: ";
|
||||||
|
os << "plugin has not been configured, or it does not implement the open "
|
||||||
|
"params suggestion functionality"
|
||||||
|
<< std::endl;
|
||||||
|
} else {
|
||||||
|
os << "Suggested open params:" << std::endl;
|
||||||
|
for(const auto &oparam : p->list_open_params()) {
|
||||||
|
if(oparam.desc == "") {
|
||||||
|
os << oparam.value << std::endl;
|
||||||
|
} else {
|
||||||
|
os << oparam.value << ": " << oparam.desc << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os << std::endl;
|
||||||
|
printf("%s", os.str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// exit
|
||||||
|
return run_result::exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return run_result::fatal("can't find plugin and print its info: " +
|
||||||
|
s.options.print_plugin_info);
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,10 @@ using namespace falco::app;
|
|||||||
using namespace falco::app::actions;
|
using namespace falco::app::actions;
|
||||||
|
|
||||||
falco::app::run_result falco::app::actions::print_rule_schema(falco::app::state &s) {
|
falco::app::run_result falco::app::actions::print_rule_schema(falco::app::state &s) {
|
||||||
if(s.options.print_rule_schema) {
|
if(!s.options.print_rule_schema) {
|
||||||
printf("%s", s.engine->m_rule_schema.dump(2).c_str());
|
return run_result::ok();
|
||||||
return run_result::exit();
|
|
||||||
}
|
}
|
||||||
return run_result::ok();
|
|
||||||
|
printf("%s", s.engine->m_rule_schema.dump(2).c_str());
|
||||||
|
return run_result::exit();
|
||||||
}
|
}
|
||||||
|
@ -88,31 +88,30 @@ static int get_sysinfo(nlohmann::json& support) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
falco::app::run_result falco::app::actions::print_support(falco::app::state& s) {
|
falco::app::run_result falco::app::actions::print_support(falco::app::state& s) {
|
||||||
if(s.options.print_support) {
|
if(!s.options.print_support) {
|
||||||
nlohmann::json support;
|
return run_result::ok();
|
||||||
|
|
||||||
if(get_sysinfo(support) != 0) {
|
|
||||||
return run_result::fatal(std::string("Could not get system info: ") + strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
const falco::versions_info infos(s.offline_inspector);
|
|
||||||
support["version"] = infos.falco_version;
|
|
||||||
support["engine_info"] = infos.as_json();
|
|
||||||
support["cmdline"] = s.cmdline;
|
|
||||||
support["config"] = s.config->dump();
|
|
||||||
support["rules_files"] = nlohmann::json::array();
|
|
||||||
for(const auto& filename : s.config->m_loaded_rules_filenames) {
|
|
||||||
nlohmann::json finfo;
|
|
||||||
finfo["name"] = filename;
|
|
||||||
nlohmann::json variant;
|
|
||||||
variant["content"] = read_file(filename);
|
|
||||||
finfo["variants"].push_back(variant);
|
|
||||||
support["rules_files"].push_back(finfo);
|
|
||||||
}
|
|
||||||
printf("%s\n", support.dump().c_str());
|
|
||||||
|
|
||||||
return run_result::exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return run_result::ok();
|
nlohmann::json support;
|
||||||
|
|
||||||
|
if(get_sysinfo(support) != 0) {
|
||||||
|
return run_result::fatal(std::string("Could not get system info: ") + strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
const falco::versions_info infos(s.offline_inspector);
|
||||||
|
support["version"] = infos.falco_version;
|
||||||
|
support["engine_info"] = infos.as_json();
|
||||||
|
support["cmdline"] = s.cmdline;
|
||||||
|
support["config"] = s.config->dump();
|
||||||
|
support["rules_files"] = nlohmann::json::array();
|
||||||
|
for(const auto& filename : s.config->m_loaded_rules_filenames) {
|
||||||
|
nlohmann::json finfo;
|
||||||
|
finfo["name"] = filename;
|
||||||
|
nlohmann::json variant;
|
||||||
|
variant["content"] = read_file(filename);
|
||||||
|
finfo["variants"].push_back(variant);
|
||||||
|
support["rules_files"].push_back(finfo);
|
||||||
|
}
|
||||||
|
printf("%s\n", support.dump().c_str());
|
||||||
|
return run_result::exit();
|
||||||
}
|
}
|
||||||
|
@ -157,30 +157,29 @@ static void print_events(const std::vector<event_entry>& events, bool markdown)
|
|||||||
}
|
}
|
||||||
|
|
||||||
falco::app::run_result falco::app::actions::print_syscall_events(falco::app::state& s) {
|
falco::app::run_result falco::app::actions::print_syscall_events(falco::app::state& s) {
|
||||||
if(s.options.list_syscall_events) {
|
if(!s.options.list_syscall_events) {
|
||||||
const falco::versions_info info(s.offline_inspector);
|
return run_result::ok();
|
||||||
printf("The events below are valid for Falco *Schema Version*: %s\n",
|
|
||||||
info.driver_schema_version.c_str());
|
|
||||||
|
|
||||||
const libsinsp::events::set<ppm_event_code> available =
|
|
||||||
libsinsp::events::all_event_set().diff(
|
|
||||||
sc_set_to_event_set(falco::app::ignored_sc_set()));
|
|
||||||
const struct events_by_category events_bc = get_event_entries_by_category(true, available);
|
|
||||||
|
|
||||||
printf("## Syscall events\n\n");
|
|
||||||
print_events(events_bc.syscalls, s.options.markdown);
|
|
||||||
|
|
||||||
printf("\n\n## Tracepoint events\n\n");
|
|
||||||
print_events(events_bc.tracepoints, s.options.markdown);
|
|
||||||
|
|
||||||
printf("\n\n## Plugin events\n\n");
|
|
||||||
print_events(events_bc.pluginevents, s.options.markdown);
|
|
||||||
|
|
||||||
printf("\n\n## Metaevents\n\n");
|
|
||||||
print_events(events_bc.metaevents, s.options.markdown);
|
|
||||||
|
|
||||||
return run_result::exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return run_result::ok();
|
const falco::versions_info info(s.offline_inspector);
|
||||||
|
printf("The events below are valid for Falco *Schema Version*: %s\n",
|
||||||
|
info.driver_schema_version.c_str());
|
||||||
|
|
||||||
|
const libsinsp::events::set<ppm_event_code> available = libsinsp::events::all_event_set().diff(
|
||||||
|
sc_set_to_event_set(falco::app::ignored_sc_set()));
|
||||||
|
const struct events_by_category events_bc = get_event_entries_by_category(true, available);
|
||||||
|
|
||||||
|
printf("## Syscall events\n\n");
|
||||||
|
print_events(events_bc.syscalls, s.options.markdown);
|
||||||
|
|
||||||
|
printf("\n\n## Tracepoint events\n\n");
|
||||||
|
print_events(events_bc.tracepoints, s.options.markdown);
|
||||||
|
|
||||||
|
printf("\n\n## Plugin events\n\n");
|
||||||
|
print_events(events_bc.pluginevents, s.options.markdown);
|
||||||
|
|
||||||
|
printf("\n\n## Metaevents\n\n");
|
||||||
|
print_events(events_bc.metaevents, s.options.markdown);
|
||||||
|
|
||||||
|
return run_result::exit();
|
||||||
}
|
}
|
||||||
|
@ -22,22 +22,22 @@ using namespace falco::app;
|
|||||||
using namespace falco::app::actions;
|
using namespace falco::app::actions;
|
||||||
|
|
||||||
falco::app::run_result falco::app::actions::print_version(falco::app::state& s) {
|
falco::app::run_result falco::app::actions::print_version(falco::app::state& s) {
|
||||||
if(s.options.print_version_info) {
|
if(!s.options.print_version_info) {
|
||||||
const falco::versions_info info(s.offline_inspector);
|
return run_result::ok();
|
||||||
if(s.config->m_json_output) {
|
|
||||||
printf("%s\n", info.as_json().dump().c_str());
|
|
||||||
} else {
|
|
||||||
printf("Falco version: %s\n", info.falco_version.c_str());
|
|
||||||
printf("Libs version: %s\n", info.libs_version.c_str());
|
|
||||||
printf("Plugin API: %s\n", info.plugin_api_version.c_str());
|
|
||||||
printf("Engine: %s\n", info.engine_version.c_str());
|
|
||||||
printf("Driver:\n");
|
|
||||||
printf(" API version: %s\n", info.driver_api_version.c_str());
|
|
||||||
printf(" Schema version: %s\n", info.driver_schema_version.c_str());
|
|
||||||
printf(" Default driver: %s\n", info.default_driver_version.c_str());
|
|
||||||
}
|
|
||||||
return run_result::exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return run_result::ok();
|
const falco::versions_info info(s.offline_inspector);
|
||||||
|
if(s.config->m_json_output) {
|
||||||
|
printf("%s\n", info.as_json().dump().c_str());
|
||||||
|
} else {
|
||||||
|
printf("Falco version: %s\n", info.falco_version.c_str());
|
||||||
|
printf("Libs version: %s\n", info.libs_version.c_str());
|
||||||
|
printf("Plugin API: %s\n", info.plugin_api_version.c_str());
|
||||||
|
printf("Engine: %s\n", info.engine_version.c_str());
|
||||||
|
printf("Driver:\n");
|
||||||
|
printf(" API version: %s\n", info.driver_api_version.c_str());
|
||||||
|
printf(" Schema version: %s\n", info.driver_schema_version.c_str());
|
||||||
|
printf(" Default driver: %s\n", info.default_driver_version.c_str());
|
||||||
|
}
|
||||||
|
return run_result::exit();
|
||||||
}
|
}
|
||||||
|
@ -27,44 +27,46 @@ using namespace falco::app::actions;
|
|||||||
falco::app::run_result falco::app::actions::start_grpc_server(falco::app::state& s) {
|
falco::app::run_result falco::app::actions::start_grpc_server(falco::app::state& s) {
|
||||||
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||||
// gRPC server
|
// gRPC server
|
||||||
if(s.config->m_grpc_enabled) {
|
if(!s.config->m_grpc_enabled) {
|
||||||
if(s.options.dry_run) {
|
return run_result::ok();
|
||||||
falco_logger::log(falco_logger::level::DEBUG,
|
|
||||||
"Skipping starting gRPC server in dry-run\n");
|
|
||||||
return run_result::ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
falco_logger::log(falco_logger::level::INFO,
|
|
||||||
"gRPC server threadiness equals to " +
|
|
||||||
std::to_string(s.config->m_grpc_threadiness) + "\n");
|
|
||||||
// TODO(fntlnz,leodido): when we want to spawn multiple threads we need to have a queue per
|
|
||||||
// thread, or implement different queuing mechanisms, round robin, fanout? What we want to
|
|
||||||
// achieve?
|
|
||||||
s.grpc_server.init(s.config->m_grpc_bind_address,
|
|
||||||
s.config->m_grpc_threadiness,
|
|
||||||
s.config->m_grpc_private_key,
|
|
||||||
s.config->m_grpc_cert_chain,
|
|
||||||
s.config->m_grpc_root_certs,
|
|
||||||
s.config->m_log_level);
|
|
||||||
s.grpc_server_thread = std::thread([&s] { s.grpc_server.run(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(s.options.dry_run) {
|
||||||
|
falco_logger::log(falco_logger::level::DEBUG, "Skipping starting gRPC server in dry-run\n");
|
||||||
|
return run_result::ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
falco_logger::log(falco_logger::level::INFO,
|
||||||
|
"gRPC server threadiness equals to " +
|
||||||
|
std::to_string(s.config->m_grpc_threadiness) + "\n");
|
||||||
|
// TODO(fntlnz,leodido): when we want to spawn multiple threads we need to have a queue per
|
||||||
|
// thread, or implement different queuing mechanisms, round robin, fanout? What we want to
|
||||||
|
// achieve?
|
||||||
|
s.grpc_server.init(s.config->m_grpc_bind_address,
|
||||||
|
s.config->m_grpc_threadiness,
|
||||||
|
s.config->m_grpc_private_key,
|
||||||
|
s.config->m_grpc_cert_chain,
|
||||||
|
s.config->m_grpc_root_certs,
|
||||||
|
s.config->m_log_level);
|
||||||
|
s.grpc_server_thread = std::thread([&s] { s.grpc_server.run(); });
|
||||||
#endif
|
#endif
|
||||||
return run_result::ok();
|
return run_result::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
falco::app::run_result falco::app::actions::stop_grpc_server(falco::app::state& s) {
|
falco::app::run_result falco::app::actions::stop_grpc_server(falco::app::state& s) {
|
||||||
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||||
if(s.config->m_grpc_enabled) {
|
if(!s.config->m_grpc_enabled) {
|
||||||
if(s.options.dry_run) {
|
return run_result::ok();
|
||||||
falco_logger::log(falco_logger::level::DEBUG,
|
}
|
||||||
"Skipping stopping gRPC server in dry-run\n");
|
|
||||||
return run_result::ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(s.grpc_server_thread.joinable()) {
|
if(s.options.dry_run) {
|
||||||
s.grpc_server.shutdown();
|
falco_logger::log(falco_logger::level::DEBUG, "Skipping stopping gRPC server in dry-run\n");
|
||||||
s.grpc_server_thread.join();
|
return run_result::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(s.grpc_server_thread.joinable()) {
|
||||||
|
s.grpc_server.shutdown();
|
||||||
|
s.grpc_server_thread.join();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return run_result::ok();
|
return run_result::ok();
|
||||||
|
@ -26,39 +26,40 @@ using namespace falco::app::actions;
|
|||||||
|
|
||||||
falco::app::run_result falco::app::actions::start_webserver(falco::app::state& state) {
|
falco::app::run_result falco::app::actions::start_webserver(falco::app::state& state) {
|
||||||
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||||
if(!state.is_capture_mode() && state.config->m_webserver_enabled) {
|
if(state.is_capture_mode() || !state.config->m_webserver_enabled) {
|
||||||
if(state.options.dry_run) {
|
return run_result::ok();
|
||||||
falco_logger::log(falco_logger::level::DEBUG,
|
|
||||||
"Skipping starting webserver in dry-run\n");
|
|
||||||
return run_result::ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
falco_configuration::webserver_config webserver_config = state.config->m_webserver_config;
|
|
||||||
std::string ssl_option = (webserver_config.m_ssl_enabled ? " (SSL)" : "");
|
|
||||||
falco_logger::log(falco_logger::level::INFO,
|
|
||||||
"Starting health webserver with threadiness " +
|
|
||||||
std::to_string(webserver_config.m_threadiness) +
|
|
||||||
", listening on " + webserver_config.m_listen_address + ":" +
|
|
||||||
std::to_string(webserver_config.m_listen_port) + ssl_option +
|
|
||||||
"\n");
|
|
||||||
|
|
||||||
state.webserver.start(state, webserver_config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(state.options.dry_run) {
|
||||||
|
falco_logger::log(falco_logger::level::DEBUG, "Skipping starting webserver in dry-run\n");
|
||||||
|
return run_result::ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
falco_configuration::webserver_config webserver_config = state.config->m_webserver_config;
|
||||||
|
std::string ssl_option = (webserver_config.m_ssl_enabled ? " (SSL)" : "");
|
||||||
|
falco_logger::log(falco_logger::level::INFO,
|
||||||
|
"Starting health webserver with threadiness " +
|
||||||
|
std::to_string(webserver_config.m_threadiness) + ", listening on " +
|
||||||
|
webserver_config.m_listen_address + ":" +
|
||||||
|
std::to_string(webserver_config.m_listen_port) + ssl_option + "\n");
|
||||||
|
|
||||||
|
state.webserver.start(state, webserver_config);
|
||||||
#endif
|
#endif
|
||||||
return run_result::ok();
|
return run_result::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
falco::app::run_result falco::app::actions::stop_webserver(falco::app::state& state) {
|
falco::app::run_result falco::app::actions::stop_webserver(falco::app::state& state) {
|
||||||
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
|
||||||
if(!state.is_capture_mode() && state.config->m_webserver_enabled) {
|
if(state.is_capture_mode() || !state.config->m_webserver_enabled) {
|
||||||
if(state.options.dry_run) {
|
return run_result::ok();
|
||||||
falco_logger::log(falco_logger::level::DEBUG,
|
|
||||||
"Skipping stopping webserver in dry-run\n");
|
|
||||||
return run_result::ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
state.webserver.stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(state.options.dry_run) {
|
||||||
|
falco_logger::log(falco_logger::level::DEBUG, "Skipping stopping webserver in dry-run\n");
|
||||||
|
return run_result::ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
state.webserver.stop();
|
||||||
#endif
|
#endif
|
||||||
return run_result::ok();
|
return run_result::ok();
|
||||||
}
|
}
|
||||||
|
@ -26,115 +26,113 @@ using namespace falco::app;
|
|||||||
using namespace falco::app::actions;
|
using namespace falco::app::actions;
|
||||||
|
|
||||||
falco::app::run_result falco::app::actions::validate_rules_files(falco::app::state& s) {
|
falco::app::run_result falco::app::actions::validate_rules_files(falco::app::state& s) {
|
||||||
if(s.options.validate_rules_filenames.size() > 0) {
|
if(s.options.validate_rules_filenames.size() == 0) {
|
||||||
std::vector<std::string> rules_contents;
|
return run_result::ok();
|
||||||
falco::load_result::rules_contents_t rc;
|
}
|
||||||
|
|
||||||
try {
|
std::vector<std::string> rules_contents;
|
||||||
read_files(s.options.validate_rules_filenames.begin(),
|
falco::load_result::rules_contents_t rc;
|
||||||
s.options.validate_rules_filenames.end(),
|
|
||||||
rules_contents,
|
try {
|
||||||
rc);
|
read_files(s.options.validate_rules_filenames.begin(),
|
||||||
} catch(falco_exception& e) {
|
s.options.validate_rules_filenames.end(),
|
||||||
return run_result::fatal(e.what());
|
rules_contents,
|
||||||
|
rc);
|
||||||
|
} catch(falco_exception& e) {
|
||||||
|
return run_result::fatal(e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool successful = true;
|
||||||
|
|
||||||
|
// The validation result is *always* printed to
|
||||||
|
// stdout. When json_output is true, the output is in
|
||||||
|
// json format and contains all errors/warnings for
|
||||||
|
// all files.
|
||||||
|
//
|
||||||
|
|
||||||
|
// When json_output is false, it contains a summary of
|
||||||
|
// each file and whether it was valid or not, along
|
||||||
|
// with any errors. To match older falco behavior,
|
||||||
|
// this *only* contains errors.
|
||||||
|
//
|
||||||
|
// So for each file stdout will contain:
|
||||||
|
//
|
||||||
|
// <filename>: Ok
|
||||||
|
// or
|
||||||
|
// <filename>: Invalid
|
||||||
|
// [All Validation Errors]
|
||||||
|
//
|
||||||
|
// Warnings are only printed to stderr, and only
|
||||||
|
// printed when verbose is true.
|
||||||
|
std::string summary;
|
||||||
|
|
||||||
|
falco_logger::log(falco_logger::level::INFO, "Validating rules file(s):\n");
|
||||||
|
for(const auto& file : s.options.validate_rules_filenames) {
|
||||||
|
falco_logger::log(falco_logger::level::INFO, " " + file + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// The json output encompasses all files so the
|
||||||
|
// validation result is a single json object.
|
||||||
|
std::string err = "";
|
||||||
|
nlohmann::json results = nlohmann::json::array();
|
||||||
|
|
||||||
|
for(auto& filename : s.options.validate_rules_filenames) {
|
||||||
|
std::unique_ptr<falco::load_result> res;
|
||||||
|
|
||||||
|
res = s.engine->load_rules(rc.at(filename), filename);
|
||||||
|
if(!check_rules_plugin_requirements(s, err)) {
|
||||||
|
return run_result::fatal(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool successful = true;
|
successful &= res->successful();
|
||||||
|
|
||||||
// The validation result is *always* printed to
|
|
||||||
// stdout. When json_output is true, the output is in
|
|
||||||
// json format and contains all errors/warnings for
|
|
||||||
// all files.
|
|
||||||
//
|
|
||||||
|
|
||||||
// When json_output is false, it contains a summary of
|
|
||||||
// each file and whether it was valid or not, along
|
|
||||||
// with any errors. To match older falco behavior,
|
|
||||||
// this *only* contains errors.
|
|
||||||
//
|
|
||||||
// So for each file stdout will contain:
|
|
||||||
//
|
|
||||||
// <filename>: Ok
|
|
||||||
// or
|
|
||||||
// <filename>: Invalid
|
|
||||||
// [All Validation Errors]
|
|
||||||
//
|
|
||||||
// Warnings are only printed to stderr, and only
|
|
||||||
// printed when verbose is true.
|
|
||||||
std::string summary;
|
|
||||||
|
|
||||||
falco_logger::log(falco_logger::level::INFO, "Validating rules file(s):\n");
|
|
||||||
for(const auto& file : s.options.validate_rules_filenames) {
|
|
||||||
falco_logger::log(falco_logger::level::INFO, " " + file + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// The json output encompasses all files so the
|
|
||||||
// validation result is a single json object.
|
|
||||||
std::string err = "";
|
|
||||||
nlohmann::json results = nlohmann::json::array();
|
|
||||||
|
|
||||||
for(auto& filename : s.options.validate_rules_filenames) {
|
|
||||||
std::unique_ptr<falco::load_result> res;
|
|
||||||
|
|
||||||
res = s.engine->load_rules(rc.at(filename), filename);
|
|
||||||
if(!check_rules_plugin_requirements(s, err)) {
|
|
||||||
return run_result::fatal(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
successful &= res->successful();
|
|
||||||
|
|
||||||
if(s.config->m_json_output) {
|
|
||||||
results.push_back(res->as_json(rc));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(summary != "") {
|
|
||||||
summary += "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add to the summary if not successful, or successful
|
|
||||||
// with no warnings.
|
|
||||||
if(!res->successful() || (res->successful() && !res->has_warnings())) {
|
|
||||||
summary += res->as_string(true, rc);
|
|
||||||
} else {
|
|
||||||
// If here, there must be only warnings.
|
|
||||||
// Add a line to the summary noting that the
|
|
||||||
// file was ok with warnings, without actually
|
|
||||||
// printing the warnings.
|
|
||||||
summary += filename + ": Ok, with warnings";
|
|
||||||
falco_logger::log(falco_logger::level::WARNING, res->as_string(true, rc) + "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// printout of `-L` option
|
|
||||||
nlohmann::json describe_res;
|
|
||||||
if(successful && (s.options.describe_all_rules || !s.options.describe_rule.empty())) {
|
|
||||||
std::string* rptr =
|
|
||||||
!s.options.describe_rule.empty() ? &(s.options.describe_rule) : nullptr;
|
|
||||||
const auto& plugins = s.offline_inspector->get_plugin_manager()->plugins();
|
|
||||||
describe_res = s.engine->describe_rule(rptr, plugins);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(s.config->m_json_output) {
|
if(s.config->m_json_output) {
|
||||||
nlohmann::json res;
|
results.push_back(res->as_json(rc));
|
||||||
res["falco_load_results"] = results;
|
|
||||||
if(!describe_res.empty() && successful) {
|
|
||||||
res["falco_describe_results"] = std::move(describe_res);
|
|
||||||
}
|
|
||||||
std::cout << res.dump() << std::endl;
|
|
||||||
} else {
|
|
||||||
std::cout << summary << std::endl;
|
|
||||||
if(!describe_res.empty() && successful) {
|
|
||||||
std::cout << std::endl;
|
|
||||||
format_described_rules_as_text(describe_res, std::cout);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(successful) {
|
if(summary != "") {
|
||||||
return run_result::exit();
|
summary += "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to the summary if not successful, or successful
|
||||||
|
// with no warnings.
|
||||||
|
if(!res->successful() || (res->successful() && !res->has_warnings())) {
|
||||||
|
summary += res->as_string(true, rc);
|
||||||
} else {
|
} else {
|
||||||
return run_result::fatal(summary);
|
// If here, there must be only warnings.
|
||||||
|
// Add a line to the summary noting that the
|
||||||
|
// file was ok with warnings, without actually
|
||||||
|
// printing the warnings.
|
||||||
|
summary += filename + ": Ok, with warnings";
|
||||||
|
falco_logger::log(falco_logger::level::WARNING, res->as_string(true, rc) + "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return run_result::ok();
|
// printout of `-L` option
|
||||||
|
nlohmann::json describe_res;
|
||||||
|
if(successful && (s.options.describe_all_rules || !s.options.describe_rule.empty())) {
|
||||||
|
std::string* rptr = !s.options.describe_rule.empty() ? &(s.options.describe_rule) : nullptr;
|
||||||
|
const auto& plugins = s.offline_inspector->get_plugin_manager()->plugins();
|
||||||
|
describe_res = s.engine->describe_rule(rptr, plugins);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(s.config->m_json_output) {
|
||||||
|
nlohmann::json res;
|
||||||
|
res["falco_load_results"] = results;
|
||||||
|
if(!describe_res.empty() && successful) {
|
||||||
|
res["falco_describe_results"] = std::move(describe_res);
|
||||||
|
}
|
||||||
|
std::cout << res.dump() << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << summary << std::endl;
|
||||||
|
if(!describe_res.empty() && successful) {
|
||||||
|
std::cout << std::endl;
|
||||||
|
format_described_rules_as_text(describe_res, std::cout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!successful) {
|
||||||
|
return run_result::fatal(summary);
|
||||||
|
}
|
||||||
|
return run_result::exit();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user