From: Thomas Markwalder Date: Mon, 12 May 2025 20:04:23 +0000 (-0400) Subject: {3831] Logger output path restricted X-Git-Tag: Kea-2.7.9~45 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a2f4cc45200f2426cc8fa77e8755441b6bb59657;p=thirdparty%2Fkea.git {3831] Logger output path restricted Initial implementaion, still need docs and autotools changes meson.build Appended "kea" to LOGDIR /src/bin/agent/tests/ca_process_tests.sh.in /src/bin/d2/tests/d2_process_tests.sh.in /src/bin/dhcp4/tests/dhcp4_process_tests.sh.in /src/bin/dhcp6/tests/dhcp6_process_tests.sh.in export KEA_LOG_FILE_DIR /src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc /src/bin/dhcp4/tests/http_control_socket_unittest.cc /src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc /src/bin/dhcp6/tests/http_control_socket_unittest.cc Updated tests /src/bin/dhcp6/tests/dhcp6_test_utils.* Added log path stuff to BaseServerTest /src/bin/keactrl/tests/keactrl_tests.sh.in /src/bin/shell/tests/ca_basic_auth_tests.sh.in /src/bin/shell/tests/d2_basic_auth_tests.sh.in /src/bin/shell/tests/dhcp4_basic_auth_tests.sh.in /src/bin/shell/tests/dhcp6_basic_auth_tests.sh.in /src/bin/shell/tests/shell_ca_process_tests.sh.in /src/bin/shell/tests/shell_d2_process_tests.sh.in /src/bin/shell/tests/tls_ca_process_tests.sh.in /src/bin/shell/tests/tls_d2_process_tests.sh.in /src/bin/shell/tests/tls_dhcp4_process_tests.sh.in /src/bin/shell/tests/tls_dhcp6_process_tests.sh.in /src/lib/process/log_parser.* Added PathChecker singleton, LogConfigParser::getLogPath() LogConfigParser::validatePath() LogConfigParser::parseOutputOptions() - throws if output uses an invalid path /src/lib/process/meson.build Defines LOGFILE_DIR /src/lib/process/tests/log_parser_unittests.cc Updated tests --- diff --git a/meson.build b/meson.build index c1faf1e6b1..f763eb9968 100644 --- a/meson.build +++ b/meson.build @@ -67,7 +67,7 @@ KEA_ADMIN_BUILT = TOP_BUILD_DIR / 'src/bin/admin/kea-admin' KEA_ADMIN_INSTALLED = PREFIX / SBINDIR / 'kea-admin' KEA_LFC_BUILT = TOP_BUILD_DIR / 'src/bin/lfc/kea-lfc' KEA_LFC_INSTALLED = PREFIX / SBINDIR / 'kea-lfc' -LOGDIR = LOCALSTATEDIR / 'log' +LOGDIR = LOCALSTATEDIR / 'log/kea' LOGDIR_INSTALLED = PREFIX / LOGDIR RUNSTATEDIR = LOCALSTATEDIR / 'run/kea' RUNSTATEDIR_INSTALLED = PREFIX / RUNSTATEDIR diff --git a/src/bin/agent/tests/ca_process_tests.sh.in b/src/bin/agent/tests/ca_process_tests.sh.in index 627f70ac0f..f01fff23f5 100755 --- a/src/bin/agent/tests/ca_process_tests.sh.in +++ b/src/bin/agent/tests/ca_process_tests.sh.in @@ -21,6 +21,9 @@ LOG_FILE="@abs_top_builddir@/src/bin/agent/tests/test.log" # Set env KEA_HOOKS_PATH to override DEFAULT_HOOKS_PATH export KEA_HOOKS_PATH="@abs_top_builddir@/src/bin/agent/tests/@dotlibs@" +# Set env KEA_LOG_FILE_DIR to override default log path +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/agent/tests" + # Control Agent configuration to be stored in the configuration file. CONFIG="{ \"Control-agent\": diff --git a/src/bin/d2/tests/d2_process_tests.sh.in b/src/bin/d2/tests/d2_process_tests.sh.in index dc9cf746aa..71cd4b22d4 100755 --- a/src/bin/d2/tests/d2_process_tests.sh.in +++ b/src/bin/d2/tests/d2_process_tests.sh.in @@ -17,6 +17,10 @@ LOG_FILE="@abs_top_builddir@/src/bin/d2/tests/test.log" # D2 configuration to be stored in the configuration file. # Set env KEA_HOOKS_PATH to override DEFAULT_HOOKS_PATH export KEA_HOOKS_PATH="@abs_top_builddir@/src/bin/d2/tests/@dotlibs@" + +# Set env KEA_LOG_FILE_DIR to override default log path +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/d2/tests" + CONFIG="{ \"DhcpDdns\": { diff --git a/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc index 4b53a26e8d..06539f3dd8 100644 --- a/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,7 @@ using namespace isc::hooks; using namespace isc::stats; using namespace isc::test; using namespace isc::util; +using namespace isc::process; namespace ph = std::placeholders; namespace { @@ -120,6 +122,7 @@ public: /// /// Sets socket path to its default value. CtrlChannelDhcpv4SrvTest() : interfaces_("\"*\"") { + resetLogPath(); const char* env = getenv("KEA_SOCKET_TEST_DIR"); if (env) { socket_path_ = string(env) + "/kea4.sock"; @@ -134,6 +137,7 @@ public: /// @brief Destructor ~CtrlChannelDhcpv4SrvTest() { + resetLogPath(); if (test_timer_) { test_timer_->cancel(); getIOService()->stopAndPoll(); @@ -154,6 +158,18 @@ public: IfaceMgr::instance().detectIfaces(); } + /// @brief Sets the log path where log output may be written. + /// @param explicit_path path to use as the log path. + void setLogTestPath(const std::string explicit_path = "") { + LogConfigParser::getLogPath(true, (!explicit_path.empty() ? + explicit_path : TEST_DATA_BUILDDIR)); + } + + /// @brief Resets the log path to TEST_DATA_BUILDDIR. + void resetLogPath() { + LogConfigParser::getLogPath(true); + } + /// @brief Returns pointer to the server's IO service. /// /// @return Pointer to the server's IO service or null pointer if the server @@ -675,6 +691,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelStats) { // Check that the "config-set" command will replace current configuration TEST_F(CtrlChannelDhcpv4SrvTest, configSet) { + setLogTestPath("/dev"); createUnixChannelServer(); // Define strings to permutate the config arguments @@ -913,6 +930,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, configHashGet) { // Verify that the "config-test" command will do what we expect. TEST_F(CtrlChannelDhcpv4SrvTest, configTest) { + setLogTestPath("/dev"); createUnixChannelServer(); // Define strings to permutate the config arguments diff --git a/src/bin/dhcp4/tests/dhcp4_process_tests.sh.in b/src/bin/dhcp4/tests/dhcp4_process_tests.sh.in index 1b6b87f595..ada74d9d1d 100755 --- a/src/bin/dhcp4/tests/dhcp4_process_tests.sh.in +++ b/src/bin/dhcp4/tests/dhcp4_process_tests.sh.in @@ -27,6 +27,9 @@ HOOK_FAIL_POLL_PATH="@abs_top_builddir@/src/bin/dhcp4/tests/@dotlibs@libco4.so" # Set env KEA_HOOKS_PATH to override DEFAULT_HOOKS_PATH export KEA_HOOKS_PATH="@abs_top_builddir@/src/bin/dhcp4/tests/@dotlibs@" +# Set env KEA_LOG_FILE_DIR to override default log path. +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/dhcp4/tests" + # Kea configuration to be stored in the configuration file. CONFIG="{ \"Dhcp4\": diff --git a/src/bin/dhcp4/tests/http_control_socket_unittest.cc b/src/bin/dhcp4/tests/http_control_socket_unittest.cc index b4b717906a..a947c683eb 100644 --- a/src/bin/dhcp4/tests/http_control_socket_unittest.cc +++ b/src/bin/dhcp4/tests/http_control_socket_unittest.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -56,6 +57,7 @@ using namespace isc::hooks; using namespace isc::http; using namespace isc::stats; using namespace isc::util; +using namespace isc::process; namespace ph = std::placeholders; namespace { @@ -99,6 +101,7 @@ public: IfaceMgr::instance().setTestMode(false); IfaceMgr::instance().setDetectCallback(std::bind(&IfaceMgr::checkDetectIfaces, IfaceMgr::instancePtr().get(), ph::_1)); + setLogTestPath("/dev"); } /// @brief Destructor @@ -117,6 +120,19 @@ public: IfaceMgr::instance().clearIfaces(); IfaceMgr::instance().closeSockets(); IfaceMgr::instance().detectIfaces(); + resetLogPath(); + } + + /// @brief Sets the log path where log output may be written. + /// @param explicit_path path to use as the log path. + void setLogTestPath(const std::string explicit_path = "") { + LogConfigParser::getLogPath(true, (!explicit_path.empty() ? + explicit_path : TEST_DATA_BUILDDIR)); + } + + /// @brief Resets the log path to TEST_DATA_BUILDDIR. + void resetLogPath() { + LogConfigParser::getLogPath(true); } /// @brief Returns pointer to the server's IO service. diff --git a/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc index 4cd19b9e5e..be1d1fa9e8 100644 --- a/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc @@ -707,6 +707,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelStats) { // Check that the "config-set" command will replace current configuration TEST_F(CtrlChannelDhcpv6SrvTest, configSet) { + setLogTestPath("/dev"); createUnixChannelServer(); // Define strings to permutate the config arguments @@ -946,6 +947,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, configHashGet) { // Verify that the "config-test" command will do what we expect. TEST_F(CtrlChannelDhcpv6SrvTest, configTest) { + setLogTestPath("/dev"); createUnixChannelServer(); // Define strings to permutate the config arguments diff --git a/src/bin/dhcp6/tests/dhcp6_process_tests.sh.in b/src/bin/dhcp6/tests/dhcp6_process_tests.sh.in index 06356538de..b84afc8eb2 100755 --- a/src/bin/dhcp6/tests/dhcp6_process_tests.sh.in +++ b/src/bin/dhcp6/tests/dhcp6_process_tests.sh.in @@ -26,6 +26,9 @@ HOOK_FAIL_POLL_PATH="@abs_top_builddir@/src/bin/dhcp6/tests/@dotlibs@libco4.so" # Set env KEA_HOOKS_PATH to override DEFAULT_HOOKS_PATH export KEA_HOOKS_PATH="@abs_top_builddir@/src/bin/dhcp6/tests/@dotlibs@" +# Set env KEA_LOG_FILE_DIR to override default log path +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/dhcp6/tests" + # Kea configuration to be stored in the configuration file. CONFIG="{ \"Dhcp6\": diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.cc b/src/bin/dhcp6/tests/dhcp6_test_utils.cc index ddb291b28b..fc8d3915ff 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.cc +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.cc @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ using namespace isc::dhcp; using namespace isc::asiolink; using namespace isc::stats; using namespace isc::util; +using namespace isc::process; using namespace boost::posix_time; namespace isc { @@ -38,6 +40,7 @@ BaseServerTest::BaseServerTest() { CfgMgr::instance().setFamily(AF_INET6); original_datadir_ = CfgMgr::instance().getDataDir(); CfgMgr::instance().getDataDir(true, TEST_DATA_BUILDDIR); + resetLogPath(); } BaseServerTest::~BaseServerTest() { @@ -56,6 +59,18 @@ BaseServerTest::~BaseServerTest() { // Revert to unit test logging, in case the test reconfigured it. isc::log::initLogger(); + resetLogPath(); +} + +void +BaseServerTest::setLogTestPath(const std::string explicit_path /* = "" */) { + LogConfigParser::getLogPath(true, (!explicit_path.empty() ? + explicit_path : TEST_DATA_BUILDDIR)); +} + +void +BaseServerTest::resetLogPath() { + LogConfigParser::getLogPath(true); } Dhcpv6SrvTest::Dhcpv6SrvTest() diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.h b/src/bin/dhcp6/tests/dhcp6_test_utils.h index 86980c09d7..4d950723e6 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.h +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.h @@ -126,6 +126,13 @@ public: /// @brief Destructor. virtual ~BaseServerTest(); + /// @brief Sets the log path where log output may be written. + /// @param explicit_path path to use as the log path. + void setLogTestPath(const std::string explicit_path = ""); + + /// @brief Resets the log path to TEST_DATA_BUILDDIR. + void resetLogPath(); + private: /// @brief Holds the original data directory. diff --git a/src/bin/dhcp6/tests/http_control_socket_unittest.cc b/src/bin/dhcp6/tests/http_control_socket_unittest.cc index 70aa9776ce..cf1552b40b 100644 --- a/src/bin/dhcp6/tests/http_control_socket_unittest.cc +++ b/src/bin/dhcp6/tests/http_control_socket_unittest.cc @@ -91,6 +91,7 @@ public: HttpCtrlDhcpv6Test() : BaseServerTest() { reset(); + setLogTestPath("/dev"); } virtual ~HttpCtrlDhcpv6Test() { diff --git a/src/bin/keactrl/tests/keactrl_tests.sh.in b/src/bin/keactrl/tests/keactrl_tests.sh.in index cd69b39633..d95b74241a 100755 --- a/src/bin/keactrl/tests/keactrl_tests.sh.in +++ b/src/bin/keactrl/tests/keactrl_tests.sh.in @@ -59,6 +59,10 @@ KEACTRL_BUILD_DIR="@abs_top_builddir@" KEACTRL_CFG_FILE="@abs_top_builddir@/src/bin/keactrl/tests/keactrl_test.conf" # Path to the Kea log file. LOG_FILE="@abs_top_builddir@/src/bin/keactrl/tests/test.log" + +# Set env KEA_LOG_FILE_DIR to override default log path +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/keactrl/tests" + # Binaries' names wildcard_name="kea-" kea4_name="${wildcard_name}dhcp4" diff --git a/src/bin/shell/tests/ca_basic_auth_tests.sh.in b/src/bin/shell/tests/ca_basic_auth_tests.sh.in index dae5f46832..287a15c1a6 100755 --- a/src/bin/shell/tests/ca_basic_auth_tests.sh.in +++ b/src/bin/shell/tests/ca_basic_auth_tests.sh.in @@ -22,6 +22,9 @@ CFG_FILE="@abs_top_builddir@/src/bin/shell/tests/test_config.json" # Path to the Control Agent log file. LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log" +# Set env KEA_LOG_FILE_DIR to override default log path. +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/shell/tests" + # Control Agent configuration to be stored in the configuration file. # todo: use actual configuration once we support it. CONFIG="{ diff --git a/src/bin/shell/tests/d2_basic_auth_tests.sh.in b/src/bin/shell/tests/d2_basic_auth_tests.sh.in index c9ceb76f33..aac0631dec 100755 --- a/src/bin/shell/tests/d2_basic_auth_tests.sh.in +++ b/src/bin/shell/tests/d2_basic_auth_tests.sh.in @@ -22,6 +22,9 @@ CFG_FILE="@abs_top_builddir@/src/bin/shell/tests/test_config.json" # Path to the D2 Server log file. LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log" +# Set env KEA_LOG_FILE_DIR to override default log path. +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/shell/tests" + # D2 Server configuration to be stored in the configuration file. # todo: use actual configuration once we support it. CONFIG="{ diff --git a/src/bin/shell/tests/dhcp4_basic_auth_tests.sh.in b/src/bin/shell/tests/dhcp4_basic_auth_tests.sh.in index 33b737ec8f..9e07744956 100755 --- a/src/bin/shell/tests/dhcp4_basic_auth_tests.sh.in +++ b/src/bin/shell/tests/dhcp4_basic_auth_tests.sh.in @@ -26,6 +26,9 @@ LEASE_FILE="@abs_top_builddir@/src/bin/shell/tests/test_leases.csv" # Path to the Dhcp4 Server log file. LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log" +# Set env KEA_LOG_FILE_DIR to override default log path. +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/shell/tests" + # Dhcp4 Server configuration to be stored in the configuration file. # todo: use actual configuration once we support it. CONFIG="{ diff --git a/src/bin/shell/tests/dhcp6_basic_auth_tests.sh.in b/src/bin/shell/tests/dhcp6_basic_auth_tests.sh.in index 07bf165077..311ee365e2 100755 --- a/src/bin/shell/tests/dhcp6_basic_auth_tests.sh.in +++ b/src/bin/shell/tests/dhcp6_basic_auth_tests.sh.in @@ -26,6 +26,9 @@ LEASE_FILE="@abs_top_builddir@/src/bin/shell/tests/test_leases.csv" # Path to the Dhcp6 Server log file. LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log" +# Set env KEA_LOG_FILE_DIR to override default log path. +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/shell/tests" + # Dhcp6 Server configuration to be stored in the configuration file. # todo: use actual configuration once we support it. CONFIG="{ diff --git a/src/bin/shell/tests/shell_ca_process_tests.sh.in b/src/bin/shell/tests/shell_ca_process_tests.sh.in index 57a47a6c1b..952bfcf69a 100755 --- a/src/bin/shell/tests/shell_ca_process_tests.sh.in +++ b/src/bin/shell/tests/shell_ca_process_tests.sh.in @@ -22,6 +22,9 @@ CFG_FILE="@abs_top_builddir@/src/bin/shell/tests/test_config.json" # Path to the Control Agent log file. LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log" +# Set env KEA_LOG_FILE_DIR to override default log path. +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/shell/tests" + # Control Agent configuration to be stored in the configuration file. # todo: use actual configuration once we support it. CONFIG="{ diff --git a/src/bin/shell/tests/shell_d2_process_tests.sh.in b/src/bin/shell/tests/shell_d2_process_tests.sh.in index cfe8dd171d..902af94806 100755 --- a/src/bin/shell/tests/shell_d2_process_tests.sh.in +++ b/src/bin/shell/tests/shell_d2_process_tests.sh.in @@ -22,6 +22,9 @@ CFG_FILE="@abs_top_builddir@/src/bin/shell/tests/test_config.json" # Path to the D2 Server log file. LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log" +# Set env KEA_LOG_FILE_DIR to override default log path. +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/shell/tests" + # D2 Server configuration to be stored in the configuration file. # todo: use actual configuration once we support it. CONFIG="{ diff --git a/src/bin/shell/tests/tls_ca_process_tests.sh.in b/src/bin/shell/tests/tls_ca_process_tests.sh.in index 8989f76403..84a5300a08 100755 --- a/src/bin/shell/tests/tls_ca_process_tests.sh.in +++ b/src/bin/shell/tests/tls_ca_process_tests.sh.in @@ -23,6 +23,9 @@ CFG_FILE="@abs_top_builddir@/src/bin/shell/tests/test_config.json" # Path to the Control Agent log file. LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log" +# Set env KEA_LOG_FILE_DIR to override default log path. +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/shell/tests" + # Path to the test certificate authority directory. TEST_CA_DIR="@abs_top_srcdir@/src/lib/asiolink/testutils/ca" diff --git a/src/bin/shell/tests/tls_d2_process_tests.sh.in b/src/bin/shell/tests/tls_d2_process_tests.sh.in index 70a5856400..ffa7e1c365 100755 --- a/src/bin/shell/tests/tls_d2_process_tests.sh.in +++ b/src/bin/shell/tests/tls_d2_process_tests.sh.in @@ -23,6 +23,9 @@ CFG_FILE="@abs_top_builddir@/src/bin/shell/tests/test_config.json" # Path to the D2 Server log file. LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log" +# Set env KEA_LOG_FILE_DIR to override default log path. +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/shell/tests" + # Path to the test certificate authority directory. TEST_CA_DIR="@abs_top_srcdir@/src/lib/asiolink/testutils/ca" diff --git a/src/bin/shell/tests/tls_dhcp4_process_tests.sh.in b/src/bin/shell/tests/tls_dhcp4_process_tests.sh.in index 7e200994de..24cb1e8c02 100755 --- a/src/bin/shell/tests/tls_dhcp4_process_tests.sh.in +++ b/src/bin/shell/tests/tls_dhcp4_process_tests.sh.in @@ -27,6 +27,9 @@ LEASE_FILE="@abs_top_builddir@/src/bin/shell/tests/test_leases.csv" # Path to the Dhcp4 Server log file. LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log" +# Set env KEA_LOG_FILE_DIR to override default log path. +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/shell/tests" + # Path to the test certificate authority directory. TEST_CA_DIR="@abs_top_srcdir@/src/lib/asiolink/testutils/ca" diff --git a/src/bin/shell/tests/tls_dhcp6_process_tests.sh.in b/src/bin/shell/tests/tls_dhcp6_process_tests.sh.in index 7f5269d9f7..29c419a7af 100755 --- a/src/bin/shell/tests/tls_dhcp6_process_tests.sh.in +++ b/src/bin/shell/tests/tls_dhcp6_process_tests.sh.in @@ -27,6 +27,9 @@ LEASE_FILE="@abs_top_builddir@/src/bin/shell/tests/test_leases.csv" # Path to the Dhcp6 Server log file. LOG_FILE="@abs_top_builddir@/src/bin/shell/tests/test.log" +# Set env KEA_LOG_FILE_DIR to override default log path. +export KEA_LOG_FILE_DIR="@abs_top_builddir@/src/bin/shell/tests" + # Path to the test certificate authority directory. TEST_CA_DIR="@abs_top_srcdir@/src/lib/asiolink/testutils/ca" diff --git a/src/lib/process/log_parser.cc b/src/lib/process/log_parser.cc index c0cc19683d..53a37bcd77 100644 --- a/src/lib/process/log_parser.cc +++ b/src/lib/process/log_parser.cc @@ -13,13 +13,20 @@ #include #include #include +#include using namespace isc::data; using namespace isc::log; +using namespace isc::util::file; namespace isc { namespace process { +namespace { + // Singleton PathChecker to set and hold valid log file path. + PathCheckerPtr log_path_checker_; +}; + LogConfigParser::LogConfigParser(const ConfigPtr& storage) :config_(storage), verbose_(false) { if (!storage) { @@ -126,6 +133,29 @@ void LogConfigParser::parseConfigEntry(isc::data::ConstElementPtr entry) { config_->addLoggingInfo(info); } +std::string +LogConfigParser::getLogPath(bool reset /* = false */, const std::string explicit_path /* = "" */) { + if (!log_path_checker_ || reset) { + log_path_checker_.reset(new PathChecker(LOGFILE_DIR, "KEA_LOG_FILE_DIR")); + if (!explicit_path.empty()) { + log_path_checker_->getPath(true, explicit_path); + } + } + + return (log_path_checker_->getPath()); +} + +std::string +LogConfigParser::validatePath(const std::string logpath, + bool enforce_path /* = true */) { + if (!log_path_checker_) { + getLogPath(); + } + + return (log_path_checker_->validatePath(logpath, enforce_path)); +} + + void LogConfigParser::parseOutputOptions(std::vector& destination, isc::data::ConstElementPtr output_options) { if (!output_options) { @@ -141,7 +171,20 @@ void LogConfigParser::parseOutputOptions(std::vector& destin isc_throw(BadValue, "output-options entry does not have a mandatory 'output' " "element (" << output_option->getPosition() << ")"); } - dest.output_ = output->stringValue(); + + auto output_str = output->stringValue(); + if ((output_str == "stdout") || + (output_str == "stderr") || + (output_str == "syslog")) { + dest.output_ = output_str; + } else { + try { + dest.output_ = validatePath(output_str); + } catch (const std::exception& ex) { + isc_throw(BadValue, "invalid path in `output`: " << ex.what() + << " (" << output_option->getPosition() << ")"); + } + } isc::data::ConstElementPtr maxver_ptr = output_option->get("maxver"); if (maxver_ptr) { diff --git a/src/lib/process/log_parser.h b/src/lib/process/log_parser.h index bfb80d0ddc..bf9e913d84 100644 --- a/src/lib/process/log_parser.h +++ b/src/lib/process/log_parser.h @@ -58,6 +58,29 @@ public: void parseConfiguration(const isc::data::ConstElementPtr& log_config, bool verbose = false); + /// @brief Fetches the supported log file path. + /// + /// The first call to this function with no arguments will set the default + /// hooks path to either the value of LOGFILE_DIR or the environment + /// variable KEA_LOG_FILE_DIR if it is defined. Subsequent calls with no + /// arguments will simply return this value. + /// + /// @param reset recalculate when true, defaults to false. + /// @param explicit_path set default log path to this value. This is + /// for testing purposes only. + /// + /// @return String containing the default log file path. + static std::string getLogPath(bool reset = false, const std::string explicit_path = ""); + + /// @brief Validates a library path against the supported path for log files. + /// + /// @param logpath path to validate. + /// @param enforce_path enables validation against the supported path. + /// If false verifies only that the path contains a file name. + /// + /// @return validated path + static std::string validatePath(const std::string logpath, bool enforce_path = true); + private: /// @brief Parses one JSON structure in Server/loggers" array diff --git a/src/lib/process/meson.build b/src/lib/process/meson.build index ba4968a5a7..f25652d037 100644 --- a/src/lib/process/meson.build +++ b/src/lib/process/meson.build @@ -12,7 +12,10 @@ kea_process_lib = shared_library( 'log_parser.cc', 'process_messages.cc', 'redact_config.cc', - cpp_args: [f'-DPIDFILE_DIR="@RUNSTATEDIR_INSTALLED@"'], + cpp_args: [ + f'-DPIDFILE_DIR="@RUNSTATEDIR_INSTALLED@"', + f'-DLOGFILE_DIR="@LOGDIR_INSTALLED@"' + ], include_directories: [include_directories('.')] + INCLUDES, install: true, install_dir: LIBDIR, diff --git a/src/lib/process/tests/log_parser_unittests.cc b/src/lib/process/tests/log_parser_unittests.cc index a09c4c2fa4..c9f907447d 100644 --- a/src/lib/process/tests/log_parser_unittests.cc +++ b/src/lib/process/tests/log_parser_unittests.cc @@ -32,7 +32,9 @@ namespace { class LoggingTest : public ::testing::Test { public: /// @brief Constructor - LoggingTest() {} + LoggingTest() { + resetLogPath(); + } /// @brief Destructor /// @@ -40,6 +42,7 @@ class LoggingTest : public ::testing::Test { ~LoggingTest() { isc::log::initLogger(); wipeFiles(); + resetLogPath(); } /// @brief Generates a log file name suffixed with a rotation number @@ -63,6 +66,19 @@ class LoggingTest : public ::testing::Test { static_cast(remove(os.str().c_str())); } + /// @brief Sets the Hooks path from which hooks can be loaded. + /// @param explicit_path path to use as the hooks path. + void setLogTestPath(const std::string explicit_path = "") { + LogConfigParser::getLogPath(true, + (!explicit_path.empty() ? + explicit_path : TEST_DATA_BUILDDIR)); + } + + /// @brief Resets the log path to default. + void resetLogPath() { + LogConfigParser::getLogPath(true); + } + /// @brief Name of the log file static const char* TEST_LOG_NAME; @@ -115,7 +131,7 @@ TEST_F(LoggingTest, parsingConsoleOutput) { // We need to parse properly formed JSON and then extract // "loggers" element from it. For some reason fromJSON is - // throwing at opening square bracket + // throwing at openin0 square bracket ConstElementPtr config = Element::fromJSON(config_txt); config = config->get("loggers"); @@ -309,7 +325,8 @@ TEST_F(LoggingTest, parsingFile) { EXPECT_EQ(isc::log::INFO, storage->getLoggingInfo()[0].severity_); ASSERT_EQ(1, storage->getLoggingInfo()[0].destinations_.size()); - EXPECT_EQ("logfile.txt" , storage->getLoggingInfo()[0].destinations_[0].output_); + EXPECT_EQ(LogConfigParser::validatePath("logfile.txt"), + storage->getLoggingInfo()[0].destinations_[0].output_); // Default for immediate flush is true EXPECT_TRUE(storage->getLoggingInfo()[0].destinations_[0].flush_); @@ -365,14 +382,15 @@ TEST_F(LoggingTest, multipleLoggers) { EXPECT_EQ(0, storage->getLoggingInfo()[0].debuglevel_); EXPECT_EQ(isc::log::INFO, storage->getLoggingInfo()[0].severity_); ASSERT_EQ(1, storage->getLoggingInfo()[0].destinations_.size()); - EXPECT_EQ("logfile.txt" , storage->getLoggingInfo()[0].destinations_[0].output_); + EXPECT_EQ(LogConfigParser::validatePath("logfile.txt"), + storage->getLoggingInfo()[0].destinations_[0].output_); EXPECT_TRUE(storage->getLoggingInfo()[0].destinations_[0].flush_); - EXPECT_EQ("wombat", storage->getLoggingInfo()[1].name_); EXPECT_EQ(99, storage->getLoggingInfo()[1].debuglevel_); EXPECT_EQ(isc::log::DEBUG, storage->getLoggingInfo()[1].severity_); ASSERT_EQ(1, storage->getLoggingInfo()[1].destinations_.size()); - EXPECT_EQ("logfile2.txt" , storage->getLoggingInfo()[1].destinations_[0].output_); + EXPECT_EQ(LogConfigParser::validatePath("logfile2.txt"), + storage->getLoggingInfo()[1].destinations_[0].output_); EXPECT_FALSE(storage->getLoggingInfo()[1].destinations_[0].flush_); } @@ -380,7 +398,7 @@ TEST_F(LoggingTest, multipleLoggers) { // into Configuration usable by log4cplus. This test checks that more than // one logging destination can be configured. TEST_F(LoggingTest, multipleLoggingDestinations) { - + setLogTestPath(); const char* config_txt = "{ \"loggers\": [" " {" @@ -415,7 +433,8 @@ TEST_F(LoggingTest, multipleLoggingDestinations) { EXPECT_EQ(0, storage->getLoggingInfo()[0].debuglevel_); EXPECT_EQ(isc::log::INFO, storage->getLoggingInfo()[0].severity_); ASSERT_EQ(2, storage->getLoggingInfo()[0].destinations_.size()); - EXPECT_EQ("logfile.txt" , storage->getLoggingInfo()[0].destinations_[0].output_); + EXPECT_EQ(LogConfigParser::validatePath("logfile.txt"), + storage->getLoggingInfo()[0].destinations_[0].output_); EXPECT_TRUE(storage->getLoggingInfo()[0].destinations_[0].flush_); EXPECT_EQ("stdout" , storage->getLoggingInfo()[0].destinations_[1].output_); EXPECT_TRUE(storage->getLoggingInfo()[0].destinations_[1].flush_); @@ -427,6 +446,7 @@ TEST_F(LoggingTest, multipleLoggingDestinations) { // we can correctly configure logging such that rotation occurs as // expected. TEST_F(LoggingTest, logRotate) { + setLogTestPath(); wipeFiles(); std::ostringstream os; @@ -467,7 +487,7 @@ TEST_F(LoggingTest, logRotate) { EXPECT_EQ(TEST_MAX_VERS, server_cfg->getLoggingInfo()[0].destinations_[0].maxver_); // Make sure we have the initial log file. - ASSERT_TRUE(isc::test::fileExists(TEST_LOG_NAME)); + ASSERT_TRUE(isc::test::fileExists(LogConfigParser::validatePath(TEST_LOG_NAME))); // Now generate a log we know will be large enough to force a rotation. // We borrow a one argument log message for the test. @@ -477,7 +497,7 @@ TEST_F(LoggingTest, logRotate) { for (int i = 1; i < TEST_MAX_VERS + 1; i++) { // Output the big log and make sure we get the expected rotation file. LOG_INFO(logger, DCTL_CONFIG_COMPLETE).arg(big_arg); - EXPECT_TRUE(isc::test::fileExists(logName(i).c_str())); + EXPECT_TRUE(isc::test::fileExists(LogConfigParser::validatePath(logName(i).c_str()))); } // Clean up. @@ -604,6 +624,7 @@ void testMaxSize(uint64_t maxsize_candidate, uint64_t expected_maxsize) { // Test that maxsize can be configured with high values. TEST_F(LoggingTest, maxsize) { + setLogTestPath(); testMaxSize(TEST_MAX_SIZE, TEST_MAX_SIZE); testMaxSize(std::numeric_limits::max(), std::numeric_limits::max()); testMaxSize(std::numeric_limits::max(), std::numeric_limits::max());