]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#103,!289] Enable deletion of shared networks by database id.
authorMarcin Siodelski <marcin@isc.org>
Thu, 4 Apr 2019 08:54:13 +0000 (10:54 +0200)
committerMarcin Siodelski <marcin@isc.org>
Wed, 10 Apr 2019 14:57:43 +0000 (16:57 +0200)
src/lib/dhcpsrv/cfg_shared_networks.h
src/lib/dhcpsrv/tests/cfg_shared_networks4_unittest.cc
src/lib/dhcpsrv/tests/cfg_shared_networks6_unittest.cc

index bd7516413fba6570e75585d70d07946160954816..21e4db2dd1f606a538ad74464900172f811afe25 100644 (file)
@@ -13,6 +13,7 @@
 #include <exceptions/exceptions.h>
 #include <dhcpsrv/shared_network.h>
 #include <boost/shared_ptr.hpp>
+#include <iterator>
 #include <string>
 
 namespace isc {
@@ -69,6 +70,42 @@ public:
         }
     }
 
+    /// @brief Deletes shared networks from the configuration by id.
+    ///
+    /// Note that there are cases when there will be multiple shared
+    /// networks having the same id (typically id of 0). When configuration
+    /// backend is in use it sets the unique ids from the database.
+    /// In cases when the configuration backend is not used, the ids
+    /// default to 0.
+    ///
+    /// @param id Identifier of the shared networks to be deleted.
+    ///
+    /// @return Number of deleted shared networks.
+    /// @throw isc::BadValue if the networks do not exist.
+    uint64_t del(const uint64_t id) {
+        auto& index = networks_.template get<SharedNetworkIdIndexTag>();
+        auto sn_range = index.equal_range(id);
+        uint64_t num = std::distance(sn_range.first, sn_range.second);
+
+        // No such shared networm found. Return an error.
+        if (num == 0) {
+            isc_throw(BadValue, "unable to delete non-existing networks "
+                      "with id of '" << id << "' from shared networks "
+                      "configuration");
+        }
+
+        // For each shared network found, dereference the subnets belonging
+        // to it.
+        for (auto it = sn_range.first; it != sn_range.second; ++it) {
+            (*it)->delAll();
+        }
+
+        // Remove the shared networks.
+        index.erase(sn_range.first, sn_range.second);
+
+        return (num);
+    }
+
     /// @brief Retrieves shared network by name.
     ///
     /// @param name Name of the network to be retrieved.
index 76991a709cb6541a45eaf50503f2463fcd1cccc9..ca6ce63ba2824c2d68df6c051932b8141e02d28a 100644 (file)
@@ -110,6 +110,67 @@ TEST(CfgSharedNetworks4Test, deleteNetworkWithSubnets) {
     EXPECT_FALSE(test);
 }
 
+// This test verifies that it is possible to delete a shared network by
+// its database identifier.
+TEST(CfgSharedNetworks4Test, deleteNetworksById) {
+    // Create three shared networks.
+    CfgSharedNetworks4 cfg;
+    SharedNetwork4Ptr network1(new SharedNetwork4("frog"));
+    SharedNetwork4Ptr network2(new SharedNetwork4("whale"));
+    SharedNetwork4Ptr network3(new SharedNetwork4("fly"));
+
+    // Add one subnet to each shared network.
+    Subnet4Ptr subnet1(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3, 1));
+    Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.3.0"), 24, 1, 2, 3, 2));
+    Subnet4Ptr subnet3(new Subnet4(IOAddress("192.0.4.0"), 24, 1, 2, 3, 3));
+
+    network1->add(subnet1);
+    network2->add(subnet2);
+    network3->add(subnet3);
+
+    // Set unique identifier for the second shared network.
+    network2->setId(123);
+
+    // Verify that we have two networks with a default identifier and one
+    // with a unique identifier.
+    EXPECT_EQ(0, network1->getId());
+    EXPECT_EQ(123, network2->getId());
+    EXPECT_EQ(0, network3->getId());
+
+    // Add our networks to the configuration.
+    cfg.add(network1);
+    cfg.add(network2);
+    cfg.add(network3);
+
+    // Delete second network by id.
+    uint64_t deleted_num = 0;
+    ASSERT_NO_THROW(deleted_num = cfg.del(network2->getId()));
+    EXPECT_EQ(1, deleted_num);
+
+    // Make sure that the subnet no longer points to the deleted network.
+    SharedNetwork4Ptr returned_network;
+    subnet2->getSharedNetwork(returned_network);
+    EXPECT_FALSE(returned_network);
+    EXPECT_FALSE(cfg.getByName("whale"));
+
+    // Delete the remaining two shared network using id of 0.
+    ASSERT_NO_THROW(deleted_num = cfg.del(network1->getId()));
+    EXPECT_EQ(2, deleted_num);
+
+    // The subnets should no longer point to the deleted networks and
+    // the shared networks should no longer exist in the configuration.
+    subnet1->getSharedNetwork(returned_network);
+    EXPECT_FALSE(returned_network);
+    EXPECT_FALSE(cfg.getByName("frog"));
+
+    subnet3->getSharedNetwork(returned_network);
+    EXPECT_FALSE(returned_network);
+    EXPECT_FALSE(cfg.getByName("fly"));
+
+    // A second attempt to delete should result in an error.
+    EXPECT_THROW(cfg.del(network1->getId()), BadValue);
+}
+
 // This test verifies that shared networks must have unique names.
 TEST(CfgSharedNetworks4Test, duplicateName) {
     SharedNetwork4Ptr network1(new SharedNetwork4("frog"));
index ba2895864fa2b6cc63c982bf1e86a74e37f5e75d..ee631ea231db754f91660f556c70e0c2acb885fa 100644 (file)
@@ -95,6 +95,68 @@ TEST(CfgSharedNetworks6Test, deleteNetworkWithSubnets) {
     EXPECT_FALSE(test);
 }
 
+
+// This test verifies that it is possible to delete a shared network by
+// its database identifier.
+TEST(CfgSharedNetworks6Test, deleteNetworksById) {
+    // Create three shared networks.
+    CfgSharedNetworks6 cfg;
+    SharedNetwork6Ptr network1(new SharedNetwork6("frog"));
+    SharedNetwork6Ptr network2(new SharedNetwork6("whale"));
+    SharedNetwork6Ptr network3(new SharedNetwork6("fly"));
+
+    // Add one subnet to each shared network.
+    Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 64, 1, 2, 3, 4, 1));
+    Subnet6Ptr subnet2(new Subnet6(IOAddress("2001:db8:2::"), 64, 1, 2, 3, 4, 2));
+    Subnet6Ptr subnet3(new Subnet6(IOAddress("2001:db8:3::"), 64, 1, 2, 3, 4, 3));
+
+    network1->add(subnet1);
+    network2->add(subnet2);
+    network3->add(subnet3);
+
+    // Set unique identifier for the second shared network.
+    network2->setId(123);
+
+    // Verify that we have two networks with a default identifier and one
+    // with a unique identifier.
+    EXPECT_EQ(0, network1->getId());
+    EXPECT_EQ(123, network2->getId());
+    EXPECT_EQ(0, network3->getId());
+
+    // Add our networks to the configuration.
+    cfg.add(network1);
+    cfg.add(network2);
+    cfg.add(network3);
+
+    // Delete second network by id.
+    uint64_t deleted_num = 0;
+    ASSERT_NO_THROW(deleted_num = cfg.del(network2->getId()));
+    EXPECT_EQ(1, deleted_num);
+
+    // Make sure that the subnet no longer points to the deleted network.
+    SharedNetwork6Ptr returned_network;
+    subnet2->getSharedNetwork(returned_network);
+    EXPECT_FALSE(returned_network);
+    EXPECT_FALSE(cfg.getByName("whale"));
+
+    // Delete the remaining two shared network using id of 0.
+    ASSERT_NO_THROW(deleted_num = cfg.del(network1->getId()));
+    EXPECT_EQ(2, deleted_num);
+
+    // The subnets should no longer point to the deleted networks and
+    // the shared networks should no longer exist in the configuration.
+    subnet1->getSharedNetwork(returned_network);
+    EXPECT_FALSE(returned_network);
+    EXPECT_FALSE(cfg.getByName("frog"));
+
+    subnet3->getSharedNetwork(returned_network);
+    EXPECT_FALSE(returned_network);
+    EXPECT_FALSE(cfg.getByName("fly"));
+
+    // A second attempt to delete should result in an error.
+    EXPECT_THROW(cfg.del(network1->getId()), BadValue);
+}
+
 // This test verifies that shared networks must have unique names.
 TEST(CfgSharedNetworks6Test, duplicateName) {
     SharedNetwork6Ptr network1(new SharedNetwork6("frog"));