From: Marcin Siodelski Date: Thu, 31 Aug 2017 11:57:10 +0000 (+0200) Subject: [5305] Basic toElement() data dump for shared network implemented. X-Git-Tag: trac5073a_base~11^2~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=47215e3743c0bc3c96f834e90f45f9ed0da1ad2a;p=thirdparty%2Fkea.git [5305] Basic toElement() data dump for shared network implemented. --- diff --git a/src/lib/dhcpsrv/Makefile.am b/src/lib/dhcpsrv/Makefile.am index 7452255123..84b4892543 100644 --- a/src/lib/dhcpsrv/Makefile.am +++ b/src/lib/dhcpsrv/Makefile.am @@ -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 diff --git a/src/lib/dhcpsrv/network.cc b/src/lib/dhcpsrv/network.cc new file mode 100644 index 0000000000..0b6cb1aa65 --- /dev/null +++ b/src/lib/dhcpsrv/network.cc @@ -0,0 +1,32 @@ +// 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 + +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 diff --git a/src/lib/dhcpsrv/network.h b/src/lib/dhcpsrv/network.h index a349b44382..a5590522c9 100644 --- a/src/lib/dhcpsrv/network.h +++ b/src/lib/dhcpsrv/network.h @@ -7,6 +7,10 @@ #ifndef NETWORK_H #define NETWORK_H +#include +#include +#include +#include #include #include @@ -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. diff --git a/src/lib/dhcpsrv/shared_network.cc b/src/lib/dhcpsrv/shared_network.cc index 117441abbf..9f7c9c43ea 100644 --- a/src/lib/dhcpsrv/shared_network.cc +++ b/src/lib/dhcpsrv/shared_network.cc @@ -6,11 +6,24 @@ #include +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 diff --git a/src/lib/dhcpsrv/shared_network.h b/src/lib/dhcpsrv/shared_network.h index 854e615245..3fab2fc4f9 100644 --- a/src/lib/dhcpsrv/shared_network.h +++ b/src/lib/dhcpsrv/shared_network.h @@ -7,6 +7,7 @@ #ifndef SHARED_NETWORK_H #define SHARED_NETWORK_H +#include #include #include #include @@ -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. diff --git a/src/lib/dhcpsrv/subnet.cc b/src/lib/dhcpsrv/subnet.cc index 14ef5e83d7..9434509d0c 100644 --- a/src/lib/dhcpsrv/subnet.cc +++ b/src/lib/dhcpsrv/subnet.cc @@ -55,13 +55,13 @@ Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len, const Triplet& valid_lifetime, const isc::dhcp::Subnet::RelayInfo& relay, const SubnetID id) - :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()) - { + : 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) { 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 @@ -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); } diff --git a/src/lib/dhcpsrv/subnet.h b/src/lib/dhcpsrv/subnet.h index 7efbdb985d..1d860fdc07 100644 --- a/src/lib/dhcpsrv/subnet.h +++ b/src/lib/dhcpsrv/subnet.h @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include #include #include @@ -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_; }; diff --git a/src/lib/dhcpsrv/tests/shared_network_unittest.cc b/src/lib/dhcpsrv/tests/shared_network_unittest.cc index 8c4a9e99a1..054961a1fc 100644 --- a/src/lib/dhcpsrv/tests/shared_network_unittest.cc +++ b/src/lib/dhcpsrv/tests/shared_network_unittest.cc @@ -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 #include #include #include #include #include #include +#include #include #include #include @@ -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(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(expected, *network); +} + } // end of anonymous namespace