Commit 5189956f authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰

[5019] subnet defaults implemented, id, rapid-commit params migrated

parent 362131cf
......@@ -208,7 +208,8 @@ protected:
///
/// @param addr is IPv4 address of the subnet.
/// @param len is the prefix length
void initSubnet(isc::asiolink::IOAddress addr, uint8_t len) {
void initSubnet(isc::data::ConstElementPtr params,
isc::asiolink::IOAddress addr, uint8_t len) {
// The renew-timer and rebind-timer are optional. If not set, the
// option 58 and 59 will not be sent to a client. In this case the
// client will use default values based on the valid-lifetime.
......@@ -218,10 +219,11 @@ protected:
// particular subnet. If not, the global value should be present.
// If there is no global value, exception is thrown.
Triplet<uint32_t> valid = getParam("valid-lifetime");
// Subnet ID is optional. If it is not supplied the value of 0 is used,
// which means autogenerate.
SubnetID subnet_id =
static_cast<SubnetID>(uint32_values_->getOptionalParam("id", 0));
// which means autogenerate. The value was inserted earlier by calling
// SimpleParser4::setAllDefaults.
SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id"));
stringstream s;
s << addr << "/" << static_cast<int>(len) << " with params: ";
......
// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2016-2017 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
......@@ -65,6 +65,11 @@ const SimpleDefaults SimpleParser4::GLOBAL4_DEFAULTS = {
{ "next-server", Element::string, "0.0.0.0" }
};
/// @brief This table defines default values for each IPv4 subnet.
const SimpleDefaults SimpleParser4::SUBNET4_DEFAULTS = {
{ "id", Element::integer, "0" } // 0 means autogenerate
};
/// @brief List of parameters that can be inherited from the global to subnet4 scope.
///
/// Some parameters may be defined on both global (directly in Dhcp4) and
......@@ -98,13 +103,18 @@ size_t SimpleParser4::setAllDefaults(isc::data::ElementPtr global) {
}
}
// Finally, set the defaults for option data
// Set the defaults for option data
ConstElementPtr options = global->get("option-data");
if (options) {
BOOST_FOREACH(ElementPtr single_option, options->listValue()) {
cnt += SimpleParser::setDefaults(single_option, OPTION4_DEFAULTS);
}
cnt += setListDefaults(options, OPTION4_DEFAULTS);
}
// Now set the defaults for defined subnets
ConstElementPtr subnets = global->get("subnet4");
if (subnets) {
cnt += setListDefaults(subnets, SUBNET4_DEFAULTS);
}
return (cnt);
}
......
// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2016-2017 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
......@@ -40,6 +40,7 @@ public:
static const isc::data::SimpleDefaults OPTION4_DEF_DEFAULTS;
static const isc::data::SimpleDefaults OPTION4_DEFAULTS;
static const isc::data::SimpleDefaults GLOBAL4_DEFAULTS;
static const isc::data::SimpleDefaults SUBNET4_DEFAULTS;
static const isc::data::ParamsList INHERIT_GLOBAL_TO_SUBNET4;
};
......
......@@ -40,6 +40,50 @@ public:
// Finally, check if its value meets expectation.
EXPECT_EQ(exp_value, elem->intValue());
}
/// @brief Checks if specified map has a string 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 checkStringValue(const ConstElementPtr& map, const std::string& param_name,
std::string 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::string, elem->getType());
// Finally, check if its value meets expectation.
EXPECT_EQ(exp_value, elem->stringValue());
}
/// @brief Checks if specified map has a boolean 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 checkBoolValue(const ConstElementPtr& map, const std::string& param_name,
bool 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::boolean, elem->getType());
// Finally, check if its value meets expectation.
EXPECT_EQ(exp_value, elem->boolValue());
}
};
// This test checks if global defaults are properly set for DHCPv4.
......@@ -68,7 +112,6 @@ TEST_F(SimpleParser4Test, globalDefaults4) {
TEST_F(SimpleParser4Test, inheritGlobalToSubnet4) {
ElementPtr global = parseJSON("{ \"renew-timer\": 1,"
" \"rebind-timer\": 2,"
" \"preferred-lifetime\": 3,"
" \"valid-lifetime\": 4,"
" \"subnet4\": [ { \"renew-timer\": 100 } ] "
"}");
......@@ -90,6 +133,77 @@ TEST_F(SimpleParser4Test, inheritGlobalToSubnet4) {
checkIntegerValue(subnet, "valid-lifetime", 4);
}
// This test checks if the parameters in "subnet4" are assigned default values
// if not explicitly specified.
TEST_F(SimpleParser4Test, subnetDefaults4) {
ElementPtr global = parseJSON("{ \"renew-timer\": 1,"
" \"rebind-timer\": 2,"
" \"valid-lifetime\": 4,"
" \"subnet4\": [ { } ] "
"}");
size_t num = 0;
EXPECT_NO_THROW(num = SimpleParser4::setAllDefaults(global));
EXPECT_LE(1, num); // at least 1 parameter has to be modified
ConstElementPtr subnets = global->find("subnet4");
ASSERT_TRUE(subnets);
ConstElementPtr subnet = subnets->get(0);
ASSERT_TRUE(subnet);
// we should have "id" parameter with the default value of 0 added for us.
checkIntegerValue(subnet, "id", 0);
}
// This test checks if the parameters in option-data are assigned default values
// if not explicitly specified.
TEST_F(SimpleParser4Test, optionDataDefaults4) {
ElementPtr global = parseJSON("{ \"renew-timer\": 1,"
" \"rebind-timer\": 2,"
" \"valid-lifetime\": 4,"
" \"option-data\": [ { } ] "
"}");
size_t num = 0;
EXPECT_NO_THROW(num = SimpleParser4::setAllDefaults(global));
EXPECT_LE(1, num); // at least 1 parameter has to be modified
ConstElementPtr options = global->find("option-data");
ASSERT_TRUE(options);
ConstElementPtr option = options->get(0);
ASSERT_TRUE(option);
// we should have appropriate default value set. See
// SimpleParser4::OPTION4_DEFAULTS for a list of default values.
checkStringValue(option, "space", "dhcp4");
checkStringValue(option, "encapsulate", "");
checkBoolValue(option, "csv-format", true);
}
// This test checks if the parameters in option-data are assigned default values
// if not explicitly specified.
TEST_F(SimpleParser4Test, optionDefDefaults4) {
ElementPtr global = parseJSON("{ "
" \"option-def\": [ { } ] "
"}");
size_t num = 0;
EXPECT_NO_THROW(num = SimpleParser4::setAllDefaults(global));
EXPECT_LE(1, num); // at least 1 parameter has to be modified
ConstElementPtr defs = global->find("option-def");
ASSERT_TRUE(defs);
ASSERT_EQ(1, defs->size());
ConstElementPtr def = defs->get(0);
ASSERT_TRUE(def);
// we should have appropriate default value set. See
// SimpleParser4::OPTION4_DEFAULTS for a list of default values.
checkStringValue(def, "record-types", "");
checkStringValue(def, "space", "dhcp4");
checkStringValue(def, "encapsulate", "");
checkBoolValue(def, "array", false);
}
};
};
......
......@@ -409,7 +409,8 @@ protected:
///
/// @param addr is IPv6 prefix of the subnet.
/// @param len is the prefix length
void initSubnet(isc::asiolink::IOAddress addr, uint8_t len) {
void initSubnet(isc::data::ConstElementPtr params,
isc::asiolink::IOAddress addr, uint8_t len) {
// Get all 'time' parameters using inheritance.
// If the subnet-specific value is defined then use it, else
// use the global value. The global value must always be
......@@ -419,10 +420,11 @@ protected:
Triplet<uint32_t> t2 = getParam("rebind-timer");
Triplet<uint32_t> pref = getParam("preferred-lifetime");
Triplet<uint32_t> valid = getParam("valid-lifetime");
// Subnet ID is optional. If it is not supplied the value of 0 is used,
// which means autogenerate.
SubnetID subnet_id =
static_cast<SubnetID>(uint32_values_->getOptionalParam("id", 0));
// which means autogenerate. The value was inserted earlier by calling
// SimpleParser6::setAllDefaults.
SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id"));
// Get interface-id option content. For now we support string
// representation only
......@@ -454,7 +456,7 @@ protected:
}
// Gather boolean parameters values.
bool rapid_commit = boolean_values_->getOptionalParam("rapid-commit", false);
bool rapid_commit = getBoolean(params, "rapid-commit");
std::ostringstream output;
output << addr << "/" << static_cast<int>(len)
......
// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2016-2017 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
......@@ -63,6 +63,12 @@ const SimpleDefaults SimpleParser6::GLOBAL6_DEFAULTS = {
{ "dhcp4o6-port", Element::integer, "0" }
};
/// @brief This table defines default values for each IPv6 subnet.
const SimpleDefaults SimpleParser6::SUBNET6_DEFAULTS = {
{ "id", Element::integer, "0" }, // 0 means autogenerate
{ "rapid-commit", Element::boolean, "false" } // rapid-commit disabled by default
};
/// @brief List of parameters that can be inherited from the global to subnet6 scope.
///
/// Some parameters may be defined on both global (directly in Dhcp6) and
......@@ -95,7 +101,7 @@ size_t SimpleParser6::setAllDefaults(isc::data::ElementPtr global) {
}
}
// Finally, set the defaults for option data
// Set the defaults for option data
ConstElementPtr options = global->get("option-data");
if (options) {
BOOST_FOREACH(ElementPtr single_option, options->listValue()) {
......@@ -103,6 +109,13 @@ size_t SimpleParser6::setAllDefaults(isc::data::ElementPtr global) {
}
}
// Now set the defaults for defined subnets
// Now set the defaults for defined subnets
ConstElementPtr subnets = global->get("subnet6");
if (subnets) {
cnt += setListDefaults(subnets, SUBNET6_DEFAULTS);
}
return (cnt);
}
......
// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2016-2017 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
......@@ -41,6 +41,7 @@ public:
static const isc::data::SimpleDefaults OPTION6_DEF_DEFAULTS;
static const isc::data::SimpleDefaults OPTION6_DEFAULTS;
static const isc::data::SimpleDefaults GLOBAL6_DEFAULTS;
static const isc::data::SimpleDefaults SUBNET6_DEFAULTS;
static const isc::data::ParamsList INHERIT_GLOBAL_TO_SUBNET6;
};
......
......@@ -41,6 +41,51 @@ public:
// Finally, check if its value meets expectation.
EXPECT_EQ(exp_value, elem->intValue());
}
/// @brief Checks if specified map has a string 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 checkStringValue(const ConstElementPtr& map, const std::string& param_name,
std::string 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::string, elem->getType());
// Finally, check if its value meets expectation.
EXPECT_EQ(exp_value, elem->stringValue());
}
/// @brief Checks if specified map has a boolean 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 checkBoolValue(const ConstElementPtr& map, const std::string& param_name,
bool 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::boolean, elem->getType());
// Finally, check if its value meets expectation.
EXPECT_EQ(exp_value, elem->boolValue());
}
};
// This test checks if global defaults are properly set for DHCPv6.
......@@ -89,5 +134,79 @@ TEST_F(SimpleParser6Test, inheritGlobalToSubnet6) {
checkIntegerValue(subnet, "valid-lifetime", 4);
}
};
// This test checks if the parameters in "subnet6" are assigned default values
// if not explicitly specified.
TEST_F(SimpleParser6Test, subnetDefaults6) {
ElementPtr global = parseJSON("{ \"renew-timer\": 1,"
" \"rebind-timer\": 2,"
" \"preferred-lifetime\": 3,"
" \"valid-lifetime\": 4,"
" \"subnet6\": [ { } ] "
"}");
size_t num = 0;
EXPECT_NO_THROW(num = SimpleParser6::setAllDefaults(global));
EXPECT_LE(1, num); // at least 1 parameter has to be modified
ConstElementPtr subnets = global->find("subnet6");
ASSERT_TRUE(subnets);
ConstElementPtr subnet = subnets->get(0);
ASSERT_TRUE(subnet);
// we should have "id" parameter with the default value of 0 added for us.
checkIntegerValue(subnet, "id", 0);
}
// This test checks if the parameters in option-data are assigned default values
// if not explicitly specified.
TEST_F(SimpleParser6Test, optionDataDefaults4) {
ElementPtr global = parseJSON("{ \"renew-timer\": 1,"
" \"rebind-timer\": 2,"
" \"preferred-lifetime\": 3,"
" \"valid-lifetime\": 4,"
" \"option-data\": [ { } ] "
"}");
size_t num = 0;
EXPECT_NO_THROW(num = SimpleParser6::setAllDefaults(global));
EXPECT_LE(1, num); // at least 1 parameter has to be modified
ConstElementPtr options = global->find("option-data");
ASSERT_TRUE(options);
ConstElementPtr option = options->get(0);
ASSERT_TRUE(option);
// we should have appropriate default value set. See
// SimpleParser4::OPTION4_DEFAULTS for a list of default values.
checkStringValue(option, "space", "dhcp6");
checkStringValue(option, "encapsulate", "");
checkBoolValue(option, "csv-format", true);
}
// This test checks if the parameters in option-data are assigned default values
// if not explicitly specified.
TEST_F(SimpleParser6Test, optionDefDefaults6) {
ElementPtr global = parseJSON("{ "
" \"option-def\": [ { } ] "
"}");
size_t num = 0;
EXPECT_NO_THROW(num = SimpleParser6::setAllDefaults(global));
EXPECT_LE(1, num); // at least 1 parameter has to be modified
ConstElementPtr defs = global->find("option-def");
ASSERT_TRUE(defs);
ASSERT_EQ(1, defs->size());
ConstElementPtr def = defs->get(0);
ASSERT_TRUE(def);
// we should have appropriate default value set. See
// SimpleParser4::OPTION4_DEFAULTS for a list of default values.
checkStringValue(def, "record-types", "");
checkStringValue(def, "space", "dhcp6");
checkStringValue(def, "encapsulate", "");
checkBoolValue(def, "array", false);
}
};
......@@ -1062,7 +1062,7 @@ SubnetConfigParser::build(ConstElementPtr subnet) {
// Create a subnet.
try {
createSubnet();
createSubnet(subnet);
} catch (const std::exception& ex) {
isc_throw(DhcpConfigError,
"subnet configuration failed (" << subnet->getPosition()
......@@ -1088,10 +1088,10 @@ SubnetConfigParser::hrModeFromText(const std::string& txt) {
}
void
SubnetConfigParser::createSubnet() {
SubnetConfigParser::createSubnet(ConstElementPtr params) {
std::string subnet_txt;
try {
subnet_txt = string_values_->getParam("subnet");
subnet_txt = getString(params, "subnet");
} catch (const DhcpConfigError &) {
// rethrow with precise error
isc_throw(DhcpConfigError,
......@@ -1121,7 +1121,7 @@ SubnetConfigParser::createSubnet() {
uint8_t len = boost::lexical_cast<unsigned int>(subnet_txt.substr(pos + 1));
// Call the subclass's method to instantiate the subnet
initSubnet(addr, len);
initSubnet(params, addr, len);
// Add pools to it.
for (PoolStorage::iterator it = pools_->begin(); it != pools_->end();
......@@ -1140,7 +1140,6 @@ SubnetConfigParser::createSubnet() {
// iface not mandatory so swallow the exception
}
// Let's set host reservation mode. If not specified, the default value of
// all will be used.
std::string hr_mode;
......
......@@ -856,9 +856,11 @@ protected:
/// @brief Instantiates the subnet based on a given IP prefix and prefix
/// length.
///
/// @param params configuration parameters for that subnet
/// @param addr is the IP prefix of the subnet.
/// @param len is the prefix length
virtual void initSubnet(isc::asiolink::IOAddress addr, uint8_t len) = 0;
virtual void initSubnet(isc::data::ConstElementPtr params,
isc::asiolink::IOAddress addr, uint8_t len) = 0;
/// @brief Returns value for a given parameter (after using inheritance)
///
......@@ -899,9 +901,10 @@ private:
/// @brief Create a new subnet using a data from child parsers.
///
/// @param data Element map that describes the subnet
/// @throw isc::dhcp::DhcpConfigError if subnet configuration parsing
/// failed.
void createSubnet();
void createSubnet(isc::data::ConstElementPtr data);
protected:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment