From: Marcin Siodelski Date: Sun, 7 Jul 2019 19:09:53 +0000 (+0200) Subject: [#716,!412] It is now possible to delete shared network by tags. X-Git-Tag: Kea-1.6.0-beta2~89 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9447f7b62f37902e3f356c80486757d24db6e264;p=thirdparty%2Fkea.git [#716,!412] It is now possible to delete shared network by tags. Support added for: any server, explicit server, all servers. --- diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc index 9c8ce4e9bb..1d532f6d80 100644 --- a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc @@ -111,7 +111,8 @@ public: 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, @@ -1391,7 +1392,6 @@ public: transaction.commit(); } - /// @brief Sends query to insert DHCP option. /// /// This method expects that the server selector contains exactly one @@ -2351,14 +2351,19 @@ TaggedStatementArray tagged_statements = { { 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. @@ -2806,8 +2811,11 @@ MySqlConfigBackendDHCPv4::deleteSharedNetwork4(const ServerSelector& server_sele 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); diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp6.cc b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp6.cc index 00f82bc16f..de1503ce1d 100644 --- a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp6.cc +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp6.cc @@ -117,7 +117,8 @@ public: 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, @@ -2711,14 +2712,19 @@ TaggedStatementArray tagged_statements = { { 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. @@ -3177,8 +3183,11 @@ MySqlConfigBackendDHCPv6::deleteSharedNetwork6(const ServerSelector& server_sele 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); diff --git a/src/hooks/dhcp/mysql_cb/mysql_query_macros_dhcp.h b/src/hooks/dhcp/mysql_cb/mysql_query_macros_dhcp.h index 855022cb4e..9f5dc3fe83 100644 --- a/src/hooks/dhcp/mysql_cb/mysql_query_macros_dhcp.h +++ b/src/hooks/dhcp/mysql_cb/mysql_query_macros_dhcp.h @@ -659,14 +659,22 @@ namespace { "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 diff --git a/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc b/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc index 971e15d984..d8db0ebd8f 100644 --- a/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc +++ b/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc @@ -1801,6 +1801,96 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedSharedNetworks4) { 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 diff --git a/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp6_unittest.cc b/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp6_unittest.cc index e54164a560..ed91ce5b11 100644 --- a/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp6_unittest.cc +++ b/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp6_unittest.cc @@ -1816,6 +1816,95 @@ TEST_F(MySqlConfigBackendDHCPv6Test, getModifiedSharedNetworks6) { 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