}
if (config_pair.first == "dhcp-ddns") {
+ // Apply defaults if not in short cut
+ if (!!D2ClientConfigParser::isShortCutDisabled(config_pair.second)) {
+ D2ClientConfigParser::setAllDefaults(config_pair.second);
+ }
D2ClientConfigParser parser;
D2ClientConfigPtr cfg = parser.parse(config_pair.second);
CfgMgr::instance().getStagingCfg()->setD2ClientConfig(cfg);
-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
"rebind-timer",
"valid-lifetime"
};
-
-/// @brief This table defines default values for D2 client configuration
-///
-const SimpleDefaults SimpleParser4::D2_CLIENT_CONFIG_DEFAULTS = {
- { "server-ip", Element::string, "127.0.0.1" },
- { "server-port", Element::integer, "53001" },
- // default sender-ip depends on server-ip family, so we leave default blank
- // parser knows to use the appropriate ZERO address based on server-ip
- { "sender-ip", Element::string, "" },
- { "sender-port", Element::integer, "0" },
- { "max-queue-size", Element::integer, "1024" },
- { "ncr-protocol", Element::string, "UDP" },
- { "ncr-format", Element::string, "JSON" },
- { "always-include-fqdn", Element::boolean, "false" },
- { "override-no-update", Element::boolean, "false" },
- { "override-client-update", Element::boolean, "false" },
- { "replace-client-name", Element::string, "NEVER" },
- { "generated-prefix", Element::string, "myhost" },
- { "qualifying-suffix", Element::string, "" }
-};
-
/// @}
/// ---------------------------------------------------------------------------
}
}
- ConstElementPtr d2_client = global->get("dhcp-ddns");
- /// @todo - what if it's not in global? should we add it?
- if (d2_client) {
- // Get the mutable form of d2 client config
- ElementPtr mutable_d2 = boost::const_pointer_cast<Element>(d2_client);
- cnt += SimpleParser::setDefaults(mutable_d2, D2_CLIENT_CONFIG_DEFAULTS);
- }
-
return (cnt);
}
-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
static const isc::data::SimpleDefaults OPTION4_DEFAULTS;
static const isc::data::SimpleDefaults GLOBAL4_DEFAULTS;
static const isc::data::ParamsList INHERIT_GLOBAL_TO_SUBNET4;
- static const isc::data::SimpleDefaults D2_CLIENT_CONFIG_DEFAULTS;
};
};
}
if (config_pair.first == "dhcp-ddns") {
+ // Apply defaults if not in short cut
+ if (!!D2ClientConfigParser::isShortCutDisabled(config_pair.second)) {
+ D2ClientConfigParser::setAllDefaults(config_pair.second);
+ }
D2ClientConfigParser parser;
D2ClientConfigPtr cfg = parser.parse(config_pair.second);
CfgMgr::instance().getStagingCfg()->setD2ClientConfig(cfg);
-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
"preferred-lifetime",
"valid-lifetime"
};
-
-/// @brief This table defines default values for D2 client configuration
-///
-const SimpleDefaults SimpleParser6::D2_CLIENT_CONFIG_DEFAULTS = {
- { "server-ip", Element::string, "127.0.0.1" },
- { "server-port", Element::integer, "53001" },
- // default sender-ip depends on server-ip family, so we leave default blank
- // parser knows to use the appropriate ZERO address based on server-ip
- { "sender-ip", Element::string, "" },
- { "sender-port", Element::integer, "0" },
- { "max-queue-size", Element::integer, "1024" },
- { "ncr-protocol", Element::string, "UDP" },
- { "ncr-format", Element::string, "JSON" },
- { "always-include-fqdn", Element::boolean, "false" },
- { "override-no-update", Element::boolean, "false" },
- { "override-client-update", Element::boolean, "false" },
- { "replace-client-name", Element::string, "NEVER" },
- { "generated-prefix", Element::string, "myhost" },
- { "qualifying-suffix", Element::string, "" }
-};
-
/// @}
/// ---------------------------------------------------------------------------
}
}
- ConstElementPtr d2_client = global->get("dhcp-ddns");
- /// @todo - what if it's not in global? should we add it?
- if (d2_client) {
- // Get the mutable form of d2 client config
- ElementPtr mutable_d2 = boost::const_pointer_cast<Element>(d2_client);
- cnt += SimpleParser::setDefaults(mutable_d2, D2_CLIENT_CONFIG_DEFAULTS);
- }
-
return (cnt);
}
-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
static const isc::data::SimpleDefaults OPTION6_DEFAULTS;
static const isc::data::SimpleDefaults GLOBAL6_DEFAULTS;
static const isc::data::ParamsList INHERIT_GLOBAL_TO_SUBNET6;
- static const isc::data::SimpleDefaults D2_CLIENT_CONFIG_DEFAULTS;
};
};
std::string qualifying_suffix;
std::string current_param;
+
+ if (isShortCutDisabled(client_config)) {
+ // If enable-updates is the only parameter and it is false then
+ // we're done. This allows for an abbreviated configuration entry
+ // that only contains that flag. Use the default D2ClientConfig
+ // constructor to a create a disabled instance.
+ new_config.reset(new D2ClientConfig());
+ return (new_config);
+ }
+
// Get all parameters that are needed to create the D2ClientConfig.
// We fetch all the parameters inside their own try clause so we
// spit out an error with an accurate text position. Use the
return(new_config);
}
+bool
+D2ClientConfigParser::isShortCutDisabled(isc::data::ConstElementPtr d2_config) {
+ if (!d2_config->contains("enable-updates")) {
+ isc_throw(DhcpConfigError,
+ "Mandatory parameter 'enable-updates' missing ("
+ << d2_config->getPosition() << ")");
+ }
+ ConstElementPtr enable = d2_config->get("enable-updates");
+ if (enable->getType() != Element::boolean) {
+ isc_throw(DhcpConfigError,
+ "invalid value type specified for parameter"
+ " 'enable-updates' (" << enable->getPosition() << ")");
+ }
+ return (!enable->boolValue() && (d2_config->mapValue().size() == 1));
+}
+
+/// @brief This table defines default values for D2 client configuration
+const SimpleDefaults D2ClientConfigParser::D2_CLIENT_CONFIG_DEFAULTS = {
+ // enable-updates is unconditionally required
+ { "server-ip", Element::string, "127.0.0.1" },
+ { "server-port", Element::integer, "53001" },
+ // default sender-ip depends on server-ip family, so we leave default blank
+ // parser knows to use the appropriate ZERO address based on server-ip
+ { "sender-ip", Element::string, "" },
+ { "sender-port", Element::integer, "0" },
+ { "max-queue-size", Element::integer, "1024" },
+ { "ncr-protocol", Element::string, "UDP" },
+ { "ncr-format", Element::string, "JSON" },
+ { "always-include-fqdn", Element::boolean, "false" },
+ { "override-no-update", Element::boolean, "false" },
+ { "override-client-update", Element::boolean, "false" },
+ { "replace-client-name", Element::string, "never" },
+ { "generated-prefix", Element::string, "myhost" }
+ // qualifying-suffix has no default
+};
+
+size_t
+D2ClientConfigParser::setAllDefaults(isc::data::ConstElementPtr d2_config) {
+ ElementPtr mutable_d2 = boost::const_pointer_cast<Element>(d2_config);
+ return (SimpleParser::setDefaults(mutable_d2, D2_CLIENT_CONFIG_DEFAULTS));
+}
+
}; // namespace dhcp
}; // namespace isc
///
/// @return returns a pointer to newly created D2ClientConfig.
D2ClientConfigPtr parse(isc::data::ConstElementPtr d2_client_cfg);
+
+ /// @brief Check the short cut disabled updates condition
+ ///
+ /// The condition is that the d2 client configuration is
+ /// reduced to "enable-updates": false
+ ///
+ /// @param d2_config d2 client configuration
+ /// @return true if and only if the condition matches.
+ /// @throw DhcpConfigError if enable-updates is not present or
+ /// is not a boolean
+ static bool isShortCutDisabled(isc::data::ConstElementPtr d2_config);
+
+ /// @brief Defaults for the D2 client configuration.
+ static const isc::data::SimpleDefaults D2_CLIENT_CONFIG_DEFAULTS;
+
+ /// @brief Sets all defaults for D2 client configuration.
+ ///
+ /// This method sets defaults value. It must not be called
+ /// before the short cut disabled updates condition was checked.
+ ///
+ /// @param d2_config d2 client configuration (will be const cast
+ // to ElementPtr)
+ /// @return number of parameters inserted
+ static size_t setAllDefaults(isc::data::ConstElementPtr d2_config);
};
// Pointers to various parser objects.
return (answer);
}
- // option parsing must be done last, so save it if we hit if first
- ParserPtr option_parser;
-
ConfigPair config_pair;
try {
// Iterate over the config elements.
// Create the parser based on element name.
ParserPtr parser(createConfigParser(config_pair.first));
- // Options must be parsed last
- if (config_pair.first == "option-data") {
- option_parser = parser;
- } else {
- // Anything else we can call build straight away.
- parser->build(config_pair.second);
- parser->commit();
- }
+ parser->build(config_pair.second);
+ parser->commit();
}
int family = parser_context_->universe_ == Option::V4
size_t setAllDefaults(isc::data::ElementPtr global,
const SimpleDefaults& global_defaults,
const SimpleDefaults& option_defaults,
- const SimpleDefaults& option_def_defaults,
- const SimpleDefaults& d2_client_defaults) {
+ const SimpleDefaults& option_def_defaults) {
size_t cnt = 0;
// Set global defaults first.
cnt = SimpleParser::setDefaults(global, global_defaults);
}
}
- ConstElementPtr d2_client = global->get("dhcp-ddns");
- /// @todo - what if it's not in global? should we add it?
- if (d2_client) {
- // Get the mutable form of d2 client config
- ElementPtr mutable_d2 =
- boost::const_pointer_cast<Element>(d2_client);
- cnt += SimpleParser::setDefaults(mutable_d2, d2_client_defaults);
- }
-
-
return (cnt);
}
{ "valid-lifetime", Element::integer, "7200" }
};
- /// @brief This table defines default values for D2 client configuration
- const SimpleDefaults D2_CLIENT_CFG_DEFAULTS = {
- { "server-ip", Element::string, "127.0.0.1" },
- { "server-port", Element::integer, "53001" },
- // default sender-ip depends on server-ip family, so we leave default blank
- // parser knows to use the appropriate ZERO address based on server-ip
- { "sender-ip", Element::string, "" },
- { "sender-port", Element::integer, "0" },
- { "max-queue-size", Element::integer, "1024" },
- { "ncr-protocol", Element::string, "UDP" },
- { "ncr-format", Element::string, "JSON" },
- { "always-include-fqdn", Element::boolean, "false" },
- { "override-no-update", Element::boolean, "false" },
- { "override-client-update", Element::boolean, "false" },
- { "replace-client-name", Element::string, "NEVER" },
- { "generated-prefix", Element::string, "myhost" },
- { "qualifying-suffix", Element::string, "" }
- };
-
if (v6) {
setAllDefaults(config, GLOBAL6_DEFAULTS, OPTION6_DEFAULTS,
- OPTION6_DEF_DEFAULTS, D2_CLIENT_CFG_DEFAULTS);
+ OPTION6_DEF_DEFAULTS);
} else {
setAllDefaults(config, GLOBAL6_DEFAULTS, OPTION4_DEFAULTS,
- OPTION4_DEF_DEFAULTS, D2_CLIENT_CFG_DEFAULTS);
+ OPTION4_DEF_DEFAULTS);
+ }
+
+ /// D2 client configuration code is in this library
+ ConstElementPtr d2_client = config->get("dhcp-ddns");
+ if (d2_client &&
+ !D2ClientConfigParser::isShortCutDisabled(d2_client)) {
+ D2ClientConfigParser::setAllDefaults(d2_client);
}
}
/// @brief Check various invalid D2 client configurations.
TEST_F(ParseConfigTest, invalidD2Config) {
+ std::string invalid_shortcuts[] = {
+ // Must supply at least enable-updates
+ "{ \"dhcp-ddns\" :"
+ " {"
+ " }"
+ "}",
+ // Enable-updates must be a boolean
+ "{ \"dhcp-ddns\" :"
+ " {"
+ " \"enable-updates\" : 0"
+ " }"
+ "}",
+ // stop
+ ""
+ };
+ int i = 0;
+ while (!invalid_shortcuts[i].empty()) {
+ // Verify that the configuration string parsing throws
+ EXPECT_THROW(parseConfiguration(invalid_shortcuts[i]),
+ DhcpConfigError);
+ i++;
+ }
+
std::string invalid_configs[] = {
+#if simple_parser_get_position_got_fixed
+ // Must supply qualifying-suffix when updates are enabled
+ "{ \"dhcp-ddns\" :"
+ " {"
+ " \"enable-updates\" : true"
+ " }"
+ "}",
+#endif
// Invalid server ip value
"{ \"dhcp-ddns\" :"
" {"
// Iterate through the invalid configuration strings, attempting to
// parse each one. They should fail to parse, but fail gracefully.
D2ClientConfigPtr current_config;
- int i = 0;
+ i = 0;
while (!invalid_configs[i].empty()) {
// Verify that the configuration string parses without throwing.
int rcode = parseConfiguration(invalid_configs[i]);