From d3eda7f2f9cd6e754a5f778bb8c20b052dcf9a61 Mon Sep 17 00:00:00 2001 From: Thomas Markwalder Date: Mon, 30 Sep 2019 13:53:40 -0400 Subject: [PATCH] [#35,!517] Added function to move of DDNS cfg elements to global scope to SrvConfig src/lib/dhcpsrv/dhcpsrv_messages.* DHCPSRV_CFGMGR_DDNS_PARAMETER_IGNORED DHCPSRV_CFGMGR_DDNS_PARAMETER_MOVED src/lib/dhcpsrv/srv_config.* SrvConfig::moveDdnsParams() - new method to move parameters from dhcp-ddns to configured globals. src/lib/dhcpsrv/tests/srv_config_unittest.cc TEST_F(SrvConfigTest, moveDdnsParamsTest) - new test --- src/lib/dhcpsrv/dhcpsrv_messages.cc | 6 +- src/lib/dhcpsrv/dhcpsrv_messages.h | 4 +- src/lib/dhcpsrv/dhcpsrv_messages.mes | 19 ++ src/lib/dhcpsrv/srv_config.cc | 46 ++++- src/lib/dhcpsrv/srv_config.h | 2 + src/lib/dhcpsrv/tests/srv_config_unittest.cc | 177 +++++++++++++++++++ 6 files changed, 250 insertions(+), 4 deletions(-) diff --git a/src/lib/dhcpsrv/dhcpsrv_messages.cc b/src/lib/dhcpsrv/dhcpsrv_messages.cc index c877d365b0..08c0d9dfac 100644 --- a/src/lib/dhcpsrv/dhcpsrv_messages.cc +++ b/src/lib/dhcpsrv/dhcpsrv_messages.cc @@ -1,4 +1,4 @@ -// File created from ../../../src/lib/dhcpsrv/dhcpsrv_messages.mes on Fri Jun 21 2019 16:14 +// File created from ../../../src/lib/dhcpsrv/dhcpsrv_messages.mes on Mon Sep 30 2019 13:41 #include #include @@ -16,6 +16,8 @@ extern const isc::log::MessageID DHCPSRV_CFGMGR_CLEAR_ACTIVE_IFACES = "DHCPSRV_C extern const isc::log::MessageID DHCPSRV_CFGMGR_CONFIG4_MERGED = "DHCPSRV_CFGMGR_CONFIG4_MERGED"; extern const isc::log::MessageID DHCPSRV_CFGMGR_CONFIG6_MERGED = "DHCPSRV_CFGMGR_CONFIG6_MERGED"; extern const isc::log::MessageID DHCPSRV_CFGMGR_CONFIGURE_SERVERID = "DHCPSRV_CFGMGR_CONFIGURE_SERVERID"; +extern const isc::log::MessageID DHCPSRV_CFGMGR_DDNS_PARAMETER_IGNORED = "DHCPSRV_CFGMGR_DDNS_PARAMETER_IGNORED"; +extern const isc::log::MessageID DHCPSRV_CFGMGR_DDNS_PARAMETER_MOVED = "DHCPSRV_CFGMGR_DDNS_PARAMETER_MOVED"; extern const isc::log::MessageID DHCPSRV_CFGMGR_DEL_SUBNET4 = "DHCPSRV_CFGMGR_DEL_SUBNET4"; extern const isc::log::MessageID DHCPSRV_CFGMGR_DEL_SUBNET6 = "DHCPSRV_CFGMGR_DEL_SUBNET6"; extern const isc::log::MessageID DHCPSRV_CFGMGR_NEW_SUBNET4 = "DHCPSRV_CFGMGR_NEW_SUBNET4"; @@ -250,6 +252,8 @@ const char* values[] = { "DHCPSRV_CFGMGR_CONFIG4_MERGED", "Configuration backend data has been merged.", "DHCPSRV_CFGMGR_CONFIG6_MERGED", "Configuration backend data has been merged.", "DHCPSRV_CFGMGR_CONFIGURE_SERVERID", "server configuration includes specification of a server identifier", + "DHCPSRV_CFGMGR_DDNS_PARAMETER_IGNORED", "dhpd-ddns:%1 is deprecated, using existing global:%2", + "DHCPSRV_CFGMGR_DDNS_PARAMETER_MOVED", "dhcp-ddns:%1 is deprecated, moving it to global:%2", "DHCPSRV_CFGMGR_DEL_SUBNET4", "IPv4 subnet %1 removed", "DHCPSRV_CFGMGR_DEL_SUBNET6", "IPv6 subnet %1 removed", "DHCPSRV_CFGMGR_NEW_SUBNET4", "a new subnet has been added to configuration: %1", diff --git a/src/lib/dhcpsrv/dhcpsrv_messages.h b/src/lib/dhcpsrv/dhcpsrv_messages.h index effc486d09..79e8c072be 100644 --- a/src/lib/dhcpsrv/dhcpsrv_messages.h +++ b/src/lib/dhcpsrv/dhcpsrv_messages.h @@ -1,4 +1,4 @@ -// File created from ../../../src/lib/dhcpsrv/dhcpsrv_messages.mes on Fri Jun 21 2019 16:14 +// File created from ../../../src/lib/dhcpsrv/dhcpsrv_messages.mes on Mon Sep 30 2019 13:41 #ifndef DHCPSRV_MESSAGES_H #define DHCPSRV_MESSAGES_H @@ -17,6 +17,8 @@ extern const isc::log::MessageID DHCPSRV_CFGMGR_CLEAR_ACTIVE_IFACES; extern const isc::log::MessageID DHCPSRV_CFGMGR_CONFIG4_MERGED; extern const isc::log::MessageID DHCPSRV_CFGMGR_CONFIG6_MERGED; extern const isc::log::MessageID DHCPSRV_CFGMGR_CONFIGURE_SERVERID; +extern const isc::log::MessageID DHCPSRV_CFGMGR_DDNS_PARAMETER_IGNORED; +extern const isc::log::MessageID DHCPSRV_CFGMGR_DDNS_PARAMETER_MOVED; extern const isc::log::MessageID DHCPSRV_CFGMGR_DEL_SUBNET4; extern const isc::log::MessageID DHCPSRV_CFGMGR_DEL_SUBNET6; extern const isc::log::MessageID DHCPSRV_CFGMGR_NEW_SUBNET4; diff --git a/src/lib/dhcpsrv/dhcpsrv_messages.mes b/src/lib/dhcpsrv/dhcpsrv_messages.mes index fa451ab7df..e8a544e1bc 100644 --- a/src/lib/dhcpsrv/dhcpsrv_messages.mes +++ b/src/lib/dhcpsrv/dhcpsrv_messages.mes @@ -54,6 +54,25 @@ there is a good reason for it, to avoid increased number of renewals and a need for rebinding (increase of multicast traffic, which may be received by multiple servers). +% DHCPSRV_CFGMGR_DDNS_PARAMETER_IGNORED dhpd-ddns:%1 is deprecated, using existing global:%2 +This is an informational message issued during configuration parsing when +the server detects that a deprecated parameter has been specified in the +"dhcp-ddns" element which conflicts with its corresponding global parameter. +When this occurs the server simply ignores the value from dhcp-ddns. +The log message shows be the deprecated and the supported parameter names. +Note the configuration change only affects the in memory configuration. +You should modify your configuration to comply the supported parameters. + +% DHCPSRV_CFGMGR_DDNS_PARAMETER_MOVED dhcp-ddns:%1 is deprecated, moving it to global:%2 +This is an informational message issued during configuration parsing when +the server detects that a deprecated parameter has been specified in the +"dhcp-ddns" element for which no corresponding global value exists. When +this occurs the server removes the parameter from dhcp-ddns and inserts the +parameter into the global scope. The log message shows be the deprecated +and the supported parameter names. Note the configuration change only affects +the in memory configuration. You should modify your configuration to comply +the supported parameters. + % DHCPSRV_CFGMGR_DEL_SUBNET4 IPv4 subnet %1 removed This debug message is issued when a subnet is successfully removed from the server configuration. The argument identifies the subnet removed. diff --git a/src/lib/dhcpsrv/srv_config.cc b/src/lib/dhcpsrv/srv_config.cc index 0c681496d1..31c7043b7b 100644 --- a/src/lib/dhcpsrv/srv_config.cc +++ b/src/lib/dhcpsrv/srv_config.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -578,7 +579,8 @@ SrvConfig::toElement() const { return (result); } -DdnsParamsPtr SrvConfig::getDdnsParams(const Subnet& subnet) const { +DdnsParamsPtr +SrvConfig::getDdnsParams(const Subnet& subnet) const { DdnsParamsPtr params(new DdnsParams()); params->enable_updates_ = (getD2ClientConfig()->getEnableUpdates() && @@ -595,5 +597,45 @@ DdnsParamsPtr SrvConfig::getDdnsParams(const Subnet& subnet) const { return params; } +void +SrvConfig::moveDdnsParams(isc::data::ElementPtr d2_cfg) { + if (!d2_cfg || (d2_cfg->getType() != Element::map)) { + isc_throw(BadValue, "moveDdnsParams must be given a map element"); + } + + struct Param { + std::string from_name; + std::string to_name; + }; + + std::vector params { + { "override-no-update", "ddns-override-no-update" }, + { "override-client-update", "ddns-override-client-update" }, + { "replace-client-name", "ddns-replace-client-name" }, + { "generated-prefix", "ddns-generated-prefix" }, + { "qualifying-suffix", "ddns-qualifying-suffix" }, + { "hostname-char-set", "hostname-char-set" }, + { "hostname-char-replacement", "hostname-char-replacement" } + }; + + for (auto param : params) { + if (d2_cfg->contains(param.from_name)) { + if (!configured_globals_->contains(param.to_name)) { + // No global value for it already, so let's add it. + addConfiguredGlobal(param.to_name, d2_cfg->get(param.from_name)); + LOG_INFO(dhcpsrv_logger, DHCPSRV_CFGMGR_DDNS_PARAMETER_MOVED) + .arg(param.from_name).arg(param.to_name); + } else { + // Already a global value, we'll use it and ignore this one. + LOG_INFO(dhcpsrv_logger, DHCPSRV_CFGMGR_DDNS_PARAMETER_IGNORED) + .arg(param.from_name).arg(param.to_name); + } + + // Now remove it from d2_data, so D2ClientCfg won't complain. + d2_cfg->remove(param.from_name); + } + } } -} + +} // namespace dhcp +} // namespace isc diff --git a/src/lib/dhcpsrv/srv_config.h b/src/lib/dhcpsrv/srv_config.h index 875143260d..289a69e6ea 100644 --- a/src/lib/dhcpsrv/srv_config.h +++ b/src/lib/dhcpsrv/srv_config.h @@ -648,6 +648,8 @@ public: configured_globals_->set(name, value); } + void moveDdnsParams(isc::data::ElementPtr d2_cfg); + /// @brief Unparse a configuration object /// /// @return a pointer to unparsed configuration diff --git a/src/lib/dhcpsrv/tests/srv_config_unittest.cc b/src/lib/dhcpsrv/tests/srv_config_unittest.cc index 13e382d2c2..c1d4482ac8 100644 --- a/src/lib/dhcpsrv/tests/srv_config_unittest.cc +++ b/src/lib/dhcpsrv/tests/srv_config_unittest.cc @@ -1108,6 +1108,181 @@ TEST_F(SrvConfigTest, mergeGlobals6) { } +// Verifies that parameters formerly in dhcp-ddns{} are correctly moved +// to configured globals. +TEST_F(SrvConfigTest, moveDdnsParamsTest) { + DdnsParamsPtr params; + + CfgMgr::instance().setFamily(AF_INET); + + struct Scenario { + std::string description; + std::string d2_input; + std::string d2_output; + std::string input_globals; + std::string exp_globals; + }; + + std::vector scenarios { + { + "scenario 1, move with no global conflicts", + // d2_input + "{\n" + " \"enable-updates\": true, \n" + " \"server-ip\" : \"192.0.2.0\",\n" + " \"server-port\" : 3432,\n" + " \"sender-ip\" : \"192.0.2.1\",\n" + " \"sender-port\" : 3433,\n" + " \"max-queue-size\" : 2048,\n" + " \"ncr-protocol\" : \"UDP\",\n" + " \"ncr-format\" : \"JSON\",\n" + " \"user-context\": { \"foo\": \"bar\" },\n" + " \"override-no-update\": true,\n" + " \"override-client-update\": false,\n" + " \"replace-client-name\": \"always\",\n" + " \"generated-prefix\": \"prefix\",\n" + " \"qualifying-suffix\": \"suffix.com.\",\n" + " \"hostname-char-set\": \"[^A-Z]\",\n" + " \"hostname-char-replacement\": \"x\"\n" + "}\n", + // d2_output + "{\n" + " \"enable-updates\": true,\n" + " \"server-ip\" : \"192.0.2.0\",\n" + " \"server-port\" : 3432,\n" + " \"sender-ip\" : \"192.0.2.1\",\n" + " \"sender-port\" : 3433,\n" + " \"max-queue-size\" : 2048,\n" + " \"ncr-protocol\" : \"UDP\",\n" + " \"ncr-format\" : \"JSON\",\n" + " \"user-context\": { \"foo\": \"bar\" }\n" + "}\n", + // input_globals - no globals to start with + "{\n" + "}\n", + // exp_globals + "{\n" + " \"ddns-override-no-update\": true,\n" + " \"ddns-override-client-update\": false,\n" + " \"ddns-replace-client-name\": \"always\",\n" + " \"ddns-generated-prefix\": \"prefix\",\n" + " \"ddns-qualifying-suffix\": \"suffix.com.\",\n" + " \"hostname-char-set\": \"[^A-Z]\",\n" + " \"hostname-char-replacement\": \"x\"\n" + "}\n" + }, + + { + "scenario 2, globals already exist for all movable params", + // d2_input + "{\n" + " \"enable-updates\": true, \n" + " \"override-no-update\": true,\n" + " \"override-client-update\": true,\n" + " \"replace-client-name\": \"always\",\n" + " \"generated-prefix\": \"prefix\",\n" + " \"qualifying-suffix\": \"suffix.com.\",\n" + " \"hostname-char-set\": \"[^A-Z]\",\n" + " \"hostname-char-replacement\": \"x\"\n" + "}\n", + // d2_output + "{\n" + " \"enable-updates\": true \n" + "}\n", + // input_globals + "{\n" + " \"ddns-override-no-update\": false,\n" + " \"ddns-override-client-update\": false,\n" + " \"ddns-replace-client-name\": \"when-present\",\n" + " \"ddns-generated-prefix\": \"org_prefix\",\n" + " \"ddns-qualifying-suffix\": \"org_suffix.com.\",\n" + " \"hostname-char-set\": \"[^a-z]\",\n" + " \"hostname-char-replacement\": \"y\"\n" + "}\n", + // exp_globals + "{\n" + " \"ddns-override-no-update\": false,\n" + " \"ddns-override-client-update\": false,\n" + " \"ddns-replace-client-name\": \"when-present\",\n" + " \"ddns-generated-prefix\": \"org_prefix\",\n" + " \"ddns-qualifying-suffix\": \"org_suffix.com.\",\n" + " \"hostname-char-set\": \"[^a-z]\",\n" + " \"hostname-char-replacement\": \"y\"\n" + "}\n" + }, + + { + "scenario 3, nothing to move", + // d2_input + "{\n" + " \"enable-updates\": true, \n" + " \"server-ip\" : \"192.0.2.0\",\n" + " \"server-port\" : 3432,\n" + " \"sender-ip\" : \"192.0.2.1\"\n" + "}\n", + // d2_output + "{\n" + " \"enable-updates\": true,\n" + " \"server-ip\" : \"192.0.2.0\",\n" + " \"server-port\" : 3432,\n" + " \"sender-ip\" : \"192.0.2.1\"\n" + "}\n", + // input_globals + "{\n" + " \"hostname-char-set\": \"[^A-Z]\",\n" + " \"hostname-char-replacement\": \"x\"\n" + "}\n", + // exp_globals + "{\n" + " \"hostname-char-set\": \"[^A-Z]\",\n" + " \"hostname-char-replacement\": \"x\"\n" + "}\n" + }, + + }; + + for (auto scenario : scenarios) { + SrvConfig conf(32); + ConstElementPtr d2_input; + ConstElementPtr exp_d2_output; + ConstElementPtr input_globals; + ConstElementPtr exp_globals; + + { + SCOPED_TRACE(scenario.description); + ASSERT_NO_THROW(d2_input = Element::fromJSON(scenario.d2_input)) + << "d2_input didn't parse, test is broken"; + + ASSERT_NO_THROW(exp_d2_output = Element::fromJSON(scenario.d2_output)) + << "d2_output didn't parse, test is broken"; + + ASSERT_NO_THROW(input_globals = Element::fromJSON(scenario.input_globals)) + << "input_globals didn't parse, test is broken"; + + ASSERT_NO_THROW(exp_globals = Element::fromJSON(scenario.exp_globals)) + << "exp_globals didn't parse, test is broken"; + + // Create the original set of configured globals. + for (auto input_global : input_globals->mapValue()) { + conf.addConfiguredGlobal(input_global.first, input_global.second); + } + + // We need a mutable copy of d2_input to pass into the move function. + ElementPtr mutable_d2 = boost::const_pointer_cast(d2_input); + // NOw call moveDdnsParams. + ASSERT_NO_THROW(conf.moveDdnsParams(mutable_d2)); + + // Make sure the content of mutable_d2 is correct. + EXPECT_TRUE(mutable_d2->equals(*exp_d2_output)); + + // Make sure the content of configured globals. + EXPECT_TRUE(conf.getConfiguredGlobals()->equals(*exp_globals)); + } + } +} + +// Verifies that the scoped values for DDNS parameters can be fetched +// for a given Subnet4. TEST_F(SrvConfigTest, getDdnsParamsTest4) { DdnsParamsPtr params; @@ -1217,6 +1392,8 @@ TEST_F(SrvConfigTest, getDdnsParamsTest4) { EXPECT_TRUE(params->enable_updates_); } +// Verifies that the scoped values for DDNS parameters can be fetched +// for a given Subnet6. TEST_F(SrvConfigTest, getDdnsParamsTest6) { DdnsParamsPtr params; -- 2.47.2