| dhcp-queue-control.capacity | dhcp-queue-control | capacity |
+------------------------------------------------------------------+------------------------------+----------------------------------+
+Some scalar parameters contained by top-level global list are supported by the configuration backend.
+
+.. table:: List of DHCPv4 list parameters supported by the configuration backend
+
+ +------------------------------------------------------------------+
+ | Parameter name | List container parameter type |
+ +==================================================================+
+ | host-reservation-identifiers | string |
+ +------------------------------------------------------------------+
+
.. _dhcp4-cb-json:
Enabling the Configuration Backend
| dhcp-queue-control.capacity | dhcp-queue-control | capacity |
+------------------------------------------------------------------+------------------------------+----------------------------------+
+Some scalar parameters contained by top-level global list are supported by the configuration backend.
+
+.. table:: List of DHCPv6 list parameters supported by the configuration backend
+
+ +------------------------------------------------------------------+
+ | Parameter name | List container parameter type |
+ +==================================================================+
+ | host-reservation-identifiers | string |
+ +------------------------------------------------------------------+
+
.. _dhcp6-cb-json:
Enabling the Configuration Backend
mutable_cfg->get("host-reservation-identifiers");
if (hr_identifiers) {
parameter_name = "host-reservation-identifiers";
- HostReservationIdsParser4 parser;
+ HostReservationIdsParser4 parser(srv_config->getCfgHostOperations4());
parser.parse(hr_identifiers);
}
StampedValuePtr renew_timer(new StampedValue("renew-timer", Element::create(500)));
StampedValuePtr mt_enabled(new StampedValue("multi-threading.enable-multi-threading", Element::create(true)));
StampedValuePtr mt_pool_size(new StampedValue("multi-threading.thread-pool-size", Element::create(256)));
+ StampedValuePtr hr_identifiers(new StampedValue("host-reservation-identifiers", "[ \"hw-address\", \"flex-id\" ]"));
// Let's add all of the globals to the second backend. This will verify
// we find them there.
db2_->createUpdateGlobalParameter4(ServerSelector::ALL(), renew_timer);
db2_->createUpdateGlobalParameter4(ServerSelector::ALL(), mt_enabled);
db2_->createUpdateGlobalParameter4(ServerSelector::ALL(), mt_pool_size);
+ db2_->createUpdateGlobalParameter4(ServerSelector::ALL(), hr_identifiers);
// Should parse and merge without error.
ASSERT_NO_FATAL_FAILURE(configure(base_config, CONTROL_RESULT_SUCCESS, ""));
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, renew_timer));
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, mt_enabled));
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, mt_pool_size));
+ ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, hr_identifiers, true));
+
+ auto const& ex_hr_i = staging_cfg->getCfgHostOperations4()->getIdentifierTypes();
+ EXPECT_EQ(ex_hr_i.size(), 2);
+ EXPECT_EQ(ex_hr_i.front(), Host::IDENT_HWADDR);
+ EXPECT_EQ(ex_hr_i.back(), Host::IDENT_FLEX);
}
// This test verifies that externally configured option definitions
mutable_cfg->get("host-reservation-identifiers");
if (hr_identifiers) {
parameter_name = "host-reservation-identifiers";
- HostReservationIdsParser6 parser;
+ HostReservationIdsParser6 parser(srv_config->getCfgHostOperations6());
parser.parse(hr_identifiers);
}
StampedValuePtr renew_timer(new StampedValue("renew-timer", Element::create(500)));
StampedValuePtr mt_enabled(new StampedValue("multi-threading.enable-multi-threading", Element::create(true)));
StampedValuePtr mt_pool_size(new StampedValue("multi-threading.thread-pool-size", Element::create(256)));
+ StampedValuePtr hr_identifiers(new StampedValue("host-reservation-identifiers", "[ \"hw-address\", \"flex-id\" ]"));
// Let's add all of the globals to the second backend. This will verify
// we find them there.
db2_->createUpdateGlobalParameter6(ServerSelector::ALL(), renew_timer);
db2_->createUpdateGlobalParameter6(ServerSelector::ALL(), mt_enabled);
db2_->createUpdateGlobalParameter6(ServerSelector::ALL(), mt_pool_size);
+ db2_->createUpdateGlobalParameter6(ServerSelector::ALL(), hr_identifiers);
// Should parse and merge without error.
ASSERT_NO_FATAL_FAILURE(configure(base_config, CONTROL_RESULT_SUCCESS, ""));
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, renew_timer));
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, mt_enabled));
ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, mt_pool_size));
+ ASSERT_NO_FATAL_FAILURE(checkConfiguredGlobal(staging_cfg, hr_identifiers, true));
+
+ auto const& ex_hr_i = staging_cfg->getCfgHostOperations6()->getIdentifierTypes();
+ EXPECT_EQ(ex_hr_i.size(), 2);
+ EXPECT_EQ(ex_hr_i.front(), Host::IDENT_HWADDR);
+ EXPECT_EQ(ex_hr_i.back(), Host::IDENT_FLEX);
}
// This test verifies that externally configured option definitions
// twice: first with the existing Element::fromJSONFile() and then
// the second time with Parser6. Both JSON trees are then compared.
TEST(ParserTest, file) {
- vector<string> configs;
- configs.push_back("advanced.json");
- configs.push_back("all-keys.json");
- configs.push_back("all-options.json");
- configs.push_back("backends.json");
- configs.push_back("classify.json");
- configs.push_back("classify2.json");
- configs.push_back("comments.json");
- configs.push_back("config-backend.json");
- configs.push_back("dhcpv4-over-dhcpv6.json");
- configs.push_back("duid.json");
- configs.push_back("global-reservations.json");
- configs.push_back("ha-hot-standby-server1-with-tls.json");
- configs.push_back("ha-hot-standby-server2.json");
- configs.push_back("hooks.json");
- configs.push_back("iPXE.json");
- configs.push_back("leases-expiration.json");
- configs.push_back("multiple-options.json");
- configs.push_back("mysql-reservations.json");
- configs.push_back("pgsql-reservations.json");
- configs.push_back("reservations.json");
- configs.push_back("several-subnets.json");
- configs.push_back("shared-network.json");
- configs.push_back("simple.json");
- configs.push_back("softwire46.json");
- configs.push_back("stateless.json");
- configs.push_back("tee-times.json");
- configs.push_back("with-ddns.json");
+ vector<string> configs = { "advanced.json",
+ "all-keys.json",
+ "all-options.json",
+ "backends.json",
+ "classify.json",
+ "classify2.json",
+ "comments.json",
+ "config-backend.json",
+ "dhcpv4-over-dhcpv6.json",
+ "duid.json",
+ "global-reservations.json",
+ "ha-hot-standby-server1-with-tls.json",
+ "ha-hot-standby-server2.json",
+ "hooks.json",
+ "iPXE.json",
+ "leases-expiration.json",
+ "multiple-options.json",
+ "mysql-reservations.json",
+ "pgsql-reservations.json",
+ "reservations.json",
+ "several-subnets.json",
+ "shared-network.json",
+ "simple.json",
+ "softwire46.json",
+ "stateless.json",
+ "tee-times.json",
+ "with-ddns.json" };
for (unsigned i = 0; i<configs.size(); i++) {
testFile(string(CFG_EXAMPLES) + "/" + configs[i]);
/// @brief It translates the top level map parameters from flat naming
/// format (e.g. param-name.sub-param-name) to proper ElementMap objects and
- /// adds all globals fetched from config backend(s) to a SrvConfig instance
+ /// adds all globals fetched from config backend(s) to a SrvConfig instance.
+ /// The top level list parameters are converted from StringElement objects to
+ /// ListElement objects.
///
/// Iterates over the given collection of global parameters and adds them to
/// the given configuration's list of configured globals.
///
- ///
/// @param external_cfg SrvConfig instance to update
/// @param cb_globals collection of global parameters supplied by configuration
/// backend
+ /// @param global_lists All keywords matching supported global list parameters.
void translateAndAddGlobalsToConfig(SrvConfigPtr external_cfg,
- data::StampedValueCollection& cb_globals) const {
+ data::StampedValueCollection& cb_globals,
+ data::SimpleKeywords global_lists) const {
auto const& index = cb_globals.get<data::StampedValueNameIndexTag>();
for (auto const& cb_global : index) {
-
if (cb_global->amNull()) {
continue;
}
-
+ data::ConstElementPtr value = cb_global->getElementValue();
+ // All ListElement parameters must be converted from StringElement
+ // (used by CB to store global list parameters).
+ data::ElementPtr mutable_value = boost::const_pointer_cast<data::Element>(value);
+ if (global_lists.count(cb_global->getName())) {
+ mutable_value = data::Element::fromJSON(value->stringValue());
+ }
+ data::ConstElementPtr global_value = boost::const_pointer_cast<data::Element>(mutable_value);
std::string param_name;
std::string sub_param_name;
if (translateName(cb_global->getName(), param_name, sub_param_name)) {
if (!sub_param) {
sub_param = data::Element::createMap();
}
- sub_param->set(sub_param_name, cb_global->getElementValue());
+ sub_param->set(sub_param_name, global_value);
external_cfg->addConfiguredGlobal(param_name, sub_param);
} else {
// Reuse name and value.
- external_cfg->addConfiguredGlobal(param_name, cb_global->getElementValue());
+ external_cfg->addConfiguredGlobal(param_name, global_value);
}
}
}
// database query and the number of global parameters is small.
data::StampedValueCollection globals;
globals = getMgr().getPool()->getAllGlobalParameters4(backend_selector, server_selector);
- translateAndAddGlobalsToConfig(external_cfg, globals);
+ translateAndAddGlobalsToConfig(external_cfg, globals, SimpleParser4::GLOBAL4_LIST_PARAMETERS);
// Add defaults.
external_cfg->applyDefaultsConfiguredGlobals(SimpleParser4::GLOBAL4_DEFAULTS);
data::StampedValueCollection globals;
globals = getMgr().getPool()->getModifiedGlobalParameters4(backend_selector, server_selector,
lb_modification_time);
- translateAndAddGlobalsToConfig(external_cfg, globals);
+ translateAndAddGlobalsToConfig(external_cfg, globals, SimpleParser4::GLOBAL4_LIST_PARAMETERS);
globals_fetched = true;
}
}
// database query and the number of global parameters is small.
data::StampedValueCollection globals;
globals = getMgr().getPool()->getAllGlobalParameters6(backend_selector, server_selector);
- translateAndAddGlobalsToConfig(external_cfg, globals);
+ translateAndAddGlobalsToConfig(external_cfg, globals, SimpleParser6::GLOBAL6_LIST_PARAMETERS);
// Add defaults.
external_cfg->applyDefaultsConfiguredGlobals(SimpleParser6::GLOBAL6_DEFAULTS);
data::StampedValueCollection globals;
globals = getMgr().getPool()->getModifiedGlobalParameters6(backend_selector, server_selector,
lb_modification_time);
- translateAndAddGlobalsToConfig(external_cfg, globals);
+ translateAndAddGlobalsToConfig(external_cfg, globals, SimpleParser6::GLOBAL6_LIST_PARAMETERS);
globals_fetched = true;
}
}
{ "ddns-ttl", DDNS_TTL },
{ "ddns-ttl-min", DDNS_TTL_MIN },
{ "ddns-ttl-max", DDNS_TTL_MAX },
+ { "host-reservation-identifiers", HOST_RESERVATION_IDENTIFIERS },
// DHCPv4 specific parameters.
{ "echo-client-id", ECHO_CLIENT_ID },
DDNS_TTL,
DDNS_TTL_MIN,
DDNS_TTL_MAX,
+ HOST_RESERVATION_IDENTIFIERS,
// DHCPv4 specific parameters.
ECHO_CLIENT_ID,
return (getSupportedParams6(identifiers_only));
}
-HostReservationIdsParser::HostReservationIdsParser()
- : staging_cfg_() {
+HostReservationIdsParser::HostReservationIdsParser(CfgHostOperationsPtr cfg)
+ : staging_cfg_(cfg) {
}
void
}
-HostReservationIdsParser4::HostReservationIdsParser4()
- : HostReservationIdsParser() {
- staging_cfg_ = CfgMgr::instance().getStagingCfg()->getCfgHostOperations4();
+HostReservationIdsParser4::HostReservationIdsParser4(CfgHostOperationsPtr cfg)
+ : HostReservationIdsParser(cfg) {
}
bool
return (getSupportedParams4(true).count(id_name) > 0);
}
-HostReservationIdsParser6::HostReservationIdsParser6()
- : HostReservationIdsParser() {
- staging_cfg_ = CfgMgr::instance().getStagingCfg()->getCfgHostOperations6();
+HostReservationIdsParser6::HostReservationIdsParser6(CfgHostOperationsPtr cfg)
+ : HostReservationIdsParser(cfg) {
}
bool
public:
/// @brief Constructor.
- HostReservationIdsParser();
+ ///
+ /// @param cfg Pointer to the object holding configuration.
+ HostReservationIdsParser(CfgHostOperationsPtr cfg);
/// @brief Destructor.
virtual ~HostReservationIdsParser() { }
///
/// Initializes staging configuration pointer to the one used for DHCPv4
/// configuration.
- HostReservationIdsParser4();
+ ///
+ /// @param cfg Pointer to the object holding configuration.
+ HostReservationIdsParser4(CfgHostOperationsPtr cfg);
protected:
///
/// Initializes staging configuration pointer to the one used for DHCPv6
/// configuration.
- HostReservationIdsParser6();
+ ///
+ /// @param cfg Pointer to the object holding configuration.
+ HostReservationIdsParser6(CfgHostOperationsPtr cfg);
protected:
{ "cache-threshold", Element::real, "0.25" },
};
+const SimpleKeywords SimpleParser4::GLOBAL4_LIST_PARAMETERS = {
+ { "host-reservation-identifiers", Element::list },
+ /* not yet supported
+ { "interfaces-config.interfaces", Element::list },
+ */
+};
+
+const SimpleKeywords SimpleParser4::GLOBAL4_LIST_PARAMETER_TYPES = {
+ { "host-reservation-identifiers", Element::string },
+ /* not yet supported
+ { "interfaces-config.interfaces", Element::string },
+ */
+};
+
/// @brief This table defines all option definition parameters.
///
/// Boolean, integer, real and string types are for scalar parameters,
static const isc::data::SimpleKeywords OPTION4_DEF_PARAMETERS;
static const isc::data::SimpleDefaults OPTION4_DEF_DEFAULTS;
+ static const isc::data::SimpleKeywords GLOBAL4_LIST_PARAMETERS;
+ static const isc::data::SimpleKeywords GLOBAL4_LIST_PARAMETER_TYPES;
+
static const isc::data::SimpleKeywords OPTION4_PARAMETERS;
static const isc::data::SimpleDefaults OPTION4_DEFAULTS;
{ "cache-threshold", Element::real, "0.25" },
};
+const SimpleKeywords SimpleParser6::GLOBAL6_LIST_PARAMETERS = {
+ { "host-reservation-identifiers", Element::list },
+ /* not yet supported
+ { "interfaces-config.interfaces", Element::list },
+ */
+};
+
+const SimpleKeywords SimpleParser6::GLOBAL6_LIST_PARAMETER_TYPES = {
+ { "host-reservation-identifiers", Element::string },
+ /* not yet supported
+ { "interfaces-config.interfaces", Element::string },
+ */
+};
+
/// @brief This table defines all option definition parameters.
///
/// Boolean, integer, real and string types are for scalar parameters,
static const isc::data::SimpleKeywords OPTION6_DEF_PARAMETERS;
static const isc::data::SimpleDefaults OPTION6_DEF_DEFAULTS;
+ static const isc::data::SimpleKeywords GLOBAL6_LIST_PARAMETERS;
+ static const isc::data::SimpleKeywords GLOBAL6_LIST_PARAMETER_TYPES;
+
static const isc::data::SimpleKeywords OPTION6_PARAMETERS;
static const isc::data::SimpleDefaults OPTION6_DEFAULTS;
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/parsers/base_network_parser.h>
#include <dhcpsrv/parsers/dhcp_parsers.h>
+#include <dhcpsrv/parsers/host_reservation_parser.h>
#include <dhcpsrv/parsers/expiration_config_parser.h>
#include <dhcpsrv/parsers/multi_threading_config_parser.h>
#include <dhcpsrv/parsers/sanity_checks_parser.h>
// Merge globals.
mergeGlobals(other_srv_config);
- // Merge global maps.
- mergeGlobalMaps(other_srv_config);
+ // Merge global containers.
+ mergeGlobalContainers(other_srv_config);
// Merge option defs. We need to do this next so we
// pass these into subsequent merges so option instances
}
void
-SrvConfig::mergeGlobalMaps(SrvConfig& other) {
+SrvConfig::mergeGlobalContainers(SrvConfig& other) {
ElementPtr config = Element::createMap();
for (auto const& other_global : other.getConfiguredGlobals()->valuesMap()) {
config->set(other_global.first, other_global.second);
}
std::string parameter_name;
try {
+ // Merge list containers.
+ ConstElementPtr host_reservation_identifiers = config->get("host-reservation-identifiers");
+ parameter_name = "host-reservation-identifiers";
+ if (host_reservation_identifiers) {
+ if (CfgMgr::instance().getFamily() == AF_INET) {
+ HostReservationIdsParser4 parser(getCfgHostOperations4());
+ parser.parse(host_reservation_identifiers);
+ } else {
+ HostReservationIdsParser6 parser(getCfgHostOperations6());
+ parser.parse(host_reservation_identifiers);
+ }
+ addConfiguredGlobal("host-reservation-identifiers", host_reservation_identifiers);
+ }
+ // Merge map containers.
ConstElementPtr compatibility = config->get("compatibility");
parameter_name = "compatibility";
if (compatibility) {
/// into this configuration.
void mergeGlobals(SrvConfig& other);
- /// @brief Merges the global maps specified in the given configuration
+ /// @brief Merges the global containers specified in the given configuration
/// into this configuration.
///
/// Configurable global values may be specified either via JSON
///
/// @param other An object holding the configuration to be merged
/// into this configuration.
- void mergeGlobalMaps(SrvConfig& other);
+ void mergeGlobalContainers(SrvConfig& other);
/// @brief Sequence number identifying the configuration.
uint32_t sequence_;
/// @brief Test verifies that invalid configuration causes an error.
///
/// @param config Configuration string.
+ /// @param cfg Pointer to the object holding configuration.
/// @tparam ParserType @ref HostReservationIdsParser4 or
/// @ref HostReservationIdsParser6
template<typename ParserType>
- void testInvalidConfig(const std::string& config) const {
+ void testInvalidConfig(const std::string& config, CfgHostOperationsPtr cfg) const {
ElementPtr config_element = Element::fromJSON(config);
- ParserType parser;
+ ParserType parser(cfg);
EXPECT_THROW(parser.parse(config_element), DhcpConfigError);
}
ElementPtr config_element = Element::fromJSON(config);
- HostReservationIdsParser4 parser;
+ HostReservationIdsParser4 parser(CfgMgr::instance().getStagingCfg()->getCfgHostOperations4());
ASSERT_NO_THROW(parser.parse(config_element));
ConstCfgHostOperationsPtr cfg = CfgMgr::instance().getStagingCfg()->
ElementPtr config_element = Element::fromJSON(config);
- HostReservationIdsParser6 parser;
+ HostReservationIdsParser6 parser(CfgMgr::instance().getStagingCfg()->getCfgHostOperations6());
ASSERT_NO_THROW(parser.parse(config_element));
ConstCfgHostOperationsPtr cfg = CfgMgr::instance().getStagingCfg()->
TEST_F(HostReservationIdsParserTest, dhcp4InvalidIdentifier) {
// Create configuration including unsupported identifier.
std::string config = "[ \"unsupported-id\" ]";
- testInvalidConfig<HostReservationIdsParser4>(config);
+ testInvalidConfig<HostReservationIdsParser4>(config, CfgMgr::instance().getStagingCfg()->getCfgHostOperations4());
}
// Test that invalid DHCPv6 identifier causes error.
// Create configuration including unsupported identifier for DHCPv6.
// The circuit-id is only supported in DHCPv4.
std::string config = "[ \"circuit-id\" ]";
- testInvalidConfig<HostReservationIdsParser6>(config);
+ testInvalidConfig<HostReservationIdsParser6>(config, CfgMgr::instance().getStagingCfg()->getCfgHostOperations6());
}
// Check that all supported identifiers are used when 'auto' keyword
std::string config = "[ \"auto\" ]";
ElementPtr config_element = Element::fromJSON(config);
- HostReservationIdsParser4 parser;
+ HostReservationIdsParser4 parser(CfgMgr::instance().getStagingCfg()->getCfgHostOperations4());
ASSERT_NO_THROW(parser.parse(config_element));
ConstCfgHostOperationsPtr cfg = CfgMgr::instance().getStagingCfg()->
// identifier.
TEST_F(HostReservationIdsParserTest, dhcp4AutoBeforeIdentifier) {
std::string config = "[ \"auto\", \"duid\" ]";
- testInvalidConfig<HostReservationIdsParser4>(config);
+ testInvalidConfig<HostReservationIdsParser4>(config, CfgMgr::instance().getStagingCfg()->getCfgHostOperations4());
}
// This test verifies that use of "auto" together with an explicit
// identifier.
TEST_F(HostReservationIdsParserTest, dhcp4AutoAfterIdentifier) {
std::string config = "[ \"duid\", \"auto\" ]";
- testInvalidConfig<HostReservationIdsParser4>(config);
+ testInvalidConfig<HostReservationIdsParser4>(config, CfgMgr::instance().getStagingCfg()->getCfgHostOperations4());
}
// Test that empty list of identifier types is not allowed.
TEST_F(HostReservationIdsParserTest, dhcp4EmptyList) {
std::string config = "[ ]";
- testInvalidConfig<HostReservationIdsParser4>(config);
+ testInvalidConfig<HostReservationIdsParser4>(config, CfgMgr::instance().getStagingCfg()->getCfgHostOperations4());
}
// Check that all supported identifiers are used when 'auto' keyword
std::string config = "[ \"auto\" ]";
ElementPtr config_element = Element::fromJSON(config);
- HostReservationIdsParser6 parser;
+ HostReservationIdsParser6 parser(CfgMgr::instance().getStagingCfg()->getCfgHostOperations6());
ASSERT_NO_THROW(parser.parse(config_element));
ConstCfgHostOperationsPtr cfg = CfgMgr::instance().getStagingCfg()->
// identifier.
TEST_F(HostReservationIdsParserTest, dhcp6AutoBeforeIdentifier) {
std::string config = "[ \"auto\", \"duid\" ]";
- testInvalidConfig<HostReservationIdsParser6>(config);
+ testInvalidConfig<HostReservationIdsParser6>(config, CfgMgr::instance().getStagingCfg()->getCfgHostOperations6());
}
// This test verifies that use of "auto" together with an explicit
// identifier.
TEST_F(HostReservationIdsParserTest, dhcp6AutoAfterIdentifier) {
std::string config = "[ \"duid\", \"auto\" ]";
- testInvalidConfig<HostReservationIdsParser6>(config);
+ testInvalidConfig<HostReservationIdsParser6>(config, CfgMgr::instance().getStagingCfg()->getCfgHostOperations6());
}
// Test that empty list of identifier types is not allowed.
TEST_F(HostReservationIdsParserTest, dhcp6EmptyList) {
std::string config = "[ ]";
- testInvalidConfig<HostReservationIdsParser6>(config);
+ testInvalidConfig<HostReservationIdsParser6>(config, CfgMgr::instance().getStagingCfg()->getCfgHostOperations6());
}
} // end of anonymous namespace
cfg_from.addConfiguredGlobal("multi-threading", mt);
mt->set("enable-multi-threading", Element::create(false));
mt->set("thread-pool-size", Element::create(256));
+ ElementPtr hr_i = Element::createList();
+ cfg_from.addConfiguredGlobal("host-reservation-identifiers", hr_i);
+ hr_i->add(Element::create("hw-address"));
+ hr_i->add(Element::create("flex-id"));
// Now let's merge.
ASSERT_NO_THROW(cfg_to.merge(cfg_from));
// echo-client-id should be the preserved "to" member value.
EXPECT_FALSE(cfg_to.getEchoClientId());
- // dhcp4o6-port should be the "from" configured value.
+ // dhcp4o6-port should be the "from" configured value.
EXPECT_EQ(999, cfg_to.getDhcp4o6Port());
- // server-tag port should be the "from" configured value.
+ // server-tag port should be the "from" configured value.
EXPECT_EQ("use_this_server", cfg_to.getServerTag().get());
- // reservations-lookup-first should be the "from" configured value.
+ // reservations-lookup-first should be the "from" configured value.
EXPECT_TRUE(cfg_to.getReservationsLookupFirst());
// ip-reservations-unique
// multi-threading
EXPECT_TRUE(cfg_to.getDHCPMultiThreading());
+ // host-reservation-identifiers
+ auto const& ex_hr_i = cfg_to.getCfgHostOperations4()->getIdentifierTypes();
+ EXPECT_EQ(ex_hr_i.size(), 2);
+ EXPECT_EQ(ex_hr_i.front(), Host::IDENT_HWADDR);
+ EXPECT_EQ(ex_hr_i.back(), Host::IDENT_FLEX);
+
// Next we check the explicitly "configured" globals.
// The list should be all of the "to" + "from", with the
// latter overwriting the former.
" \"dhcp4o6-port\": 999, \n"
" \"ip-reservations-unique\": false, \n"
" \"server-tag\": \"use_this_server\", \n"
- " \"reservations-lookup-first\": true,"
+ " \"reservations-lookup-first\": true, \n"
+ " \"host-reservation-identifiers\": [ \"hw-address\", \"flex-id\" ], \n"
" \"multi-threading\": { \"enable-multi-threading\": false, \n"
" \"packet-queue-size\": 64, \n"
" \"thread-pool-size\": 256 \n"
cfg_from.addConfiguredGlobal("multi-threading", mt);
mt->set("enable-multi-threading", Element::create(false));
mt->set("thread-pool-size", Element::create(256));
+ ElementPtr hr_i = Element::createList();
+ cfg_from.addConfiguredGlobal("host-reservation-identifiers", hr_i);
+ hr_i->add(Element::create("hw-address"));
+ hr_i->add(Element::create("flex-id"));
// Now let's merge.
ASSERT_NO_THROW(cfg_to.merge(cfg_from));
// decline-probation-period should be the "to" configured value.
EXPECT_EQ(300, cfg_to.getDeclinePeriod());
- // dhcp4o6-port should be the "from" configured value.
+ // dhcp4o6-port should be the "from" configured value.
EXPECT_EQ(999, cfg_to.getDhcp4o6Port());
- // server-tag port should be the "from" configured value.
+ // server-tag port should be the "from" configured value.
EXPECT_EQ("use_this_server", cfg_to.getServerTag().get());
- // reservations-lookup-first should be the "from" configured value.
+ // reservations-lookup-first should be the "from" configured value.
EXPECT_TRUE(cfg_to.getReservationsLookupFirst());
// ip-reservations-unique
// multi-threading
EXPECT_TRUE(cfg_to.getDHCPMultiThreading());
+ // host-reservation-identifiers
+ auto const& ex_hr_i = cfg_to.getCfgHostOperations6()->getIdentifierTypes();
+ EXPECT_EQ(ex_hr_i.size(), 2);
+ EXPECT_EQ(ex_hr_i.front(), Host::IDENT_HWADDR);
+ EXPECT_EQ(ex_hr_i.back(), Host::IDENT_FLEX);
+
// Next we check the explicitly "configured" globals.
// The list should be all of the "to" + "from", with the
// latter overwriting the former.
" \"ip-reservations-unique\": false, \n"
" \"server-tag\": \"use_this_server\", \n"
" \"reservations-lookup-first\": true, \n"
+ " \"host-reservation-identifiers\": [ \"hw-address\", \"flex-id\" ], \n"
" \"multi-threading\": { \"enable-multi-threading\": false, \n"
" \"packet-queue-size\": 64, \n"
" \"thread-pool-size\": 256 \n"
void
GenericBackendTest::checkConfiguredGlobal(const SrvConfigPtr& srv_cfg,
const std::string &name,
- ConstElementPtr exp_value) {
+ ConstElementPtr exp_value,
+ bool is_list) {
ConstCfgGlobalsPtr globals = srv_cfg->getConfiguredGlobals();
std::string param_name;
std::string sub_param_name;
<< name << " not found";
}
- ASSERT_EQ(exp_value->getType(), found_global->getType())
- << "expected global: " << name << " has wrong type";
-
- ASSERT_EQ(*exp_value, *found_global)
- << "expected global: " << name << " has wrong value";
+ if (is_list) {
+ ASSERT_EQ(Element::list, found_global->getType())
+ << "expected global: " << name << " has wrong type";
+ ASSERT_EQ(*data::Element::fromJSON(exp_value->stringValue()), *found_global)
+ << "expected global: " << name << " has wrong value";
+ } else {
+ ASSERT_EQ(exp_value->getType(), found_global->getType())
+ << "expected global: " << name << " has wrong type";
+ ASSERT_EQ(*exp_value, *found_global)
+ << "expected global: " << name << " has wrong value";
+ }
}
void
GenericBackendTest::checkConfiguredGlobal(const SrvConfigPtr& srv_cfg,
- StampedValuePtr& exp_global) {
- checkConfiguredGlobal(srv_cfg, exp_global->getName(), exp_global->getElementValue());
+ StampedValuePtr& exp_global,
+ bool is_list) {
+ checkConfiguredGlobal(srv_cfg, exp_global->getName(), exp_global->getElementValue(), is_list);
}
void
/// @brief Tests that a given global is in the configured globals
///
/// @param srv_cfg server config where the global should be checked.
- /// @param name name of the global parameter
- /// @param exp_value expected value of the global parameter as an Element
+ /// @param name name of the global parameter.
+ /// @param exp_value expected value of the global parameter as an Element.
+ /// @param is_list Flag which indicates if the parameter is a global list.
void checkConfiguredGlobal(const SrvConfigPtr& srv_cfg,
const std::string &name,
- data::ConstElementPtr exp_value);
+ data::ConstElementPtr exp_value,
+ bool is_list = false);
/// @brief Tests that a given global is in the configured globals
///
/// @param srv_cfg server config where the global should be checked.
- /// @param exp_global StampedValue representing the global value to verify
+ /// @param exp_global StampedValue representing the global value to verify.
+ /// @param is_list Flag which indicates if the parameter is a global list.
///
/// @todo At the point in time StampedVlaue carries type, exp_type should be
- /// replaced with exp_global->getType()
+ /// replaced with exp_global->getType().
void checkConfiguredGlobal(const SrvConfigPtr& srv_cfg,
- data::StampedValuePtr& exp_global);
+ data::StampedValuePtr& exp_global,
+ bool is_list = false);
/// @brief Tests that the new audit entry is added.
///
"hook": "cb_cmds",
"name": "remote-global-parameter4-get-all",
"resp-comment": [
- "The returned response contains a list of maps. Each map contains a global parameter name:value pair. The value may be a JSON string, integer, real, boolean or a map containing only one of these types. The metadata is appended to each parameter and provides database-specific information associated with the returned objects. If the server tag \"all\" is included in the command, the response contains the global parameters shared among all servers. It excludes server-specific global parameters. If an explicit server tag is included in the command, the response contains all global parameters directly associated with the given server, and the global parameters associated with all servers when server-specific values are not present."
+ "The returned response contains a list of maps. Each map contains a global parameter name:value pair. The value may be a JSON string, integer, real, boolean, list of these scalar types or a map containing only one of these scalar types. The metadata is appended to each parameter and provides database-specific information associated with the returned objects. If the server tag \"all\" is included in the command, the response contains the global parameters shared among all servers. It excludes server-specific global parameters. If an explicit server tag is included in the command, the response contains all global parameters directly associated with the given server, and the global parameters associated with all servers when server-specific values are not present."
],
"resp-syntax": [
"{",
"hook": "cb_cmds",
"name": "remote-global-parameter4-get",
"resp-comment": [
- "The returned response contains a map with a global parameter name:value pair. The value may be a JSON string, integer, real, boolean or a map containing only one of these types. The metadata is included and provides database-specific information associated with the returned object. If the \"all\" server tag is specified, the command attempts to fetch the global parameter value associated with all servers. If the explicit server tag is specified, the command fetches the value associated with the given server. If the server-specific value does not exist, the ``remote-global-parameter4-get`` command fetches the value associated with all servers."
+ "The returned response contains a map with a global parameter name:value pair. The value may be a JSON string, integer, real, boolean, list of these scalar types or a map containing only one of these scalar types. The metadata is included and provides database-specific information associated with the returned object. If the \"all\" server tag is specified, the command attempts to fetch the global parameter value associated with all servers. If the explicit server tag is specified, the command fetches the value associated with the given server. If the server-specific value does not exist, the ``remote-global-parameter4-get`` command fetches the value associated with all servers."
],
"resp-syntax": [
"{",
"This command creates or updates one or more global parameters in the configuration database."
],
"cmd-comment": [
- "This command carries multiple global parameters with their values (including maps with scalar parameters). Care should be taken when specifying more than one parameter; in some cases, only a subset of the parameters may be successfully stored in the database and other parameters may fail to be stored. In such cases the ``remote-global-parameter4-get-all`` command may be useful to verify the contents of the database after the update. The ``server-tags`` list is mandatory and must contain exactly one server tag. Specifying an empty list, a value of ``null``, or multiple server tags will result in an error. The server tag \"all\" is allowed; it associates the specified parameters with all servers."
+ "This command carries multiple global parameters with their values (including lists or maps with scalar parameters). Care should be taken when specifying more than one parameter; in some cases, only a subset of the parameters may be successfully stored in the database and other parameters may fail to be stored. In such cases the ``remote-global-parameter4-get-all`` command may be useful to verify the contents of the database after the update. The ``server-tags`` list is mandatory and must contain exactly one server tag. Specifying an empty list, a value of ``null``, or multiple server tags will result in an error. The server tag \"all\" is allowed; it associates the specified parameters with all servers."
],
"cmd-syntax": [
"{",
"hook": "cb_cmds",
"name": "remote-global-parameter6-get-all",
"resp-comment": [
- "The returned response contains a list of maps. Each map contains a global parameter name:value pair. The value may be a JSON string, integer, real, boolean or a map containing only one of these types. The metadata is appended to each parameter and provides database-specific information associated with the returned objects. If the server tag \"all\" is included in the command, the response contains the global parameters shared among all servers. It excludes server-specific global parameters. If an explicit server tag is included in the command, the response contains all global parameters directly associated with the given server, and the global parameters associated with all servers when server-specific values are not present."
+ "The returned response contains a list of maps. Each map contains a global parameter name:value pair. The value may be a JSON string, integer, real, boolean, list of these scalar types or a map containing only one of these scalar types. The metadata is appended to each parameter and provides database-specific information associated with the returned objects. If the server tag \"all\" is included in the command, the response contains the global parameters shared among all servers. It excludes server-specific global parameters. If an explicit server tag is included in the command, the response contains all global parameters directly associated with the given server, and the global parameters associated with all servers when server-specific values are not present."
],
"resp-syntax": [
"{",
"hook": "cb_cmds",
"name": "remote-global-parameter6-get",
"resp-comment": [
- "The returned response contains a map with a global parameter name:value pair. The value may be a JSON string, integer, real, boolean or a map containing only one of these types. The metadata is included and provides database-specific information associated with the returned object. If the \"all\" server tag is specified, the command attempts to fetch the global parameter value associated with all servers. If the explicit server tag is specified, the command fetches the value associated with the given server. If the server-specific value does not exist, the ``remote-global-parameter6-get`` fetches the value associated with all servers."
+ "The returned response contains a map with a global parameter name:value pair. The value may be a JSON string, integer, real, boolean, list of these scalar types or a map containing only one of these scalar types. The metadata is included and provides database-specific information associated with the returned object. If the \"all\" server tag is specified, the command attempts to fetch the global parameter value associated with all servers. If the explicit server tag is specified, the command fetches the value associated with the given server. If the server-specific value does not exist, the ``remote-global-parameter6-get`` fetches the value associated with all servers."
],
"resp-syntax": [
"{",
"This command creates or updates one or more global parameters in the configuration database."
],
"cmd-comment": [
- "This command carries multiple global parameters with their values (including maps with scalar parameters). Care should be taken when specifying more than one parameter; in some cases, only a subset of the parameters may be successfully stored in the database and other parameters may fail to be stored. In such cases the ``remote-global-parameter6-get-all`` command may be useful to verify the contents of the database after the update. The ``server-tags`` list is mandatory and must contain exactly one server tag. Specifying an empty list, a value of ``null``, or multiple server tags will result in an error. The server tag \"all\" is allowed; it associates the specified parameters with all servers."
+ "This command carries multiple global parameters with their values (including lists or maps with scalar parameters). Care should be taken when specifying more than one parameter; in some cases, only a subset of the parameters may be successfully stored in the database and other parameters may fail to be stored. In such cases the ``remote-global-parameter6-get-all`` command may be useful to verify the contents of the database after the update. The ``server-tags`` list is mandatory and must contain exactly one server tag. Specifying an empty list, a value of ``null``, or multiple server tags will result in an error. The server tag \"all\" is allowed; it associates the specified parameters with all servers."
],
"cmd-syntax": [
"{",