Commit b6a202af authored by Francis Dupont's avatar Francis Dupont
Browse files

[5351] Last fix lost reservations: better fix now

parent b46747b2
......@@ -1584,6 +1584,27 @@ const char* EXTRACTED_CONFIGS[] = {
" }\n"
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 58
"{\n"
" \"shared-networks\": [\n"
" {\n"
" \"comment\": \"A shared-network\",\n"
" \"name\": \"foo\",\n"
" \"subnet4\": [\n"
" {\n"
" \"comment\": \"A subnet\",\n"
" \"pools\": [\n"
" {\n"
" \"comment\": \"A pool\",\n"
" \"pool\": \"192.0.1.1-192.0.1.10\"\n"
" }\n"
" ],\n"
" \"subnet\": \"192.0.1.0/24\"\n"
" }\n"
" ]\n"
" }\n"
" ]\n"
" }\n"
};
......@@ -6227,6 +6248,92 @@ const char* UNPARSED_CONFIGS[] = {
" \"valid-lifetime\": 4000\n"
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 58
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
" \"always-include-fqdn\": false,\n"
" \"enable-updates\": false,\n"
" \"generated-prefix\": \"myhost\",\n"
" \"max-queue-size\": 1024,\n"
" \"ncr-format\": \"JSON\",\n"
" \"ncr-protocol\": \"UDP\",\n"
" \"override-client-update\": false,\n"
" \"override-no-update\": false,\n"
" \"qualifying-suffix\": \"\",\n"
" \"replace-client-name\": \"never\",\n"
" \"sender-ip\": \"0.0.0.0\",\n"
" \"sender-port\": 0,\n"
" \"server-ip\": \"127.0.0.1\",\n"
" \"server-port\": 53001\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
" \"max-reclaim-leases\": 100,\n"
" \"max-reclaim-time\": 250,\n"
" \"reclaim-timer-wait-time\": 10,\n"
" \"unwarned-reclaim-cycles\": 5\n"
" },\n"
" \"hooks-libraries\": [ ],\n"
" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ ],\n"
" \"re-detect\": false\n"
" },\n"
" \"lease-database\": {\n"
" \"type\": \"memfile\"\n"
" },\n"
" \"option-data\": [ ],\n"
" \"option-def\": [ ],\n"
" \"shared-networks\": [\n"
" {\n"
" \"comment\": \"A shared-network\",\n"
" \"match-client-id\": true,\n"
" \"name\": \"foo\",\n"
" \"option-data\": [ ],\n"
" \"rebind-timer\": 0,\n"
" \"relay\": {\n"
" \"ip-address\": \"0.0.0.0\"\n"
" },\n"
" \"renew-timer\": 0,\n"
" \"reservation-mode\": \"all\",\n"
" \"subnet4\": [\n"
" {\n"
" \"comment\": \"A subnet\",\n"
" \"4o6-interface\": \"\",\n"
" \"4o6-interface-id\": \"\",\n"
" \"4o6-subnet\": \"\",\n"
" \"boot-file-name\": \"\",\n"
" \"id\": 1,\n"
" \"match-client-id\": true,\n"
" \"next-server\": \"0.0.0.0\",\n"
" \"option-data\": [ ],\n"
" \"pools\": [\n"
" {\n"
" \"comment\": \"A pool\",\n"
" \"option-data\": [ ],\n"
" \"pool\": \"192.0.1.1-192.0.1.10\"\n"
" }\n"
" ],\n"
" \"rebind-timer\": 1800,\n"
" \"relay\": {\n"
" \"ip-address\": \"0.0.0.0\"\n"
" },\n"
" \"renew-timer\": 900,\n"
" \"reservation-mode\": \"all\",\n"
" \"server-hostname\": \"\",\n"
" \"subnet\": \"192.0.1.0/24\",\n"
" \"valid-lifetime\": 7200\n"
" }\n"
" ],\n"
" \"valid-lifetime\": 0\n"
" }\n"
" ],\n"
" \"subnet4\": [ ]\n"
" }\n"
};
......@@ -6474,6 +6581,7 @@ TEST_P(Dhcp4GetConfigTest, run) {
expected = UNPARSED_CONFIGS[config_counter];
ConstElementPtr json;
ASSERT_NO_THROW(json = parseDHCP4(expected, true));
ASSERT_NO_THROW(json = parseJSON(expected));
EXPECT_TRUE(isEquivalent(dhcp, json));
std::string current = prettyPrint(dhcp, 4, 4) + "\n";
EXPECT_EQ(expected, current);
......
......@@ -317,6 +317,7 @@ TEST_P(Dhcp4GetConfigTest, run) {
expected = UNPARSED_CONFIGS[config_counter];
ConstElementPtr json;
ASSERT_NO_THROW(json = parseDHCP4(expected, true));
ASSERT_NO_THROW(json = parseJSON(expected));
EXPECT_TRUE(isEquivalent(dhcp, json));
std::string current = prettyPrint(dhcp, 4, 4) + "\n";
EXPECT_EQ(expected, current);
......
......@@ -6049,5 +6049,95 @@ TEST_F(Dhcp6ParserTest, sharedNetworksRapidCommitMix) {
"shared-network or the shared-network itself used rapid-commit true");
}
// This test checks comments. Please keep it last.
TEST_F(Dhcp6ParserTest, comments) {
string config = "{\n"
"\"shared-networks\": [ {\n"
" \"name\": \"foo\"\n,"
" \"comment\": \"A shared-network\"\n,"
" \"subnet6\": [\n"
" { \n"
" \"subnet\": \"2001:db1::/48\",\n"
" \"comment\": \"A subnet\"\n,"
" \"pools\": [\n"
" {\n"
" \"pool\": \"2001:db1::/64\",\n"
" \"comment\": \"A pool\"\n"
" }\n"
" ],\n"
" \"pd-pools\": [\n"
" {\n"
" \"prefix\": \"2001:db2::\",\n"
" \"prefix-len\": 48,\n"
" \"delegated-len\": 64,\n"
" \"comment\": \"A prefix pool\"\n"
" }\n"
" ]\n"
" }\n"
" ]\n"
" } ]\n"
"} \n";
extractConfig(config);
configure(config, CONTROL_RESULT_SUCCESS, "");
// Now verify that the shared network was indeed configured.
CfgSharedNetworks6Ptr cfg_net = CfgMgr::instance().getStagingCfg()
->getCfgSharedNetworks6();
ASSERT_TRUE(cfg_net);
const SharedNetwork6Collection* nets = cfg_net->getAll();
ASSERT_TRUE(nets);
ASSERT_EQ(1, nets->size());
SharedNetwork6Ptr net = nets->at(0);
ASSERT_TRUE(net);
// Check shared network user context
ConstElementPtr ctx_net = net->getContext();
ASSERT_TRUE(ctx_net);
ASSERT_EQ(1, ctx_net->size());
ASSERT_TRUE(ctx_net->get("comment"));
EXPECT_EQ("\"A shared-network\"", ctx_net->get("comment")->str());
// The shared network has a subnet.
const Subnet6Collection * subs = net->getAllSubnets();
ASSERT_TRUE(subs);
ASSERT_EQ(1, subs->size());
Subnet6Ptr sub = subs->at(0);
ASSERT_TRUE(sub);
// Check subnet user context
ConstElementPtr ctx_sub = sub->getContext();
ASSERT_TRUE(ctx_sub);
ASSERT_EQ(1, ctx_sub->size());
ASSERT_TRUE(ctx_sub->get("comment"));
EXPECT_EQ("\"A subnet\"", ctx_sub->get("comment")->str());
// The subnet has a pool
const PoolCollection& pools = sub->getPools(Lease::TYPE_NA);
ASSERT_EQ(1, pools.size());
PoolPtr pool = pools.at(0);
ASSERT_TRUE(pool);
// Check pool user context
ConstElementPtr ctx_pool = pool->getContext();
ASSERT_TRUE(ctx_pool);
ASSERT_EQ(1, ctx_pool->size());
ASSERT_TRUE(ctx_pool->get("comment"));
EXPECT_EQ("\"A pool\"", ctx_pool->get("comment")->str());
// The subnet has a prefix pool
const PoolCollection& pdpools = sub->getPools(Lease::TYPE_PD);
ASSERT_EQ(1, pdpools.size());
PoolPtr pdpool = pdpools.at(0);
ASSERT_TRUE(pdpool);
// Check prefix pool user context
ConstElementPtr ctx_pdpool = pdpool->getContext();
ASSERT_TRUE(ctx_pdpool);
ASSERT_EQ(1, ctx_pdpool->size());
ASSERT_TRUE(ctx_pdpool->get("comment"));
EXPECT_EQ("\"A prefix pool\"", ctx_pdpool->get("comment")->str());
}
};
......@@ -1459,6 +1459,35 @@ const char* EXTRACTED_CONFIGS[] = {
" }\n"
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 51
"{\n"
" \"shared-networks\": [\n"
" {\n"
" \"comment\": \"A shared-network\",\n"
" \"name\": \"foo\",\n"
" \"subnet6\": [\n"
" {\n"
" \"comment\": \"A subnet\",\n"
" \"pd-pools\": [\n"
" {\n"
" \"comment\": \"A prefix pool\",\n"
" \"delegated-len\": 64,\n"
" \"prefix\": \"2001:db2::\",\n"
" \"prefix-len\": 48\n"
" }\n"
" ],\n"
" \"pools\": [\n"
" {\n"
" \"comment\": \"A pool\",\n"
" \"pool\": \"2001:db1::/64\"\n"
" }\n"
" ],\n"
" \"subnet\": \"2001:db1::/48\"\n"
" }\n"
" ]\n"
" }\n"
" ]\n"
" }\n"
};
......@@ -5830,6 +5859,106 @@ const char* UNPARSED_CONFIGS[] = {
" \"valid-lifetime\": 4000\n"
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 51
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
" \"always-include-fqdn\": false,\n"
" \"enable-updates\": false,\n"
" \"generated-prefix\": \"myhost\",\n"
" \"max-queue-size\": 1024,\n"
" \"ncr-format\": \"JSON\",\n"
" \"ncr-protocol\": \"UDP\",\n"
" \"override-client-update\": false,\n"
" \"override-no-update\": false,\n"
" \"qualifying-suffix\": \"\",\n"
" \"replace-client-name\": \"never\",\n"
" \"sender-ip\": \"0.0.0.0\",\n"
" \"sender-port\": 0,\n"
" \"server-ip\": \"127.0.0.1\",\n"
" \"server-port\": 53001\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
" \"max-reclaim-leases\": 100,\n"
" \"max-reclaim-time\": 250,\n"
" \"reclaim-timer-wait-time\": 10,\n"
" \"unwarned-reclaim-cycles\": 5\n"
" },\n"
" \"hooks-libraries\": [ ],\n"
" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ ],\n"
" \"re-detect\": false\n"
" },\n"
" \"lease-database\": {\n"
" \"type\": \"memfile\"\n"
" },\n"
" \"mac-sources\": [ \"any\" ],\n"
" \"option-data\": [ ],\n"
" \"option-def\": [ ],\n"
" \"relay-supplied-options\": [ \"65\" ],\n"
" \"server-id\": {\n"
" \"enterprise-id\": 0,\n"
" \"htype\": 0,\n"
" \"identifier\": \"\",\n"
" \"persist\": true,\n"
" \"time\": 0,\n"
" \"type\": \"LLT\"\n"
" },\n"
" \"shared-networks\": [\n"
" {\n"
" \"comment\": \"A shared-network\",\n"
" \"name\": \"foo\",\n"
" \"option-data\": [ ],\n"
" \"preferred-lifetime\": 0,\n"
" \"rapid-commit\": false,\n"
" \"rebind-timer\": 0,\n"
" \"relay\": {\n"
" \"ip-address\": \"::\"\n"
" },\n"
" \"renew-timer\": 0,\n"
" \"reservation-mode\": \"all\",\n"
" \"subnet6\": [\n"
" {\n"
" \"comment\": \"A subnet\",\n"
" \"id\": 1,\n"
" \"option-data\": [ ],\n"
" \"pd-pools\": [\n"
" {\n"
" \"comment\": \"A prefix pool\",\n"
" \"delegated-len\": 64,\n"
" \"option-data\": [ ],\n"
" \"prefix\": \"2001:db2::\",\n"
" \"prefix-len\": 48\n"
" }\n"
" ],\n"
" \"pools\": [\n"
" {\n"
" \"comment\": \"A pool\",\n"
" \"option-data\": [ ],\n"
" \"pool\": \"2001:db1::/64\"\n"
" }\n"
" ],\n"
" \"preferred-lifetime\": 3600,\n"
" \"rapid-commit\": false,\n"
" \"rebind-timer\": 1800,\n"
" \"relay\": {\n"
" \"ip-address\": \"::\"\n"
" },\n"
" \"renew-timer\": 900,\n"
" \"reservation-mode\": \"all\",\n"
" \"subnet\": \"2001:db1::/48\",\n"
" \"valid-lifetime\": 7200\n"
" }\n"
" ],\n"
" \"valid-lifetime\": 0\n"
" }\n"
" ],\n"
" \"subnet6\": [ ]\n"
" }\n"
};
......@@ -6080,6 +6209,7 @@ TEST_P(Dhcp6GetConfigTest, run) {
expected = UNPARSED_CONFIGS[config_counter];
ConstElementPtr json;
ASSERT_NO_THROW(json = parseDHCP6(expected, true));
ASSERT_NO_THROW(json = parseJSON(expected));
EXPECT_TRUE(isEquivalent(dhcp, json));
std::string current = prettyPrint(dhcp, 4, 4) + "\n";
EXPECT_EQ(expected, current);
......
......@@ -320,6 +320,7 @@ TEST_P(Dhcp6GetConfigTest, run) {
expected = UNPARSED_CONFIGS[config_counter];
ConstElementPtr json;
ASSERT_NO_THROW(json = parseDHCP6(expected, true));
ASSERT_NO_THROW(json = parseJSON(expected));
EXPECT_TRUE(isEquivalent(dhcp, json));
std::string current = prettyPrint(dhcp, 4, 4) + "\n";
EXPECT_EQ(expected, current);
......
......@@ -234,21 +234,22 @@ SrvConfig::toElement() const {
dhcp->set("option-data", cfg_option_->toElement());
// Set subnets and shared networks.
ConstElementPtr subnets;
std::vector<ElementPtr> sn_list;
if (family == AF_INET) {
subnets = cfg_subnets4_->toElement();
ElementPtr plain_subnets = Element::createList();
const Subnet4Collection* subs = cfg_subnets4_->getAll();
for (Subnet4Collection::const_iterator subnet = subs->cbegin();
subnet != subs->cend(); ++subnet) {
const Subnet4Collection* subnets = cfg_subnets4_->getAll();
for (Subnet4Collection::const_iterator subnet = subnets->cbegin();
subnet != subnets->cend(); ++subnet) {
ElementPtr subnet_cfg = (*subnet)->toElement();
sn_list.push_back(subnet_cfg);
// Skip subnets which are in a shared-network
SharedNetwork4Ptr network;
(*subnet)->getSharedNetwork(network);
if (network) {
continue;
}
plain_subnets->add((*subnet)->toElement());
plain_subnets->add(subnet_cfg);
}
dhcp->set("subnet4", plain_subnets);
......@@ -256,19 +257,20 @@ SrvConfig::toElement() const {
dhcp->set("shared-networks", shared_networks);
} else {
subnets = cfg_subnets6_->toElement();
ElementPtr plain_subnets = Element::createList();
const Subnet6Collection* subs = cfg_subnets6_->getAll();
for (Subnet6Collection::const_iterator subnet = subs->cbegin();
subnet != subs->cend(); ++subnet) {
const Subnet6Collection* subnets = cfg_subnets6_->getAll();
for (Subnet6Collection::const_iterator subnet = subnets->cbegin();
subnet != subnets->cend(); ++subnet) {
ElementPtr subnet_cfg = (*subnet)->toElement();
sn_list.push_back(subnet_cfg);
// Skip subnets which are in a shared-network
SharedNetwork6Ptr network;
(*subnet)->getSharedNetwork(network);
if (network) {
continue;
}
plain_subnets->add((*subnet)->toElement());
plain_subnets->add(subnet_cfg);
}
dhcp->set("subnet6", plain_subnets);
......@@ -278,9 +280,8 @@ SrvConfig::toElement() const {
// Insert reservations
CfgHostsList resv_list;
resv_list.internalize(cfg_hosts_->toElement());
const std::vector<ElementPtr>& sn_list = subnets->listValue();
for (std::vector<ElementPtr>::const_iterator subnet = sn_list.begin();
subnet != sn_list.end(); ++subnet) {
for (std::vector<ElementPtr>::const_iterator subnet = sn_list.cbegin();
subnet != sn_list.cend(); ++subnet) {
ConstElementPtr id = (*subnet)->get("id");
if (isNull(id)) {
isc_throw(ToElementError, "subnet has no id");
......
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