Parcourir la source

[4096] Added client class dictionary to SrvConfig

src/lib/dhcpsrv/parsers/client_class_def_parser.cc
    ClientClassDefListParser::commit() - pushes the newly built local
    dictionary to CfgMgr staging

src/lib/dhcpsrv/srv_config.h
src/lib/dhcpsrv/srv_config.cc
    Added client class dictionary member to SrvConfig

src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc
    TEST_F(ClientClassDefListParserTest, simpleValidList) - now
    verifies that ClientClassDefListParser::commit() pushes its
    local dictionary to CfgMgr staging.

src/lib/dhcpsrv/tests/srv_config_unittest.cc
    Added support to test new client class dictionary member
Thomas Markwalder il y a 9 ans
Parent
commit
559c0a696a

+ 1 - 1
src/lib/dhcpsrv/parsers/client_class_def_parser.cc

@@ -147,7 +147,7 @@ ClientClassDefListParser::build(ConstElementPtr client_class_def_list) {
 
 void
 ClientClassDefListParser::commit() {
-    //  CfgMgr::instance().setClientClassConfig(local_dictionary_);
+    CfgMgr::instance().getStagingCfg()->setClientClassDictionary(local_dictionary_);
 }
 
 } // end of namespace isc::dhcp

+ 7 - 1
src/lib/dhcpsrv/srv_config.cc

@@ -32,6 +32,7 @@ SrvConfig::SrvConfig()
       cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()),
       cfg_hosts_(new CfgHosts()), cfg_rsoo_(new CfgRSOO()),
       cfg_expiration_(new CfgExpiration()),
+      class_dictionary_(new ClientClassDictionary()),
       decline_timer_(0) {
 }
 
@@ -41,6 +42,7 @@ SrvConfig::SrvConfig(const uint32_t sequence)
       cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()),
       cfg_hosts_(new CfgHosts()), cfg_rsoo_(new CfgRSOO()),
       cfg_expiration_(new CfgExpiration()),
+      class_dictionary_(new ClientClassDictionary()),
       decline_timer_(0) {
 }
 
@@ -103,6 +105,9 @@ SrvConfig::copy(SrvConfig& new_config) const {
     // Replace option definitions.
     cfg_option_def_->copyTo(*new_config.cfg_option_def_);
     cfg_option_->copyTo(*new_config.cfg_option_);
+    // Replace the client class dictionary
+    new_config.class_dictionary_.reset(new ClientClassDictionary(*class_dictionary_));
+
 }
 
 void
@@ -146,7 +151,8 @@ SrvConfig::equals(const SrvConfig& other) const {
     // Logging information is equal between objects, so check other values.
     return ((*cfg_iface_ == *other.cfg_iface_) &&
             (*cfg_option_def_ == *other.cfg_option_def_) &&
-            (*cfg_option_ == *other.cfg_option_));
+            (*cfg_option_ == *other.cfg_option_) &&
+            (*class_dictionary_ == *other.class_dictionary_));
 }
 
 void

+ 22 - 0
src/lib/dhcpsrv/srv_config.h

@@ -24,6 +24,7 @@
 #include <dhcpsrv/cfg_subnets4.h>
 #include <dhcpsrv/cfg_subnets6.h>
 #include <dhcpsrv/cfg_mac_source.h>
+#include <dhcpsrv/client_class_def.h>
 #include <dhcpsrv/logging_info.h>
 #include <cc/data.h>
 #include <boost/shared_ptr.hpp>
@@ -302,6 +303,24 @@ public:
         control_socket_ = control_socket;
     }
 
+    /// @brief Returns pointer to the dictionary of global client
+    /// class definitions
+    ClientClassDictionaryPtr getClientClassDictionary() {
+        return (class_dictionary_);
+    }
+
+    /// @brief Returns pointer to const dictionary of global client
+    /// class definitions
+    const ClientClassDictionaryPtr getClientClassDictionary() const {
+        return (class_dictionary_);
+    }
+
+    /// @brief Sets the client class dictionary
+    /// @param dictionary pointer to the new class dictionary
+    void setClientClassDictionary(const ClientClassDictionaryPtr& dictionary) {
+        class_dictionary_ = dictionary;
+    }
+
     /// @brief Copies the currnet configuration to a new configuration.
     ///
     /// This method copies the parameters stored in the configuration to
@@ -461,6 +480,9 @@ private:
     /// @brief Pointer to the control-socket information
     isc::data::ConstElementPtr control_socket_;
 
+    /// @brief Pointer to the dictionary of global client class definitions
+    ClientClassDictionaryPtr class_dictionary_;
+
     /// @brief Decline Period time
     ///
     /// This timer specifies decline probation period, the time after a declined

+ 10 - 0
src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc

@@ -101,6 +101,9 @@ protected:
         ClientClassDefListParser parser("", context);
         parser.build(config_element);
 
+        // Commit should push it to CfgMgr staging
+        parser.commit();
+
         // Return the parser's local dicationary
         return (parser.local_dictionary_);
     }
@@ -417,6 +420,13 @@ TEST_F(ClientClassDefListParserTest, simpleValidList) {
     // For good measure, make sure we can't find a non-existant class.
     ASSERT_NO_THROW(cclass = dictionary->findClass("bogus"));
     EXPECT_FALSE(cclass);
+
+    // Verify that the dictionary was pushed to the CfgMgr's staging config.
+    SrvConfigPtr staging = CfgMgr::instance().getStagingCfg();
+    ASSERT_TRUE(staging);
+    ClientClassDictionaryPtr staged_dictionary = staging->getClientClassDictionary();
+    ASSERT_TRUE(staged_dictionary);
+    EXPECT_TRUE(*staged_dictionary == *dictionary);
 }
 
 // Verifies that class list containing a duplicate class entries, fails

+ 43 - 1
src/lib/dhcpsrv/tests/srv_config_unittest.cc

@@ -40,7 +40,8 @@ public:
     /// Creates IPv4 and IPv6 subnets for unit test. The number of subnets
     /// is @c TEST_SUBNETS_NUM for IPv4 and IPv6 each.
     SrvConfigTest()
-        : iface_mgr_test_config_(true) {
+        : iface_mgr_test_config_(true),
+          ref_dictionary_(new ClientClassDictionary()) {
 
         // Disable DDNS.
         enableDDNS(false);
@@ -69,8 +70,14 @@ public:
             Subnet6Ptr subnet(new Subnet6(prefix, 64, 1000, 2000, 3000, 4000));
             test_subnets6_.push_back(subnet);
         }
+
+        // Build our reference dictionary of client classes
+        ref_dictionary_->addClass("cc1", ExpressionPtr(), CfgOptionPtr());
+        ref_dictionary_->addClass("cc2", ExpressionPtr(), CfgOptionPtr());
+        ref_dictionary_->addClass("cc3", ExpressionPtr(), CfgOptionPtr());
     }
 
+
     /// @brief Destructor.
     virtual ~SrvConfigTest() {
     }
@@ -118,6 +125,8 @@ public:
     /// @brief Fakes interface configuration.
     isc::dhcp::test::IfaceMgrTestConfig iface_mgr_test_config_;
 
+    /// @brief Client class dictionary with fixed content
+    ClientClassDictionaryPtr ref_dictionary_;
 };
 
 void
@@ -239,6 +248,26 @@ TEST_F(SrvConfigTest, summarySubnets) {
 
 }
 
+// Verifies that we can get and set the client class dictionary
+TEST_F(SrvConfigTest, classDictionaryBasics) {
+    ClientClassDictionaryPtr d1;
+    SrvConfig conf(32);
+
+    // Upon construction the dictionary should be empty.
+    ASSERT_TRUE(d1 = conf.getClientClassDictionary());
+    EXPECT_EQ(0, d1->getClasses()->size());
+
+    // Verify we can replace it with a new dictionary.
+    ASSERT_NO_THROW(conf.setClientClassDictionary(ref_dictionary_));
+    ASSERT_TRUE(d1 = conf.getClientClassDictionary());
+    EXPECT_EQ(ref_dictionary_->getClasses()->size(), d1->getClasses()->size());
+
+    // Verify const fetcher works too.
+    const ClientClassDictionaryPtr cd = conf.getClientClassDictionary();
+    ASSERT_TRUE(cd);
+    EXPECT_EQ(ref_dictionary_->getClasses()->size(), cd->getClasses()->size());
+}
+
 // This test checks if entire configuration can be copied and that the sequence
 // number is not affected.
 TEST_F(SrvConfigTest, copy) {
@@ -265,6 +294,9 @@ TEST_F(SrvConfigTest, copy) {
     OptionPtr option(new Option(Option::V6, 1000, OptionBuffer(10, 0xFF)));
     conf1.getCfgOption()->add(option, true, "dhcp6");
 
+    // Add a class dictionary
+    conf1.setClientClassDictionary(ref_dictionary_);
+
     // Make sure both configurations are different.
     ASSERT_TRUE(conf1 != conf2);
 
@@ -342,6 +374,16 @@ TEST_F(SrvConfigTest, equality) {
 
     EXPECT_TRUE(conf1 == conf2);
     EXPECT_FALSE(conf1 != conf2);
+
+    // Add a class dictionary to conf1
+    conf1.setClientClassDictionary(ref_dictionary_);
+    EXPECT_FALSE(conf1 == conf2);
+    EXPECT_TRUE(conf1 != conf2);
+
+    // Add same class dictionary to conf2
+    conf2.setClientClassDictionary(ref_dictionary_);
+    EXPECT_TRUE(conf1 == conf2);
+    EXPECT_FALSE(conf1 != conf2);
 }
 
 } // end of anonymous namespace