|
@@ -7,6 +7,7 @@
|
|
|
#include <config.h>
|
|
|
#include <cc/command_interpreter.h>
|
|
|
#include <cc/data.h>
|
|
|
+#include <cc/simple_parser.h>
|
|
|
#include <dhcp/option.h>
|
|
|
#include <dhcp/option_custom.h>
|
|
|
#include <dhcp/option_int.h>
|
|
@@ -16,7 +17,6 @@
|
|
|
#include <dhcpsrv/subnet.h>
|
|
|
#include <dhcpsrv/cfg_mac_source.h>
|
|
|
#include <dhcpsrv/parsers/dhcp_parsers.h>
|
|
|
-#include <dhcpsrv/parsers/simple_parser.h>
|
|
|
#include <dhcpsrv/tests/test_libraries.h>
|
|
|
#include <dhcpsrv/testutils/config_result_check.h>
|
|
|
#include <exceptions/exceptions.h>
|
|
@@ -412,6 +412,101 @@ public:
|
|
|
return (parser);
|
|
|
}
|
|
|
|
|
|
+ /// @brief DHCP-specific method that sets global, and option specific defaults
|
|
|
+ ///
|
|
|
+ /// This method sets the defaults in the global scope, in option definitions,
|
|
|
+ /// and in option data.
|
|
|
+ ///
|
|
|
+ /// @param global pointer to the Element tree that holds configuration
|
|
|
+ /// @param global_defaults array with global default values
|
|
|
+ /// @param option_defaults array with option-data default values
|
|
|
+ /// @param option_def_defaults array with default values for option definitions
|
|
|
+ /// @return number of default values inserted.
|
|
|
+ size_t setAllDefaults(isc::data::ElementPtr global,
|
|
|
+ const SimpleDefaults& global_defaults,
|
|
|
+ const SimpleDefaults& option_defaults,
|
|
|
+ const SimpleDefaults& option_def_defaults) {
|
|
|
+ size_t cnt = 0;
|
|
|
+ // Set global defaults first.
|
|
|
+ /// @todo: Uncomment as part of the ticket 5019 work.
|
|
|
+ cnt = SimpleParser::setDefaults(global, global_defaults);
|
|
|
+
|
|
|
+ // Now set option defintion defaults for each specified option definition
|
|
|
+ ConstElementPtr option_defs = global->get("option-def");
|
|
|
+ if (option_defs) {
|
|
|
+ BOOST_FOREACH(ElementPtr single_def, option_defs->listValue()) {
|
|
|
+ cnt += SimpleParser::setDefaults(single_def, option_def_defaults);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ConstElementPtr options = global->get("option-data");
|
|
|
+ if (options) {
|
|
|
+ BOOST_FOREACH(ElementPtr single_option, options->listValue()) {
|
|
|
+ cnt += SimpleParser::setDefaults(single_option, option_defaults);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (cnt);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// @brief sets all default values for DHCPv4 and DHCPv6
|
|
|
+ ///
|
|
|
+ /// This function largely duplicates what SimpleParser4 and SimpleParser6 classes
|
|
|
+ /// provide. However, since there are tons of unit-tests in dhcpsrv that need
|
|
|
+ /// this functionality and there are good reasons to keep those classes in
|
|
|
+ /// src/bin/dhcp{4,6}, the most straightforward way is to simply copy the
|
|
|
+ /// minimum code here. Hence this method.
|
|
|
+ ///
|
|
|
+ /// @param config configuration structure to be filled with default values
|
|
|
+ /// @param v6 true = DHCPv6, false = DHCPv4
|
|
|
+ void setAllDefaults(ElementPtr config, bool v6) {
|
|
|
+ /// This table defines default values for option definitions in DHCPv6
|
|
|
+ const SimpleDefaults OPTION6_DEF_DEFAULTS = {
|
|
|
+ { "record-types", Element::string, ""},
|
|
|
+ { "space", Element::string, "dhcp6"},
|
|
|
+ { "array", Element::boolean, "false"},
|
|
|
+ { "encapsulate", Element::string, "" }
|
|
|
+ };
|
|
|
+
|
|
|
+ /// This table defines default values for option definitions in DHCPv4
|
|
|
+ const SimpleDefaults OPTION4_DEF_DEFAULTS = {
|
|
|
+ { "record-types", Element::string, ""},
|
|
|
+ { "space", Element::string, "dhcp4"},
|
|
|
+ { "array", Element::boolean, "false"},
|
|
|
+ { "encapsulate", Element::string, "" }
|
|
|
+ };
|
|
|
+
|
|
|
+ /// This table defines default values for options in DHCPv6
|
|
|
+ const SimpleDefaults OPTION6_DEFAULTS = {
|
|
|
+ { "space", Element::string, "dhcp6"},
|
|
|
+ { "csv-format", Element::boolean, "true"},
|
|
|
+ { "encapsulate", Element::string, "" }
|
|
|
+ };
|
|
|
+
|
|
|
+ /// This table defines default values for options in DHCPv4
|
|
|
+ const SimpleDefaults OPTION4_DEFAULTS = {
|
|
|
+ { "space", Element::string, "dhcp4"},
|
|
|
+ { "csv-format", Element::boolean, "true"},
|
|
|
+ { "encapsulate", Element::string, "" }
|
|
|
+ };
|
|
|
+
|
|
|
+ /// This table defines default values for both DHCPv4 and DHCPv6
|
|
|
+ const SimpleDefaults GLOBAL6_DEFAULTS = {
|
|
|
+ { "renew-timer", Element::integer, "900" },
|
|
|
+ { "rebind-timer", Element::integer, "1800" },
|
|
|
+ { "preferred-lifetime", Element::integer, "3600" },
|
|
|
+ { "valid-lifetime", Element::integer, "7200" }
|
|
|
+ };
|
|
|
+
|
|
|
+ if (v6) {
|
|
|
+ setAllDefaults(config, GLOBAL6_DEFAULTS, OPTION6_DEFAULTS,
|
|
|
+ OPTION6_DEF_DEFAULTS);
|
|
|
+ } else {
|
|
|
+ setAllDefaults(config, GLOBAL6_DEFAULTS, OPTION4_DEFAULTS,
|
|
|
+ OPTION4_DEF_DEFAULTS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/// @brief Convenience method for parsing a configuration
|
|
|
///
|
|
|
/// Given a configuration string, convert it into Elements
|
|
@@ -427,7 +522,7 @@ public:
|
|
|
ElementPtr json = Element::fromJSON(config);
|
|
|
EXPECT_TRUE(json);
|
|
|
if (json) {
|
|
|
- SimpleParser::setAllDefaults(json, v6);
|
|
|
+ setAllDefaults(json, v6);
|
|
|
|
|
|
ConstElementPtr status = parseElementSet(json);
|
|
|
ConstElementPtr comment = parseAnswer(rcode_, status);
|
|
@@ -487,28 +582,6 @@ public:
|
|
|
CfgMgr::instance().setD2ClientConfig(tmp);
|
|
|
}
|
|
|
|
|
|
- /// @brief Checks if specified map has an integer parameter with expected value
|
|
|
- ///
|
|
|
- /// @param map map to be checked
|
|
|
- /// @param param_name name of the parameter to be checked
|
|
|
- /// @param exp_value expected value of the parameter.
|
|
|
- void checkIntegerValue(const ConstElementPtr& map, const std::string& param_name,
|
|
|
- int64_t exp_value) {
|
|
|
-
|
|
|
- // First check if the passed element is a map.
|
|
|
- ASSERT_EQ(Element::map, map->getType());
|
|
|
-
|
|
|
- // Now try to get the element being checked
|
|
|
- ConstElementPtr elem = map->get(param_name);
|
|
|
- ASSERT_TRUE(elem);
|
|
|
-
|
|
|
- // Now check if it's indeed integer
|
|
|
- ASSERT_EQ(Element::integer, elem->getType());
|
|
|
-
|
|
|
- // Finally, check if its value meets expectation.
|
|
|
- EXPECT_EQ(exp_value, elem->intValue());
|
|
|
- }
|
|
|
-
|
|
|
/// @brief Parsers used in the parsing of the configuration
|
|
|
///
|
|
|
/// Allows the tests to interrogate the state of the parsers (if required).
|
|
@@ -2425,65 +2498,4 @@ TEST_F(ParseConfigTest, validRelayInfo6) {
|
|
|
// (see CtrlDhcpv4SrvTest.commandSocketBasic in
|
|
|
// src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc).
|
|
|
|
|
|
-// This test checks if global defaults are properly set for DHCPv6.
|
|
|
-TEST_F(ParseConfigTest, globalDefaults6) {
|
|
|
-
|
|
|
- ElementPtr empty = Element::fromJSON("{ }");
|
|
|
- size_t num;
|
|
|
-
|
|
|
- EXPECT_NO_THROW(num = SimpleParser::setGlobalDefaults(empty, true));
|
|
|
-
|
|
|
- // We expect at least 4 parameters to be inserted.
|
|
|
- EXPECT_TRUE(num >= 4);
|
|
|
-
|
|
|
- checkIntegerValue(empty, "valid-lifetime", 7200);
|
|
|
- checkIntegerValue(empty, "preferred-lifetime", 3600);
|
|
|
- checkIntegerValue(empty, "rebind-timer", 1800);
|
|
|
- checkIntegerValue(empty, "renew-timer", 900);
|
|
|
-}
|
|
|
-
|
|
|
-// This test checks if global defaults are properly set for DHCPv4.
|
|
|
-TEST_F(ParseConfigTest, DISABLED_globalDefaults4) {
|
|
|
-
|
|
|
- ElementPtr empty = Element::fromJSON("{ }");
|
|
|
- size_t num;
|
|
|
-
|
|
|
- EXPECT_NO_THROW(num = SimpleParser::setGlobalDefaults(empty, false));
|
|
|
-
|
|
|
- // We expect at least 3 parameters to be inserted.
|
|
|
- EXPECT_TRUE(num >= 3);
|
|
|
-
|
|
|
- checkIntegerValue(empty, "valid-lifetime", 7200);
|
|
|
- checkIntegerValue(empty, "rebind-timer", 1800);
|
|
|
- checkIntegerValue(empty, "renew-timer", 900);
|
|
|
-
|
|
|
- // Make sure that preferred-lifetime is not set for v4 (it's v6 only
|
|
|
- // parameter)
|
|
|
- EXPECT_FALSE(empty->get("preferred-lifetime"));
|
|
|
-}
|
|
|
-
|
|
|
-// This test checks if the parameters can be inherited from the global
|
|
|
-// scope to the subnet scope.
|
|
|
-TEST_F(ParseConfigTest, inheritGlobalToSubnet) {
|
|
|
- ElementPtr global = Element::fromJSON("{ \"renew-timer\": 1,"
|
|
|
- " \"rebind-timer\": 2,"
|
|
|
- " \"preferred-lifetime\": 3,"
|
|
|
- " \"valid-lifetime\": 4"
|
|
|
- "}");
|
|
|
- ElementPtr subnet = Element::fromJSON("{ \"renew-timer\": 100 }");
|
|
|
-
|
|
|
- // we should inherit 3 parameters. Renew-timer should remain intact,
|
|
|
- // as it was already defined in the subnet scope.
|
|
|
- size_t num;
|
|
|
- EXPECT_NO_THROW(num = SimpleParser::inheritGlobalToSubnet(global, subnet));
|
|
|
- EXPECT_EQ(3, num);
|
|
|
-
|
|
|
- // Check the values. 3 of them are interited, while the fourth one
|
|
|
- // was already defined in the subnet, so should not be inherited.
|
|
|
- checkIntegerValue(subnet, "renew-timer", 100);
|
|
|
- checkIntegerValue(subnet, "rebind-timer", 2);
|
|
|
- checkIntegerValue(subnet, "preferred-lifetime", 3);
|
|
|
- checkIntegerValue(subnet, "valid-lifetime", 4);
|
|
|
-}
|
|
|
-
|
|
|
}; // Anonymous namespace
|