mirror of
https://github.com/falcosecurity/falco.git
synced 2026-04-02 18:12:15 +00:00
Compare commits
2 Commits
add-load-f
...
test/ci
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9d5c39dd4 | ||
|
|
fd6e149db0 |
12
.github/workflows/ci.yml
vendored
12
.github/workflows/ci.yml
vendored
@@ -13,6 +13,18 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
my-test:
|
||||||
|
runs-on: [ "self-hosted", "linux", "ARM64" ]
|
||||||
|
steps:
|
||||||
|
- name: etc os release
|
||||||
|
run: cat /etc/os-release
|
||||||
|
|
||||||
|
- name: uname
|
||||||
|
run: uname -a
|
||||||
|
|
||||||
|
- name: install deps
|
||||||
|
run: sudo yum update && sudo yum install make
|
||||||
|
|
||||||
fetch-version:
|
fetch-version:
|
||||||
uses: ./.github/workflows/reusable_fetch_version.yaml
|
uses: ./.github/workflows/reusable_fetch_version.yaml
|
||||||
|
|
||||||
|
|||||||
15
.github/workflows/reusable_test_packages.yaml
vendored
15
.github/workflows/reusable_test_packages.yaml
vendored
@@ -44,7 +44,14 @@ jobs:
|
|||||||
cd falco-${{ inputs.version }}-${{ inputs.arch }}
|
cd falco-${{ inputs.version }}-${{ inputs.arch }}
|
||||||
sudo cp -r * /
|
sudo cp -r * /
|
||||||
|
|
||||||
# x86_64 job run on ubuntu-22.04 and here we can install kernel-headers
|
# aarch64 job run on amazon-linux-2
|
||||||
|
- name: Install dependencies for falco-driver-loader tests on aarch64
|
||||||
|
if: ${{ inputs.arch == 'aarch64' }}
|
||||||
|
run: |
|
||||||
|
sudo yum update -y
|
||||||
|
sudo yum install -y build-essential clang make llvm gcc dkms kernel-devel-$(uname -r)
|
||||||
|
|
||||||
|
# x86_64 job run on ubuntu-22.04
|
||||||
- name: Install dependencies for falco-driver-loader tests on x86
|
- name: Install dependencies for falco-driver-loader tests on x86
|
||||||
if: ${{ inputs.arch == 'x86_64' }}
|
if: ${{ inputs.arch == 'x86_64' }}
|
||||||
run: |
|
run: |
|
||||||
@@ -63,8 +70,6 @@ jobs:
|
|||||||
go generate ./...
|
go generate ./...
|
||||||
popd
|
popd
|
||||||
|
|
||||||
# Right now we are not able to install kernel-headers on our ARM64 self-hosted runner.
|
|
||||||
# For this reason, we disable the falco-driver-loader tests, which require kernel headers on the host.
|
|
||||||
- name: Run regression tests
|
- name: Run regression tests
|
||||||
run: |
|
run: |
|
||||||
pushd submodules/falcosecurity-testing
|
pushd submodules/falcosecurity-testing
|
||||||
@@ -72,9 +77,7 @@ jobs:
|
|||||||
if ${{ inputs.static && 'false' || 'true' }}; then
|
if ${{ inputs.static && 'false' || 'true' }}; then
|
||||||
./build/falcoctl.test -test.timeout=90s -test.v >> ./report.txt 2>&1 || true
|
./build/falcoctl.test -test.timeout=90s -test.v >> ./report.txt 2>&1 || true
|
||||||
./build/k8saudit.test -test.timeout=90s -test.v >> ./report.txt 2>&1 || true
|
./build/k8saudit.test -test.timeout=90s -test.v >> ./report.txt 2>&1 || true
|
||||||
if ${{ inputs.arch == 'x86_64' && 'true' || 'false' }}; then
|
sudo ./build/falco-driver-loader.test -test.timeout=90s -test.v >> ./report.txt 2>&1 || true
|
||||||
sudo ./build/falco-driver-loader.test -test.timeout=90s -test.v >> ./report.txt 2>&1 || true
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
cat ./report.txt | go-junit-report -set-exit-code > report.xml
|
cat ./report.txt | go-junit-report -set-exit-code > report.xml
|
||||||
popd
|
popd
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ Considerations and guidance for Falco adopters:
|
|||||||
|
|
||||||
## How to Contribute
|
## How to Contribute
|
||||||
|
|
||||||
Please refer to the [contributing guide](https://github.com/falcosecurity/.github/blob/main/CONTRIBUTING.md) and the [code of conduct](https://github.com/falcosecurity/evolution/blob/main/CODE_OF_CONDUCT.md) for more information on how to contribute.
|
Please refer to the [contributing guide](https://github.com/falcosecurity/.github/blob/main/CONTRIBUTING.md) and the [code of conduct](https://github.com/falcosecurity/evolution/CODE_OF_CONDUCT.md) for more information on how to contribute.
|
||||||
|
|
||||||
|
|
||||||
## Join the Community
|
## Join the Community
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ else()
|
|||||||
# In case you want to test against another driver version (or branch, or commit) just pass the variable -
|
# In case you want to test against another driver version (or branch, or commit) just pass the variable -
|
||||||
# ie., `cmake -DDRIVER_VERSION=dev ..`
|
# ie., `cmake -DDRIVER_VERSION=dev ..`
|
||||||
if(NOT DRIVER_VERSION)
|
if(NOT DRIVER_VERSION)
|
||||||
set(DRIVER_VERSION "6.0.0+driver")
|
set(DRIVER_VERSION "6301c01b9279c3f4981df24b3e8e0d97c18f76e8")
|
||||||
set(DRIVER_CHECKSUM "SHA256=573cef7b9c69cfe1d5d8b873d2a20ad8235a2a96997df6bcebd120692dee7a91")
|
set(DRIVER_CHECKSUM "SHA256=cc5c51b4a01cf83d36c3af0670a36b2c8b55f3baebc03736725dc6425898d018")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# cd /path/to/build && cmake /path/to/source
|
# cd /path/to/build && cmake /path/to/source
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ else()
|
|||||||
# In case you want to test against another falcosecurity/libs version (or branch, or commit) just pass the variable -
|
# In case you want to test against another falcosecurity/libs version (or branch, or commit) just pass the variable -
|
||||||
# ie., `cmake -DFALCOSECURITY_LIBS_VERSION=dev ..`
|
# ie., `cmake -DFALCOSECURITY_LIBS_VERSION=dev ..`
|
||||||
if(NOT FALCOSECURITY_LIBS_VERSION)
|
if(NOT FALCOSECURITY_LIBS_VERSION)
|
||||||
set(FALCOSECURITY_LIBS_VERSION "0.13.0-rc1")
|
set(FALCOSECURITY_LIBS_VERSION "6301c01b9279c3f4981df24b3e8e0d97c18f76e8")
|
||||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=a75526b664bce2ba05912e056e48be39b0b1cb797b2055d107e55afbee2c8233")
|
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=cc5c51b4a01cf83d36c3af0670a36b2c8b55f3baebc03736725dc6425898d018")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# cd /path/to/build && cmake /path/to/source
|
# cd /path/to/build && cmake /path/to/source
|
||||||
|
|||||||
Submodule submodules/falcosecurity-rules updated: 6ed73fee78...b42893a6eb
@@ -101,75 +101,3 @@ TEST(Configuration, modify_yaml_fields)
|
|||||||
conf.set_scalar<bool>(key, true);
|
conf.set_scalar<bool>(key, true);
|
||||||
ASSERT_EQ(conf.get_scalar<bool>(key, false), true);
|
ASSERT_EQ(conf.get_scalar<bool>(key, false), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Configuration, configuration_environment_variables)
|
|
||||||
{
|
|
||||||
// Set an environment variable for testing purposes
|
|
||||||
std::string env_var_value = "envVarValue";
|
|
||||||
std::string env_var_name = "ENV_VAR";
|
|
||||||
std::string default_value = "default";
|
|
||||||
setenv(env_var_name.c_str(), env_var_value.c_str(), 1);
|
|
||||||
yaml_helper conf;
|
|
||||||
|
|
||||||
std::string sample_yaml =
|
|
||||||
"base_value:\n"
|
|
||||||
" id: $ENV_VAR\n"
|
|
||||||
" name: '${ENV_VAR}'\n"
|
|
||||||
" string: my_string\n"
|
|
||||||
" invalid: $${ENV_VAR}\n"
|
|
||||||
" invalid_env: $$ENV_VAR\n"
|
|
||||||
" escaped: \"${ENV_VAR}\"\n"
|
|
||||||
" subvalue:\n"
|
|
||||||
" subvalue2:\n"
|
|
||||||
" boolean: ${UNSED_XX_X_X_VAR}\n"
|
|
||||||
"base_value_2:\n"
|
|
||||||
" sample_list:\n"
|
|
||||||
" - ${ENV_VAR}\n"
|
|
||||||
" - ' ${ENV_VAR}'\n"
|
|
||||||
" - $UNSED_XX_X_X_VAR\n";
|
|
||||||
conf.load_from_string(sample_yaml);
|
|
||||||
|
|
||||||
/* Check if the base values are defined */
|
|
||||||
ASSERT_TRUE(conf.is_defined("base_value"));
|
|
||||||
ASSERT_TRUE(conf.is_defined("base_value_2"));
|
|
||||||
ASSERT_FALSE(conf.is_defined("unknown_base_value"));
|
|
||||||
|
|
||||||
/* Test fetching of a regular string without any environment variable */
|
|
||||||
std::string base_value_string = conf.get_scalar<std::string>("base_value.string", default_value);
|
|
||||||
ASSERT_EQ(base_value_string, "my_string");
|
|
||||||
|
|
||||||
/* Test fetching of escaped environment variable format. Should return the string as-is after stripping the leading `$` */
|
|
||||||
std::string base_value_invalid = conf.get_scalar<std::string>("base_value.invalid", default_value);
|
|
||||||
ASSERT_EQ(base_value_invalid, "${ENV_VAR}");
|
|
||||||
|
|
||||||
/* Test fetching of invalid escaped environment variable format. Should return the string as-is */
|
|
||||||
std::string base_value_invalid_env = conf.get_scalar<std::string>("base_value.invalid_env", default_value);
|
|
||||||
ASSERT_EQ(base_value_invalid_env, "$$ENV_VAR");
|
|
||||||
|
|
||||||
/* Test fetching of strings that contain environment variables */
|
|
||||||
std::string base_value_id = conf.get_scalar<std::string>("base_value.id", default_value);
|
|
||||||
ASSERT_EQ(base_value_id, "$ENV_VAR"); // Does not follow the `${VAR}` format, so it should be treated as a regular string
|
|
||||||
|
|
||||||
std::string base_value_name = conf.get_scalar<std::string>("base_value.name", default_value);
|
|
||||||
ASSERT_EQ(base_value_name, env_var_value); // Proper environment variable format
|
|
||||||
|
|
||||||
std::string base_value_escaped = conf.get_scalar<std::string>("base_value.escaped", default_value);
|
|
||||||
ASSERT_EQ(base_value_escaped, env_var_value); // Environment variable within quotes
|
|
||||||
|
|
||||||
/* Test fetching of an undefined environment variable. Expected to return the default value.*/
|
|
||||||
std::string unknown_boolean = conf.get_scalar<std::string>("base_value.subvalue.subvalue2.boolean", default_value);
|
|
||||||
ASSERT_EQ(unknown_boolean, default_value);
|
|
||||||
|
|
||||||
/* Test fetching of environment variables from a list */
|
|
||||||
std::string base_value_2_list_0 = conf.get_scalar<std::string>("base_value_2.sample_list[0]", default_value);
|
|
||||||
ASSERT_EQ(base_value_2_list_0, env_var_value); // Proper environment variable format
|
|
||||||
|
|
||||||
std::string base_value_2_list_1 = conf.get_scalar<std::string>("base_value_2.sample_list[1]", default_value);
|
|
||||||
ASSERT_EQ(base_value_2_list_1, " ${ENV_VAR}"); // Environment variable preceded by a space, hence treated as a regular string
|
|
||||||
|
|
||||||
std::string base_value_2_list_2 = conf.get_scalar<std::string>("base_value_2.sample_list[2]", default_value);
|
|
||||||
ASSERT_EQ(base_value_2_list_2, "$UNSED_XX_X_X_VAR"); // Does not follow the `${VAR}` format, so should be treated as a regular string
|
|
||||||
|
|
||||||
/* Clear the set environment variable after testing */
|
|
||||||
unsetenv(env_var_name.c_str());
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -189,69 +189,26 @@ void falco_engine::load_rules(const std::string &rules_content, bool verbose, bo
|
|||||||
|
|
||||||
std::unique_ptr<load_result> falco_engine::load_rules(const std::string &rules_content, const std::string &name)
|
std::unique_ptr<load_result> falco_engine::load_rules(const std::string &rules_content, const std::string &name)
|
||||||
{
|
{
|
||||||
std::vector<std::reference_wrapper<const std::string>> rules_contents;
|
rule_loader::configuration cfg(rules_content, m_sources, name);
|
||||||
std::vector<std::reference_wrapper<const std::string>> names;
|
cfg.min_priority = m_min_priority;
|
||||||
|
cfg.output_extra = m_extra;
|
||||||
|
cfg.replace_output_container_info = m_replace_container_info;
|
||||||
|
cfg.default_ruleset_id = m_default_ruleset_id;
|
||||||
|
|
||||||
rules_contents.emplace_back(rules_content);
|
rule_loader::reader reader;
|
||||||
names.emplace_back(name);
|
if (reader.read(cfg, m_rule_collector))
|
||||||
|
|
||||||
return load_rules_refs(rules_contents, names);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<load_result> falco_engine::load_rules(const std::vector<std::string> &rules_contents,
|
|
||||||
const std::vector<std::string> &names)
|
|
||||||
{
|
|
||||||
std::vector<std::reference_wrapper<const std::string>> rules_contents_refs(rules_contents.begin(), rules_contents.end());
|
|
||||||
std::vector<std::reference_wrapper<const std::string>> names_refs(names.begin(), names.end());
|
|
||||||
|
|
||||||
return load_rules_refs(rules_contents_refs, names_refs);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<load_result> falco_engine::load_rules_refs(const std::vector<std::reference_wrapper<const std::string>> &rules_contents,
|
|
||||||
const std::vector<std::reference_wrapper<const std::string>> &names)
|
|
||||||
{
|
|
||||||
if(rules_contents.size() != names.size() ||
|
|
||||||
rules_contents.size() == 0)
|
|
||||||
{
|
{
|
||||||
rule_loader::context ctx("Provided rules contents arrays");
|
for (auto &src : m_sources)
|
||||||
|
|
||||||
std::unique_ptr<rule_loader::result> res(new rule_loader::result("Provided rules contents arrays"));
|
|
||||||
|
|
||||||
res->add_error(load_result::LOAD_ERR_FILE_READ, "Lists of rules contents and names must have same non-zero length", ctx);
|
|
||||||
|
|
||||||
// Old gcc versions (e.g. 4.8.3) won't allow move elision but newer versions
|
|
||||||
// (e.g. 10.2.1) would complain about the redundant move.
|
|
||||||
#if __GNUC__ > 4
|
|
||||||
return res;
|
|
||||||
#else
|
|
||||||
return std::move(res);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<rule_loader::configuration> cfg;
|
|
||||||
for(size_t idx = 0; idx < rules_contents.size(); idx++)
|
|
||||||
{
|
|
||||||
cfg = std::make_unique<rule_loader::configuration>(rules_contents[idx], m_sources, names[idx]);
|
|
||||||
cfg->min_priority = m_min_priority;
|
|
||||||
cfg->output_extra = m_extra;
|
|
||||||
cfg->replace_output_container_info = m_replace_container_info;
|
|
||||||
cfg->default_ruleset_id = m_default_ruleset_id;
|
|
||||||
|
|
||||||
rule_loader::reader reader;
|
|
||||||
if (reader.read(*(cfg.get()), m_rule_collector))
|
|
||||||
{
|
{
|
||||||
for (auto &src : m_sources)
|
src.ruleset = src.ruleset_factory->new_ruleset();
|
||||||
{
|
|
||||||
src.ruleset = src.ruleset_factory->new_ruleset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rule_loader::compiler compiler;
|
||||||
|
m_rules.clear();
|
||||||
|
compiler.compile(cfg, m_rule_collector, m_rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
rule_loader::compiler compiler;
|
if (cfg.res->successful())
|
||||||
m_rules.clear();
|
|
||||||
compiler.compile(*(cfg.get()), m_rule_collector, m_rules);
|
|
||||||
|
|
||||||
if (cfg->res->successful())
|
|
||||||
{
|
{
|
||||||
m_rule_stats_manager.clear();
|
m_rule_stats_manager.clear();
|
||||||
for (const auto &r : m_rules)
|
for (const auto &r : m_rules)
|
||||||
@@ -260,7 +217,7 @@ std::unique_ptr<load_result> falco_engine::load_rules_refs(const std::vector<std
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::move(cfg->res);
|
return std::move(cfg.res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void falco_engine::load_rules_file(const std::string &rules_filename, bool verbose, bool all_events)
|
void falco_engine::load_rules_file(const std::string &rules_filename, bool verbose, bool all_events)
|
||||||
@@ -276,44 +233,29 @@ void falco_engine::load_rules_file(const std::string &rules_filename, bool verbo
|
|||||||
|
|
||||||
std::unique_ptr<load_result> falco_engine::load_rules_file(const std::string &rules_filename)
|
std::unique_ptr<load_result> falco_engine::load_rules_file(const std::string &rules_filename)
|
||||||
{
|
{
|
||||||
std::vector<std::string> rules_filenames;
|
std::string rules_content;
|
||||||
|
|
||||||
rules_filenames.emplace_back(rules_filename);
|
try {
|
||||||
|
read_file(rules_filename, rules_content);
|
||||||
return load_rules_files(rules_filenames);
|
}
|
||||||
}
|
catch (falco_exception &e)
|
||||||
|
|
||||||
std::unique_ptr<load_result> falco_engine::load_rules_files(const std::vector<std::string> &rules_filenames)
|
|
||||||
{
|
|
||||||
std::vector<std::string> rules_contents;
|
|
||||||
|
|
||||||
for(auto &filename : rules_filenames)
|
|
||||||
{
|
{
|
||||||
std::string rules_content;
|
rule_loader::context ctx(rules_filename);
|
||||||
|
|
||||||
try {
|
std::unique_ptr<rule_loader::result> res(new rule_loader::result(rules_filename));
|
||||||
read_file(filename, rules_content);
|
|
||||||
rules_contents.emplace_back(std::move(rules_content));
|
|
||||||
}
|
|
||||||
catch (falco_exception &e)
|
|
||||||
{
|
|
||||||
rule_loader::context ctx(filename);
|
|
||||||
|
|
||||||
std::unique_ptr<rule_loader::result> res(new rule_loader::result(filename));
|
res->add_error(load_result::LOAD_ERR_FILE_READ, e.what(), ctx);
|
||||||
|
|
||||||
res->add_error(load_result::LOAD_ERR_FILE_READ, e.what(), ctx);
|
|
||||||
|
|
||||||
// Old gcc versions (e.g. 4.8.3) won't allow move elision but newer versions
|
// Old gcc versions (e.g. 4.8.3) won't allow move elision but newer versions
|
||||||
// (e.g. 10.2.1) would complain about the redundant move.
|
// (e.g. 10.2.1) would complain about the redundant move.
|
||||||
#if __GNUC__ > 4
|
#if __GNUC__ > 4
|
||||||
return res;
|
return res;
|
||||||
#else
|
#else
|
||||||
return std::move(res);
|
return std::move(res);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return load_rules(rules_contents, rules_filenames);
|
return load_rules(rules_content, rules_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void falco_engine::enable_rule(const std::string &substring, bool enabled, const std::string &ruleset)
|
void falco_engine::enable_rule(const std::string &substring, bool enabled, const std::string &ruleset)
|
||||||
|
|||||||
@@ -23,11 +23,9 @@ limitations under the License.
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <functional>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
@@ -75,15 +73,6 @@ public:
|
|||||||
std::unique_ptr<falco::load_result> load_rules_file(const std::string &rules_filename);
|
std::unique_ptr<falco::load_result> load_rules_file(const std::string &rules_filename);
|
||||||
std::unique_ptr<falco::load_result> load_rules(const std::string &rules_content, const std::string &name);
|
std::unique_ptr<falco::load_result> load_rules(const std::string &rules_content, const std::string &name);
|
||||||
|
|
||||||
//
|
|
||||||
// Identical to above, but allows providing a vector of files
|
|
||||||
// instead of a single file at a time. (This speeds up loading
|
|
||||||
// a bit because rule compilation can be deferred until all
|
|
||||||
// the files are read).
|
|
||||||
std::unique_ptr<falco::load_result> load_rules_files(const std::vector<std::string> &rules_filenames);
|
|
||||||
std::unique_ptr<falco::load_result> load_rules(const std::vector<std::string> &rules_contents,
|
|
||||||
const std::vector<std::string> &names);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Enable/Disable any rules matching the provided substring.
|
// Enable/Disable any rules matching the provided substring.
|
||||||
// If the substring is "", all rules are enabled/disabled.
|
// If the substring is "", all rules are enabled/disabled.
|
||||||
@@ -284,11 +273,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Used by all the load_rules_* variants above with
|
|
||||||
// reference_wrapper to avoid copies.
|
|
||||||
std::unique_ptr<falco::load_result> load_rules_refs(const std::vector<std::reference_wrapper<const std::string>> &rules_contents,
|
|
||||||
const std::vector<std::reference_wrapper<const std::string>> &names);
|
|
||||||
|
|
||||||
// Throws falco_exception if the file can not be read
|
// Throws falco_exception if the file can not be read
|
||||||
void read_file(const std::string& filename, std::string& contents);
|
void read_file(const std::string& filename, std::string& contents);
|
||||||
|
|
||||||
|
|||||||
@@ -50,25 +50,11 @@ falco::app::run_result falco::app::actions::load_rules_files(falco::app::state&
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> rules_contents;
|
std::vector<std::string> rules_contents;
|
||||||
std::vector<std::string> rules_filenames;
|
|
||||||
falco::load_result::rules_contents_t rc;
|
falco::load_result::rules_contents_t rc;
|
||||||
std::string filenames;
|
|
||||||
|
|
||||||
for(auto &filename : s.config->m_loaded_rules_filenames)
|
|
||||||
{
|
|
||||||
if(!filenames.empty())
|
|
||||||
{
|
|
||||||
filenames += ", ";
|
|
||||||
}
|
|
||||||
|
|
||||||
filenames += filename;
|
|
||||||
|
|
||||||
rules_filenames.push_back(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
read_files(rules_filenames.begin(),
|
read_files(s.config->m_loaded_rules_filenames.begin(),
|
||||||
rules_filenames.end(),
|
s.config->m_loaded_rules_filenames.end(),
|
||||||
rules_contents,
|
rules_contents,
|
||||||
rc);
|
rc);
|
||||||
}
|
}
|
||||||
@@ -78,22 +64,25 @@ falco::app::run_result falco::app::actions::load_rules_files(falco::app::state&
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string err = "";
|
std::string err = "";
|
||||||
|
for(auto &filename : s.config->m_loaded_rules_filenames)
|
||||||
falco_logger::log(LOG_INFO, "Loading rules from file(s): " + filenames);
|
|
||||||
std::unique_ptr<falco::load_result> res;
|
|
||||||
|
|
||||||
res = s.engine->load_rules(rules_contents, rules_filenames);
|
|
||||||
|
|
||||||
if(!res->successful())
|
|
||||||
{
|
{
|
||||||
// Return the summary version as the error
|
falco_logger::log(LOG_INFO, "Loading rules from file " + filename + "\n");
|
||||||
err = res->as_string(true, rc);
|
std::unique_ptr<falco::load_result> res;
|
||||||
}
|
|
||||||
|
|
||||||
// If verbose is true, also print any warnings
|
res = s.engine->load_rules(rc.at(filename), filename);
|
||||||
if(s.options.verbose && res->has_warnings())
|
|
||||||
{
|
if(!res->successful())
|
||||||
fprintf(stderr, "%s\n", res->as_string(true, rc).c_str());
|
{
|
||||||
|
// Return the summary version as the error
|
||||||
|
err = res->as_string(true, rc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If verbose is true, also print any warnings
|
||||||
|
if(s.options.verbose && res->has_warnings())
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s\n", res->as_string(true, rc).c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// note: we have an egg-and-chicken problem here. We would like to check
|
// note: we have an egg-and-chicken problem here. We would like to check
|
||||||
|
|||||||
@@ -72,41 +72,6 @@ public:
|
|||||||
get_node(node, key);
|
get_node(node, key);
|
||||||
if(node.IsDefined())
|
if(node.IsDefined())
|
||||||
{
|
{
|
||||||
std::string value = node.as<std::string>();
|
|
||||||
|
|
||||||
// Helper function to convert string to the desired type T
|
|
||||||
auto convert_str_to_t = [&default_value](const std::string& str) -> T {
|
|
||||||
std::stringstream ss(str);
|
|
||||||
T result;
|
|
||||||
if (ss >> result) return result;
|
|
||||||
return default_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// If the value starts with `$$`, check for a subsequent `{...}`
|
|
||||||
if (value.size() >= 3 && value[0] == '$' && value[1] == '$')
|
|
||||||
{
|
|
||||||
// If after stripping the first `$`, the string format is like `${VAR}`, treat it as a plain string and don't resolve.
|
|
||||||
if (value[2] == '{' && value[value.size() - 1] == '}')
|
|
||||||
{
|
|
||||||
value = value.substr(1);
|
|
||||||
return convert_str_to_t(value);
|
|
||||||
}
|
|
||||||
else return convert_str_to_t(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the value is an environment variable reference
|
|
||||||
if(value.size() >= 2 && value[0] == '$' && value[1] == '{' && value[value.size() - 1] == '}')
|
|
||||||
{
|
|
||||||
// Format: ${ENV_VAR_NAME}
|
|
||||||
std::string env_var = value.substr(2, value.size() - 3);
|
|
||||||
|
|
||||||
const char* env_value = std::getenv(env_var.c_str()); // Get the environment variable value
|
|
||||||
if(env_value) return convert_str_to_t(env_value);
|
|
||||||
|
|
||||||
return default_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it's not an environment variable reference, return the value as is
|
|
||||||
return node.as<T>();
|
return node.as<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user