From: Marcin Siodelski Date: Mon, 8 Jul 2019 16:23:14 +0000 (+0200) Subject: [#716,!412] Added support for unassigned networks addition/deletion. X-Git-Tag: Kea-1.6.0-beta2~87 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8acc4361478ec00c83ed7ed130660f9345684700;p=thirdparty%2Fkea.git [#716,!412] Added support for unassigned networks addition/deletion. --- diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc index 1d2d932e7b..48f015fd1e 100644 --- a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc @@ -67,8 +67,12 @@ public: GET_SHARED_NETWORK_SUBNETS4, GET_POOL4_RANGE, GET_SHARED_NETWORK4_NAME_NO_TAG, + GET_SHARED_NETWORK4_NAME_ANY, + GET_SHARED_NETWORK4_NAME_UNASSIGNED, GET_ALL_SHARED_NETWORKS4, + GET_ALL_SHARED_NETWORKS4_UNASSIGNED, GET_MODIFIED_SHARED_NETWORKS4, + GET_MODIFIED_SHARED_NETWORKS4_UNASSIGNED, GET_OPTION_DEF4_CODE_SPACE, GET_ALL_OPTION_DEFS4, GET_MODIFIED_OPTION_DEFS4, @@ -111,7 +115,7 @@ public: DELETE_ALL_SUBNETS4_SHARED_NETWORK_NAME, DELETE_POOLS4_SUBNET_ID, DELETE_SHARED_NETWORK4_NAME_WITH_TAG, - DELETE_SHARED_NETWORK4_NAME_NO_TAG, + DELETE_SHARED_NETWORK4_NAME_ANY, DELETE_ALL_SHARED_NETWORKS4, DELETE_SHARED_NETWORK4_SERVER, DELETE_OPTION_DEF4_CODE_NAME, @@ -1238,22 +1242,25 @@ public: SharedNetwork4Ptr getSharedNetwork4(const ServerSelector& server_selector, const std::string& name) { - if (server_selector.amUnassigned()) { - isc_throw(NotImplemented, "managing configuration for no particular server" - " (unassigned) is unsupported at the moment"); - - } else if (server_selector.hasMultipleTags()) { + if (server_selector.hasMultipleTags()) { isc_throw(InvalidOperation, "expected one server tag to be specified" " while fetching a shared network. Got: " << getServerTagsAsText(server_selector)); } MySqlBindingCollection in_bindings = { MySqlBinding::createString(name) }; + auto index = GET_SHARED_NETWORK4_NAME_NO_TAG; + if (server_selector.amUnassigned()) { + index = GET_SHARED_NETWORK4_NAME_UNASSIGNED; + + } else if (server_selector.amAny()) { + index = GET_SHARED_NETWORK4_NAME_ANY; + } + SharedNetwork4Collection shared_networks; - getSharedNetworks4(GET_SHARED_NETWORK4_NAME_NO_TAG, server_selector, in_bindings, - shared_networks); + getSharedNetworks4(index, server_selector, in_bindings, shared_networks); return (shared_networks.empty() ? SharedNetwork4Ptr() : *shared_networks.begin()); } @@ -1265,9 +1272,10 @@ public: /// structure where shared networks should be inserted. void getAllSharedNetworks4(const ServerSelector& server_selector, SharedNetwork4Collection& shared_networks) { + auto index = (server_selector.amUnassigned() ? GET_ALL_SHARED_NETWORKS4_UNASSIGNED : + GET_ALL_SHARED_NETWORKS4); MySqlBindingCollection in_bindings; - getSharedNetworks4(GET_ALL_SHARED_NETWORKS4, server_selector, in_bindings, - shared_networks); + getSharedNetworks4(index, server_selector, in_bindings, shared_networks); } /// @brief Sends query to retrieve modified shared networks. @@ -1283,8 +1291,9 @@ public: MySqlBinding::createTimestamp(modification_ts) }; - getSharedNetworks4(GET_MODIFIED_SHARED_NETWORKS4, server_selector, in_bindings, - shared_networks); + auto index = (server_selector.amUnassigned() ? GET_MODIFIED_SHARED_NETWORKS4_UNASSIGNED : + GET_MODIFIED_SHARED_NETWORKS4); + getSharedNetworks4(index, server_selector, in_bindings, shared_networks); } /// @brief Sends query to insert or update shared network. @@ -2024,21 +2033,41 @@ TaggedStatementArray tagged_statements = { { "ORDER BY p.id, x.option_id" }, - // Select shared network by name without filtering by server tag. + // Select shared network by name. { MySqlConfigBackendDHCPv4Impl::GET_SHARED_NETWORK4_NAME_NO_TAG, MYSQL_GET_SHARED_NETWORK4_NO_TAG(WHERE n.name = ?) }, + // Select shared network by name without specifying server tags. + { MySqlConfigBackendDHCPv4Impl::GET_SHARED_NETWORK4_NAME_ANY, + MYSQL_GET_SHARED_NETWORK4_ANY(WHERE n.name = ?) + }, + + // Select unassigned shared network by name. + { MySqlConfigBackendDHCPv4Impl::GET_SHARED_NETWORK4_NAME_UNASSIGNED, + MYSQL_GET_SHARED_NETWORK4_UNASSIGNED(AND n.name = ?) + }, + // Select all shared networks. { MySqlConfigBackendDHCPv4Impl::GET_ALL_SHARED_NETWORKS4, MYSQL_GET_SHARED_NETWORK4_NO_TAG() }, + // Select all unassigned shared networks. + { MySqlConfigBackendDHCPv4Impl::GET_ALL_SHARED_NETWORKS4_UNASSIGNED, + MYSQL_GET_SHARED_NETWORK4_UNASSIGNED() + }, + // Select modified shared networks. { MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_SHARED_NETWORKS4, MYSQL_GET_SHARED_NETWORK4_NO_TAG(WHERE n.modification_ts > ?) }, + // Select modified and unassigned shared networks. + { MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_SHARED_NETWORKS4_UNASSIGNED, + MYSQL_GET_SHARED_NETWORK4_UNASSIGNED(AND n.modification_ts > ?) + }, + // Retrieves option definition by code and space. { MySqlConfigBackendDHCPv4Impl::GET_OPTION_DEF4_CODE_SPACE, MYSQL_GET_OPTION_DEF(dhcp4, AND d.code = ? AND d.space = ?) @@ -2346,8 +2375,8 @@ TaggedStatementArray tagged_statements = { { }, // 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 = ?) + { MySqlConfigBackendDHCPv4Impl::DELETE_SHARED_NETWORK4_NAME_ANY, + MYSQL_DELETE_SHARED_NETWORK_ANY(dhcp4, WHERE n.name = ?) }, // Delete all shared networks. @@ -2800,8 +2829,9 @@ 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); + int index = (server_selector.amAny() ? - MySqlConfigBackendDHCPv4Impl::DELETE_SHARED_NETWORK4_NAME_NO_TAG : + MySqlConfigBackendDHCPv4Impl::DELETE_SHARED_NETWORK4_NAME_ANY : MySqlConfigBackendDHCPv4Impl::DELETE_SHARED_NETWORK4_NAME_WITH_TAG); uint64_t result = impl_->deleteTransactional(index, server_selector, "deleting a shared network", diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp6.cc b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp6.cc index f7412ad252..d89c346589 100644 --- a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp6.cc +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp6.cc @@ -69,8 +69,12 @@ public: GET_POOL6_RANGE, GET_PD_POOL, GET_SHARED_NETWORK6_NAME_NO_TAG, + GET_SHARED_NETWORK6_NAME_ANY, + GET_SHARED_NETWORK6_NAME_UNASSIGNED, GET_ALL_SHARED_NETWORKS6, + GET_ALL_SHARED_NETWORKS6_UNASSIGNED, GET_MODIFIED_SHARED_NETWORKS6, + GET_MODIFIED_SHARED_NETWORKS6_UNASSIGNED, GET_OPTION_DEF6_CODE_SPACE, GET_ALL_OPTION_DEFS6, GET_MODIFIED_OPTION_DEFS6, @@ -117,7 +121,7 @@ public: DELETE_POOLS6_SUBNET_ID, DELETE_PD_POOLS_SUBNET_ID, DELETE_SHARED_NETWORK6_NAME_WITH_TAG, - DELETE_SHARED_NETWORK6_NAME_NO_TAG, + DELETE_SHARED_NETWORK6_NAME_ANY, DELETE_ALL_SHARED_NETWORKS6, DELETE_SHARED_NETWORK6_SERVER, DELETE_OPTION_DEF6_CODE_NAME, @@ -1440,19 +1444,23 @@ public: SharedNetwork6Ptr getSharedNetwork6(const ServerSelector& server_selector, const std::string& name) { - if (server_selector.amUnassigned()) { - isc_throw(NotImplemented, "managing configuration for no particular server" - " (unassigned) is unsupported at the moment"); - - } else if (server_selector.hasMultipleTags()) { + if (server_selector.hasMultipleTags()) { isc_throw(InvalidOperation, "expected one server tag to be specified" " while fetching a shared network. Got: " << getServerTagsAsText(server_selector)); } MySqlBindingCollection in_bindings = { MySqlBinding::createString(name) }; + auto index = GET_SHARED_NETWORK6_NAME_NO_TAG; + if (server_selector.amUnassigned()) { + index = GET_SHARED_NETWORK6_NAME_UNASSIGNED; + + } else if (server_selector.amAny()) { + index = GET_SHARED_NETWORK6_NAME_ANY; + } + SharedNetwork6Collection shared_networks; getSharedNetworks6(index, server_selector, in_bindings, shared_networks); @@ -1466,9 +1474,10 @@ public: /// structure where shared networks should be inserted. void getAllSharedNetworks6(const ServerSelector& server_selector, SharedNetwork6Collection& shared_networks) { + auto index = (server_selector.amUnassigned() ? GET_ALL_SHARED_NETWORKS6_UNASSIGNED : + GET_ALL_SHARED_NETWORKS6); MySqlBindingCollection in_bindings; - getSharedNetworks6(GET_ALL_SHARED_NETWORKS6, server_selector, in_bindings, - shared_networks); + getSharedNetworks6(index, server_selector, in_bindings, shared_networks); } /// @brief Sends query to retrieve modified shared networks. @@ -1484,8 +1493,9 @@ public: MySqlBinding::createTimestamp(modification_ts) }; - getSharedNetworks6(GET_MODIFIED_SHARED_NETWORKS6, server_selector, in_bindings, - shared_networks); + auto index = (server_selector.amUnassigned() ? GET_MODIFIED_SHARED_NETWORKS6_UNASSIGNED : + GET_MODIFIED_SHARED_NETWORKS6); + getSharedNetworks6(index, server_selector, in_bindings, shared_networks); } /// @brief Sends query to insert or update shared network. @@ -2375,21 +2385,41 @@ TaggedStatementArray tagged_statements = { { "ORDER BY p.id, x.option_id" }, - // Select shared network by name without filtering by server tag. + // Select shared network by name. { MySqlConfigBackendDHCPv6Impl::GET_SHARED_NETWORK6_NAME_NO_TAG, MYSQL_GET_SHARED_NETWORK6_NO_TAG(WHERE n.name = ?) }, + // Select shared network by name without specifying server tags. + { MySqlConfigBackendDHCPv6Impl::GET_SHARED_NETWORK6_NAME_ANY, + MYSQL_GET_SHARED_NETWORK6_ANY(WHERE n.name = ?) + }, + + // Select unassigned shared network by name. + { MySqlConfigBackendDHCPv6Impl::GET_SHARED_NETWORK6_NAME_UNASSIGNED, + MYSQL_GET_SHARED_NETWORK6_UNASSIGNED(AND n.name = ?) + }, + // Select all shared networks. { MySqlConfigBackendDHCPv6Impl::GET_ALL_SHARED_NETWORKS6, MYSQL_GET_SHARED_NETWORK6_NO_TAG() }, + // Select all unassigned shared networks. + { MySqlConfigBackendDHCPv6Impl::GET_ALL_SHARED_NETWORKS6_UNASSIGNED, + MYSQL_GET_SHARED_NETWORK6_UNASSIGNED() + }, + // Select modified shared networks. { MySqlConfigBackendDHCPv6Impl::GET_MODIFIED_SHARED_NETWORKS6, MYSQL_GET_SHARED_NETWORK6_NO_TAG(WHERE n.modification_ts > ?) }, + // Select modified and unassigned shared networks. + { MySqlConfigBackendDHCPv6Impl::GET_MODIFIED_SHARED_NETWORKS6_UNASSIGNED, + MYSQL_GET_SHARED_NETWORK6_UNASSIGNED(AND n.modification_ts > ?) + }, + // Retrieves option definition by code and space. { MySqlConfigBackendDHCPv6Impl::GET_OPTION_DEF6_CODE_SPACE, MYSQL_GET_OPTION_DEF(dhcp6, AND d.code = ? AND d.space = ?) @@ -2706,8 +2736,8 @@ TaggedStatementArray tagged_statements = { { }, // 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 = ?) + { MySqlConfigBackendDHCPv6Impl::DELETE_SHARED_NETWORK6_NAME_ANY, + MYSQL_DELETE_SHARED_NETWORK_ANY(dhcp6, WHERE n.name = ?) }, // Delete all shared networks. @@ -3172,7 +3202,7 @@ MySqlConfigBackendDHCPv6::deleteSharedNetwork6(const ServerSelector& server_sele LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_SHARED_NETWORK6) .arg(name); int index = (server_selector.amAny() ? - MySqlConfigBackendDHCPv6Impl::DELETE_SHARED_NETWORK6_NAME_NO_TAG : + MySqlConfigBackendDHCPv6Impl::DELETE_SHARED_NETWORK6_NAME_ANY : MySqlConfigBackendDHCPv6Impl::DELETE_SHARED_NETWORK6_NAME_WITH_TAG); uint64_t result = impl_->deleteTransactional(index, server_selector, "deleting a shared network", diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_impl.h b/src/hooks/dhcp/mysql_cb/mysql_cb_impl.h index a8749582da..7e54c1c063 100644 --- a/src/hooks/dhcp/mysql_cb/mysql_cb_impl.h +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_impl.h @@ -707,6 +707,14 @@ public: continue; } + } else if (server_selector.amUnassigned()) { + // Returned element has server tags but we expect that the + // elements are unassigned. + if (!(*elem)->getServerTags().empty()) { + elem = index.erase(elem); + continue; + } + } else { // Server selector contains explicit server tags, so // let's see if the returned elements includes any of 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 a5e5e1158b..f56d2dab72 100644 --- a/src/hooks/dhcp/mysql_cb/mysql_query_macros_dhcp.h +++ b/src/hooks/dhcp/mysql_cb/mysql_query_macros_dhcp.h @@ -211,7 +211,7 @@ namespace { #endif #ifndef MYSQL_GET_SHARED_NETWORK4 -#define MYSQL_GET_SHARED_NETWORK4_COMMON(...) \ +#define MYSQL_GET_SHARED_NETWORK4_COMMON(server_join, ...) \ "SELECT" \ " n.id," \ " n.name," \ @@ -249,21 +249,39 @@ namespace { " n.max_valid_lifetime," \ " s.tag " \ "FROM dhcp4_shared_network AS n " \ - "INNER JOIN dhcp4_shared_network_server AS a " \ - " ON n.id = a.shared_network_id " \ - "INNER JOIN dhcp4_server AS s " \ - " ON (a.server_id = s.id) " \ + server_join \ "LEFT JOIN dhcp4_options AS o ON o.scope_id = 4 AND n.name = o.shared_network_name " \ #__VA_ARGS__ \ " ORDER BY n.id, s.id, o.option_id" #define MYSQL_GET_SHARED_NETWORK4_NO_TAG(...) \ - MYSQL_GET_SHARED_NETWORK4_COMMON(__VA_ARGS__) + MYSQL_GET_SHARED_NETWORK4_COMMON( \ + "INNER JOIN dhcp4_shared_network_server AS a " \ + " ON n.id = a.shared_network_id " \ + "INNER JOIN dhcp4_server AS s " \ + " ON (a.server_id = s.id) ", \ + __VA_ARGS__) + +#define MYSQL_GET_SHARED_NETWORK4_ANY(...) \ + MYSQL_GET_SHARED_NETWORK4_COMMON( \ + "LEFT JOIN dhcp4_shared_network_server AS a " \ + " ON n.id = a.shared_network_id " \ + "LEFT JOIN dhcp4_server AS s " \ + " ON a.server_id = s.id ", \ + __VA_ARGS__) + +#define MYSQL_GET_SHARED_NETWORK4_UNASSIGNED(...) \ + MYSQL_GET_SHARED_NETWORK4_COMMON( \ + "LEFT JOIN dhcp4_shared_network_server AS a " \ + " ON n.id = a.shared_network_id " \ + "LEFT JOIN dhcp4_server AS s " \ + " ON a.server_id = s.id ", \ + WHERE a.shared_network_id IS NULL __VA_ARGS__) #endif #ifndef MYSQL_GET_SHARED_NETWORK6 -#define MYSQL_GET_SHARED_NETWORK6_COMMON(...) \ +#define MYSQL_GET_SHARED_NETWORK6_COMMON(server_join, ...) \ "SELECT" \ " n.id," \ " n.name," \ @@ -302,16 +320,34 @@ namespace { " n.max_valid_lifetime," \ " s.tag " \ "FROM dhcp6_shared_network AS n " \ - "INNER JOIN dhcp6_shared_network_server AS a " \ - " ON n.id = a.shared_network_id " \ - "INNER JOIN dhcp6_server AS s " \ - " ON (a.server_id = s.id) " \ + server_join \ "LEFT JOIN dhcp6_options AS o ON o.scope_id = 4 AND n.name = o.shared_network_name " \ #__VA_ARGS__ \ " ORDER BY n.id, s.id, o.option_id" #define MYSQL_GET_SHARED_NETWORK6_NO_TAG(...) \ - MYSQL_GET_SHARED_NETWORK6_COMMON(__VA_ARGS__) + MYSQL_GET_SHARED_NETWORK6_COMMON( \ + "INNER JOIN dhcp6_shared_network_server AS a " \ + " ON n.id = a.shared_network_id " \ + "INNER JOIN dhcp6_server AS s " \ + " ON (a.server_id = s.id) ", \ + __VA_ARGS__) + +#define MYSQL_GET_SHARED_NETWORK6_ANY(...) \ + MYSQL_GET_SHARED_NETWORK6_COMMON( \ + "LEFT JOIN dhcp6_shared_network_server AS a " \ + " ON n.id = a.shared_network_id " \ + "LEFT JOIN dhcp6_server AS s " \ + " ON a.server_id = s.id ", \ + __VA_ARGS__) + +#define MYSQL_GET_SHARED_NETWORK6_UNASSIGNED(...) \ + MYSQL_GET_SHARED_NETWORK6_COMMON( \ + "LEFT JOIN dhcp6_shared_network_server AS a " \ + " ON n.id = a.shared_network_id " \ + "LEFT JOIN dhcp6_server AS s " \ + " ON a.server_id = s.id ", \ + WHERE a.shared_network_id IS NULL __VA_ARGS__) #endif @@ -665,9 +701,9 @@ namespace { #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__) - +#define MYSQL_DELETE_SHARED_NETWORK_ANY(table_prefix, ...) \ + "DELETE n FROM " #table_prefix "_shared_network AS n " \ + #__VA_ARGS__ #endif 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 5abd2c4982..336f7b74ae 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 @@ -1460,12 +1460,6 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getSharedNetwork4) { EXPECT_THROW(cbptr_->getSharedNetwork4(ServerSelector::MULTIPLE({ "server1", "server2" }), test_networks_[0]->getName()), isc::InvalidOperation); - // We currently don't support fetching a shared network which is assigned - // to no servers. - EXPECT_THROW(cbptr_->getSharedNetwork4(ServerSelector::UNASSIGNED(), - test_networks_[0]->getName()), - isc::NotImplemented); - // Test that this shared network will be fetched for various server selectors. auto test_get_network = [this, &shared_network] (const std::string& test_case_name, @@ -1962,6 +1956,84 @@ TEST_F(MySqlConfigBackendDHCPv4Test, deleteSharedNetwork4) { test_delete("one server", ServerSelector::ONE("server1"), shared_network3); } +// Test that it is possible to retrieve and delete orphaned shared network. +TEST_F(MySqlConfigBackendDHCPv4Test, unassignedSharedNetwork) { + // Create the server. + EXPECT_NO_THROW(cbptr_->createUpdateServer4(test_servers_[0])); + + // Create the shared network and associate it with the server1. + auto shared_network = test_networks_[0]; + EXPECT_NO_THROW( + cbptr_->createUpdateSharedNetwork4(ServerSelector::ONE("server1"), shared_network) + ); + + // Delete the server. The shared network should be preserved but is + // considered orhpaned, i.e. does 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 this shared network by server tag should return no result. + SharedNetwork4Ptr returned_network; + EXPECT_NO_THROW(returned_network = cbptr_->getSharedNetwork4(ServerSelector::ONE("server1"), + "level1")); + EXPECT_FALSE(returned_network); + + // The same if we use other calls. + SharedNetwork4Collection returned_networks; + EXPECT_NO_THROW( + returned_networks = cbptr_->getAllSharedNetworks4(ServerSelector::ONE("server1")) + ); + EXPECT_TRUE(returned_networks.empty()); + + EXPECT_NO_THROW( + returned_networks = cbptr_->getModifiedSharedNetworks4(ServerSelector::ONE("server1"), + timestamps_["two days ago"]) + ); + EXPECT_TRUE(returned_networks.empty()); + + // We should get the shared network if we ask for unassigned. + EXPECT_NO_THROW(returned_network = cbptr_->getSharedNetwork4(ServerSelector::UNASSIGNED(), + "level1")); + ASSERT_TRUE(returned_network); + + // Also if we ask for all unassigned networks it should be returned. + EXPECT_NO_THROW(returned_networks = cbptr_->getAllSharedNetworks4(ServerSelector::UNASSIGNED())); + ASSERT_EQ(1, returned_networks.size()); + + // And all modified. + EXPECT_NO_THROW( + returned_networks = cbptr_->getModifiedSharedNetworks4(ServerSelector::UNASSIGNED(), + timestamps_["two days ago"]) + ); + ASSERT_EQ(1, returned_networks.size()); + + // If we ask for any network with this name, it should be returned too. + EXPECT_NO_THROW(returned_network = cbptr_->getSharedNetwork4(ServerSelector::ANY(), + "level1")); + ASSERT_TRUE(returned_network); + + // Deleting a shared network with the mismatched server tag should not affect + // our shared network. + EXPECT_NO_THROW( + deleted_count = cbptr_->deleteSharedNetwork4(ServerSelector::ONE("server1"), + "level1") + ); + EXPECT_EQ(0, deleted_count); + + // Also, if we delete all shared networks for server1. + EXPECT_NO_THROW( + deleted_count = cbptr_->deleteAllSharedNetworks4(ServerSelector::ONE("server1")) + ); + EXPECT_EQ(0, deleted_count); + + // We can delete this shared network when we specify ANY and the matching name. + EXPECT_NO_THROW( + deleted_count = cbptr_->deleteSharedNetwork4(ServerSelector::ANY(), "level1") + ); + EXPECT_EQ(1, deleted_count); +} + // 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 a9af75113b..0998b1f1b6 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 @@ -1475,11 +1475,6 @@ TEST_F(MySqlConfigBackendDHCPv6Test, getSharedNetwork6) { EXPECT_THROW(cbptr_->getSharedNetwork6(ServerSelector::MULTIPLE({ "server1", "server2" }), test_networks_[0]->getName()), isc::InvalidOperation); - // We currently don't support fetching a shared network which is assigned - // to no servers. - EXPECT_THROW(cbptr_->getSharedNetwork6(ServerSelector::UNASSIGNED(), - test_networks_[0]->getName()), - isc::NotImplemented); // Test that this shared network will be fetched for various server selectors. auto test_get_network = [this, &shared_network] (const std::string& test_case_name, @@ -1977,6 +1972,84 @@ TEST_F(MySqlConfigBackendDHCPv6Test, deleteSharedNetwork6) { test_delete("one server", ServerSelector::ONE("server1"), shared_network3); } +// Test that it is possible to retrieve and delete orphaned shared network. +TEST_F(MySqlConfigBackendDHCPv6Test, unassignedSharedNetwork) { + // Create the server. + EXPECT_NO_THROW(cbptr_->createUpdateServer6(test_servers_[0])); + + // Create the shared network and associate it with the server1. + auto shared_network = test_networks_[0]; + EXPECT_NO_THROW( + cbptr_->createUpdateSharedNetwork6(ServerSelector::ONE("server1"), shared_network) + ); + + // Delete the server. The shared network should be preserved but is + // considered orhpaned, i.e. does 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 this shared network by server tag should return no result. + SharedNetwork6Ptr returned_network; + EXPECT_NO_THROW(returned_network = cbptr_->getSharedNetwork6(ServerSelector::ONE("server1"), + "level1")); + EXPECT_FALSE(returned_network); + + // The same if we use other calls. + SharedNetwork6Collection returned_networks; + EXPECT_NO_THROW( + returned_networks = cbptr_->getAllSharedNetworks6(ServerSelector::ONE("server1")) + ); + EXPECT_TRUE(returned_networks.empty()); + + EXPECT_NO_THROW( + returned_networks = cbptr_->getModifiedSharedNetworks6(ServerSelector::ONE("server1"), + timestamps_["two days ago"]) + ); + EXPECT_TRUE(returned_networks.empty()); + + // We should get the shared network if we ask for unassigned. + EXPECT_NO_THROW(returned_network = cbptr_->getSharedNetwork6(ServerSelector::UNASSIGNED(), + "level1")); + ASSERT_TRUE(returned_network); + + // Also if we ask for all unassigned networks it should be returned. + EXPECT_NO_THROW(returned_networks = cbptr_->getAllSharedNetworks6(ServerSelector::UNASSIGNED())); + ASSERT_EQ(1, returned_networks.size()); + + // And all modified. + EXPECT_NO_THROW( + returned_networks = cbptr_->getModifiedSharedNetworks6(ServerSelector::UNASSIGNED(), + timestamps_["two days ago"]) + ); + ASSERT_EQ(1, returned_networks.size()); + + // If we ask for any network with this name, it should be returned too. + EXPECT_NO_THROW(returned_network = cbptr_->getSharedNetwork6(ServerSelector::ANY(), + "level1")); + ASSERT_TRUE(returned_network); + + // Deleting a shared network with the mismatched server tag should not affect + // our shared network. + EXPECT_NO_THROW( + deleted_count = cbptr_->deleteSharedNetwork6(ServerSelector::ONE("server1"), + "level1") + ); + EXPECT_EQ(0, deleted_count); + + // Also, if we delete all shared networks for server1. + EXPECT_NO_THROW( + deleted_count = cbptr_->deleteAllSharedNetworks6(ServerSelector::ONE("server1")) + ); + EXPECT_EQ(0, deleted_count); + + // We can delete this shared network when we specify ANY and the matching name. + EXPECT_NO_THROW( + deleted_count = cbptr_->deleteSharedNetwork6(ServerSelector::ANY(), "level1") + ); + EXPECT_EQ(1, deleted_count); +} + // Test that lifetimes in shared networks are handled as expected. TEST_F(MySqlConfigBackendDHCPv6Test, sharedNetworkLifetime) { // Insert new shared network with unspecified valid lifetime