Browse Source

[3034] Add dhcp-ddns element to b10-dhcp6 configuration

Added "dhpc-ddns" element to dhcp6.spec file.
Added "dhcp-ddns" to list of elements recognized in createGlobal6DhcpConfigParser()
Added unit tests for dhcp-ddns parsing.
Thomas Markwalder 11 years ago
parent
commit
9e8af834e7

+ 2 - 0
src/bin/dhcp6/config_parser.cc

@@ -640,6 +640,8 @@ DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id) {
         parser = new DbAccessParser(config_id);
     } else if (config_id.compare("hooks-libraries") == 0) {
         parser = new HooksLibrariesParser(config_id);
+    } else if (config_id.compare("dhcp-ddns") == 0) {
+        parser = new D2ClientConfigParser(config_id);
     } else {
         isc_throw(NotImplemented,
                 "Parser error: Global configuration parameter not supported: "

+ 88 - 1
src/bin/dhcp6/dhcp6.spec

@@ -352,7 +352,94 @@
                   }
                 } ]
             }
-       }
+      },
+      { "item_name": "dhcp-ddns",
+        "item_type": "map",
+        "item_optional": false,
+        "item_default": {"enable-updates": false},
+        "item_description" : "Contains parameters pertaining DHCP-driven DDNS updates",
+        "map_item_spec": [
+            {
+                "item_name": "enable-updates",
+                "item_type": "boolean",
+                "item_optional": false,
+                "item_default": false,
+                "item_description" : "Enables DDNS update processing"
+            },
+            {
+                "item_name": "server-ip",
+                "item_type": "string",
+                "item_optional": true,
+                "item_default": "127.0.0.1",
+                "item_description" : "IP address of b10-dhcp-ddns (IPv4 or IPv6)"
+            },
+            {
+                "item_name": "server-port",
+                "item_type": "integer",
+                "item_optional": true,
+                "item_default": 53001,
+                "item_description" : "port number of b10-dhcp-ddns"
+            },
+            {
+                "item_name": "ncr-protocol",
+                "item_type": "string",
+                "item_optional": true,
+                "item_default": "UDP",
+                "item_description" : "Socket protocol to use with b10-dhcp-ddns"
+            },
+            {
+                "item_name": "ncr-format",
+                "item_type": "string",
+                "item_optional": true,
+                "item_default": "JSON",
+                "item_description" : "Format of the update request packet"
+            },
+            {
+
+                "item_name": "always-include-fqdn",
+                "item_type": "boolean",
+                "item_optional": true,
+                "item_default": false,
+                "item_description": "Enable always including the FQDN option in its response"
+            },
+            {
+                "item_name": "override-no-update",
+                "item_type": "boolean",
+                "item_optional": true,
+                "item_default": false,
+                "item_description": "Do update, even if client requested no updates with N flag"
+            },
+            {
+                "item_name": "override-client-update",
+                "item_type": "boolean",
+                "item_optional": true,
+                "item_default": false,
+                "item_description": "Server performs an update even if client requested delegation"
+            },
+            {
+                "item_name": "replace-client-name",
+                "item_type": "boolean",
+                "item_optional": true,
+                "item_default": false,
+                "item_description": "Should server replace the domain-name supplied by the client"
+            },
+            {
+                "item_name": "generated-prefix",
+                "item_type": "string",
+                "item_optional": true,
+                "item_default": "myhost",
+                "item_description": "Prefix to use when generating the client's name"
+            },
+
+            {
+                "item_name": "qualifying-suffix",
+                "item_type": "string",
+                "item_optional": true,
+                "item_default": "example.com",
+                "item_description": "Fully qualified domain-name suffix if partial name provided by client"
+            },
+        ]
+      },
     ],
     "commands": [
         {

+ 109 - 0
src/bin/dhcp6/tests/config_parser_unittest.cc

@@ -347,6 +347,7 @@ public:
             "\"renew-timer\": 1000, "
             "\"valid-lifetime\": 4000, "
             "\"subnet6\": [ ], "
+            "\"dhcp-ddns\": { \"enable-updates\" : false }, "
             "\"option-def\": [ ], "
             "\"option-data\": [ ] }";
         static_cast<void>(executeConfiguration(config,
@@ -3091,5 +3092,113 @@ TEST_F(Dhcp6ParserTest, classifySubnets) {
     EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
 }
 
+// This test checks the ability of the server to parse a configuration
+// containing a full, valid dhcp-ddns (D2ClientConfig) entry.
+TEST_F(Dhcp6ParserTest, d2ClientConfig) {
+    ConstElementPtr status;
+
+    // Verify that the D2 configuraiton can be fetched and is set to disabled.
+    D2ClientConfigPtr d2_client_config = CfgMgr::instance().getD2ClientConfig();
+    EXPECT_FALSE(d2_client_config->getEnableUpdates());
+
+    // Verify that the convenience method agrees.
+    ASSERT_FALSE(CfgMgr::instance().ddnsEnabled());
+
+    string config_str = "{ \"interfaces\": [ \"*\" ],"
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"subnet6\": [ { "
+        "    \"pool\": [ \"2001:db8:1::/80\" ],"
+        "    \"subnet\": \"2001:db8:1::/64\" } ], "
+        " \"dhcp-ddns\" : {"
+        "     \"enable-updates\" : true, "
+        "     \"server-ip\" : \"192.168.2.1\", "
+        "     \"server-port\" : 777, "
+        "     \"ncr-protocol\" : \"UDP\", "
+        "     \"ncr-format\" : \"JSON\", "
+        "     \"always-include-fqdn\" : true, "
+        "     \"allow-client-update\" : true, "
+        "     \"override-no-update\" : true, "
+        "     \"override-client-update\" : true, "
+        "     \"replace-client-name\" : true, "
+        "     \"generated-prefix\" : \"test.prefix\", "
+        "     \"qualifying-suffix\" : \"test.suffix.\" },"
+        "\"valid-lifetime\": 4000 }";
+
+    // Convert the JSON string to configuration elements.
+    ElementPtr config;
+    ASSERT_NO_THROW(config = Element::fromJSON(config_str));
+
+    // Pass the configuration in for parsing.
+    EXPECT_NO_THROW(status = configureDhcp6Server(srv_, config));
+
+    // check if returned status is OK
+    checkResult(status, 0);
+
+    // Verify that DHCP-DDNS updating is enabled.
+    EXPECT_TRUE(CfgMgr::instance().ddnsEnabled());
+
+    // Verify that the D2 configuration can be retrieved.
+    d2_client_config = CfgMgr::instance().getD2ClientConfig();
+    ASSERT_TRUE(d2_client_config);
+
+    // Verify that the configuration values are correct.
+    EXPECT_TRUE(d2_client_config->getEnableUpdates());
+    EXPECT_EQ("192.168.2.1", d2_client_config->getServerIp().toText());
+    EXPECT_EQ(777, d2_client_config->getServerPort());
+    EXPECT_EQ(dhcp_ddns::NCR_UDP, d2_client_config->getNcrProtocol());
+    EXPECT_EQ(dhcp_ddns::FMT_JSON, d2_client_config->getNcrFormat());
+    EXPECT_TRUE(d2_client_config->getAlwaysIncludeFqdn());
+    EXPECT_TRUE(d2_client_config->getOverrideNoUpdate());
+    EXPECT_TRUE(d2_client_config->getOverrideClientUpdate());
+    EXPECT_TRUE(d2_client_config->getReplaceClientName());
+    EXPECT_EQ("test.prefix", d2_client_config->getGeneratedPrefix());
+    EXPECT_EQ("test.suffix.", d2_client_config->getQualifyingSuffix());
+}
+
+// This test checks the ability of the server to handle a configuration
+// containing an invalid dhcp-ddns (D2ClientConfig) entry.
+TEST_F(Dhcp6ParserTest, invalidD2ClientConfig) {
+    ConstElementPtr status;
+
+    // Configuration string with an invalid D2 client config,
+    // "server-ip" is missing.
+    string config_str = "{ \"interfaces\": [ \"*\" ],"
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"subnet6\": [ { "
+        "    \"pool\": [ \"2001:db8:1::/80\" ],"
+        "    \"subnet\": \"2001:db8:1::/64\" } ], "
+        " \"dhcp-ddns\" : {"
+        "     \"enable-updates\" : true, "
+        "     \"server-port\" : 5301, "
+        "     \"ncr-protocol\" : \"UDP\", "
+        "     \"ncr-format\" : \"JSON\", "
+        "     \"always-include-fqdn\" : true, "
+        "     \"allow-client-update\" : true, "
+        "     \"override-no-update\" : true, "
+        "     \"override-client-update\" : true, "
+        "     \"replace-client-name\" : true, "
+        "     \"generated-prefix\" : \"test.prefix\", "
+        "     \"qualifying-suffix\" : \"test.suffix.\" },"
+        "\"valid-lifetime\": 4000 }";
+
+    // Convert the JSON string to configuration elements.
+    ElementPtr config;
+    ASSERT_NO_THROW(config = Element::fromJSON(config_str));
+
+    // Configuration should not throw, but should fail.
+    EXPECT_NO_THROW(status = configureDhcp6Server(srv_, config));
+
+    // check if returned status is failed.
+    checkResult(status, 1);
+
+    // Verify that the D2 configuraiton can be fetched and is set to disabled.
+    D2ClientConfigPtr d2_client_config = CfgMgr::instance().getD2ClientConfig();
+    EXPECT_FALSE(d2_client_config->getEnableUpdates());
+
+    // Verify that the convenience method agrees.
+    ASSERT_FALSE(CfgMgr::instance().ddnsEnabled());
+}
 
 };