Browse Source

[5396] delAll method implemented in SharedNetwork{4,6}

Tomek Mrugalski 7 years ago
parent
commit
11be0c5170

+ 4 - 1
src/lib/dhcpsrv/cfg_shared_networks.h

@@ -58,8 +58,11 @@ public:
         auto& index = networks_.template get<SharedNetworkNameIndexTag>();
         auto shared_network = index.find(name);
         if (shared_network != index.end()) {
-            index.erase(shared_network);
+            // Delete all subnets from the network
+            (*shared_network)->delAll();
 
+            // Then delete the network from the networks list.
+            index.erase(shared_network);
         } else {
             isc_throw(BadValue, "unable to delete non-existing network '"
                       << name << "' from shared networks configuration");

+ 15 - 0
src/lib/dhcpsrv/shared_network.cc

@@ -219,6 +219,14 @@ SharedNetwork4::del(const SubnetID& subnet_id) {
     clearSharedNetwork(subnet);
 }
 
+void
+SharedNetwork4::delAll() {
+    for (auto subnet = subnets_.cbegin(); subnet != subnets_.cend(); ++subnet) {
+        clearSharedNetwork(*subnet);
+    }
+    subnets_.clear();
+}
+
 Subnet4Ptr
 SharedNetwork4::getSubnet(const SubnetID& subnet_id) const {
     return (Impl::getSubnet<Subnet4Ptr>(subnets_, subnet_id));
@@ -267,6 +275,13 @@ SharedNetwork6::del(const SubnetID& subnet_id) {
     clearSharedNetwork(subnet);
 }
 
+void
+SharedNetwork6::delAll() {
+    for (auto subnet = subnets_.cbegin(); subnet != subnets_.cend(); ++subnet) {
+        clearSharedNetwork(*subnet);
+    }
+    subnets_.clear();
+}
 Subnet6Ptr
 SharedNetwork6::getSubnet(const SubnetID& subnet_id) const {
     return (Impl::getSubnet<Subnet6Ptr>(subnets_, subnet_id));

+ 6 - 0
src/lib/dhcpsrv/shared_network.h

@@ -86,6 +86,9 @@ public:
     /// @throw BadValue When specified subnet doesn't exist.
     void del(const SubnetID& subnet_id);
 
+    /// @brief Removes all subnets from a shared network.
+    void delAll();
+
     /// @brief Returns a pointer to the collection of subnets within this
     /// shared network.
     const Subnet4Collection* getAllSubnets() const {
@@ -217,6 +220,9 @@ public:
     /// @throw BadValue When specified subnet doesn't exist.
     void del(const SubnetID& subnet_id);
 
+    /// @brief Removes all subnets from a shared network.
+    void delAll();
+
     /// @brief Returns a pointer to the collection of subnets within this
     /// shared network.
     const Subnet6Collection* getAllSubnets() const {

+ 33 - 0
src/lib/dhcpsrv/tests/cfg_shared_networks4_unittest.cc

@@ -8,10 +8,12 @@
 #include <exceptions/exceptions.h>
 #include <dhcpsrv/cfg_shared_networks.h>
 #include <testutils/test_to_element.h>
+#include <asiolink/io_address.h>
 #include <gtest/gtest.h>
 
 using namespace isc;
 using namespace isc::dhcp;
+using namespace asiolink;
 
 namespace {
 
@@ -62,6 +64,37 @@ TEST(CfgSharedNetworks4Test, deleteByName) {
     ASSERT_THROW(cfg.del(network2->getName()), BadValue);
 }
 
+// Checks that subnets have their shared network pointers updated when
+// the network is deleted. This is used when the shared network is deleted
+// by admin commands.
+TEST(CfgSharedNetworks4Test, deleteNetworkWithSubnets) {
+    CfgSharedNetworks4 cfg;
+    SharedNetwork4Ptr network(new SharedNetwork4("frog"));
+    SubnetID id1(100);
+    SubnetID id2(101);
+    Subnet4Ptr sub1(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3, id1));
+    Subnet4Ptr sub2(new Subnet4(IOAddress("192.0.3.0"), 24, 1, 2, 3, id2));
+    network->add(sub1);
+    network->add(sub2);
+    cfg.add(network);
+
+    // Make sure the subnets are part of the network.
+    SharedNetwork4Ptr test;
+    sub1->getSharedNetwork(test);
+    EXPECT_TRUE(test);
+    EXPECT_EQ(network->toElement()->str(), test->toElement()->str());
+    sub2->getSharedNetwork(test);
+    EXPECT_TRUE(test);
+    EXPECT_EQ(network->toElement()->str(), test->toElement()->str());
+
+    // Now remove the network. Subnets should be disassociated with the network.
+    cfg.del("frog");
+    sub1->getSharedNetwork(test);
+    EXPECT_FALSE(test);
+    sub2->getSharedNetwork(test);
+    EXPECT_FALSE(test);
+}
+
 // This test verifies that shared networks must have unique names.
 TEST(CfgSharedNetworks4Test, duplicateName) {
     SharedNetwork4Ptr network1(new SharedNetwork4("frog"));

+ 33 - 0
src/lib/dhcpsrv/tests/cfg_shared_networks6_unittest.cc

@@ -7,11 +7,13 @@
 #include <config.h>
 #include <exceptions/exceptions.h>
 #include <dhcpsrv/cfg_shared_networks.h>
+#include <asiolink/io_address.h>
 #include <testutils/test_to_element.h>
 #include <gtest/gtest.h>
 
 using namespace isc;
 using namespace isc::dhcp;
+using namespace asiolink;
 
 namespace {
 
@@ -62,6 +64,37 @@ TEST(CfgSharedNetworks6Test, deleteByName) {
     ASSERT_THROW(cfg.del(network2->getName()), BadValue);
 }
 
+// Checks that subnets have their shared network pointers updated when
+// the network is deleted. This is used when the shared network is deleted
+// by admin commands.
+TEST(CfgSharedNetworks4Test, deleteNetworkWithSubnets) {
+    CfgSharedNetworks6 cfg;
+    SharedNetwork6Ptr network(new SharedNetwork6("frog"));
+    SubnetID id1(100);
+    SubnetID id2(101);
+    Subnet6Ptr sub1(new Subnet6(IOAddress("2001:db8::"), 48, 1, 2, 3, 4, id1));
+    Subnet6Ptr sub2(new Subnet6(IOAddress("fec0::"), 12, 1, 2, 3, 4, id2));
+    network->add(sub1);
+    network->add(sub2);
+    cfg.add(network);
+
+    // Make sure the subnets are part of the network.
+    SharedNetwork6Ptr test;
+    sub1->getSharedNetwork(test);
+    EXPECT_TRUE(test);
+    EXPECT_EQ(network->toElement()->str(), test->toElement()->str());
+    sub2->getSharedNetwork(test);
+    EXPECT_TRUE(test);
+    EXPECT_EQ(network->toElement()->str(), test->toElement()->str());
+
+    // Now remove the network. Subnets should be disassociated with the network.
+    cfg.del("frog");
+    sub1->getSharedNetwork(test);
+    EXPECT_FALSE(test);
+    sub2->getSharedNetwork(test);
+    EXPECT_FALSE(test);
+}
+
 // This test verifies that shared networks must have unique names.
 TEST(CfgSharedNetworks6Test, duplicateName) {
     SharedNetwork6Ptr network1(new SharedNetwork6("frog"));

+ 42 - 0
src/lib/dhcpsrv/tests/shared_network_unittest.cc

@@ -284,6 +284,27 @@ TEST(SharedNetwork4Test, destructSharedNetwork) {
     ASSERT_FALSE(subnet_to_network);
 }
 
+// This test verifies that it is possible to remove all subnets.
+TEST(SharedNetwork4Test, delAll) {
+    // Create two subnets and add them to the shared network.
+    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)));
+
+    SharedNetwork4Ptr network(new SharedNetwork4("frog"));
+    ASSERT_NO_THROW(network->add(subnet1));
+    ASSERT_NO_THROW(network->add(subnet2));
+
+    // Make sure they have been added successfully.
+    ASSERT_EQ(2, network->getAllSubnets()->size());
+
+    ASSERT_NO_THROW(network->delAll());
+
+    // Now check that there are no subnets.
+    ASSERT_EQ(0, network->getAllSubnets()->size());
+}
+
 // This test verifies that shared network can be given a name and that
 // this name can be retrieved.
 TEST(SharedNetwork6Test, getName) {
@@ -541,5 +562,26 @@ TEST(SharedNetwork6Test, destructSharedNetwork) {
     ASSERT_FALSE(subnet_to_network);
 }
 
+// This test verifies that it is possible to remove all subnets.
+TEST(SharedNetwork6Test, delAll) {
+    // Create two subnets and add them to the shared network.
+    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)));
+
+    SharedNetwork6Ptr network(new SharedNetwork6("frog"));
+    ASSERT_NO_THROW(network->add(subnet1));
+    ASSERT_NO_THROW(network->add(subnet2));
+
+    // Make sure they have been added successfully.
+    ASSERT_EQ(2, network->getAllSubnets()->size());
+
+    ASSERT_NO_THROW(network->delAll());
+
+    // Now check that there are no subnets.
+    ASSERT_EQ(0, network->getAllSubnets()->size());
+}
+
 
 } // end of anonymous namespace