Commit ef1c0b74 authored by Thomas Markwalder's avatar Thomas Markwalder

[5378] kea-dhcp4/6 now keep track of their configured global params

src/bin/dhcp4/json_config_parser.cc
    configureDhcp4Server() - added extract of configured globals

src/bin/dhcp4/tests/get_config_unittest.cc
src/bin/dhcp6/tests/get_config_unittest.cc
    Updated extracted and unparsed configs.

src/bin/dhcp6/json_config_parser.cc
    configureDhcp6Server() - added extract of configured globals

src/lib/dhcpsrv/srv_config.h
src/lib/dhcpsrv/srv_config.cc
    Added storage and maintence of configured globals
    SrvConfig::toElement() - added configured globals to result

src/lib/dhcpsrv/tests/srv_config_unittest.cc
    TEST_F(SrvConfigTest, configuredGlobals) - new test
parent df869a79
......@@ -316,6 +316,9 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
SrvConfigPtr srv_cfg = CfgMgr::instance().getStagingCfg();
// Preserve all scalar global parameters
srv_cfg->extractConfiguredGlobals(config_set);
// This is a way to convert ConstElementPtr to ElementPtr.
// We need a config that can be edited, because we will insert
// default values and will insert derived values as well.
......
This diff is collapsed.
......@@ -419,6 +419,9 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
SrvConfigPtr srv_config = CfgMgr::instance().getStagingCfg();
// Preserve all scalar global parameters
srv_config->extractConfiguredGlobals(config_set);
// Set all default values if not specified by the user.
SimpleParser6::setAllDefaults(mutable_cfg);
......
This diff is collapsed.
......@@ -34,7 +34,8 @@ SrvConfig::SrvConfig()
cfg_host_operations6_(CfgHostOperations::createConfig6()),
class_dictionary_(new ClientClassDictionary()),
decline_timer_(0), echo_v4_client_id_(true), dhcp4o6_port_(0),
d2_client_config_(new D2ClientConfig()) {
d2_client_config_(new D2ClientConfig()),
configured_globals_(Element::createMap()) {
}
SrvConfig::SrvConfig(const uint32_t sequence)
......@@ -50,7 +51,8 @@ SrvConfig::SrvConfig(const uint32_t sequence)
cfg_host_operations6_(CfgHostOperations::createConfig6()),
class_dictionary_(new ClientClassDictionary()),
decline_timer_(0), echo_v4_client_id_(true), dhcp4o6_port_(0),
d2_client_config_(new D2ClientConfig()) {
d2_client_config_(new D2ClientConfig()),
configured_globals_(Element::createMap()) {
}
std::string
......@@ -206,6 +208,21 @@ SrvConfig::updateStatistics() {
}
}
void
SrvConfig::extractConfiguredGlobals(isc::data::ConstElementPtr config) {
if (config->getType() != Element::map) {
isc_throw(BadValue, "extractConfiguredGlobals must be given a map element");
}
const std::map<std::string, ConstElementPtr>& values = config->mapValue();
for (auto value = values.begin(); value != values.end(); ++value) {
if (value->second->getType() != Element::list &&
value->second->getType() != Element::map) {
addConfiguredGlobal(value->first, value->second);
}
}
}
ElementPtr
SrvConfig::toElement() const {
// Get family for the configuration manager
......@@ -214,8 +231,13 @@ SrvConfig::toElement() const {
ElementPtr result = Element::createMap();
// DhcpX global map
ElementPtr dhcp = Element::createMap();
// Add in explicitly configured globals.
dhcp->setValue(configured_globals_->mapValue());
// Set user-context
contextToElement(dhcp);
// Set decline-probation-period
dhcp->set("decline-probation-period",
Element::create(static_cast<long long>(decline_timer_)));
......@@ -226,6 +248,7 @@ SrvConfig::toElement() const {
// Set dhcp4o6-port
dhcp->set("dhcp4o6-port",
Element::create(static_cast<int>(dhcp4o6_port_)));
// Set dhcp-ddns
dhcp->set("dhcp-ddns", d2_client_config_->toElement());
// Set interfaces-config
......
......@@ -59,10 +59,12 @@ public:
static const uint32_t CFGSEL_DDNS = 0x00000010;
/// Number of all subnets
static const uint32_t CFGSEL_SUBNET = 0x00000003;
/// Configured globals
static const uint32_t CFGSEL_GLOBALS = 0x00000020;
/// IPv4 related config
static const uint32_t CFGSEL_ALL4 = 0x00000015;
static const uint32_t CFGSEL_ALL4 = 0x00000035;
/// IPv6 related config
static const uint32_t CFGSEL_ALL6 = 0x0000001A;
static const uint32_t CFGSEL_ALL6 = 0x0000003A;
/// Whole config
static const uint32_t CFGSEL_ALL = 0xFFFFFFFF;
//@}
......@@ -556,6 +558,21 @@ public:
d2_client_config_ = d2_client_config;
}
/// @brief Returns pointer to configured global parameters
isc::data::ConstElementPtr getConfiguredGlobals() const {
return (isc::data::ConstElementPtr(configured_globals_));
}
/// @brief Saves scalar elements from the global scope of a configuration
void extractConfiguredGlobals(isc::data::ConstElementPtr config);
/// @brief Adds a parameter to the collection configured globals
/// @param name std::string name of the global to add
/// @param value ElementPtr containing the value of the global
void addConfiguredGlobal(const std::string& name, isc::data::ConstElementPtr value) {
configured_globals_->set(name, value);
}
/// @brief Unparse a configuration object
///
/// @return a pointer to unparsed configuration
......@@ -657,7 +674,11 @@ private:
/// this socket is bound and connected to this port and port + 1
uint16_t dhcp4o6_port_;
/// @brief Stores D2 client configuration
D2ClientConfigPtr d2_client_config_;
/// @brief Stores the global parameters specified via configuration
isc::data::ElementPtr configured_globals_;
};
/// @name Pointers to the @c SrvConfig object.
......
......@@ -431,6 +431,61 @@ TEST_F(SrvConfigTest, hooksLibraries) {
EXPECT_TRUE(copied.getHooksConfig().equal(conf.getHooksConfig()));
}
// Verifies basic functions of configured global handling.
TEST_F(SrvConfigTest, configuredGlobals) {
// Create an instance.
SrvConfig conf(32);
// The map of configured globals should be empty.
ConstElementPtr srv_globals = conf.getConfiguredGlobals();
ASSERT_TRUE(srv_globals);
ASSERT_EQ(Element::map, srv_globals->getType());
ASSERT_TRUE(srv_globals->mapValue().empty());
// Attempting to extract globals from a non-map should throw.
ASSERT_THROW(conf.extractConfiguredGlobals(Element::create(777)), isc::BadValue);
// Now let's create a configuration from which to extract global scalars.
// Extraction (currently) has no business logic, so the elements we use
// can be arbitrary.
ConstElementPtr global_cfg;
std::string global_cfg_str =
"{\n"
" \"astring\": \"okay\",\n"
" \"amap\": { \"not-this\":777, \"not-that\": \"poo\" },\n"
" \"anint\": 444,\n"
" \"alist\": [ 1, 2, 3 ],\n"
" \"abool\": true\n"
"}\n";
ASSERT_NO_THROW(global_cfg = Element::fromJSON(global_cfg_str));
// Extract globals from the config.
ASSERT_NO_THROW(conf.extractConfiguredGlobals(global_cfg));
// Now see if the extract was correct.
srv_globals = conf.getConfiguredGlobals();
ASSERT_TRUE(srv_globals);
ASSERT_EQ(Element::map, srv_globals->getType());
ASSERT_FALSE(srv_globals->mapValue().empty());
// Maps and lists should be excluded.
auto globals = srv_globals->mapValue();
for (auto global = globals.begin(); global != globals.end(); ++global) {
if (global->first == "astring") {
ASSERT_EQ(Element::string, global->second->getType());
EXPECT_EQ("okay", global->second->stringValue());
} else if (global->first == "anint") {
ASSERT_EQ(Element::integer, global->second->getType());
EXPECT_EQ(444, global->second->intValue());
} else if (global->first == "abool") {
ASSERT_EQ(Element::boolean, global->second->getType());
EXPECT_TRUE(global->second->boolValue());
} else {
ADD_FAILURE() << "unexpected element found:" << global->first;
}
}
}
// Verifies that the toElement method works well (tests limited to
// direct parameters)
TEST_F(SrvConfigTest, unparse) {
......@@ -448,8 +503,7 @@ TEST_F(SrvConfigTest, unparse) {
defaults += conf.getCfgExpiration()->toElement()->str() + ",\n";
defaults += "\"lease-database\": { \"type\": \"memfile\" },\n";
defaults += "\"hooks-libraries\": [ ],\n";
defaults += "\"dhcp-ddns\": \n";
defaults += conf.getD2ClientConfig()->toElement()->str() + ",\n";
defaults += "\"dhcp-ddns\": \n"; defaults += conf.getD2ClientConfig()->toElement()->str() + ",\n";
std::string defaults4 = "\"echo-client-id\": true,\n";
defaults4 += "\"shared-networks\": [ ],\n";
......@@ -481,15 +535,28 @@ TEST_F(SrvConfigTest, unparse) {
isc::test::runToElementTest<SrvConfig>
(header6 + defaults + defaults6 + trailer, conf);
// Verify direct non-default parameters
// Verify direct non-default parameters and configured globals
CfgMgr::instance().setFamily(AF_INET);
conf.setEchoClientId(false);
conf.setDhcp4o6Port(6767);
// Add "configured globals"
conf.addConfiguredGlobal("renew-timer", Element::create(777));
conf.addConfiguredGlobal("foo", Element::create("bar"));
params = "\"echo-client-id\": false,\n";
params += "\"dhcp4o6-port\": 6767\n";
params += "\"dhcp4o6-port\": 6767,\n";
params += "\"renew-timer\": 777,\n";
params += "\"foo\": \"bar\"\n";
isc::test::runToElementTest<SrvConfig>
(header4 + defaults + defaults4 + params + trailer, conf);
}
// Verify direct non-default parameters and configured globals
CfgMgr::instance().setFamily(AF_INET6);
params = ",\"dhcp4o6-port\": 6767,\n";
params += "\"renew-timer\": 777,\n";
params += "\"foo\": \"bar\"\n";
isc::test::runToElementTest<SrvConfig>
(header6 + defaults + defaults6 + params + trailer, conf);
}
// Verifies that the toElement method does not miss host reservations
TEST_F(SrvConfigTest, unparseHR) {
......
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