]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2101] load hooks using name only
authorRazvan Becheriu <razvan@isc.org>
Thu, 19 Dec 2024 14:50:20 +0000 (16:50 +0200)
committerFrancis Dupont <fdupont@isc.org>
Tue, 24 Dec 2024 13:03:04 +0000 (13:03 +0000)
doc/sphinx/arm/hooks.rst
src/lib/dhcpsrv/tests/Makefile.am
src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc
src/lib/hooks/Makefile.am
src/lib/hooks/hooks_parser.cc
src/lib/hooks/hooks_parser.h

index b661bedfcfc7ff34ebc95047f1e72abf52abf9ad..1bd1bc4623075d23fdc4389be5d8ab14cd934f32 100644 (file)
@@ -213,6 +213,33 @@ configuration would be:
    because the parameters specified for the library (or the files those
    parameters point to) may have changed.
 
+Since Kea-2.7.5, the server is able to load hooks specified only by name, if
+they reside in the default install location (the path is OS specific).
+
+::
+
+       "hooks-libraries": [
+           {
+               "library": "first_custom_hooks_example.so"
+           },
+           {
+               "library": "second_custom_hooks_example.so"
+           }
+       ]
+
+This snipper (on Ubuntu 24.04) is equivalent to:
+
+::
+
+       "hooks-libraries": [
+           {
+               "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/first_custom_hooks_example.so"
+           },
+           {
+               "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/second_custom_hooks_example.so"
+           }
+       ]
+
 Libraries may have additional parameters that are not mandatory, in the
 sense that there may be libraries that do not require them. However, for any
 given library there is often a requirement to specify a certain
index 289a8fdc9f547b7eed25cb7cb0e674e818e450fd..bc9b150ab0e6b4fb4e8b700207949a78c6766084 100644 (file)
@@ -6,6 +6,7 @@ AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/lib/dhcpsrv/tests\
 AM_CPPFLAGS += -DDHCP_DATA_DIR=\"$(abs_top_builddir)/src/lib/dhcpsrv/tests\"
 AM_CPPFLAGS += -DKEA_LFC_BUILD_DIR=\"$(abs_top_builddir)/src/bin/lfc\"
 AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
+AM_CPPFLAGS += -DDEFAULT_HOOKS_PATH=\"$(libdir)/kea/hooks\"
 
 AM_CXXFLAGS = $(KEA_CXXFLAGS)
 
index 9ea17057c315a302bb4a0d054f6fac418a74c51c..af1ef3dacab4b2724e2bf28ff7672ed57702b3c1 100644 (file)
@@ -34,6 +34,7 @@
 #include <exceptions/exceptions.h>
 #include <hooks/hooks_parser.h>
 #include <hooks/hooks_manager.h>
+#include <util/filesystem.h>
 #include <testutils/gtest_utils.h>
 #include <testutils/test_to_element.h>
 
@@ -52,6 +53,7 @@ using namespace isc::dhcp;
 using namespace isc::dhcp::test;
 using namespace isc::hooks;
 using namespace isc::test;
+using namespace isc::util::file;
 
 namespace {
 
@@ -327,11 +329,13 @@ public:
     ParseConfigTest()
         :family_(AF_INET6) {
         reset_context();
+        HooksLibrariesParser::default_hooks_path_ = string(DEFAULT_HOOKS_PATH);
     }
 
     ~ParseConfigTest() {
         reset_context();
         CfgMgr::instance().clear();
+        HooksLibrariesParser::default_hooks_path_ = string(DEFAULT_HOOKS_PATH);
     }
 
     /// @brief Parses a configuration.
@@ -2277,6 +2281,45 @@ TEST_F(ParseConfigTest, oneHooksLibrary) {
     EXPECT_EQ(CALLOUT_LIBRARY_1, hooks_libraries[0]);
 }
 
+// hooks-libraries element that contains a single library with relative path.
+TEST_F(ParseConfigTest, oneHooksLibraryRelativePath) {
+    // Check that no libraries are currently loaded
+    vector<string> hooks_libraries = HooksManager::getLibraryNames();
+    EXPECT_TRUE(hooks_libraries.empty());
+
+    Path path(CALLOUT_LIBRARY_1);
+
+    HooksLibrariesParser::default_hooks_path_ = path.parentPath();
+
+    // Configuration with hooks-libraries set to a single library.
+    string config = setHooksLibrariesConfig(path.filename().c_str());
+
+    // Verify that the configuration string parses.
+    const int rcode = parseConfiguration(config);
+    ASSERT_TRUE(rcode == 0) << error_text_;
+
+    config = setHooksLibrariesConfig(CALLOUT_LIBRARY_1);
+
+    // Verify that the configuration object unparses.
+    ConstElementPtr expected;
+    ASSERT_NO_THROW(expected =
+                    Element::fromJSON(config)->get("hooks-libraries"));
+    ASSERT_TRUE(expected);
+    const HooksConfig& cfg =
+        CfgMgr::instance().getStagingCfg()->getHooksConfig();
+    runToElementTest<HooksConfig>(expected, cfg);
+
+    // Check that the parser recorded a single library.
+    isc::hooks::HookLibsCollection libraries = getLibraries();
+    ASSERT_EQ(1, libraries.size());
+    EXPECT_EQ(CALLOUT_LIBRARY_1, libraries[0].first);
+
+    // Check that the change was propagated to the hooks manager.
+    hooks_libraries = HooksManager::getLibraryNames();
+    ASSERT_EQ(1, hooks_libraries.size());
+    EXPECT_EQ(CALLOUT_LIBRARY_1, hooks_libraries[0]);
+}
+
 // hooks-libraries element that contains two libraries
 TEST_F(ParseConfigTest, twoHooksLibraries) {
     // Check that no libraries are currently loaded
index 44a61fd3d1d25ab5e79c0bdc9b4e844568c93172..94143c251b371a7f29e0f307bd288ca94106d4de 100644 (file)
@@ -1,6 +1,7 @@
 SUBDIRS = . tests
 
 AM_CPPFLAGS  = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += -DDEFAULT_HOOKS_PATH=\"$(libdir)/kea/hooks\"
 AM_CPPFLAGS += $(BOOST_INCLUDES)
 AM_CXXFLAGS  = $(KEA_CXXFLAGS)
 
index 56029896fe77c31278df1f0f71e25344ad04bbf0..62c47b13e831eaf9397a134dfc1d778f96abe433 100644 (file)
@@ -23,6 +23,8 @@ namespace hooks {
 
 // @todo use the flat style, split into list and item
 
+string HooksLibrariesParser::default_hooks_path_ = string(DEFAULT_HOOKS_PATH);
+
 void
 HooksLibrariesParser::parse(HooksConfig& libraries, ConstElementPtr value) {
     // Initialize.
@@ -77,6 +79,11 @@ HooksLibrariesParser::parse(HooksConfig& libraries, ConstElementPtr value) {
                         entry_item.second->getPosition() << ")");
                 }
 
+                // If only the name of the library was provided, add the full path.
+                if (libname.find("/") == string::npos) {
+                    libname = HooksLibrariesParser::default_hooks_path_ + "/" + libname;
+                }
+
                 // Note we have found the library name.
                 lib_found = true;
                 continue;
index 441e56c1f1da75625c589ad0e9b48280d764987b..0fea1fe26b340ef373889f64e112e5c46eddc429 100644 (file)
@@ -57,6 +57,10 @@ public:
     /// @param libraries parsed libraries information will be stored here
     /// @param value pointer to the content to be parsed
     void parse(HooksConfig& libraries, isc::data::ConstElementPtr value);
+
+    /// @brief The default installation path for hooks, used to generate full
+    /// path if only the hook name is provided.
+    static std::string default_hooks_path_;
 };
 
 }  // namespace isc::hooks