new(userspace/falco): add action and option to print detailed plugin info

Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
This commit is contained in:
Jason Dellaluce 2022-06-10 11:48:04 +00:00 committed by poiana
parent 625201f9f6
commit eb365f1a3e
7 changed files with 137 additions and 15 deletions

View File

@ -32,6 +32,7 @@ set(
app_actions/process_events.cpp
app_actions/print_help.cpp
app_actions/print_ignored_events.cpp
app_actions/print_plugin_info.cpp
app_actions/print_support.cpp
app_actions/print_version.cpp
app_actions/start_grpc_server.cpp

View File

@ -27,21 +27,7 @@ application::run_result application::list_plugins()
const auto &plugins = m_state->inspector->get_plugin_manager()->plugins();
for (auto &p : plugins)
{
os << "Name: " << p->name() << std::endl;
os << "Description: " << p->description() << std::endl;
os << "Contact: " << p->contact() << std::endl;
os << "Version: " << p->plugin_version().as_string() << std::endl;
os << "Capabilities: " << std::endl;
if(p->caps() & CAP_SOURCING)
{
os << " - Event Sourcing (ID=" << p->id();
os << ", source='" << p->event_source() << "')" << std::endl;
}
if(p->caps() & CAP_EXTRACTION)
{
os << " - Field Extraction" << std::endl;
}
format_plugin_info(p, os);
os << std::endl;
}

View File

@ -0,0 +1,130 @@
/*
Copyright (C) 2022 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "application.h"
#include <plugin_manager.h>
using namespace falco::app;
void application::format_plugin_info(std::shared_ptr<sinsp_plugin> p, std::ostream& os) const
{
os << "Name: " << p->name() << std::endl;
os << "Description: " << p->description() << std::endl;
os << "Contact: " << p->contact() << std::endl;
os << "Version: " << p->plugin_version().as_string() << std::endl;
os << "Capabilities: " << std::endl;
if(p->caps() & CAP_SOURCING)
{
os << " - Event Sourcing (ID=" << p->id();
os << ", source='" << p->event_source() << "')" << std::endl;
}
if(p->caps() & CAP_EXTRACTION)
{
os << " - Field Extraction" << std::endl;
}
}
application::run_result application::print_plugin_info()
{
#ifdef MUSL_OPTIMIZED
if(!m_options.print_plugin_info.empty())
{
return run_result::fatal("Can not load or use plugins with musl optimized build");
}
#else // MUSL_OPTIMIZED
if(!m_options.print_plugin_info.empty())
{
for(auto &pc : m_state->config->m_plugins)
{
if (pc.m_name == m_options.print_plugin_info
|| pc.m_library_path == m_options.print_plugin_info)
{
// load the plugin
auto p = m_state->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(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: " + m_options.print_plugin_info);
}
#endif // MUSL_OPTIMIZED
return run_result::ok();
}

View File

@ -182,6 +182,7 @@ void cmdline_options::define()
("markdown", "When used with --list/--list-syscall-events, print the content in Markdown format", cxxopts::value<bool>(markdown))
("N", "When used with --list, only print field names.", cxxopts::value(names_only)->default_value("false"))
("o,option", "Set the value of option <opt> to <val>. Overrides values in configuration file. <opt> can be identified using its location in configuration file using dot notation. Elements which are entries of lists can be accessed via square brackets [].\n E.g. base.id = val\n base.subvalue.subvalue2 = val\n base.list[1]=val", cxxopts::value(cmdline_config_options), "<opt>=<val>")
("plugin-info", "Print info for a single plugin and exit.\nThis includes all descriptivo info like name and author, along with the\nschema format for the init configuration and a list of suggested open parameters.\n<plugin_name> can be the name of the plugin or its configured library_path.", cxxopts::value(print_plugin_info), "<plugin_name>")
("p,print", "Add additional information to each falco notification's output.\nWith -pc or -pcontainer will use a container-friendly format.\nWith -pk or -pkubernetes will use a kubernetes-friendly format.\nWith -pm or -pmesos will use a mesos-friendly format.\nAdditionally, specifying -pc/-pk/-pm will change the interpretation of %container.info in rule output fields.", cxxopts::value(print_additional), "<output_format>")
("P,pidfile", "When run as a daemon, write pid to specified file", cxxopts::value(pidfilename)->default_value("/var/run/falco.pid"), "<pid_file>")
("r", "Rules file/directory (defaults to value set in configuration file, or /etc/falco_rules.yaml). Can be specified multiple times to read from multiple files/directories.", cxxopts::value<std::vector<std::string>>(), "<rules_file>")

View File

@ -52,6 +52,7 @@ public:
bool list_fields;
std::string list_source_fields;
bool list_plugins;
std::string print_plugin_info;
bool list_syscall_events;
bool markdown;
std::string mesos_api;

View File

@ -128,6 +128,7 @@ bool application::run(std::string &errstr, bool &restart)
std::bind(&application::create_signal_handlers, this),
std::bind(&application::load_config, this),
std::bind(&application::init_inspector, this),
std::bind(&application::print_plugin_info, this),
std::bind(&application::load_plugins, this),
std::bind(&application::init_falco_engine, this),
std::bind(&application::list_fields, this),

View File

@ -153,6 +153,7 @@ private:
run_result open_inspector();
run_result print_help();
run_result print_ignored_events();
run_result print_plugin_info();
run_result print_support();
run_result print_version();
run_result process_events();
@ -176,6 +177,7 @@ private:
void configure_output_format();
void check_for_ignored_events();
void print_all_ignored_events();
void format_plugin_info(std::shared_ptr<sinsp_plugin> p, std::ostream& os) const;
run_result do_inspect(syscall_evt_drop_mgr &sdropmgr,
uint64_t duration_to_tot_ns,
uint64_t &num_events);