refactor(configuration): move webserver items in own struct

This makes things easier to pass around like when starting the
web server.

This has the added benefit of simplifying further extension such as
making the metrics endpoint name configurable without adding yet another
parameter to the start function.

Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
This commit is contained in:
Samuel Gaist 2024-03-24 10:56:52 +01:00 committed by poiana
parent 968a403cba
commit e50d647dc9
6 changed files with 50 additions and 66 deletions

View File

@ -801,7 +801,7 @@ TEST(Configuration, configuration_webserver_ip)
EXPECT_NO_THROW(falco_config.init(cmdline_config_options)); EXPECT_NO_THROW(falco_config.init(cmdline_config_options));
ASSERT_EQ(falco_config.m_webserver_listen_address, address); ASSERT_EQ(falco_config.m_webserver_config.m_listen_address, address);
} }
std::vector<std::string> invalid_addresses = {"327.0.0.1", std::vector<std::string> invalid_addresses = {"327.0.0.1",

View File

@ -24,61 +24,57 @@ limitations under the License.
using namespace falco::app; using namespace falco::app;
using namespace falco::app::actions; using namespace falco::app::actions;
falco::app::run_result falco::app::actions::start_webserver(falco::app::state& s) 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(!s.is_capture_mode() && s.config->m_webserver_enabled) if(!state.is_capture_mode() && state.config->m_webserver_enabled)
{ {
if (s.options.dry_run) if (state.options.dry_run)
{ {
falco_logger::log(falco_logger::level::DEBUG, "Skipping starting webserver in dry-run\n"); falco_logger::log(falco_logger::level::DEBUG, "Skipping starting webserver in dry-run\n");
return run_result::ok(); return run_result::ok();
} }
std::string ssl_option = (s.config->m_webserver_ssl_enabled ? " (SSL)" : ""); 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 " falco_logger::log(falco_logger::level::INFO, "Starting health webserver with threadiness "
+ std::to_string(s.config->m_webserver_threadiness) + std::to_string(webserver_config.m_threadiness)
+ ", listening on " + ", listening on "
+ s.config->m_webserver_listen_address + webserver_config.m_listen_address
+ ":" + ":"
+ std::to_string(s.config->m_webserver_listen_port) + std::to_string(webserver_config.m_listen_port)
+ ssl_option + "\n"); + ssl_option + "\n");
std::vector<libs::metrics::libs_metrics_collector> metrics_collectors; std::vector<libs::metrics::libs_metrics_collector> metrics_collectors;
if (s.config->m_metrics_enabled && s.config->m_webserver_metrics_enabled) if (state.config->m_metrics_enabled && webserver_config.m_metrics_enabled)
{ {
for (const auto& source_info: s.source_infos) for (const auto& source_info: state.source_infos)
{ {
metrics_collectors.push_back(libs::metrics::libs_metrics_collector(source_info.inspector.get(), s.config->m_metrics_flags)); metrics_collectors.push_back(libs::metrics::libs_metrics_collector(source_info.inspector.get(), state.config->m_metrics_flags));
} }
} }
s.webserver.start( state.webserver.start(
s.offline_inspector, state.offline_inspector,
metrics_collectors, metrics_collectors,
s.config->m_webserver_threadiness, webserver_config);
s.config->m_webserver_listen_port,
s.config->m_webserver_listen_address,
s.config->m_webserver_k8s_healthz_endpoint,
s.config->m_webserver_ssl_certificate,
s.config->m_webserver_ssl_enabled);
} }
#endif #endif
return run_result::ok(); return run_result::ok();
} }
falco::app::run_result falco::app::actions::stop_webserver(falco::app::state& s) 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(!s.is_capture_mode() && s.config->m_webserver_enabled) if(!state.is_capture_mode() && state.config->m_webserver_enabled)
{ {
if (s.options.dry_run) if (state.options.dry_run)
{ {
falco_logger::log(falco_logger::level::DEBUG, "Skipping stopping webserver in dry-run\n"); falco_logger::log(falco_logger::level::DEBUG, "Skipping stopping webserver in dry-run\n");
return run_result::ok(); return run_result::ok();
} }
s.webserver.stop(); state.webserver.stop();
} }
#endif #endif
return run_result::ok(); return run_result::ok();

View File

@ -60,12 +60,6 @@ falco_configuration::falco_configuration():
m_grpc_enabled(false), m_grpc_enabled(false),
m_grpc_threadiness(0), m_grpc_threadiness(0),
m_webserver_enabled(false), m_webserver_enabled(false),
m_webserver_threadiness(0),
m_webserver_listen_port(8765),
m_webserver_listen_address("0.0.0.0"),
m_webserver_k8s_healthz_endpoint("/healthz"),
m_webserver_ssl_enabled(false),
m_webserver_metrics_enabled(false),
m_syscall_evt_drop_threshold(.1), m_syscall_evt_drop_threshold(.1),
m_syscall_evt_drop_rate(.03333), m_syscall_evt_drop_rate(.03333),
m_syscall_evt_drop_max_burst(1), m_syscall_evt_drop_max_burst(1),
@ -447,22 +441,22 @@ void falco_configuration::load_yaml(const std::string& config_name)
m_time_format_iso_8601 = config.get_scalar<bool>("time_format_iso_8601", false); m_time_format_iso_8601 = config.get_scalar<bool>("time_format_iso_8601", false);
m_webserver_enabled = config.get_scalar<bool>("webserver.enabled", false); m_webserver_enabled = config.get_scalar<bool>("webserver.enabled", false);
m_webserver_threadiness = config.get_scalar<uint32_t>("webserver.threadiness", 0); m_webserver_config.m_threadiness = config.get_scalar<uint32_t>("webserver.threadiness", 0);
m_webserver_listen_port = config.get_scalar<uint32_t>("webserver.listen_port", 8765); m_webserver_config.m_listen_port = config.get_scalar<uint32_t>("webserver.listen_port", 8765);
m_webserver_listen_address = config.get_scalar<std::string>("webserver.listen_address", "0.0.0.0"); m_webserver_config.m_listen_address = config.get_scalar<std::string>("webserver.listen_address", "0.0.0.0");
if(!re2::RE2::FullMatch(m_webserver_listen_address, ip_address_re)) if(!re2::RE2::FullMatch(m_webserver_config.m_listen_address, ip_address_re))
{ {
throw std::logic_error("Error reading config file (" + config_name + "): webserver listen address \"" + m_webserver_listen_address + "\" is not a valid IP address"); throw std::logic_error("Error reading config file (" + config_name + "): webserver listen address \"" + m_webserver_config.m_listen_address + "\" is not a valid IP address");
} }
m_webserver_k8s_healthz_endpoint = config.get_scalar<std::string>("webserver.k8s_healthz_endpoint", "/healthz"); m_webserver_config.m_k8s_healthz_endpoint = config.get_scalar<std::string>("webserver.k8s_healthz_endpoint", "/healthz");
m_webserver_ssl_enabled = config.get_scalar<bool>("webserver.ssl_enabled", false); m_webserver_config.m_ssl_enabled = config.get_scalar<bool>("webserver.ssl_enabled", false);
m_webserver_ssl_certificate = config.get_scalar<std::string>("webserver.ssl_certificate", "/etc/falco/falco.pem"); m_webserver_config.m_ssl_certificate = config.get_scalar<std::string>("webserver.ssl_certificate", "/etc/falco/falco.pem");
if(m_webserver_threadiness == 0) if(m_webserver_config.m_threadiness == 0)
{ {
m_webserver_threadiness = falco::utils::hardware_concurrency(); m_webserver_config.m_threadiness = falco::utils::hardware_concurrency();
} }
m_webserver_metrics_enabled = config.get_scalar<bool>("webserver.metrics_enabled", false); m_webserver_config.m_metrics_enabled = config.get_scalar<bool>("webserver.metrics_enabled", false);
std::list<std::string> syscall_event_drop_acts; std::list<std::string> syscall_event_drop_acts;
config.get_sequence(syscall_event_drop_acts, "syscall_event_drops.actions"); config.get_sequence(syscall_event_drop_acts, "syscall_event_drops.actions");

View File

@ -83,6 +83,16 @@ public:
std::string m_root; std::string m_root;
}; };
struct webserver_config {
uint32_t m_threadiness = 0;
uint32_t m_listen_port = 8765;
std::string m_listen_address = "0.0.0.0";
std::string m_k8s_healthz_endpoint = "/healthz";
bool m_ssl_enabled = false;
std::string m_ssl_certificate;
bool m_metrics_enabled = false;
};
falco_configuration(); falco_configuration();
virtual ~falco_configuration() = default; virtual ~falco_configuration() = default;
@ -127,13 +137,7 @@ public:
std::string m_grpc_root_certs; std::string m_grpc_root_certs;
bool m_webserver_enabled; bool m_webserver_enabled;
uint32_t m_webserver_threadiness; webserver_config m_webserver_config;
uint32_t m_webserver_listen_port;
std::string m_webserver_listen_address;
std::string m_webserver_k8s_healthz_endpoint;
bool m_webserver_ssl_enabled;
std::string m_webserver_ssl_certificate;
bool m_webserver_metrics_enabled;
syscall_evt_drop_actions m_syscall_evt_drop_actions; syscall_evt_drop_actions m_syscall_evt_drop_actions;
double m_syscall_evt_drop_threshold; double m_syscall_evt_drop_threshold;

View File

@ -28,12 +28,7 @@ falco_webserver::~falco_webserver()
void falco_webserver::start( void falco_webserver::start(
const std::shared_ptr<sinsp>& inspector, const std::shared_ptr<sinsp>& inspector,
const std::vector<libs::metrics::libs_metrics_collector>& metrics_collectors, const std::vector<libs::metrics::libs_metrics_collector>& metrics_collectors,
uint32_t threadiness, const falco_configuration::webserver_config& configuration)
uint32_t listen_port,
std::string& listen_address,
std::string& healthz_endpoint,
std::string &ssl_certificate,
bool ssl_enabled)
{ {
if (m_running) if (m_running)
{ {
@ -42,11 +37,11 @@ void falco_webserver::start(
} }
// allocate and configure server // allocate and configure server
if (ssl_enabled) if (configuration.m_ssl_enabled)
{ {
m_server = std::make_unique<httplib::SSLServer>( m_server = std::make_unique<httplib::SSLServer>(
ssl_certificate.c_str(), configuration.m_ssl_certificate.c_str(),
ssl_certificate.c_str()); configuration.m_ssl_certificate.c_str());
} }
else else
{ {
@ -54,10 +49,10 @@ void falco_webserver::start(
} }
// configure server // configure server
m_server->new_task_queue = [&threadiness] { return new httplib::ThreadPool(threadiness); }; m_server->new_task_queue = [configuration] { return new httplib::ThreadPool(configuration.m_threadiness); };
// setup healthz endpoint // setup healthz endpoint
m_server->Get(healthz_endpoint, m_server->Get(configuration.m_k8s_healthz_endpoint,
[](const httplib::Request &, httplib::Response &res) { [](const httplib::Request &, httplib::Response &res) {
res.set_content("{\"status\": \"ok\"}", "application/json"); res.set_content("{\"status\": \"ok\"}", "application/json");
}); });
@ -100,11 +95,11 @@ void falco_webserver::start(
std::atomic<bool> failed; std::atomic<bool> failed;
failed.store(false, std::memory_order_release); failed.store(false, std::memory_order_release);
m_server_thread = std::thread([this, listen_address, listen_port, &failed] m_server_thread = std::thread([this, configuration, &failed]
{ {
try try
{ {
this->m_server->listen(listen_address, listen_port); this->m_server->listen(configuration.m_listen_address, configuration.m_listen_port);
} }
catch(std::exception &e) catch(std::exception &e)
{ {

View File

@ -37,12 +37,7 @@ public:
virtual void start( virtual void start(
const std::shared_ptr<sinsp>& inspector, const std::shared_ptr<sinsp>& inspector,
const std::vector<libs::metrics::libs_metrics_collector>& metrics_collectors, const std::vector<libs::metrics::libs_metrics_collector>& metrics_collectors,
uint32_t threadiness, const falco_configuration::webserver_config& configuration);
uint32_t listen_port,
std::string& list_address,
std::string& healthz_endpoint,
std::string &ssl_certificate,
bool ssl_enabled);
virtual void stop(); virtual void stop();
private: private: