Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions cmake/modules/ConfigMaturity.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2026 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.
#

# Generate a C++ header mapping config keys to their maturity levels by parsing the structured
# comments in falco.yaml.
#
# The expected comment format is: # [Level] `key` where Level is one of: Stable, Incubating,
# Sandbox, Deprecated.

function(generate_config_maturity YAML_FILE OUTPUT_FILE)
file(STRINGS "${YAML_FILE}" YAML_LINES)

set(ENTRIES "")
set(ENTRY_COUNT 0)

foreach(LINE ${YAML_LINES})
# Match lines like: # [Stable] `config_files`
string(REGEX MATCH "^# \\[(Stable|Incubating|Sandbox|Deprecated)\\] `([^`]+)`" _MATCH
"${LINE}"
)

if(_MATCH)
set(LEVEL "${CMAKE_MATCH_1}")
set(KEY "${CMAKE_MATCH_2}")

string(TOUPPER "${LEVEL}" LEVEL_UPPER)
string(APPEND ENTRIES "\t{\"${KEY}\", maturity_level::${LEVEL_UPPER}},\n")
math(EXPR ENTRY_COUNT "${ENTRY_COUNT} + 1")
endif()
endforeach()

if(ENTRY_COUNT EQUAL 0)
message(FATAL_ERROR "ConfigMaturity: no maturity tags found in ${YAML_FILE}")
endif()

set(HEADER_CONTENT
"// Auto-generated from falco.yaml — do not edit.
// See: cmake/modules/ConfigMaturity.cmake
#pragma once

#include \"maturity.h\"

#include <array>
#include <string_view>

struct config_maturity_entry {
\tstd::string_view key;
\tmaturity_level level;
};

inline constexpr std::array<config_maturity_entry, ${ENTRY_COUNT}> config_maturity_table = {{
${ENTRIES}}};
"
)
file(WRITE "${OUTPUT_FILE}" "${HEADER_CONTENT}")

message(STATUS "ConfigMaturity: generated ${OUTPUT_FILE} with ${ENTRY_COUNT} entries")
endfunction()
23 changes: 12 additions & 11 deletions falco.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@
# Falco engine
# engine [Stable]
# Falco captures
# capture [Sandbox]
# capture [Incubating]
# Falco plugins
# load_plugins [Stable]
# plugins [Stable]
# plugins_hostinfo [Sandbox]
# Falco outputs settings
# time_format_iso_8601 [Stable]
# buffer_format_base64 [Stable]
Expand All @@ -63,7 +64,8 @@
# buffered_outputs [Stable]
# rule_matching [Incubating]
# outputs_queue [Stable]
# append_output [Stable]
# append_output [Incubating]
# static_fields [Sandbox]
# Falco outputs channels
# stdout_output [Stable]
# syslog_output [Stable]
Expand All @@ -72,6 +74,7 @@
# program_output [Stable]
# Falco exposed services
# webserver [Stable]
# webserver.prometheus_metrics_enabled [Incubating]
# Falco logging / alerting / metrics related to software functioning (basic)
# log_stderr [Stable]
# log_syslog [Stable]
Expand All @@ -80,7 +83,7 @@
# Falco logging / alerting / metrics related to software functioning (advanced)
# output_timeout [Stable]
# syscall_event_timeouts [Stable]
# syscall_event_drops [Stable] -> [CHANGE NOTICE] Automatic notifications will be simplified in Falco 0.38! If you depend on the detailed drop counters payload, use 'metrics.output_rule' along with 'metrics.kernel_event_counters_enabled' instead
# syscall_event_drops [Stable]
# metrics [Stable]
# Falco performance tuning (advanced)
# base_syscalls [Stable]
Expand Down Expand Up @@ -447,7 +450,7 @@ engine:
# Falco captures #
##################

# [Sandbox] `capture`
# [Incubating] `capture`
#
# -- Falco captures allow you to record events and their associated data for
# later analysis. This feature is particularly useful for debugging and
Expand Down Expand Up @@ -596,7 +599,7 @@ plugins_hostinfo: true
# the /etc/localtime configuration.
time_format_iso_8601: false

# [Incubating] `buffer_format_base64`
# [Stable] `buffer_format_base64`
#
# -- When enabled, Falco will output data buffer with base64 encoding. This is useful
# for encoding binary data that needs to be used over media designed to consume
Expand Down Expand Up @@ -629,7 +632,7 @@ json_output: false
# case.
json_include_output_property: true

# [Incubating] `json_include_message_property`
# [Stable] `json_include_message_property`
#
# -- When using JSON output in Falco, you have the option to include the formatted
# rule output without timestamp or priority. For instance, if a rule specifies
Expand All @@ -638,7 +641,7 @@ json_include_output_property: true
# information.
json_include_message_property: false

# [Incubating] `json_include_output_fields_property`
# [Stable] `json_include_output_fields_property`
#
# -- When using JSON output in Falco, you have the option to include the individual
# output fields for easier access. To reduce the logging volume, it is recommended
Expand Down Expand Up @@ -711,7 +714,7 @@ outputs_queue:
# effectively set to the largest possible long value, disabling this setting.
capacity: 0

# [Sandbox] `append_output`
# [Incubating] `append_output`
#
# -- Add information to the Falco output.
# With this setting you can add more information to the Falco output message, customizable by
Expand Down Expand Up @@ -1108,9 +1111,7 @@ syscall_event_drops:
# before events are sent to userspace, but can include scap userspace stats as
# well.
#
# It's important to note that the output fields and their names can be subject
# to change until the metrics feature reaches a stable release.
# In addition, the majority of fields represent an instant snapshot, with the
# The majority of fields represent an instant snapshot, with the
# exception of event rates per second and drop percentage stats. These values
# are computed based on the delta between two snapshots.
#
Expand Down
64 changes: 64 additions & 0 deletions unit_tests/falco/test_configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,70 @@ TEST(Configuration, modify_yaml_fields) {
ASSERT_EQ(conf.get_scalar<bool>(key, false), true);
}

TEST(Configuration, is_node_truthy) {
yaml_helper conf;

/* undefined key */
conf.load_from_string("key: true\n");
ASSERT_FALSE(conf.is_node_truthy("nonexistent"));

/* null value */
conf.load_from_string("key: null\n");
ASSERT_FALSE(conf.is_node_truthy("key"));

/* boolean scalars */
conf.load_from_string("key: true\n");
ASSERT_TRUE(conf.is_node_truthy("key"));

conf.load_from_string("key: false\n");
ASSERT_FALSE(conf.is_node_truthy("key"));

/* YAML boolean aliases */
conf.load_from_string("key: yes\n");
ASSERT_TRUE(conf.is_node_truthy("key"));

conf.load_from_string("key: no\n");
ASSERT_FALSE(conf.is_node_truthy("key"));

/* non-boolean string */
conf.load_from_string("key: hello\n");
ASSERT_TRUE(conf.is_node_truthy("key"));

/* empty string */
conf.load_from_string("key: ''\n");
ASSERT_FALSE(conf.is_node_truthy("key"));

/* numeric scalars are truthy (non-empty strings, not YAML booleans) */
conf.load_from_string("key: 0\n");
ASSERT_TRUE(conf.is_node_truthy("key"));

conf.load_from_string("key: 42\n");
ASSERT_TRUE(conf.is_node_truthy("key"));

/* empty sequence */
conf.load_from_string("key: []\n");
ASSERT_FALSE(conf.is_node_truthy("key"));

/* non-empty sequence */
conf.load_from_string("key:\n - item\n");
ASSERT_TRUE(conf.is_node_truthy("key"));

/* empty map */
conf.load_from_string("key: {}\n");
ASSERT_FALSE(conf.is_node_truthy("key"));

/* non-empty map */
conf.load_from_string("key:\n sub: val\n");
ASSERT_TRUE(conf.is_node_truthy("key"));

/* nested key */
conf.load_from_string("parent:\n child: true\n");
ASSERT_TRUE(conf.is_node_truthy("parent.child"));

conf.load_from_string("parent:\n child: false\n");
ASSERT_FALSE(conf.is_node_truthy("parent.child"));
}

TEST(Configuration, configuration_webserver_ip) {
falco_configuration falco_config;

Expand Down
22 changes: 22 additions & 0 deletions userspace/engine/yaml_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,28 @@ class yaml_helper {
return node.IsDefined();
}

/**
* Return true if the node identified by key holds an "active" value:
* - Scalars: true if the value is a truthy boolean or non-empty string.
* - Sequences/Maps: true if non-empty.
* - Undefined/Null: false.
*/
bool is_node_truthy(const std::string& key) const {
YAML::Node node;
get_node(node, key);
if(!node.IsDefined() || node.IsNull()) {
return false;
}
if(node.IsScalar()) {
try {
return node.as<bool>();
} catch(...) {
}
return !node.Scalar().empty();
}
return node.size() > 0;
}

std::string dump() const {
YAML::Emitter emitter;
emitter << YAML::DoubleQuoted << YAML::Flow << YAML::LowerNull << YAML::BeginSeq << m_root;
Expand Down
7 changes: 6 additions & 1 deletion userspace/falco/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2026 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
Expand All @@ -15,6 +15,11 @@

configure_file(config_falco.h.in config_falco.h)

include(ConfigMaturity)
generate_config_maturity(
"${PROJECT_SOURCE_DIR}/falco.yaml" "${CMAKE_CURRENT_BINARY_DIR}/config_maturity.h"
)

add_library(
falco_application STATIC
app/app.cpp
Expand Down
17 changes: 14 additions & 3 deletions userspace/falco/app/options.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2026 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.
Expand Down Expand Up @@ -118,11 +118,22 @@ bool options::parse(int argc, char **argv, std::string &errstr) {
return false;
}
} else if(markdown) {
// If markdown flag is set and format is not specified, use MARKDOWN format
fprintf(stderr, "WARNING: --markdown is deprecated, use --format markdown instead.\n");
output_fmt = output_format::MARKDOWN;
}

// Emit maturity notices for any flagged CLI options that were used.
// The logger is not initialized yet, so use stderr directly.
for(const auto &entry : flag_maturity_table) {
if(m_cmdline_parsed.count(std::string(entry.flag)) > 0) {
fprintf(stderr,
"%s: --%s is %s.\n",
entry.level == maturity_level::DEPRECATED ? "WARNING" : "NOTICE",
std::string(entry.flag).c_str(),
entry.level == maturity_level::DEPRECATED ? "deprecated"
: "experimental (sandbox)");
}
}

return true;
}

Expand Down
17 changes: 16 additions & 1 deletion userspace/falco/app/options.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2026 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.
Expand All @@ -21,10 +21,13 @@ limitations under the License.
#include "../../engine/output_format.h"

#include <string>
#include <string_view>
#include <vector>
#include <set>
#include <list>

#include "../maturity.h"

namespace cxxopts {
class Options;
};
Expand Down Expand Up @@ -84,5 +87,17 @@ class options {
std::string m_usage_str;
};

// CLI flag maturity table. Add entries here for sandbox or deprecated flags.
// Stable/incubating flags do not need to be listed.
struct flag_maturity_entry {
std::string_view flag;
maturity_level level;
};

inline constexpr flag_maturity_entry flag_maturity_table[] = {
{"markdown", maturity_level::DEPRECATED},
{"p", maturity_level::DEPRECATED},
};

}; // namespace app
}; // namespace falco
Loading
Loading