Commit 47215e37 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[5305] Basic toElement() data dump for shared network implemented.

parent b038ebda
......@@ -141,7 +141,7 @@ libkea_dhcpsrv_la_SOURCES += mysql_host_data_source.cc mysql_host_data_source.h
endif
libkea_dhcpsrv_la_SOURCES += ncr_generator.cc ncr_generator.h
libkea_dhcpsrv_la_SOURCES += network.h
libkea_dhcpsrv_la_SOURCES += network.cc network.h
if HAVE_PGSQL
libkea_dhcpsrv_la_SOURCES += pgsql_connection.cc pgsql_connection.h
......
// Copyright (C) 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
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <dhcpsrv/network.h>
using namespace isc::data;
namespace isc {
namespace dhcp {
ElementPtr
Network::toElement() const {
ElementPtr map = Element::createMap();
// Set interface
const std::string& iface = getIface();
if (!iface.empty()) {
map->set("interface", Element::create(iface));
}
// Set options
ConstCfgOptionPtr opts = getCfgOption();
map->set("option-data", opts->toElement());
return (map);
}
} // end of namespace isc::dhcp
} // end of namespace isc
......@@ -7,6 +7,10 @@
#ifndef NETWORK_H
#define NETWORK_H
#include <cc/cfg_to_element.h>
#include <cc/data.h>
#include <dhcpsrv/cfg_option.h>
#include <dhcpsrv/cfg_4o6.h>
#include <boost/shared_ptr.hpp>
#include <string>
......@@ -30,9 +34,14 @@ namespace dhcp {
/// class provides an abstract interface that must be implemented by derived
/// classes and, where appropriate, implements common methods used by the
/// derived classes.
class Network {
class Network : public data::CfgToElement {
public:
/// @brief Constructor.
Network()
: iface_name_(), cfg_option_(new CfgOption()) {
}
/// @brief Virtual destructor.
///
/// Does nothing at the moment.
......@@ -58,11 +67,29 @@ public:
return (iface_name_);
};
/// @brief Returns pointer to the option data configuration for this subnet.
CfgOptionPtr getCfgOption() {
return (cfg_option_);
}
/// @brief Returns const pointer to the option data configuration for this
/// subnet.
ConstCfgOptionPtr getCfgOption() const {
return (cfg_option_);
}
/// @brief Unparses network object.
///
/// @return A pointer to unparsed network configuration.
virtual data::ElementPtr toElement() const;
protected:
/// @brief Holds interface name for which this network is selected.
std::string iface_name_;
/// @brief Pointer to the option data configuration for this subnet.
CfgOptionPtr cfg_option_;
};
/// @brief Pointer to the @ref Network object.
......
......@@ -6,11 +6,24 @@
#include <dhcpsrv/shared_network.h>
using namespace isc::data;
using namespace isc::dhcp;
namespace isc {
namespace dhcp {
ElementPtr
SharedNetwork::toElement() const {
ElementPtr map = Network::toElement();
// Set shared network name.
if (!name_.empty()) {
map->set("name", Element::create(name_));
}
return (map);
}
NetworkPtr
SharedNetwork4::sharedFromThis() {
return (shared_from_this());
......@@ -38,6 +51,20 @@ SharedNetwork4::getNextSubnet(const Subnet4Ptr& first_subnet,
current_subnet));
}
ElementPtr
SharedNetwork4::toElement() const {
ElementPtr map = SharedNetwork::toElement();
ElementPtr subnet4 = Element::createList();
for (auto subnet = subnets_.cbegin(); subnet != subnets_.cend(); ++subnet) {
subnet4->add((*subnet)->toElement());
}
map->set("subnet4", subnet4);
return (map);
}
NetworkPtr
SharedNetwork6::sharedFromThis() {
return (shared_from_this());
......@@ -65,5 +92,19 @@ SharedNetwork6::getNextSubnet(const Subnet6Ptr& first_subnet,
current_subnet));
}
ElementPtr
SharedNetwork6::toElement() const {
ElementPtr map = SharedNetwork::toElement();
ElementPtr subnet6 = Element::createList();
for (auto subnet = subnets_.cbegin(); subnet != subnets_.cend(); ++subnet) {
subnet6->add((*subnet)->toElement());
}
map->set("subnet6", subnet6);
return (map);
}
} // end of namespace isc::dhcp
} // end of namespace isc
......@@ -7,6 +7,7 @@
#ifndef SHARED_NETWORK_H
#define SHARED_NETWORK_H
#include <cc/data.h>
#include <exceptions/exceptions.h>
#include <dhcpsrv/assignable_network.h>
#include <dhcpsrv/subnet.h>
......@@ -245,7 +246,10 @@ protected:
return (*subnet_it);
}
protected:
/// @brief Unparses shared network object.
///
/// @return A pointer to unparsed shared network configuration.
virtual data::ElementPtr toElement() const;
/// @brief Holds a name of a shared network.
std::string name_;
......@@ -322,6 +326,11 @@ public:
Subnet4Ptr getNextSubnet(const Subnet4Ptr& first_subnet,
const Subnet4Ptr& current_subnet) const;
/// @brief Unparses shared network object.
///
/// @return A pointer to unparsed shared network configuration.
virtual data::ElementPtr toElement() const;
private:
/// @brief Collection of IPv4 subnets within shared network.
......@@ -402,6 +411,11 @@ public:
Subnet6Ptr getNextSubnet(const Subnet6Ptr& first_subnet,
const Subnet6Ptr& current_subnet) const;
/// @brief Unparses shared network object.
///
/// @return A pointer to unparsed shared network configuration.
virtual data::ElementPtr toElement() const;
private:
/// @brief Collection of IPv6 subnets within shared network.
......
......@@ -55,13 +55,13 @@ Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
const Triplet<uint32_t>& valid_lifetime,
const isc::dhcp::Subnet::RelayInfo& relay,
const SubnetID id)
:id_(id == 0 ? generateNextID() : id), prefix_(prefix), prefix_len_(len),
: Network(), id_(id == 0 ? generateNextID() : id), prefix_(prefix),
prefix_len_(len),
t1_(t1), t2_(t2), valid_(valid_lifetime),
last_allocated_ia_(lastAddrInPrefix(prefix, len)),
last_allocated_ta_(lastAddrInPrefix(prefix, len)),
last_allocated_pd_(lastAddrInPrefix(prefix, len)), relay_(relay),
host_reservation_mode_(HR_ALL), cfg_option_(new CfgOption())
{
host_reservation_mode_(HR_ALL) {
if ((prefix.isV6() && len > 128) ||
(prefix.isV4() && len > 32)) {
isc_throw(BadValue,
......@@ -465,8 +465,7 @@ void Subnet6::checkType(Lease::Type type) const {
data::ElementPtr
Subnet::toElement() const {
// Prepare the map
ElementPtr map = Element::createMap();
ElementPtr map = Network::toElement();
// Set subnet id
SubnetID id = getID();
......@@ -481,12 +480,6 @@ Subnet::toElement() const {
// Set subnet
map->set("subnet", Element::create(toText()));
// Set interface
const std::string& iface = getIface();
if (!iface.empty()) {
map->set("interface", Element::create(iface));
}
// Set renew-timer
map->set("renew-timer",
Element::create(static_cast<long long>
......@@ -528,10 +521,6 @@ Subnet::toElement() const {
map->set("client-class", Element::create(*cclasses.cbegin()));
}
// Set options
ConstCfgOptionPtr opts = getCfgOption();
map->set("option-data", opts->toElement());
return (map);
}
......
......@@ -13,8 +13,6 @@
#include <dhcp/classify.h>
#include <dhcp/option_space_container.h>
#include <dhcpsrv/assignable_network.h>
#include <dhcpsrv/cfg_option.h>
#include <dhcpsrv/cfg_4o6.h>
#include <dhcpsrv/lease.h>
#include <dhcpsrv/pool.h>
#include <dhcpsrv/subnet_id.h>
......@@ -114,17 +112,6 @@ public:
return (t2_);
}
/// @brief Returns pointer to the option data configuration for this subnet.
CfgOptionPtr getCfgOption() {
return (cfg_option_);
}
/// @brief Returns const pointer to the option data configuration for this
/// subnet.
ConstCfgOptionPtr getCfgOption() const {
return (cfg_option_);
}
/// @brief returns the last address that was tried from this pool
///
/// This method returns the last address that was attempted to be allocated
......@@ -551,9 +538,6 @@ protected:
/// See @ref HRMode type for details.
HRMode host_reservation_mode_;
/// @brief Pointer to the option data configuration for this subnet.
CfgOptionPtr cfg_option_;
NetworkPtr shared_network_;
};
......
......@@ -4,12 +4,14 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
#include <asiolink/io_address.h>
#include <dhcpsrv/shared_network.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/subnet_id.h>
#include <dhcpsrv/triplet.h>
#include <exceptions/exceptions.h>
#include <testutils/test_to_element.h>
#include <gtest/gtest.h>
#include <cstdint>
#include <vector>
......@@ -181,6 +183,68 @@ TEST(SharedNetwork4Test, getNextSubnet) {
}
}
// This test verifies that unparsing shared network returns valid structure.
TEST(SharedNetwork4Test, unparse) {
SharedNetwork4Ptr network(new SharedNetwork4("frog"));
// Set interface name.
network->setIface("eth1");
// Add several subnets.
Subnet4Ptr subnet1(new Subnet4(IOAddress("10.0.0.0"), 8, 10, 20, 30,
SubnetID(1)));
Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.0"), 24, 10, 20, 30,
SubnetID(2)));
network->add(subnet1);
network->add(subnet2);
std::string expected = "{\n"
" \"interface\": \"eth1\",\n"
" \"name\": \"frog\",\n"
" \"option-data\": [ ],\n"
" \"subnet4\": [\n"
" {\n"
" \"4o6-interface\": \"\",\n"
" \"4o6-interface-id\": \"\",\n"
" \"4o6-subnet\": \"\",\n"
" \"id\": 1,\n"
" \"match-client-id\": true,\n"
" \"next-server\": \"0.0.0.0\",\n"
" \"option-data\": [ ],\n"
" \"pools\": [ ],\n"
" \"rebind-timer\": 20,\n"
" \"relay\": {\n"
" \"ip-address\": \"0.0.0.0\"\n"
" },\n"
" \"renew-timer\": 10,\n"
" \"reservation-mode\": \"all\",\n"
" \"subnet\": \"10.0.0.0/8\",\n"
" \"valid-lifetime\": 30\n"
" },\n"
" {\n"
" \"4o6-interface\": \"\",\n"
" \"4o6-interface-id\": \"\",\n"
" \"4o6-subnet\": \"\",\n"
" \"id\": 2,\n"
" \"match-client-id\": true,\n"
" \"next-server\": \"0.0.0.0\",\n"
" \"option-data\": [ ],\n"
" \"pools\": [ ],\n"
" \"rebind-timer\": 20,\n"
" \"relay\": {\n"
" \"ip-address\": \"0.0.0.0\"\n"
" },\n"
" \"renew-timer\": 10,\n"
" \"reservation-mode\": \"all\",\n"
" \"subnet\": \"192.0.2.0/24\",\n"
" \"valid-lifetime\": 30\n"
" }\n"
" ]\n"
"}\n";
test::runToElementTest<SharedNetwork4>(expected, *network);
}
// This test verifies that shared network can be given a name and that
// this name can be retrieved.
TEST(SharedNetwork6Test, getName) {
......@@ -342,4 +406,60 @@ TEST(SharedNetwork6Test, getNextSubnet) {
}
}
// This test verifies that unparsing shared network returns valid structure.
TEST(SharedNetwork6Test, unparse) {
SharedNetwork6Ptr network(new SharedNetwork6("frog"));
network->setIface("eth1");
// Add several subnets.
Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 64, 10, 20, 30,
40, SubnetID(1)));
Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 16, 10, 20, 30, 40,
SubnetID(2)));
network->add(subnet1);
network->add(subnet2);
std::string expected = "{\n"
" \"interface\": \"eth1\",\n"
" \"name\": \"frog\",\n"
" \"option-data\": [ ],\n"
" \"subnet6\": [\n"
" {\n"
" \"id\": 1,\n"
" \"option-data\": [ ],\n"
" \"pd-pools\": [ ],\n"
" \"pools\": [ ],\n"
" \"preferred-lifetime\": 30,\n"
" \"rapid-commit\": false,\n"
" \"rebind-timer\": 20,\n"
" \"relay\": {\n"
" \"ip-address\": \"::\"\n"
" },\n"
" \"renew-timer\": 10,\n"
" \"reservation-mode\": \"all\",\n"
" \"subnet\": \"2001:db8:1::/64\",\n"
" \"valid-lifetime\": 40\n"
" },\n"
" {\n"
" \"id\": 2,\n"
" \"option-data\": [ ],\n"
" \"pd-pools\": [ ],\n"
" \"pools\": [ ],\n"
" \"preferred-lifetime\": 30,\n"
" \"rapid-commit\": false,\n"
" \"rebind-timer\": 20,\n"
" \"relay\": {\n"
" \"ip-address\": \"::\"\n"
" },\n"
" \"renew-timer\": 10,\n"
" \"reservation-mode\": \"all\",\n"
" \"subnet\": \"3000::/16\",\n"
" \"valid-lifetime\": 40\n"
" }\n"
" ]\n"
"}\n";
test::runToElementTest<SharedNetwork6>(expected, *network);
}
} // end of anonymous namespace
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