GET_SUBNET4_PREFIX,
GET_ALL_SUBNETS4,
GET_MODIFIED_SUBNETS4,
+ GET_SHARED_NETWORK_SUBNETS4,
GET_POOL4_RANGE,
GET_SHARED_NETWORK4_NAME,
GET_ALL_SHARED_NETWORKS4,
}
}
+ /// @brief Sends query to retrieve all subnets belonging to a shared network.
+ ///
+ /// @param server_selector Server selector.
+ /// @param shared_network_name Name of the shared network for which the
+ /// subnets should be retrieved.
+ /// @param [out] subnets Reference to the subnet collection structure where
+ /// subnets should be inserted.
+ void getSharedNetworkSubnets4(const ServerSelector& server_selector,
+ const std::string& shared_network_name,
+ Subnet4Collection& subnets) {
+ auto tags = getServerTags(server_selector);
+
+ for (auto tag : tags) {
+ MySqlBindingCollection in_bindings = {
+ MySqlBinding::createString(tag),
+ MySqlBinding::createString(shared_network_name)
+ };
+
+ getSubnets4(GET_SHARED_NETWORK_SUBNETS4, in_bindings, subnets);
+ }
+ }
+
/// @brief Sends query to retrieve multiple pools.
///
/// Query should order pools by id.
// Create binding with shared network name if the subnet belongs to a
// shared network.
+ MySqlBindingPtr shared_network_binding;
+
SharedNetwork4Ptr shared_network;
subnet->getSharedNetwork(shared_network);
- MySqlBindingPtr shared_network_binding =
- (shared_network ? MySqlBinding::createString(shared_network->getName()) :
- MySqlBinding::createNull());
+
+ // Check if the subnet is associated with a shared network instance.
+ // If it is, create the binding using the name of the shared network
+ // returned by this instance.
+ if (shared_network) {
+ shared_network_binding = MySqlBinding::createString(shared_network->getName());
+
+ // If the subnet is associated with a shared network by name (no
+ // shared network instance), use this name to create the binding.
+ // This may be the case if the subnet is added as a result of
+ // receiving a control command that merely specifies shared
+ // network name. In that case, it is expected that the shared
+ // network data is already stored in the database.
+ } else if (!subnet->getSharedNetworkName().empty()) {
+ shared_network_binding = MySqlBinding::createString(subnet->getSharedNetworkName());
+
+ // If the subnet is not associated with a shared network, create
+ // null binding.
+ } else {
+ shared_network_binding = MySqlBinding::createNull();
+ }
// Create input bindings.
MySqlBindingCollection in_bindings = {
MYSQL_GET_SUBNET4(AND s.modification_ts > ?)
},
+ // Select subnets belonging to a shared network.
+ { MySqlConfigBackendDHCPv4Impl::GET_SHARED_NETWORK_SUBNETS4,
+ MYSQL_GET_SUBNET4(AND s.shared_network_name = ?)
+ },
+
// Select pool by address range.
{ MySqlConfigBackendDHCPv4Impl::GET_POOL4_RANGE,
"SELECT"
return (subnets);
}
+Subnet4Collection
+MySqlConfigBackendDHCPv4::getSharedNetworkSubnets4(const ServerSelector& server_selector,
+ const std::string& shared_network_name) const {
+ Subnet4Collection subnets;
+ impl_->getSharedNetworkSubnets4(server_selector, shared_network_name, subnets);
+ return (subnets);
+}
+
SharedNetwork4Ptr
MySqlConfigBackendDHCPv4::getSharedNetwork4(const ServerSelector& server_selector,
const std::string& name) const {
getModifiedSubnets4(const db::ServerSelector& server_selector,
const boost::posix_time::ptime& modification_time) const;
+ /// @brief Retrieves all subnets belonging to a specified shared network.
+ ///
+ /// @param server_selector Server selector.
+ /// @param shared_network_name Name of the shared network for which the
+ /// subnets should be retrieved.
+ /// @return Collection of subnets or empty collection if no subnet found.
+ virtual Subnet4Collection
+ getSharedNetworkSubnets4(const db::ServerSelector& server_selector,
+ const std::string& shared_network_name) const;
+
/// @brief Retrieves shared network by name.
///
/// @param server_selector Server selector.
ASSERT_TRUE(subnets.empty());
}
+// Test that subnets belonging to a shared network can be retrieved.
+TEST_F(MySqlConfigBackendDHCPv4Test, getSharedNetworkSubnets4) {
+ // Assign test subnets into shared networks level1 and level2.
+ test_subnets_[1]->setSharedNetworkName("level1");
+ test_subnets_[2]->setSharedNetworkName("level2");
+ test_subnets_[3]->setSharedNetworkName("level2");
+
+ // Store shared networks in the database.
+ for (auto network : test_networks_) {
+ cbptr_->createUpdateSharedNetwork4(ServerSelector::ALL(), network);
+ }
+
+ // Store subnets in the database.
+ for (auto subnet : test_subnets_) {
+ cbptr_->createUpdateSubnet4(ServerSelector::ALL(), subnet);
+ }
+
+ // Fetch all subnets belonging to shared network level1.
+ Subnet4Collection subnets = cbptr_->getSharedNetworkSubnets4(ServerSelector::ALL(),
+ "level1");
+ ASSERT_EQ(1, subnets.size());
+
+ // Returned subnet should match test subnet #1.
+ EXPECT_EQ(test_subnets_[1]->toElement()->str(), subnets[0]->toElement()->str());
+
+ // All subnets should also be returned for explicitly specified server tag.
+ subnets = cbptr_->getSharedNetworkSubnets4(ServerSelector::ONE("server1"), "level1");
+ ASSERT_EQ(1, subnets.size());
+
+ // Returned subnet should match test subnet #1.
+ EXPECT_EQ(test_subnets_[1]->toElement()->str(), subnets[0]->toElement()->str());
+
+ // Fetch all subnets belonging to shared network level2.
+ subnets = cbptr_->getSharedNetworkSubnets4(ServerSelector::ALL(), "level2");
+ ASSERT_EQ(2, subnets.size());
+
+ // Verify the subnets. It is safe to assume the order in which they have
+ // been returned, because the SELECT statement orders by subnet id.
+ EXPECT_EQ(test_subnets_[2]->toElement()->str(), subnets[0]->toElement()->str());
+ EXPECT_EQ(test_subnets_[3]->toElement()->str(), subnets[1]->toElement()->str());
+
+ // All subnets should also be returned for explicitly specified server tag.
+ subnets = cbptr_->getSharedNetworkSubnets4(ServerSelector::ONE("server1"), "level2");
+ ASSERT_EQ(2, subnets.size());
+
+ EXPECT_EQ(test_subnets_[2]->toElement()->str(), subnets[0]->toElement()->str());
+ EXPECT_EQ(test_subnets_[3]->toElement()->str(), subnets[1]->toElement()->str());
+}
+
// Test that shared network can be inserted, fetched, updated and then
// fetched again.
TEST_F(MySqlConfigBackendDHCPv4Test, getSharedNetwork4) {
virtual Subnet4Collection
getAllSubnets4(const db::ServerSelector& server_selector) const = 0;
+ /// @brief Retrieves all subnets belonging to a specified shared network.
+ ///
+ /// @param server_selector Server selector.
+ /// @param shared_network_name Name of the shared network for which the
+ /// subnets should be retrieved.
+ /// @return Collection of subnets or empty collection if no subnet found.
+ virtual Subnet4Collection
+ getSharedNetworkSubnets4(const db::ServerSelector& server_selector,
+ const std::string& shared_network_name) const = 0;
+
/// @brief Retrieves subnets modified after specified time.
///
/// @param server_selector Server selector.
return (subnets);
}
+Subnet4Collection
+ConfigBackendPoolDHCPv4::getSharedNetworkSubnets4(const db::BackendSelector& backend_selector,
+ const db::ServerSelector& server_selector,
+ const std::string& shared_network_name) const {
+ Subnet4Collection subnets;
+ getMultiplePropertiesConst<Subnet4Collection, const std::string&>
+ (&ConfigBackendDHCPv4::getSharedNetworkSubnets4, backend_selector, server_selector,
+ subnets, shared_network_name);
+ return (subnets);
+}
+
SharedNetwork4Ptr
ConfigBackendPoolDHCPv4::getSharedNetwork4(const BackendSelector& backend_selector,
const ServerSelector& server_selector,
const db::ServerSelector& server_selector,
const boost::posix_time::ptime& modification_time) const;
+ /// @brief Retrieves all subnets belonging to a specified shared network.
+ ///
+ /// @param backend_selector Backend selector.
+ /// @param server_selector Server selector.
+ /// @param shared_network_name Name of the shared network for which the
+ /// subnets should be retrieved.
+ /// @return Collection of subnets or empty collection if no subnet found.
+ virtual Subnet4Collection
+ getSharedNetworkSubnets4(const db::BackendSelector& backend_selector,
+ const db::ServerSelector& server_selector,
+ const std::string& shared_network_name) const;
+
/// @brief Retrieves shared network by name.
///
/// @param backend_selector Backend selector.
return (subnets);
}
+Subnet4Collection
+TestConfigBackendDHCPv4::getSharedNetworkSubnets4(const db::ServerSelector& /* server_selector */,
+ const std::string& shared_network_name) const {
+ Subnet4Collection subnets;
+
+ // Subnet collection does not include the index by shared network name.
+ // We need to iterate over the subnets and pick those that are associated
+ // with a shared network.
+ for (auto subnet = subnets_.begin(); subnet != subnets_.end();
+ ++subnet) {
+ // The subnet can be associated with a shared network instance or
+ // it may just point to the shared network name. The former is
+ // the case when the subnet belongs to the server configuration.
+ // The latter is the case when the subnet is fetched from the
+ // database.
+ SharedNetwork4Ptr network;
+ (*subnet)->getSharedNetwork(network);
+ if (((network && (network->getName() == shared_network_name)) ||
+ ((*subnet)->getSharedNetworkName() == shared_network_name))) {
+ subnets.push_back(*subnet);
+ }
+ }
+ return (subnets);
+}
+
SharedNetwork4Ptr
TestConfigBackendDHCPv4::getSharedNetwork4(const db::ServerSelector& /* server_selector */,
const std::string& name) const {
getModifiedSubnets4(const db::ServerSelector& server_selector,
const boost::posix_time::ptime& modification_time) const;
+ /// @brief Retrieves all subnets belonging to a specified shared network.
+ ///
+ /// @param server_selector Server selector.
+ /// @param shared_network_name Name of the shared network for which the
+ /// subnets should be retrieved.
+ /// @return Collection of subnets or empty collection if no subnet found.
+ virtual Subnet4Collection
+ getSharedNetworkSubnets4(const db::ServerSelector& server_selector,
+ const std::string& shared_network_name) const;
+
/// @brief Retrieves shared network by name.
///
/// @param server_selector Server selector.