Commit ce12414d authored by Marcin Siodelski's avatar Marcin Siodelski

[#717,!417] Added support for deleting unassigned subnets.

parent 7e5e5a0b
......@@ -120,6 +120,7 @@ public:
DELETE_SUBNET4_PREFIX_WITH_TAG,
DELETE_SUBNET4_PREFIX_ANY,
DELETE_ALL_SUBNETS4,
DELETE_ALL_SUBNETS4_UNASSIGNED,
DELETE_ALL_SUBNETS4_SHARED_NETWORK_NAME,
DELETE_SUBNET4_SERVER,
DELETE_POOLS4_SUBNET_ID,
......@@ -2465,6 +2466,11 @@ TaggedStatementArray tagged_statements = { {
MYSQL_DELETE_SUBNET_WITH_TAG(dhcp4)
},
// Delete all unassigned subnets.
{ MySqlConfigBackendDHCPv4Impl::DELETE_ALL_SUBNETS4_UNASSIGNED,
MYSQL_DELETE_SUBNET_UNASSIGNED(dhcp4)
},
// Delete all subnets for a shared network.
{ MySqlConfigBackendDHCPv4Impl::DELETE_ALL_SUBNETS4_SHARED_NETWORK_NAME,
MYSQL_DELETE_SUBNET_WITH_TAG(dhcp4, AND s.shared_network_name = ?)
......@@ -2910,8 +2916,11 @@ MySqlConfigBackendDHCPv4::deleteSubnet4(const ServerSelector& server_selector,
uint64_t
MySqlConfigBackendDHCPv4::deleteAllSubnets4(const ServerSelector& server_selector) {
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_ALL_SUBNETS4);
uint64_t result = impl_->deleteTransactional(MySqlConfigBackendDHCPv4Impl::DELETE_ALL_SUBNETS4,
server_selector, "deleting all subnets",
int index = (server_selector.amUnassigned() ?
MySqlConfigBackendDHCPv4Impl::DELETE_ALL_SUBNETS4_UNASSIGNED :
MySqlConfigBackendDHCPv4Impl::DELETE_ALL_SUBNETS4);
uint64_t result = impl_->deleteTransactional(index, server_selector, "deleting all subnets",
"deleted all subnets", true);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_ALL_SUBNETS4_RESULT)
.arg(result);
......
......@@ -125,6 +125,7 @@ public:
DELETE_SUBNET6_PREFIX_WITH_TAG,
DELETE_SUBNET6_PREFIX_ANY,
DELETE_ALL_SUBNETS6,
DELETE_ALL_SUBNETS6_UNASSIGNED,
DELETE_ALL_SUBNETS6_SHARED_NETWORK_NAME,
DELETE_SUBNET6_SERVER,
DELETE_POOLS6_SUBNET_ID,
......@@ -2823,6 +2824,11 @@ TaggedStatementArray tagged_statements = { {
MYSQL_DELETE_SUBNET_WITH_TAG(dhcp6)
},
// Delete all unassigned subnets.
{ MySqlConfigBackendDHCPv6Impl::DELETE_ALL_SUBNETS6_UNASSIGNED,
MYSQL_DELETE_SUBNET_UNASSIGNED(dhcp6)
},
// Delete all subnets for a shared network.
{ MySqlConfigBackendDHCPv6Impl::DELETE_ALL_SUBNETS6_SHARED_NETWORK_NAME,
MYSQL_DELETE_SUBNET_WITH_TAG(dhcp6, AND s.shared_network_name = ?)
......@@ -3289,8 +3295,11 @@ MySqlConfigBackendDHCPv6::deleteSubnet6(const ServerSelector& server_selector,
uint64_t
MySqlConfigBackendDHCPv6::deleteAllSubnets6(const ServerSelector& server_selector) {
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_ALL_SUBNETS6);
uint64_t result = impl_->deleteTransactional(MySqlConfigBackendDHCPv6Impl::DELETE_ALL_SUBNETS6,
server_selector, "deleting all subnets",
int index = (server_selector.amUnassigned() ?
MySqlConfigBackendDHCPv6Impl::DELETE_ALL_SUBNETS6_UNASSIGNED :
MySqlConfigBackendDHCPv6Impl::DELETE_ALL_SUBNETS6);
uint64_t result = impl_->deleteTransactional(index, server_selector, "deleting all subnets",
"deleted all subnets", true);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_ALL_SUBNETS6_RESULT)
.arg(result);
......
......@@ -726,6 +726,12 @@ namespace {
"DELETE s FROM " #table_prefix "_subnet AS s " \
#__VA_ARGS__
#define MYSQL_DELETE_SUBNET_UNASSIGNED(table_prefix, ...) \
"DELETE s FROM " #table_prefix "_subnet AS s " \
"LEFT JOIN " #table_prefix "_subnet_server AS a" \
" ON s.subnet_id = a.subnet_id " \
"WHERE a.subnet_id IS NULL " #__VA_ARGS__
#endif
#ifndef MYSQL_DELETE_SUBNET_SERVER
......
......@@ -1536,6 +1536,104 @@ TEST_F(MySqlConfigBackendDHCPv4Test, deleteSubnet4) {
test_delete_by_prefix("one server", ServerSelector::ONE("server1"), subnet3);
}
// Test that it is possible to retrieve and delete orphaned subnet.
TEST_F(MySqlConfigBackendDHCPv4Test, unassignedSubnet4) {
// Create the server.
EXPECT_NO_THROW(cbptr_->createUpdateServer4(test_servers_[0]));
// Create the shared networks and associate them with the server1.
auto subnet = test_subnets_[0];
auto subnet2 = test_subnets_[2];
EXPECT_NO_THROW(
cbptr_->createUpdateSubnet4(ServerSelector::ONE("server1"), subnet)
);
EXPECT_NO_THROW(
cbptr_->createUpdateSubnet4(ServerSelector::ONE("server1"), subnet2)
);
// Delete the server. The subnets should be preserved but are considered orphaned,
// i.e. do not belong to any server.
uint64_t deleted_count = 0;
EXPECT_NO_THROW(deleted_count = cbptr_->deleteServer4(ServerTag("server1")));
EXPECT_EQ(1, deleted_count);
// Trying to fetch the subnet by server tag should return no result.
Subnet4Ptr returned_subnet;
EXPECT_NO_THROW(returned_subnet = cbptr_->getSubnet4(ServerSelector::ONE("server1"),
subnet->getID()));
EXPECT_FALSE(returned_subnet);
// The same if we use other calls.
EXPECT_NO_THROW(returned_subnet = cbptr_->getSubnet4(ServerSelector::ONE("server1"),
subnet->toText()));
EXPECT_FALSE(returned_subnet);
Subnet4Collection returned_subnets;
EXPECT_NO_THROW(returned_subnets = cbptr_->getAllSubnets4(ServerSelector::ONE("server1")));
EXPECT_TRUE(returned_subnets.empty());
EXPECT_NO_THROW(
returned_subnets = cbptr_->getModifiedSubnets4(ServerSelector::ONE("server1"),
timestamps_["two days ago"])
);
EXPECT_TRUE(returned_subnets.empty());
// We should get the subnet if we ask for unassigned.
EXPECT_NO_THROW(returned_subnet = cbptr_->getSubnet4(ServerSelector::UNASSIGNED(),
subnet->getID()));
ASSERT_TRUE(returned_subnet);
EXPECT_NO_THROW(returned_subnet = cbptr_->getSubnet4(ServerSelector::UNASSIGNED(),
subnet->toText()));
ASSERT_TRUE(returned_subnet);
// Also if we ask for all unassigned subnets it should be returned.
EXPECT_NO_THROW(returned_subnets = cbptr_->getAllSubnets4(ServerSelector::UNASSIGNED()));
ASSERT_EQ(2, returned_subnets.size());
// Same for modified subnets.
EXPECT_NO_THROW(
returned_subnets = cbptr_->getModifiedSubnets4(ServerSelector::UNASSIGNED(),
timestamps_["two days ago"])
);
ASSERT_EQ(2, returned_subnets.size());
// If we ask for any subnet by subnet id, it should be returned too.
EXPECT_NO_THROW(returned_subnet = cbptr_->getSubnet4(ServerSelector::ANY(),
subnet->getID()));
ASSERT_TRUE(returned_subnet);
EXPECT_NO_THROW(returned_subnet = cbptr_->getSubnet4(ServerSelector::ANY(),
subnet->toText()));
ASSERT_TRUE(returned_subnet);
// Deleting the subnet with the mismatched server tag should not affect our
// subnet.
EXPECT_NO_THROW(
deleted_count = cbptr_->deleteSubnet4(ServerSelector::ONE("server1"),
subnet->getID())
);
EXPECT_EQ(0, deleted_count);
// Also, if we delete all subnets for server1.
EXPECT_NO_THROW(
deleted_count = cbptr_->deleteAllSubnets4(ServerSelector::ONE("server1"))
);
EXPECT_EQ(0, deleted_count);
// We can delete this subnet when we specify ANY and the matching id.
EXPECT_NO_THROW(
deleted_count = cbptr_->deleteSubnet4(ServerSelector::ANY(), subnet->getID())
);
EXPECT_EQ(1, deleted_count);
// We can delete all subnets using UNASSIGNED selector.
EXPECT_NO_THROW(
deleted_count = cbptr_->deleteAllSubnets4(ServerSelector::UNASSIGNED());
);
EXPECT_EQ(1, deleted_count);
}
// Test that subnets modified after given time can be fetched.
TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedSubnets4) {
// Explicitly set timestamps of subnets. First subnet has a timestamp
......@@ -2383,7 +2481,7 @@ TEST_F(MySqlConfigBackendDHCPv4Test, unassignedSharedNetwork) {
);
EXPECT_EQ(1, deleted_count);
// We can delete all second networks using UNASSIGNED selector.
// We can delete all networks using UNASSIGNED selector.
EXPECT_NO_THROW(
deleted_count = cbptr_->deleteAllSharedNetworks4(ServerSelector::UNASSIGNED());
);
......
......@@ -1554,6 +1554,104 @@ TEST_F(MySqlConfigBackendDHCPv6Test, deleteSubnet6) {
test_delete_by_prefix("one server", ServerSelector::ONE("server1"), subnet3);
}
// Test that it is possible to retrieve and delete orphaned subnet.
TEST_F(MySqlConfigBackendDHCPv6Test, unassignedSubnet6) {
// Create the server.
EXPECT_NO_THROW(cbptr_->createUpdateServer6(test_servers_[0]));
// Create the shared networks and associate them with the server1.
auto subnet = test_subnets_[0];
auto subnet2 = test_subnets_[2];
EXPECT_NO_THROW(
cbptr_->createUpdateSubnet6(ServerSelector::ONE("server1"), subnet)
);
EXPECT_NO_THROW(
cbptr_->createUpdateSubnet6(ServerSelector::ONE("server1"), subnet2)
);
// Delete the server. The subnets should be preserved but are considered orphaned,
// i.e. do not belong to any server.
uint64_t deleted_count = 0;
EXPECT_NO_THROW(deleted_count = cbptr_->deleteServer6(ServerTag("server1")));
EXPECT_EQ(1, deleted_count);
// Trying to fetch the subnet by server tag should return no result.
Subnet6Ptr returned_subnet;
EXPECT_NO_THROW(returned_subnet = cbptr_->getSubnet6(ServerSelector::ONE("server1"),
subnet->getID()));
EXPECT_FALSE(returned_subnet);
// The same if we use other calls.
EXPECT_NO_THROW(returned_subnet = cbptr_->getSubnet6(ServerSelector::ONE("server1"),
subnet->toText()));
EXPECT_FALSE(returned_subnet);
Subnet6Collection returned_subnets;
EXPECT_NO_THROW(returned_subnets = cbptr_->getAllSubnets6(ServerSelector::ONE("server1")));
EXPECT_TRUE(returned_subnets.empty());
EXPECT_NO_THROW(
returned_subnets = cbptr_->getModifiedSubnets6(ServerSelector::ONE("server1"),
timestamps_["two days ago"])
);
EXPECT_TRUE(returned_subnets.empty());
// We should get the subnet if we ask for unassigned.
EXPECT_NO_THROW(returned_subnet = cbptr_->getSubnet6(ServerSelector::UNASSIGNED(),
subnet->getID()));
ASSERT_TRUE(returned_subnet);
EXPECT_NO_THROW(returned_subnet = cbptr_->getSubnet6(ServerSelector::UNASSIGNED(),
subnet->toText()));
ASSERT_TRUE(returned_subnet);
// Also if we ask for all unassigned subnets it should be returned.
EXPECT_NO_THROW(returned_subnets = cbptr_->getAllSubnets6(ServerSelector::UNASSIGNED()));
ASSERT_EQ(2, returned_subnets.size());
// Same for modified subnets.
EXPECT_NO_THROW(
returned_subnets = cbptr_->getModifiedSubnets6(ServerSelector::UNASSIGNED(),
timestamps_["two days ago"])
);
ASSERT_EQ(2, returned_subnets.size());
// If we ask for any subnet by subnet id, it should be returned too.
EXPECT_NO_THROW(returned_subnet = cbptr_->getSubnet6(ServerSelector::ANY(),
subnet->getID()));
ASSERT_TRUE(returned_subnet);
EXPECT_NO_THROW(returned_subnet = cbptr_->getSubnet6(ServerSelector::ANY(),
subnet->toText()));
ASSERT_TRUE(returned_subnet);
// Deleting the subnet with the mismatched server tag should not affect our
// subnet.
EXPECT_NO_THROW(
deleted_count = cbptr_->deleteSubnet6(ServerSelector::ONE("server1"),
subnet->getID())
);
EXPECT_EQ(0, deleted_count);
// Also, if we delete all subnets for server1.
EXPECT_NO_THROW(
deleted_count = cbptr_->deleteAllSubnets6(ServerSelector::ONE("server1"))
);
EXPECT_EQ(0, deleted_count);
// We can delete this subnet when we specify ANY and the matching id.
EXPECT_NO_THROW(
deleted_count = cbptr_->deleteSubnet6(ServerSelector::ANY(), subnet->getID())
);
EXPECT_EQ(1, deleted_count);
// We can delete all subnets using UNASSIGNED selector.
EXPECT_NO_THROW(
deleted_count = cbptr_->deleteAllSubnets6(ServerSelector::UNASSIGNED());
);
EXPECT_EQ(1, deleted_count);
}
// Test that subnets modified after given time can be fetched.
TEST_F(MySqlConfigBackendDHCPv6Test, getModifiedSubnets6) {
// Explicitly set timestamps of subnets. First subnet has a timestamp
......
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