Support added for: any server, explicit server, all servers.
DELETE_ALL_SUBNETS4,
DELETE_ALL_SUBNETS4_SHARED_NETWORK_NAME,
DELETE_POOLS4_SUBNET_ID,
- DELETE_SHARED_NETWORK4_NAME,
+ DELETE_SHARED_NETWORK4_NAME_WITH_TAG,
+ DELETE_SHARED_NETWORK4_NAME_NO_TAG,
DELETE_ALL_SHARED_NETWORKS4,
DELETE_SHARED_NETWORK4_SERVER,
DELETE_OPTION_DEF4_CODE_NAME,
transaction.commit();
}
-
/// @brief Sends query to insert DHCP option.
///
/// This method expects that the server selector contains exactly one
MYSQL_DELETE_POOLS(dhcp4)
},
- // Delete shared network by name.
- { MySqlConfigBackendDHCPv4Impl::DELETE_SHARED_NETWORK4_NAME,
- MYSQL_DELETE_SHARED_NETWORK(dhcp4, AND n.name = ?)
+ // Delete shared network by name with specifying server tag.
+ { MySqlConfigBackendDHCPv4Impl::DELETE_SHARED_NETWORK4_NAME_WITH_TAG,
+ MYSQL_DELETE_SHARED_NETWORK_WITH_TAG(dhcp4, AND n.name = ?)
+ },
+
+ // Delete shared network by name without specifying server tag.
+ { MySqlConfigBackendDHCPv4Impl::DELETE_SHARED_NETWORK4_NAME_NO_TAG,
+ MYSQL_DELETE_SHARED_NETWORK_NO_TAG(dhcp4, AND n.name = ?)
},
// Delete all shared networks.
{ MySqlConfigBackendDHCPv4Impl::DELETE_ALL_SHARED_NETWORKS4,
- MYSQL_DELETE_SHARED_NETWORK(dhcp4)
+ MYSQL_DELETE_SHARED_NETWORK_WITH_TAG(dhcp4)
},
// Delete associations of a shared network with server.
const std::string& name) {
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_SHARED_NETWORK4)
.arg(name);
- uint64_t result = impl_->deleteTransactional(MySqlConfigBackendDHCPv4Impl::DELETE_SHARED_NETWORK4_NAME,
- server_selector, "deleting a shared network",
+ int index = (server_selector.amAny() ?
+ MySqlConfigBackendDHCPv4Impl::DELETE_SHARED_NETWORK4_NAME_NO_TAG :
+ MySqlConfigBackendDHCPv4Impl::DELETE_SHARED_NETWORK4_NAME_WITH_TAG);
+ uint64_t result = impl_->deleteTransactional(index, server_selector,
+ "deleting a shared network",
"shared network deleted", true, name);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_SHARED_NETWORK4_RESULT)
.arg(result);
DELETE_ALL_SUBNETS6_SHARED_NETWORK_NAME,
DELETE_POOLS6_SUBNET_ID,
DELETE_PD_POOLS_SUBNET_ID,
- DELETE_SHARED_NETWORK6_NAME,
+ DELETE_SHARED_NETWORK6_NAME_WITH_TAG,
+ DELETE_SHARED_NETWORK6_NAME_NO_TAG,
DELETE_ALL_SHARED_NETWORKS6,
DELETE_SHARED_NETWORK6_SERVER,
DELETE_OPTION_DEF6_CODE_NAME,
MYSQL_DELETE_PD_POOLS()
},
- // Delete shared network by name.
- { MySqlConfigBackendDHCPv6Impl::DELETE_SHARED_NETWORK6_NAME,
- MYSQL_DELETE_SHARED_NETWORK(dhcp6, AND n.name = ?)
+ // Delete shared network by name with specifying server tag.
+ { MySqlConfigBackendDHCPv6Impl::DELETE_SHARED_NETWORK6_NAME_WITH_TAG,
+ MYSQL_DELETE_SHARED_NETWORK_WITH_TAG(dhcp6, AND n.name = ?)
+ },
+
+ // Delete shared network by name without specifying server tag.
+ { MySqlConfigBackendDHCPv6Impl::DELETE_SHARED_NETWORK6_NAME_NO_TAG,
+ MYSQL_DELETE_SHARED_NETWORK_NO_TAG(dhcp6, AND n.name = ?)
},
// Delete all shared networks.
{ MySqlConfigBackendDHCPv6Impl::DELETE_ALL_SHARED_NETWORKS6,
- MYSQL_DELETE_SHARED_NETWORK(dhcp6)
+ MYSQL_DELETE_SHARED_NETWORK_WITH_TAG(dhcp6)
},
// Delete associations of a shared network with server.
const std::string& name) {
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_SHARED_NETWORK6)
.arg(name);
- uint64_t result = impl_->deleteTransactional(MySqlConfigBackendDHCPv6Impl::DELETE_SHARED_NETWORK6_NAME,
- server_selector, "deleting a shared network",
+ int index = (server_selector.amAny() ?
+ MySqlConfigBackendDHCPv6Impl::DELETE_SHARED_NETWORK6_NAME_NO_TAG :
+ MySqlConfigBackendDHCPv6Impl::DELETE_SHARED_NETWORK6_NAME_WITH_TAG);
+ uint64_t result = impl_->deleteTransactional(index, server_selector,
+ "deleting a shared network",
"shared network deleted", true, name);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_SHARED_NETWORK6_RESULT)
.arg(result);
"WHERE subnet_id = ?"
#endif
-#ifndef MYSQL_DELETE_SHARED_NETWORK
-#define MYSQL_DELETE_SHARED_NETWORK(table_prefix, ...) \
+#ifndef MYSQL_DELETE_SHARED_NETWORK_COMMON
+#define MYSQL_DELETE_SHARED_NETWORK_COMMON(table_prefix, ...) \
"DELETE n FROM " #table_prefix "_shared_network AS n " \
"INNER JOIN " #table_prefix "_shared_network_server AS a" \
" ON n.id = a.shared_network_id " \
"INNER JOIN " #table_prefix "_server AS s" \
" ON a.server_id = s.id " \
- "WHERE s.tag = ? " #__VA_ARGS__
+ #__VA_ARGS__
+
+#define MYSQL_DELETE_SHARED_NETWORK_WITH_TAG(table_prefix, ...) \
+ MYSQL_DELETE_SHARED_NETWORK_COMMON(table_prefix, WHERE s.tag = ? __VA_ARGS__)
+
+#define MYSQL_DELETE_SHARED_NETWORK_NO_TAG(table_prefix, ...) \
+ MYSQL_DELETE_SHARED_NETWORK_COMMON(table_prefix, __VA_ARGS__)
+
+
#endif
#ifndef MYSQL_DELETE_SHARED_NETWORK_SERVER
ASSERT_TRUE(networks.empty());
}
+// Test that selected shared network can be deleted.
+TEST_F(MySqlConfigBackendDHCPv4Test, deleteSharedNetwork4) {
+ // Create two servers in the database.
+ EXPECT_NO_THROW(cbptr_->createUpdateServer4(test_servers_[0]));
+ {
+ SCOPED_TRACE("CREATE audit entry for server");
+ testNewAuditEntry("dhcp4_server",
+ AuditEntry::ModificationType::CREATE,
+ "server set");
+ }
+
+ EXPECT_NO_THROW(cbptr_->createUpdateServer4(test_servers_[2]));
+ {
+ SCOPED_TRACE("CREATE audit entry for server");
+ testNewAuditEntry("dhcp4_server",
+ AuditEntry::ModificationType::CREATE,
+ "server set");
+ }
+
+ auto shared_network1 = test_networks_[0];
+ auto shared_network2 = test_networks_[2];
+ auto shared_network3 = test_networks_[3];
+
+ // Insert two shared networks, one for all servers, and one for server2.
+ EXPECT_NO_THROW(
+ cbptr_->createUpdateSharedNetwork4(ServerSelector::ALL(), shared_network1)
+ );
+ EXPECT_NO_THROW(
+ cbptr_->createUpdateSharedNetwork4(ServerSelector::ONE("server2"), shared_network2)
+ );
+ EXPECT_NO_THROW(
+ cbptr_->createUpdateSharedNetwork4(ServerSelector::MULTIPLE({ "server1", "server2" }),
+ shared_network3)
+ );
+
+ auto test_no_delete = [this] (const std::string& test_case_name,
+ const ServerSelector& server_selector,
+ const SharedNetwork4Ptr& shared_network) {
+ SCOPED_TRACE(test_case_name);
+ uint64_t deleted_count = 0;
+ EXPECT_NO_THROW(
+ deleted_count = cbptr_->deleteSharedNetwork4(server_selector,
+ shared_network->getName())
+ );
+ EXPECT_EQ(0, deleted_count);
+ };
+
+ {
+ SCOPED_TRACE("Test valid but non matching server selectors");
+ test_no_delete("selector: one, actual: all", ServerSelector::ONE("server2"),
+ shared_network1);
+ test_no_delete("selector: all, actual: one", ServerSelector::ALL(),
+ shared_network2);
+ test_no_delete("selector: all, actual: multiple", ServerSelector::ALL(),
+ shared_network3);
+ }
+
+ // We are not going to support deletion of a single entry for multiple servers.
+ EXPECT_THROW(cbptr_->deleteSharedNetwork4(ServerSelector::MULTIPLE({ "server1", "server2" }),
+ shared_network3->getName()),
+ isc::InvalidOperation);
+
+ // We currently don't support deleting a shared network with specifying
+ // an unassigned server tag. Use ANY to delete any subnet instead.
+ EXPECT_THROW(cbptr_->deleteSharedNetwork4(ServerSelector::UNASSIGNED(),
+ shared_network1->getName()),
+ isc::NotImplemented);
+
+ // Test successful deletion of a shared network.
+ auto test_delete = [this] (const std::string& test_case_name,
+ const ServerSelector& server_selector,
+ const SharedNetwork4Ptr& shared_network) {
+ SCOPED_TRACE(test_case_name);
+ uint64_t deleted_count = 0;
+ EXPECT_NO_THROW(
+ deleted_count = cbptr_->deleteSharedNetwork4(server_selector,
+ shared_network->getName())
+ );
+ EXPECT_EQ(1, deleted_count);
+
+ EXPECT_FALSE(cbptr_->getSharedNetwork4(server_selector,
+ shared_network->getName()));
+ };
+
+ test_delete("all servers", ServerSelector::ALL(), shared_network1);
+ test_delete("any server", ServerSelector::ANY(), shared_network2);
+ test_delete("one server", ServerSelector::ONE("server1"), shared_network3);
+
+}
+
// Test that lifetimes in shared networks are handled as expected.
TEST_F(MySqlConfigBackendDHCPv4Test, sharedNetworkLifetime) {
// Insert new shared network with unspecified valid lifetime
ASSERT_TRUE(networks.empty());
}
+// Test that selected shared network can be deleted.
+TEST_F(MySqlConfigBackendDHCPv6Test, deleteSharedNetwork6) {
+ // Create two servers in the database.
+ EXPECT_NO_THROW(cbptr_->createUpdateServer6(test_servers_[0]));
+ {
+ SCOPED_TRACE("CREATE audit entry for server");
+ testNewAuditEntry("dhcp6_server",
+ AuditEntry::ModificationType::CREATE,
+ "server set");
+ }
+
+ EXPECT_NO_THROW(cbptr_->createUpdateServer6(test_servers_[2]));
+ {
+ SCOPED_TRACE("CREATE audit entry for server");
+ testNewAuditEntry("dhcp6_server",
+ AuditEntry::ModificationType::CREATE,
+ "server set");
+ }
+
+ auto shared_network1 = test_networks_[0];
+ auto shared_network2 = test_networks_[2];
+ auto shared_network3 = test_networks_[3];
+
+ // Insert two shared networks, one for all servers, and one for server2.
+ EXPECT_NO_THROW(
+ cbptr_->createUpdateSharedNetwork6(ServerSelector::ALL(), shared_network1)
+ );
+ EXPECT_NO_THROW(
+ cbptr_->createUpdateSharedNetwork6(ServerSelector::ONE("server2"), shared_network2)
+ );
+ EXPECT_NO_THROW(
+ cbptr_->createUpdateSharedNetwork6(ServerSelector::MULTIPLE({ "server1", "server2" }),
+ shared_network3)
+ );
+
+ auto test_no_delete = [this] (const std::string& test_case_name,
+ const ServerSelector& server_selector,
+ const SharedNetwork6Ptr& shared_network) {
+ SCOPED_TRACE(test_case_name);
+ uint64_t deleted_count = 0;
+ EXPECT_NO_THROW(
+ deleted_count = cbptr_->deleteSharedNetwork6(server_selector,
+ shared_network->getName())
+ );
+ EXPECT_EQ(0, deleted_count);
+ };
+
+ {
+ SCOPED_TRACE("Test valid but non matching server selectors");
+ test_no_delete("selector: one, actual: all", ServerSelector::ONE("server2"),
+ shared_network1);
+ test_no_delete("selector: all, actual: one", ServerSelector::ALL(),
+ shared_network2);
+ test_no_delete("selector: all, actual: multiple", ServerSelector::ALL(),
+ shared_network3);
+ }
+
+ // We are not going to support deletion of a single entry for multiple servers.
+ EXPECT_THROW(cbptr_->deleteSharedNetwork6(ServerSelector::MULTIPLE({ "server1", "server2" }),
+ shared_network3->getName()),
+ isc::InvalidOperation);
+
+ // We currently don't support deleting a shared network with specifying
+ // an unassigned server tag. Use ANY to delete any subnet instead.
+ EXPECT_THROW(cbptr_->deleteSharedNetwork6(ServerSelector::UNASSIGNED(),
+ shared_network1->getName()),
+ isc::NotImplemented);
+
+ // Test successful deletion of a shared network.
+ auto test_delete = [this] (const std::string& test_case_name,
+ const ServerSelector& server_selector,
+ const SharedNetwork6Ptr& shared_network) {
+ SCOPED_TRACE(test_case_name);
+ uint64_t deleted_count = 0;
+ EXPECT_NO_THROW(
+ deleted_count = cbptr_->deleteSharedNetwork6(server_selector,
+ shared_network->getName())
+ );
+ EXPECT_EQ(1, deleted_count);
+
+ EXPECT_FALSE(cbptr_->getSharedNetwork6(server_selector,
+ shared_network->getName()));
+ };
+
+ test_delete("all servers", ServerSelector::ALL(), shared_network1);
+ test_delete("any server", ServerSelector::ANY(), shared_network2);
+ test_delete("one server", ServerSelector::ONE("server1"), shared_network3);
+}
+
// Test that lifetimes in shared networks are handled as expected.
TEST_F(MySqlConfigBackendDHCPv6Test, sharedNetworkLifetime) {
// Insert new shared network with unspecified valid lifetime