Browse Source

[3432] Replaced sting key_name with TSIGKeyInfo in d2::DdnsDomain

Rather than each DdnsDomain storing only the string name of its TSIG key,
it now contains an pointer to the TSIGKeyInfo which corresponds to the
key name given in its configuration.
Thomas Markwalder 11 years ago
parent
commit
d980423746

+ 27 - 8
src/bin/d2/d2_config.cc

@@ -110,14 +110,25 @@ operator<<(std::ostream& os, const DnsServerInfo& server) {
 
 // *********************** DdnsDomain  *************************
 
-DdnsDomain::DdnsDomain(const std::string& name, const std::string& key_name,
-                       DnsServerInfoStoragePtr servers)
-    : name_(name), key_name_(key_name), servers_(servers) {
+DdnsDomain::DdnsDomain(const std::string& name,
+                       DnsServerInfoStoragePtr servers,
+                       const TSIGKeyInfoPtr& tsig_key_info)
+    : name_(name), servers_(servers),
+      tsig_key_info_(tsig_key_info) {
 }
 
 DdnsDomain::~DdnsDomain() {
 }
 
+const std::string
+DdnsDomain::getKeyName() const {
+    if (tsig_key_info_) {
+        return (tsig_key_info_->getName());
+    }
+
+    return ("");
+}
+
 // *********************** DdnsDomainLstMgr  *************************
 
 const char* DdnsDomainListMgr::wildcard_domain_name_ = "*";
@@ -546,18 +557,26 @@ DdnsDomainParser::build(isc::data::ConstElementPtr domain_config) {
         isc_throw(D2CfgError, "Duplicate domain specified:" << name);
     }
 
-    // Key name is optional. If it is not blank, then validate it against
-    // the defined list of keys.
+    // Key name is optional. If it is not blank, then find the key in the
+    /// list of defined keys.
+    TSIGKeyInfoPtr tsig_key_info;
     local_scalars_.getParam("key_name", key_name, DCfgContextBase::OPTIONAL);
     if (!key_name.empty()) {
-        if ((!keys_) || (keys_->find(key_name) == keys_->end())) {
+        if (keys_) {
+            TSIGKeyInfoMap::iterator kit = keys_->find(key_name);
+            if (kit != keys_->end()) {
+                tsig_key_info = kit->second;
+            }
+        }
+
+        if (!tsig_key_info) {
             isc_throw(D2CfgError, "DdnsDomain :" << name <<
-                     " specifies and undefined key:" << key_name);
+                     " specifies an undefined key:" << key_name);
         }
     }
 
     // Instantiate the new domain and add it to domain storage.
-    DdnsDomainPtr domain(new DdnsDomain(name, key_name, local_servers_));
+    DdnsDomainPtr domain(new DdnsDomain(name, local_servers_, tsig_key_info));
 
     // Add the new domain to the domain storage.
     (*domains_)[name] = domain;

+ 16 - 11
src/bin/d2/d2_config.h

@@ -390,10 +390,12 @@ public:
     /// @brief Constructor
     ///
     /// @param name is the domain name of the domain.
-    /// @param key_name is the TSIG key name for use with this domain.
     /// @param servers is the list of server(s) supporting this domain.
-    DdnsDomain(const std::string& name, const std::string& key_name,
-               DnsServerInfoStoragePtr servers);
+    /// @param tsig_key_info pointer to the TSIGKeyInfo for the dommain's key
+    /// It defaults to an empty pointer, signifying the domain has no key.
+    DdnsDomain(const std::string& name,
+               DnsServerInfoStoragePtr servers,
+               const TSIGKeyInfoPtr& tsig_key_info = TSIGKeyInfoPtr());
 
     /// @brief Destructor
     virtual ~DdnsDomain();
@@ -405,12 +407,11 @@ public:
         return (name_);
     }
 
-    /// @brief Getter which returns the domain's TSIG key name.
+    /// @brief Conveneince method which returns the domain's TSIG key name.
     ///
-    /// @return returns the key name in an std::string.
-    const std::string getKeyName() const {
-        return (key_name_);
-    }
+    /// @return returns the key name in an std::string. If domain has no
+    /// TSIG key, the string will empty.
+    const std::string getKeyName() const;
 
     /// @brief Getter which returns the domain's list of servers.
     ///
@@ -419,15 +420,19 @@ public:
         return (servers_);
     }
 
+    const TSIGKeyInfoPtr& getTSIGKeyInfo() {
+        return (tsig_key_info_);
+    }
+
 private:
     /// @brief The domain name of the domain.
     std::string name_;
 
-    /// @brief The name of the TSIG key for use with this domain.
-    std::string key_name_;
-
     /// @brief The list of server(s) supporting this domain.
     DnsServerInfoStoragePtr servers_;
+
+    /// @brief
+    TSIGKeyInfoPtr tsig_key_info_;
 };
 
 /// @brief Defines a pointer for DdnsDomain instances.

+ 6 - 0
src/bin/d2/tests/d2_cfg_mgr_unittests.cc

@@ -741,6 +741,8 @@ TEST_F(DdnsDomainTest, ddnsDomainParsing) {
     // Verify the name and key_name values.
     EXPECT_EQ("tmark.org", domain->getName());
     EXPECT_EQ("d2_key.tmark.org", domain->getKeyName());
+    ASSERT_TRUE(domain->getTSIGKeyInfo());
+    ASSERT_TRUE(domain->getTSIGKeyInfo()->getTSIGKey());
 
     // Verify that the server list exists and contains the correct number of
     // servers.
@@ -822,6 +824,8 @@ TEST_F(DdnsDomainTest, DdnsDomainListParsing) {
     // Verify the name and key_name values of the first domain.
     EXPECT_EQ("tmark.org", domain->getName());
     EXPECT_EQ("d2_key.tmark.org", domain->getKeyName());
+    ASSERT_TRUE(domain->getTSIGKeyInfo());
+    ASSERT_TRUE(domain->getTSIGKeyInfo()->getTSIGKey());
 
     // Verify the each of the first domain's servers
     DnsServerInfoStoragePtr servers = domain->getServers();
@@ -849,6 +853,8 @@ TEST_F(DdnsDomainTest, DdnsDomainListParsing) {
     // Verify the name and key_name values of the second domain.
     EXPECT_EQ("billcat.net", domain->getName());
     EXPECT_EQ("d2_key.billcat.net", domain->getKeyName());
+    ASSERT_TRUE(domain->getTSIGKeyInfo());
+    ASSERT_TRUE(domain->getTSIGKeyInfo()->getTSIGKey());
 
     // Verify the each of second domain's servers
     servers = domain->getServers();

+ 2 - 2
src/bin/d2/tests/nc_add_unittests.cc

@@ -284,8 +284,8 @@ TEST(NameAddTransaction, construction) {
     DdnsDomainPtr empty_domain;
 
     ASSERT_NO_THROW(ncr = dhcp_ddns::NameChangeRequest::fromJSON(msg_str));
-    ASSERT_NO_THROW(forward_domain.reset(new DdnsDomain("*", "", servers)));
-    ASSERT_NO_THROW(reverse_domain.reset(new DdnsDomain("*", "", servers)));
+    ASSERT_NO_THROW(forward_domain.reset(new DdnsDomain("*", servers)));
+    ASSERT_NO_THROW(reverse_domain.reset(new DdnsDomain("*", servers)));
 
     // Verify that construction with wrong change type fails.
     EXPECT_THROW(NameAddTransaction(io_service, ncr,

+ 2 - 2
src/bin/d2/tests/nc_remove_unittests.cc

@@ -286,8 +286,8 @@ TEST(NameRemoveTransaction, construction) {
     DdnsDomainPtr empty_domain;
 
     ASSERT_NO_THROW(ncr = dhcp_ddns::NameChangeRequest::fromJSON(msg_str));
-    ASSERT_NO_THROW(forward_domain.reset(new DdnsDomain("*", "", servers)));
-    ASSERT_NO_THROW(reverse_domain.reset(new DdnsDomain("*", "", servers)));
+    ASSERT_NO_THROW(forward_domain.reset(new DdnsDomain("*", servers)));
+    ASSERT_NO_THROW(reverse_domain.reset(new DdnsDomain("*", servers)));
 
     // Verify that construction with wrong change type fails.
     EXPECT_THROW(NameRemoveTransaction(io_service, ncr,

+ 18 - 1
src/bin/d2/tests/nc_test_utils.cc

@@ -418,10 +418,27 @@ DdnsDomainPtr makeDomain(const std::string& zone_name,
                          const std::string& key_name) {
     DdnsDomainPtr domain;
     DnsServerInfoStoragePtr servers(new DnsServerInfoStorage());
-    domain.reset(new DdnsDomain(zone_name, key_name, servers));
+    domain.reset(new DdnsDomain(zone_name, servers, makeTSIGKey(key_name)));
     return (domain);
 }
 
+TSIGKeyInfoPtr makeTSIGKey(const std::string& key_name,
+                           const std::string& secret,
+                           const std::string& algorithm) {
+    TSIGKeyInfoPtr key_info;
+    if (!key_name.empty()) {
+        if (!secret.empty()) {
+            key_info.reset(new TSIGKeyInfo(key_name, algorithm, secret));
+        } else {
+            // if no secret, then just use the key_name for it
+            key_info.reset(new TSIGKeyInfo(key_name, algorithm, key_name));
+        }
+    }
+
+    return (key_info);
+
+}
+
 void addDomainServer(DdnsDomainPtr& domain, const std::string& name,
                      const std::string& ip, const size_t port) {
     DnsServerInfoPtr server(new DnsServerInfo(name, asiolink::IOAddress(ip),

+ 15 - 1
src/bin/d2/tests/nc_test_utils.h

@@ -349,12 +349,26 @@ dhcp_ddns::NameChangeRequestPtr makeNcrFromString(const std::string& ncr_str);
 /// @brief Creates a DdnsDomain with the one server.
 ///
 /// @param zone_name zone name of the domain
-/// @param key_name TSIG key name of the TSIG key for this domain
+/// @param key_name TSIG key name of the TSIG key for this domain. Defaults to
+/// blank which means the DdnsDomain does not have a key.
 ///
 /// @throw Underlying methods may throw.
 extern DdnsDomainPtr makeDomain(const std::string& zone_name,
                                 const std::string& key_name = "");
 
+/// @brief Creates a TSIGKeyInfo
+///
+/// @param key_name name of the key
+/// @param secret key secret data.  If blank, the key_name will be used.
+/// @param algorithm algorithm to use. Defaults to MD5.
+/// @return a TSIGKeyInfoPtr for the newly created key.  If key_name is blank
+/// the pointer will be empty.
+/// @throw Underlying methods may throw.
+extern
+TSIGKeyInfoPtr makeTSIGKey(const std::string& key_name,
+                           const std::string& secret = "",
+                           const std::string& algorithm = TSIGKeyInfo::MD5_STR);
+
 /// @brief Creates a DnsServerInfo and adds it to the given DdnsDomain.
 ///
 /// The server is created and added to the domain, without duplicate entry

+ 2 - 2
src/bin/d2/tests/nc_trans_unittests.cc

@@ -371,8 +371,8 @@ TEST(NameChangeTransaction, construction) {
     DdnsDomainPtr empty_domain;
 
     ASSERT_NO_THROW(ncr = dhcp_ddns::NameChangeRequest::fromJSON(msg_str));
-    ASSERT_NO_THROW(forward_domain.reset(new DdnsDomain("*", "", servers)));
-    ASSERT_NO_THROW(reverse_domain.reset(new DdnsDomain("*", "", servers)));
+    ASSERT_NO_THROW(forward_domain.reset(new DdnsDomain("*", servers)));
+    ASSERT_NO_THROW(reverse_domain.reset(new DdnsDomain("*", servers)));
 
     // Verify that construction with a null IOServicePtr fails.
     // @todo Subject to change if multi-threading is implemented.