GET_MODIFIED_SUBNETS4,
GET_SHARED_NETWORK_SUBNETS4,
GET_POOL4_RANGE,
- GET_SHARED_NETWORK4_NAME,
+ GET_SHARED_NETWORK4_NAME_WITH_TAG,
+ GET_SHARED_NETWORK4_NAME_NO_TAG,
GET_ALL_SHARED_NETWORKS4,
GET_MODIFIED_SHARED_NETWORKS4,
GET_OPTION_DEF4_CODE_SPACE,
DELETE_POOLS4_SUBNET_ID,
DELETE_SHARED_NETWORK4_NAME,
DELETE_ALL_SHARED_NETWORKS4,
+ DELETE_SHARED_NETWORK4_SERVER,
DELETE_OPTION_DEF4_CODE_NAME,
DELETE_ALL_OPTION_DEFS4,
DELETE_ALL_OPTION_DEFS4_UNASSIGNED,
DELETE_OPTION4_SHARED_NETWORK,
DELETE_OPTIONS4_SUBNET_ID,
DELETE_OPTIONS4_SHARED_NETWORK,
+ DELETE_OPTION4_SERVER,
DELETE_SERVER4,
DELETE_ALL_SERVERS4,
NUM_STATEMENTS
conn_.insertQuery(MySqlConfigBackendDHCPv4Impl::INSERT_GLOBAL_PARAMETER4,
in_bindings);
- // Successfully inserted global parameter. Now, we have to associate it
- // with the server tag.
-
// Let's first get the primary key of the global parameter.
uint64_t id = mysql_insert_id(conn_.mysql_);
- // Create bindings for inserting the association into
- // dhcp4_global_parameter_server table.
- MySqlBindingCollection in_server_bindings = {
- MySqlBinding::createInteger<uint64_t>(id), // parameter_id
- MySqlBinding::createString(tag), // tag used to obtain server_id
- MySqlBinding::createTimestamp(value->getModificationTime()), // modification_ts
- };
-
- // Insert association.
- conn_.insertQuery(MySqlConfigBackendDHCPv4Impl::INSERT_GLOBAL_PARAMETER4_SERVER,
- in_server_bindings);
-
+ // Successfully inserted global parameter. Now, we have to associate it
+ // with the server tag.
+ attachElementToServers(MySqlConfigBackendDHCPv4Impl::INSERT_GLOBAL_PARAMETER4_SERVER,
+ server_selector,
+ MySqlBinding::createInteger<uint64_t>(id),
+ MySqlBinding::createTimestamp(value->getModificationTime()));
}
transaction.commit();
conn_.insertQuery(MySqlConfigBackendDHCPv4Impl::INSERT_SUBNET4,
in_bindings);
- // Create bindings for inserting the association into
- // dhcp4_subnet_server table.
- MySqlBindingCollection in_server_bindings = {
- MySqlBinding::createInteger<uint32_t>(subnet->getID()), // subnet_id
- MySqlBinding::createString(tag), // tag used to obtain server_id
- MySqlBinding::createTimestamp(subnet->getModificationTime()), // modification_ts
- };
-
- // Insert association.
- conn_.insertQuery(MySqlConfigBackendDHCPv4Impl::INSERT_SUBNET4_SERVER,
- in_server_bindings);
+ // Insert associations with the servers.
+ attachElementToServers(MySqlConfigBackendDHCPv4Impl::INSERT_SUBNET4_SERVER,
+ server_selector,
+ MySqlBinding::createInteger<uint32_t>(subnet->getID()),
+ MySqlBinding::createTimestamp(subnet->getModificationTime()));
} catch (const DuplicateEntry&) {
deletePools4(subnet);
- deleteOptions4(server_selector, subnet);
+ deleteOptions4(ServerSelector::ANY(), subnet);
// Need to add two more bindings for WHERE clause.
in_bindings.push_back(MySqlBinding::createInteger<uint32_t>(subnet->getID()));
uint64_t last_network_id = 0;
uint64_t last_option_id = 0;
+ std::string last_tag;
conn_.selectQuery(index, in_bindings, out_bindings,
- [this, &shared_networks, &last_network_id, &last_option_id]
+ [this, &shared_networks, &last_network_id, &last_option_id,
+ &last_tag]
(MySqlBindingCollection& out_bindings) {
SharedNetwork4Ptr last_network;
if (!shared_networks.empty()) {
// row to create the new shared network instance.
if (last_network_id != out_bindings[0]->getInteger<uint64_t>()) {
+ // Reset last server tag as we're now starting to process new
+ // shared network.
+ last_tag.clear();
+
last_network_id = out_bindings[0]->getInteger<uint64_t>();
last_network = SharedNetwork4::create(out_bindings[1]->getString());
last_network->setId(last_network_id);
// {min,max}_valid_lifetime
- // server_tag
- last_network->setServerTag(out_bindings[34]->getString());
-
// Add the shared network.
auto ret = shared_networks.push_back(last_network);
}
}
+ // Check for new server tags.
+ if (!out_bindings[34]->amNull() &&
+ (last_tag != out_bindings[34]->getString())) {
+ last_tag = out_bindings[34]->getString();
+ if (!last_tag.empty() && !last_network->hasServerTag(ServerTag(last_tag))) {
+ last_network->setServerTag(last_tag);
+ }
+ }
+
// Parse option.
if (!out_bindings[13]->amNull() &&
(last_option_id < out_bindings[13]->getInteger<uint64_t>())) {
" (unassigned) is unsupported at the moment");
}
- auto tag = getServerTag(server_selector, "fetching shared network");
+ MySqlBindingCollection in_bindings;
+ auto index = GET_SHARED_NETWORK4_NAME_NO_TAG;
- MySqlBindingCollection in_bindings = {
- MySqlBinding::createString(tag),
- MySqlBinding::createString(name)
- };
+ if (!server_selector.amAny()) {
+ auto tag = getServerTag(server_selector, "fetching shared network");
+ in_bindings.push_back(MySqlBinding::createString(tag));
+
+ index = GET_SHARED_NETWORK4_NAME_WITH_TAG;
+ }
+
+ in_bindings.push_back(MySqlBinding::createString(name));
SharedNetwork4Collection shared_networks;
- getSharedNetworks4(GET_SHARED_NETWORK4_NAME, in_bindings, shared_networks);
+ getSharedNetworks4(index, in_bindings, shared_networks);
return (shared_networks.empty() ? SharedNetwork4Ptr() : *shared_networks.begin());
}
" (unassigned) is unsupported at the moment");
}
- auto tag = getServerTag(server_selector, "creating or updating shared network");
-
// Create binding for host reservation mode.
MySqlBindingPtr hr_mode_binding;
auto hr_mode = shared_network->getHostReservationMode(Network::Inheritance::NONE);
conn_.insertQuery(MySqlConfigBackendDHCPv4Impl::INSERT_SHARED_NETWORK4,
in_bindings);
- // Create bindings for inserting association into dhcp4_shared_network_server
- // table.
- MySqlBindingCollection in_server_bindings = {
- MySqlBinding::createString(shared_network->getName()), // shared network name
- MySqlBinding::createString(tag), // server tag
- MySqlBinding::createTimestamp(shared_network->getModificationTime()), // modification_ts
- };
-
- // Insert association.
- conn_.insertQuery(MySqlConfigBackendDHCPv4Impl::INSERT_SHARED_NETWORK4_SERVER,
- in_server_bindings);
-
-
} catch (const DuplicateEntry&) {
- deleteOptions4(server_selector, shared_network);
+ deleteOptions4(ServerSelector::ANY(), shared_network);
// Need to add one more binding for WHERE clause.
in_bindings.push_back(MySqlBinding::createString(shared_network->getName()));
conn_.updateDeleteQuery(MySqlConfigBackendDHCPv4Impl::UPDATE_SHARED_NETWORK4,
in_bindings);
+
+ MySqlBindingCollection in_server_bindings = {
+ MySqlBinding::createString(shared_network->getName())
+ };
+ conn_.updateDeleteQuery(MySqlConfigBackendDHCPv4Impl::DELETE_SHARED_NETWORK4_SERVER,
+ in_server_bindings);
}
+ // Associate the shared network with the servers.
+ attachElementToServers(MySqlConfigBackendDHCPv4Impl::INSERT_SHARED_NETWORK4_SERVER,
+ server_selector,
+ MySqlBinding::createString(shared_network->getName()),
+ MySqlBinding::createTimestamp(shared_network->getModificationTime()));
+
// (Re)create options.
auto option_spaces = shared_network->getCfgOption()->getOptionSpaceNames();
for (auto option_space : option_spaces) {
conn_.insertQuery(MySqlConfigBackendDHCPv4Impl::INSERT_OPTION4,
in_bindings);
- // Fetch unique identifier of the inserted option.
- uint64_t id = mysql_insert_id(conn_.mysql_);
-
- // Create bindings needed to insert association of that option with
- // a server into the dhcp4_options_server table.
- MySqlBindingCollection in_server_bindings = {
- MySqlBinding::createInteger<uint64_t>(id), // option_id
- MySqlBinding::createString(server_selector.getTags().begin()->get()), // server_tag
- in_bindings[11] // copy modification timestamp from option
- };
-
- conn_.insertQuery(MySqlConfigBackendDHCPv4Impl::INSERT_OPTION4_SERVER,
- in_server_bindings);
+ // Associate the option with the servers.
+ attachElementToServers(MySqlConfigBackendDHCPv4Impl::INSERT_OPTION4_SERVER,
+ server_selector,
+ MySqlBinding::createInteger<uint64_t>(mysql_insert_id(conn_.mysql_)),
+ in_bindings[11]);
}
/// @brief Sends query to insert or update global DHCP option.
" (unassigned) is unsupported at the moment");
}
- auto tag = getServerTag(server_selector, "creating or updating shared"
- " network level option");
-
MySqlBindingCollection in_bindings = {
MySqlBinding::createInteger<uint8_t>(option->option_->getType()),
createOptionValueBinding(option),
MySqlBinding::createString(shared_network_name),
MySqlBinding::createNull(),
MySqlBinding::createTimestamp(option->getModificationTime()),
- MySqlBinding::createString(tag),
MySqlBinding::createString(shared_network_name),
MySqlBinding::createInteger<uint8_t>(option->option_->getType()),
MySqlBinding::condCreateString(option->space_name_)
if (conn_.updateDeleteQuery(MySqlConfigBackendDHCPv4Impl::
UPDATE_OPTION4_SHARED_NETWORK,
in_bindings) == 0) {
- // Remove the 4 bindings used only in case of update.
- in_bindings.resize(in_bindings.size() - 4);
+ // Remove the 3 bindings used only in case of update.
+ in_bindings.resize(in_bindings.size() - 3);
insertOption4(server_selector, in_bindings);
}
"ORDER BY p.id, x.option_id"
},
- // Select shared network by name.
- { MySqlConfigBackendDHCPv4Impl::GET_SHARED_NETWORK4_NAME,
- MYSQL_GET_SHARED_NETWORK4(AND n.name = ?)
+ // Select shared network by name and filter by server tag.
+ { MySqlConfigBackendDHCPv4Impl::GET_SHARED_NETWORK4_NAME_WITH_TAG,
+ MYSQL_GET_SHARED_NETWORK4_WITH_TAG(AND n.name = ?)
+ },
+
+ // Select shared network by name without filtering by server tag.
+ { MySqlConfigBackendDHCPv4Impl::GET_SHARED_NETWORK4_NAME_NO_TAG,
+ MYSQL_GET_SHARED_NETWORK4_NO_TAG(WHERE n.name = ?)
},
// Select all shared networks.
{ MySqlConfigBackendDHCPv4Impl::GET_ALL_SHARED_NETWORKS4,
- MYSQL_GET_SHARED_NETWORK4()
+ MYSQL_GET_SHARED_NETWORK4_WITH_TAG()
},
// Select modified shared networks.
{ MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_SHARED_NETWORKS4,
- MYSQL_GET_SHARED_NETWORK4(AND n.modification_ts > ?)
+ MYSQL_GET_SHARED_NETWORK4_WITH_TAG(AND n.modification_ts > ?)
},
// Retrieves option definition by code and space.
// Update existing global option.
{ MySqlConfigBackendDHCPv4Impl::UPDATE_OPTION4,
- MYSQL_UPDATE_OPTION4(AND o.scope_id = 0 AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION4_WITH_TAG(AND o.scope_id = 0 AND o.code = ? AND o.space = ?)
},
// Update existing subnet level option.
{ MySqlConfigBackendDHCPv4Impl::UPDATE_OPTION4_SUBNET_ID,
- MYSQL_UPDATE_OPTION4(AND o.scope_id = 1 AND o.dhcp4_subnet_id = ? AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION4_WITH_TAG(AND o.scope_id = 1 AND o.dhcp4_subnet_id = ? AND o.code = ? AND o.space = ?)
},
// Update existing pool level option.
{ MySqlConfigBackendDHCPv4Impl::UPDATE_OPTION4_POOL_ID,
- MYSQL_UPDATE_OPTION4(AND o.scope_id = 5 AND o.pool_id = ? AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION4_WITH_TAG(AND o.scope_id = 5 AND o.pool_id = ? AND o.code = ? AND o.space = ?)
},
// Update existing shared network level option.
{ MySqlConfigBackendDHCPv4Impl::UPDATE_OPTION4_SHARED_NETWORK,
- MYSQL_UPDATE_OPTION4(AND o.scope_id = 4 AND o.shared_network_name = ? AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION4_NO_TAG(o.scope_id = 4 AND o.shared_network_name = ? AND o.code = ? AND o.space = ?)
},
// Update existing server, e.g. server description.
MYSQL_DELETE_SHARED_NETWORK(dhcp4)
},
+ // Delete associations of a shared network with server.
+ { MySqlConfigBackendDHCPv4Impl::DELETE_SHARED_NETWORK4_SERVER,
+ MYSQL_DELETE_SHARED_NETWORK_SERVER(dhcp4)
+ },
+
// Delete option definition.
{ MySqlConfigBackendDHCPv4Impl::DELETE_OPTION_DEF4_CODE_NAME,
MYSQL_DELETE_OPTION_DEF(dhcp4, AND code = ? AND space = ?)
// Delete single global option.
{ MySqlConfigBackendDHCPv4Impl::DELETE_OPTION4,
- MYSQL_DELETE_OPTION(dhcp4, AND o.scope_id = 0 AND o.code = ? AND o.space = ?)
+ MYSQL_DELETE_OPTION_WITH_TAG(dhcp4, AND o.scope_id = 0 AND o.code = ? AND o.space = ?)
},
// Delete all global options which are unassigned to any servers.
// Delete single option from a subnet.
{ MySqlConfigBackendDHCPv4Impl::DELETE_OPTION4_SUBNET_ID,
- MYSQL_DELETE_OPTION(dhcp4,
- AND o.scope_id = 1 AND o.dhcp4_subnet_id = ? AND o.code = ? AND o.space = ?)
+ MYSQL_DELETE_OPTION_NO_TAG(dhcp4,
+ WHERE o.scope_id = 1 AND o.dhcp4_subnet_id = ? AND o.code = ? AND o.space = ?)
},
// Delete single option from a pool.
{ MySqlConfigBackendDHCPv4Impl::DELETE_OPTION4_POOL_RANGE,
- MYSQL_DELETE_OPTION_POOL_RANGE(dhcp4, AND o.scope_id = 5 AND o.code = ? AND o.space = ?)
+ MYSQL_DELETE_OPTION_POOL_RANGE(dhcp4, o.scope_id = 5 AND o.code = ? AND o.space = ?)
},
// Delete single option from a shared network.
{ MySqlConfigBackendDHCPv4Impl::DELETE_OPTION4_SHARED_NETWORK,
- MYSQL_DELETE_OPTION(dhcp4,
- AND o.scope_id = 4 AND o.shared_network_name = ? AND o.code = ? AND o.space = ?)
+ MYSQL_DELETE_OPTION_NO_TAG(dhcp4,
+ WHERE o.scope_id = 4 AND o.shared_network_name = ? AND o.code = ? AND o.space = ?)
},
// Delete options belonging to a subnet.
{ MySqlConfigBackendDHCPv4Impl::DELETE_OPTIONS4_SUBNET_ID,
- MYSQL_DELETE_OPTION(dhcp4, AND o.scope_id = 1 AND o.dhcp4_subnet_id = ?)
+ MYSQL_DELETE_OPTION_NO_TAG(dhcp4, WHERE o.scope_id = 1 AND o.dhcp4_subnet_id = ?)
},
// Delete options belonging to a shared_network.
{ MySqlConfigBackendDHCPv4Impl::DELETE_OPTIONS4_SHARED_NETWORK,
- MYSQL_DELETE_OPTION(dhcp4, AND o.scope_id = 4 AND o.shared_network_name = ?)
+ MYSQL_DELETE_OPTION_NO_TAG(dhcp4, WHERE o.scope_id = 4 AND o.shared_network_name = ?)
+ },
+
+ // Delete associations of an option with the server.
+ { MySqlConfigBackendDHCPv4Impl::DELETE_OPTION4_SERVER,
+ MYSQL_DELETE_OPTION_SERVER(dhcp4)
},
// Delete a server by tag.
}
uint64_t
-MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& server_selector,
+MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& /* server_selector */,
const std::string& shared_network_name,
const uint16_t code,
const std::string& space) {
+ /// @todo In the future we might use the server selector to make sure that the
+ /// option is only deleted if the pool belongs to a given server. For now, we
+ /// just delete it when there is a match with the parent object.
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_SHARED_NETWORK_OPTION4)
.arg(shared_network_name).arg(code).arg(space);
- uint64_t result = impl_->deleteOption4(server_selector, shared_network_name,
+ uint64_t result = impl_->deleteOption4(ServerSelector::ANY(), shared_network_name,
code, space);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_SHARED_NETWORK_OPTION4_RESULT)
.arg(result);
}
uint64_t
-MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& server_selector,
+MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& /* server_selector */,
const SubnetID& subnet_id,
const uint16_t code,
const std::string& space) {
+ /// @todo In the future we might use the server selector to make sure that the
+ /// option is only deleted if the pool belongs to a given server. For now, we
+ /// just delete it when there is a match with the parent object.
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_SUBNET_ID_OPTION4)
.arg(subnet_id).arg(code).arg(space);
- uint64_t result = impl_->deleteOption4(server_selector, subnet_id, code, space);
+ uint64_t result = impl_->deleteOption4(ServerSelector::ANY(), subnet_id, code, space);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_SUBNET_ID_OPTION4_RESULT)
.arg(result);
return (result);
}
uint64_t
-MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& server_selector,
+MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& /* server_selector */,
const asiolink::IOAddress& pool_start_address,
const asiolink::IOAddress& pool_end_address,
const uint16_t code,
const std::string& space) {
+ /// @todo In the future we might use the server selector to make sure that the
+ /// option is only deleted if the pool belongs to a given server. For now, we
+ /// just delete it when there is a match with the parent object.
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_POOL_OPTION4)
.arg(pool_start_address.toText()).arg(pool_end_address.toText()).arg(code).arg(space);
- uint64_t result = impl_->deleteOption4(server_selector, pool_start_address, pool_end_address,
- code, space);
+ uint64_t result = impl_->deleteOption4(ServerSelector::ANY(), pool_start_address,
+ pool_end_address, code, space);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_POOL_OPTION4_RESULT)
.arg(result);
return (result);
GET_SHARED_NETWORK_SUBNETS6,
GET_POOL6_RANGE,
GET_PD_POOL,
- GET_SHARED_NETWORK6_NAME,
+ GET_SHARED_NETWORK6_NAME_WITH_TAG,
+ GET_SHARED_NETWORK6_NAME_NO_TAG,
GET_ALL_SHARED_NETWORKS6,
GET_MODIFIED_SHARED_NETWORKS6,
GET_OPTION_DEF6_CODE_SPACE,
DELETE_PD_POOLS_SUBNET_ID,
DELETE_SHARED_NETWORK6_NAME,
DELETE_ALL_SHARED_NETWORKS6,
+ DELETE_SHARED_NETWORK6_SERVER,
DELETE_OPTION_DEF6_CODE_NAME,
DELETE_ALL_OPTION_DEFS6,
DELETE_ALL_OPTION_DEFS6_UNASSIGNED,
// Let's first get the primary key of the global parameter.
uint64_t id = mysql_insert_id(conn_.mysql_);
- // Create bindings for inserting the association into
- // dhcp6_global_parameter_server table.
- MySqlBindingCollection in_server_bindings = {
- MySqlBinding::createInteger<uint64_t>(id), // parameter_id
- MySqlBinding::createString(tag), // tag used to obtain server_id
- MySqlBinding::createTimestamp(value->getModificationTime()), // modification_ts
- };
-
- // Insert association.
- conn_.insertQuery(MySqlConfigBackendDHCPv6Impl::INSERT_GLOBAL_PARAMETER6_SERVER,
- in_server_bindings);
-
+ // Successfully inserted global parameter. Now, we have to associate it
+ // with the server tag.
+ attachElementToServers(MySqlConfigBackendDHCPv6Impl::INSERT_GLOBAL_PARAMETER6_SERVER,
+ server_selector,
+ MySqlBinding::createInteger<uint64_t>(id),
+ MySqlBinding::createTimestamp(value->getModificationTime()));
}
transaction.commit();
conn_.insertQuery(MySqlConfigBackendDHCPv6Impl::INSERT_SUBNET6,
in_bindings);
- // Create bindings for inserting the association into
- // dhcp6_subnet_server table.
- MySqlBindingCollection in_server_bindings = {
- MySqlBinding::createInteger<uint32_t>(subnet->getID()), // subnet_id
- MySqlBinding::createString(tag), // tag used to obtain server_id
- MySqlBinding::createTimestamp(subnet->getModificationTime()), // modification_ts
- };
-
- // Insert association.
- conn_.insertQuery(MySqlConfigBackendDHCPv6Impl::INSERT_SUBNET6_SERVER,
- in_server_bindings);
+ // Insert associations with the servers.
+ attachElementToServers(MySqlConfigBackendDHCPv6Impl::INSERT_SUBNET6_SERVER,
+ server_selector,
+ MySqlBinding::createInteger<uint32_t>(subnet->getID()),
+ MySqlBinding::createTimestamp(subnet->getModificationTime()));
} catch (const DuplicateEntry&) {
deletePools6(subnet);
deletePdPools6(subnet);
- deleteOptions6(server_selector, subnet);
+ deleteOptions6(ServerSelector::ANY(), subnet);
// Need to add two more bindings for WHERE clause.
in_bindings.push_back(MySqlBinding::createInteger<uint32_t>(subnet->getID()));
uint64_t last_network_id = 0;
uint64_t last_option_id = 0;
+ std::string last_tag;
conn_.selectQuery(index, in_bindings, out_bindings,
- [this, &shared_networks, &last_network_id, &last_option_id]
+ [this, &shared_networks, &last_network_id, &last_option_id,
+ &last_tag]
(MySqlBindingCollection& out_bindings) {
SharedNetwork6Ptr last_network;
if (!shared_networks.empty()) {
// row to create the new shared network instance.
if (last_network_id != out_bindings[0]->getInteger<uint64_t>()) {
+ // Reset last server tag as we're now starting to process new
+ // shared network.
+ last_tag.clear();
+
last_network_id = out_bindings[0]->getInteger<uint64_t>();
last_network = SharedNetwork6::create(out_bindings[1]->getString());
last_network->setId(last_network_id);
// {min,max)_valid_lifetime
- // server_tag
- last_network->setServerTag(out_bindings[35]->getString());
-
// Add the shared network.
auto ret = shared_networks.push_back(last_network);
last_network->getCfgOption()->add(*desc, desc->space_name_);
}
}
+
+ // Check for new server tags.
+ if (!out_bindings[35]->amNull() &&
+ (last_tag != out_bindings[35]->getString())) {
+ last_tag = out_bindings[35]->getString();
+ if (!last_tag.empty() && !last_network->hasServerTag(ServerTag(last_tag))) {
+ last_network->setServerTag(last_tag);
+ }
+ }
});
}
" (unassigned) is unsupported at the moment");
}
- auto tag = getServerTag(server_selector, "fetching shared network");
+ MySqlBindingCollection in_bindings;
+ auto index = GET_SHARED_NETWORK6_NAME_NO_TAG;
- MySqlBindingCollection in_bindings = {
- MySqlBinding::createString(tag),
- MySqlBinding::createString(name)
- };
+ if (!server_selector.amAny()) {
+ auto tag = getServerTag(server_selector, "fetching shared network");
+ in_bindings.push_back(MySqlBinding::createString(tag));
+
+ index = GET_SHARED_NETWORK6_NAME_WITH_TAG;
+ }
+
+ in_bindings.push_back(MySqlBinding::createString(name));
SharedNetwork6Collection shared_networks;
- getSharedNetworks6(GET_SHARED_NETWORK6_NAME, in_bindings, shared_networks);
+ getSharedNetworks6(index, in_bindings, shared_networks);
return (shared_networks.empty() ? SharedNetwork6Ptr() : *shared_networks.begin());
}
" (unassigned) is unsupported at the moment");
}
- auto tag = getServerTag(server_selector, "creating or updating shared network");
-
// Create binding for host reservation mode.
MySqlBindingPtr hr_mode_binding;
auto hr_mode = shared_network->getHostReservationMode(Network::Inheritance::NONE);
conn_.insertQuery(MySqlConfigBackendDHCPv6Impl::INSERT_SHARED_NETWORK6,
in_bindings);
- // Create bindings for inserting association into dhcp6_shared_network_server
- // table.
- MySqlBindingCollection in_server_bindings = {
- MySqlBinding::createString(shared_network->getName()), // shared network name
- MySqlBinding::createString(tag), // server tag
- MySqlBinding::createTimestamp(shared_network->getModificationTime()), // modification_ts
- };
-
- // Insert association.
- conn_.insertQuery(MySqlConfigBackendDHCPv6Impl::INSERT_SHARED_NETWORK6_SERVER,
- in_server_bindings);
-
-
} catch (const DuplicateEntry&) {
- deleteOptions6(server_selector, shared_network);
+ deleteOptions6(ServerSelector::ANY(), shared_network);
// Need to add one more binding for WHERE clause.
in_bindings.push_back(MySqlBinding::createString(shared_network->getName()));
conn_.updateDeleteQuery(MySqlConfigBackendDHCPv6Impl::UPDATE_SHARED_NETWORK6,
in_bindings);
+
+ MySqlBindingCollection in_server_bindings = {
+ MySqlBinding::createString(shared_network->getName())
+ };
+ conn_.updateDeleteQuery(MySqlConfigBackendDHCPv6Impl::DELETE_SHARED_NETWORK6_SERVER,
+ in_server_bindings);
+
}
+ attachElementToServers(MySqlConfigBackendDHCPv6Impl::INSERT_SHARED_NETWORK6_SERVER,
+ server_selector,
+ MySqlBinding::createString(shared_network->getName()),
+ MySqlBinding::createTimestamp(shared_network->getModificationTime()));
+
// (Re)create options.
auto option_spaces = shared_network->getCfgOption()->getOptionSpaceNames();
for (auto option_space : option_spaces) {
conn_.insertQuery(MySqlConfigBackendDHCPv6Impl::INSERT_OPTION6,
in_bindings);
- // Fetch unique identifier of the inserted option.
- uint64_t id = mysql_insert_id(conn_.mysql_);
-
- // Create bindings needed to insert association of that option with
- // a server into the dhcp6_options_server table.
- MySqlBindingCollection in_server_bindings = {
- MySqlBinding::createInteger<uint64_t>(id), // option_id
- MySqlBinding::createString(server_selector.getTags().begin()->get()), // server_tag
- in_bindings[11] // copy modification timestamp from option
- };
-
- conn_.insertQuery(MySqlConfigBackendDHCPv6Impl::INSERT_OPTION6_SERVER,
- in_server_bindings);
+ // Associate the option with the servers.
+ attachElementToServers(MySqlConfigBackendDHCPv6Impl::INSERT_OPTION6_SERVER,
+ server_selector,
+ MySqlBinding::createInteger<uint64_t>(mysql_insert_id(conn_.mysql_)),
+ in_bindings[11]);
}
/// @brief Sends query to insert or update global DHCP option.
" (unassigned) is unsupported at the moment");
}
- auto tag = getServerTag(server_selector, "creating or updating shared"
- " network level option");
-
MySqlBindingCollection in_bindings = {
MySqlBinding::createInteger<uint16_t>(option->option_->getType()),
createOptionValueBinding(option),
MySqlBinding::createNull(),
MySqlBinding::createTimestamp(option->getModificationTime()),
MySqlBinding::createNull(),
- MySqlBinding::createString(tag),
MySqlBinding::createString(shared_network_name),
MySqlBinding::createInteger<uint16_t>(option->option_->getType()),
MySqlBinding::condCreateString(option->space_name_)
if (conn_.updateDeleteQuery(MySqlConfigBackendDHCPv6Impl::
UPDATE_OPTION6_SHARED_NETWORK,
in_bindings) == 0) {
- // Remove the 4 bindings used only in case of update.
- in_bindings.resize(in_bindings.size() - 4);
+ // Remove the 3 bindings used only in case of update.
+ in_bindings.resize(in_bindings.size() - 3);
insertOption6(server_selector, in_bindings);
}
},
// Select shared network by name.
- { MySqlConfigBackendDHCPv6Impl::GET_SHARED_NETWORK6_NAME,
- MYSQL_GET_SHARED_NETWORK6(AND n.name = ?)
+ { MySqlConfigBackendDHCPv6Impl::GET_SHARED_NETWORK6_NAME_WITH_TAG,
+ MYSQL_GET_SHARED_NETWORK6_WITH_TAG(AND n.name = ?)
+ },
+
+ // Select shared network by name without filtering by server tag.
+ { MySqlConfigBackendDHCPv6Impl::GET_SHARED_NETWORK6_NAME_NO_TAG,
+ MYSQL_GET_SHARED_NETWORK6_NO_TAG(WHERE n.name = ?)
},
// Select all shared networks.
{ MySqlConfigBackendDHCPv6Impl::GET_ALL_SHARED_NETWORKS6,
- MYSQL_GET_SHARED_NETWORK6()
+ MYSQL_GET_SHARED_NETWORK6_WITH_TAG()
},
// Select modified shared networks.
{ MySqlConfigBackendDHCPv6Impl::GET_MODIFIED_SHARED_NETWORKS6,
- MYSQL_GET_SHARED_NETWORK6(AND n.modification_ts > ?)
+ MYSQL_GET_SHARED_NETWORK6_WITH_TAG(AND n.modification_ts > ?)
},
// Retrieves option definition by code and space.
// Update existing global option.
{ MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6,
- MYSQL_UPDATE_OPTION6(AND o.scope_id = 0 AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION6_WITH_TAG(AND o.scope_id = 0 AND o.code = ? AND o.space = ?)
},
// Update existing subnet level option.
{ MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_SUBNET_ID,
- MYSQL_UPDATE_OPTION6(AND o.scope_id = 1 AND o.dhcp6_subnet_id = ? AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION6_WITH_TAG(AND o.scope_id = 1 AND o.dhcp6_subnet_id = ? AND o.code = ? AND o.space = ?)
},
// Update existing pool level option.
{ MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_POOL_ID,
- MYSQL_UPDATE_OPTION6(AND o.scope_id = 5 AND o.pool_id = ? AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION6_WITH_TAG(AND o.scope_id = 5 AND o.pool_id = ? AND o.code = ? AND o.space = ?)
},
// Update existing pd pool level option.
{ MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_PD_POOL_ID,
- MYSQL_UPDATE_OPTION6(AND o.scope_id = 6 AND o.pd_pool_id = ? AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION6_WITH_TAG(AND o.scope_id = 6 AND o.pd_pool_id = ? AND o.code = ? AND o.space = ?)
},
// Update existing shared network level option.
{ MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_SHARED_NETWORK,
- MYSQL_UPDATE_OPTION6(AND o.scope_id = 4 AND o.shared_network_name = ? AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 4 AND o.shared_network_name = ? AND o.code = ? AND o.space = ?)
},
// Update existing server, e.g. server description.
MYSQL_DELETE_SHARED_NETWORK(dhcp6)
},
+ // Delete associations of a shared network with server.
+ { MySqlConfigBackendDHCPv6Impl::DELETE_SHARED_NETWORK6_SERVER,
+ MYSQL_DELETE_SHARED_NETWORK_SERVER(dhcp6)
+ },
+
// Delete option definition.
{ MySqlConfigBackendDHCPv6Impl::DELETE_OPTION_DEF6_CODE_NAME,
MYSQL_DELETE_OPTION_DEF(dhcp6, AND code = ? AND space = ?)
// Delete single global option.
{ MySqlConfigBackendDHCPv6Impl::DELETE_OPTION6,
- MYSQL_DELETE_OPTION(dhcp6, AND o.scope_id = 0 AND o.code = ? AND o.space = ?)
+ MYSQL_DELETE_OPTION_WITH_TAG(dhcp6, AND o.scope_id = 0 AND o.code = ? AND o.space = ?)
},
// Delete all global options which are unassigned to any servers.
// Delete single option from a subnet.
{ MySqlConfigBackendDHCPv6Impl::DELETE_OPTION6_SUBNET_ID,
- MYSQL_DELETE_OPTION(dhcp6,
- AND o.scope_id = 1 AND o.dhcp6_subnet_id = ? AND o.code = ? AND o.space = ?)
+ MYSQL_DELETE_OPTION_NO_TAG(dhcp6,
+ WHERE o.scope_id = 1 AND o.dhcp6_subnet_id = ? AND o.code = ? AND o.space = ?)
},
// Delete single option from a pool.
{ MySqlConfigBackendDHCPv6Impl::DELETE_OPTION6_POOL_RANGE,
- MYSQL_DELETE_OPTION_POOL_RANGE(dhcp6, AND o.scope_id = 5 AND o.code = ? AND o.space = ?)
+ MYSQL_DELETE_OPTION_POOL_RANGE(dhcp6, o.scope_id = 5 AND o.code = ? AND o.space = ?)
},
// Delete single option from a pd pool.
{ MySqlConfigBackendDHCPv6Impl::DELETE_OPTION6_PD_POOL,
- MYSQL_DELETE_OPTION_PD_POOL(AND o.scope_id = 6 AND o.code = ? AND o.space = ?)
+ MYSQL_DELETE_OPTION_PD_POOL(o.scope_id = 6 AND o.code = ? AND o.space = ?)
},
// Delete single option from a shared network.
{ MySqlConfigBackendDHCPv6Impl::DELETE_OPTION6_SHARED_NETWORK,
- MYSQL_DELETE_OPTION(dhcp6,
- AND o.scope_id = 4 AND o.shared_network_name = ? AND o.code = ? AND o.space = ?)
+ MYSQL_DELETE_OPTION_NO_TAG(dhcp6,
+ WHERE o.scope_id = 4 AND o.shared_network_name = ? AND o.code = ? AND o.space = ?)
},
// Delete options belonging to a subnet.
{ MySqlConfigBackendDHCPv6Impl::DELETE_OPTIONS6_SUBNET_ID,
- MYSQL_DELETE_OPTION(dhcp6, AND o.scope_id = 1 AND o.dhcp6_subnet_id = ?)
+ MYSQL_DELETE_OPTION_NO_TAG(dhcp6, WHERE o.scope_id = 1 AND o.dhcp6_subnet_id = ?)
},
// Delete options belonging to a shared_network.
{ MySqlConfigBackendDHCPv6Impl::DELETE_OPTIONS6_SHARED_NETWORK,
- MYSQL_DELETE_OPTION(dhcp6, AND o.scope_id = 4 AND o.shared_network_name = ?)
+ MYSQL_DELETE_OPTION_NO_TAG(dhcp6, WHERE o.scope_id = 4 AND o.shared_network_name = ?)
},
// Delete a server by tag.
const std::string& shared_network_name,
const uint16_t code,
const std::string& space) {
+ /// @todo In the future we might use the server selector to make sure that the
+ /// option is only deleted if the pool belongs to a given server. For now, we
+ /// just delete it when there is a match with the parent object.
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_SHARED_NETWORK_OPTION6)
.arg(shared_network_name).arg(code).arg(space);
- uint64_t result = impl_->deleteOption6(server_selector, shared_network_name,
+ uint64_t result = impl_->deleteOption6(ServerSelector::ANY(), shared_network_name,
code, space);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_SHARED_NETWORK_OPTION6_RESULT)
.arg(result);
}
uint64_t
-MySqlConfigBackendDHCPv6::deleteOption6(const ServerSelector& server_selector,
+MySqlConfigBackendDHCPv6::deleteOption6(const ServerSelector& /* server_selector */,
const SubnetID& subnet_id,
const uint16_t code,
const std::string& space) {
+ /// @todo In the future we might use the server selector to make sure that the
+ /// option is only deleted if the pool belongs to a given server. For now, we
+ /// just delete it when there is a match with the parent object.
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_SUBNET_ID_OPTION6)
.arg(subnet_id).arg(code).arg(space);
- uint64_t result = impl_->deleteOption6(server_selector, subnet_id, code, space);
+ uint64_t result = impl_->deleteOption6(ServerSelector::ANY(), subnet_id, code, space);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_SUBNET_ID_OPTION6_RESULT)
.arg(result);
return (result);
}
uint64_t
-MySqlConfigBackendDHCPv6::deleteOption6(const ServerSelector& server_selector,
+MySqlConfigBackendDHCPv6::deleteOption6(const ServerSelector& /* server_selector */,
const asiolink::IOAddress& pool_start_address,
const asiolink::IOAddress& pool_end_address,
const uint16_t code,
const std::string& space) {
+ /// @todo In the future we might use the server selector to make sure that the
+ /// option is only deleted if the pool belongs to a given server. For now, we
+ /// just delete it when there is a match with the parent object.
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_POOL_OPTION6)
.arg(pool_start_address.toText()).arg(pool_end_address.toText()).arg(code).arg(space);
- uint64_t result = impl_->deleteOption6(server_selector, pool_start_address, pool_end_address,
+ uint64_t result = impl_->deleteOption6(ServerSelector::ANY(), pool_start_address, pool_end_address,
code, space);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_POOL_OPTION6_RESULT)
.arg(result);
}
uint64_t
-MySqlConfigBackendDHCPv6::deleteOption6(const ServerSelector& server_selector,
+MySqlConfigBackendDHCPv6::deleteOption6(const ServerSelector& /* server_selector */,
const asiolink::IOAddress& pd_pool_prefix,
const uint8_t pd_pool_prefix_length,
const uint16_t code,
const std::string& space) {
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_POOL_PREFIX_OPTION6)
.arg(pd_pool_prefix.toText()).arg(pd_pool_prefix_length).arg(code).arg(space);
- uint64_t result = impl_->deleteOption6(server_selector, pd_pool_prefix,
+ uint64_t result = impl_->deleteOption6(ServerSelector::ANY(), pd_pool_prefix,
pd_pool_prefix_length, code, space);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_POOL_PREFIX_OPTION6_RESULT)
.arg(result);
return;
}
- auto tag = getServerTag(server_selector, "creating new configuration "
- "audit revision");
+ /// @todo The audit trail is not really well prepared to handle multiple server
+ /// tags or no server tags. Therefore, if the server selector appears to be
+ /// pointing to multiple servers, no servers or any server we simply associate the
+ /// audit revision with all servers. The only case when we create a dedicated
+ /// audit entry is when there is a single server tag, i.e. "all" or explicit
+ /// server name. In fact, these are the most common two cases.
+ std::string tag = ServerTag::ALL;
+ auto tags = server_selector.getTags();
+ if (tags.size() == 1) {
+ tag = tags.begin()->get();
+ }
MySqlBindingCollection in_bindings = {
MySqlBinding::createTimestamp(audit_ts),
// as input to the next query.
uint64_t id = mysql_insert_id(conn_.mysql_);
- MySqlBindingCollection in_server_bindings = {
- MySqlBinding::createInteger<uint64_t>(id), // option_def_id
- MySqlBinding::createString(tag), // tag used to obtain server_id
- MySqlBinding::createTimestamp(option_def->getModificationTime()), // modification_ts
- };
-
- // Insert association.
- conn_.insertQuery(insert_option_def_server, in_server_bindings);
+ // Insert associations of the option definition with servers.
+ attachElementToServers(insert_option_def_server,
+ server_selector,
+ MySqlBinding::createInteger<uint64_t>(id),
+ MySqlBinding::createTimestamp(option_def->getModificationTime()));
}
transaction.commit();
return (desc);
}
+void
+MySqlConfigBackendImpl::attachElementToServers(const int index,
+ const ServerSelector& server_selector,
+ const MySqlBindingPtr& first_binding,
+ const MySqlBindingPtr& in_bindings...) {
+ // Create the vector from the parameter pack.
+ MySqlBindingCollection in_server_bindings = { first_binding, in_bindings };
+ for (auto tag : server_selector.getTags()) {
+ in_server_bindings.push_back(MySqlBinding::createString(tag.get()));
+ conn_.insertQuery(index, in_server_bindings);
+ in_server_bindings.pop_back();
+ }
+}
+
MySqlBindingPtr
MySqlConfigBackendImpl::createInputRelayBinding(const NetworkPtr& network) {
ElementPtr relay_element = Element::createList();
" (unassigned) is unsupported at the moment");
}
- auto tag = getServerTag(server_selector, operation);
-
- in_bindings.insert(in_bindings.begin(), db::MySqlBinding::createString(tag));
+ // For ANY server, we use queries that lack server tag.
+ if (!server_selector.amAny()) {
+ auto tag = getServerTag(server_selector, operation);
+ in_bindings.insert(in_bindings.begin(), db::MySqlBinding::createString(tag));
+ }
return (conn_.updateDeleteQuery(index, in_bindings));
}
processOptionRow(const Option::Universe& universe,
db::MySqlBindingCollection::iterator first_binding);
+ /// @brief Associates a configuration element with multiple servers.
+ ///
+ /// @param index Query index.
+ /// @param server_selector Server selector, perhaps with multiple server tags.
+ /// @param first_binding First binding to be used in the query.
+ /// @param in_bindings Parameter pack holding bindings for the query. Note that
+ /// the server tag (or server id) must be the last binding in the prepared
+ /// statement. The caller must not include this binding in the parameter pack.
+ void attachElementToServers(const int index,
+ const db::ServerSelector& server_selector,
+ const db::MySqlBindingPtr& first_binding,
+ const db::MySqlBindingPtr& in_bindings...);
+
/// @brief Creates input binding for relay addresses.
///
/// @param network Pointer to a shared network or subnet for which binding
#endif
#ifndef MYSQL_GET_SHARED_NETWORK4
-#define MYSQL_GET_SHARED_NETWORK4(...) \
+#define MYSQL_GET_SHARED_NETWORK4_COMMON(...) \
"SELECT" \
" n.id," \
" n.name," \
"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) OR (a.server_id = 1) " \
+ " ON (a.server_id = s.id) " \
"LEFT JOIN dhcp4_options AS o ON o.scope_id = 4 AND n.name = o.shared_network_name " \
- "WHERE (s.tag = ? OR s.id = 1) " #__VA_ARGS__ \
- " ORDER BY n.id, o.option_id"
+ #__VA_ARGS__ \
+ " ORDER BY n.id, s.id, o.option_id"
+
+#define MYSQL_GET_SHARED_NETWORK4_WITH_TAG(...) \
+ MYSQL_GET_SHARED_NETWORK4_COMMON(WHERE (s.tag = ? OR s.id = 1) __VA_ARGS__)
+
+#define MYSQL_GET_SHARED_NETWORK4_NO_TAG(...) \
+ MYSQL_GET_SHARED_NETWORK4_COMMON(__VA_ARGS__)
+
#endif
#ifndef MYSQL_GET_SHARED_NETWORK6
-#define MYSQL_GET_SHARED_NETWORK6(...) \
+#define MYSQL_GET_SHARED_NETWORK6_COMMON(...) \
"SELECT" \
" n.id," \
" n.name," \
"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) OR (a.server_id = 1) " \
+ " ON (a.server_id = s.id) " \
"LEFT JOIN dhcp6_options AS o ON o.scope_id = 4 AND n.name = o.shared_network_name " \
- "WHERE (s.tag = ? OR s.id = 1) " #__VA_ARGS__ \
- " ORDER BY n.id, o.option_id"
+ #__VA_ARGS__ \
+ " ORDER BY n.id, s.id, o.option_id"
+
+#define MYSQL_GET_SHARED_NETWORK6_WITH_TAG(...) \
+ MYSQL_GET_SHARED_NETWORK6_COMMON(WHERE (s.tag = ? OR s.id = 1) __VA_ARGS__)
+
+#define MYSQL_GET_SHARED_NETWORK6_NO_TAG(...) \
+ MYSQL_GET_SHARED_NETWORK6_COMMON(__VA_ARGS__)
+
#endif
#ifndef MYSQL_GET_OPTION_DEF
#define MYSQL_INSERT_GLOBAL_PARAMETER_SERVER(table_prefix) \
"INSERT INTO " #table_prefix "_global_parameter_server(" \
" parameter_id," \
- " server_id," \
- " modification_ts" \
- ") VALUES (?, (SELECT id FROM " #table_prefix "_server WHERE tag = ?), ?)"
+ " modification_ts," \
+ " server_id" \
+ ") VALUES (?, ?, (SELECT id FROM " #table_prefix "_server WHERE tag = ?))"
#endif
#ifndef MYSQL_INSERT_SUBNET_SERVER
#define MYSQL_INSERT_SUBNET_SERVER(table_prefix) \
"INSERT INTO " #table_prefix "_subnet_server(" \
" subnet_id," \
- " server_id," \
- " modification_ts" \
- ") VALUES (?, (SELECT id FROM " #table_prefix "_server WHERE tag = ?), ?)"
+ " modification_ts," \
+ " server_id" \
+ ") VALUES (?, ?, (SELECT id FROM " #table_prefix "_server WHERE tag = ?))"
#endif
#ifndef MYSQL_INSERT_POOL
#define MYSQL_INSERT_SHARED_NETWORK_SERVER(table_prefix) \
"INSERT INTO " #table_prefix "_shared_network_server(" \
" shared_network_id," \
- " server_id," \
- " modification_ts" \
+ " modification_ts," \
+ " server_id" \
") VALUES (" \
- " (SELECT id FROM " #table_prefix "_shared_network WHERE name = ?)," \
- " (SELECT id FROM " #table_prefix "_server WHERE tag = ?), ?" \
+ " (SELECT id FROM " #table_prefix "_shared_network WHERE name = ?), ?," \
+ " (SELECT id FROM " #table_prefix "_server WHERE tag = ?)" \
")"
#endif
#define MYSQL_INSERT_OPTION_DEF_SERVER(table_prefix) \
"INSERT INTO " #table_prefix "_option_def_server(" \
" option_def_id," \
- " server_id," \
- " modification_ts" \
- ") VALUES (?, (SELECT id FROM " #table_prefix "_server WHERE tag = ?), ?)"
+ " modification_ts," \
+ " server_id" \
+ ") VALUES (?, ?, (SELECT id FROM " #table_prefix "_server WHERE tag = ?))"
#endif
#ifndef MYSQL_INSERT_OPTION_COMMON
#define MYSQL_INSERT_OPTION_SERVER(table_prefix) \
"INSERT INTO " #table_prefix "_options_server (" \
" option_id," \
- " server_id," \
- " modification_ts" \
- ") VALUES (?, (SELECT id FROM " #table_prefix "_server WHERE tag = ?), ?)"
+ " modification_ts," \
+ " server_id" \
+ ") VALUES (?, ?, (SELECT id FROM " #table_prefix "_server WHERE tag = ?))"
#endif
#ifndef MYSQL_INSERT_SERVER
"INNER JOIN " #table_prefix "_server AS s" \
" ON a.server_id = s.id " \
"SET" \
+ " o.option_id = LAST_INSERT_ID(o.option_id)," \
" o.code = ?," \
" o.value = ?," \
" o.formatted_value = ?," \
" o.pool_id = ?," \
" o.modification_ts = ? " \
pd_pool_id \
- "WHERE s.tag = ? " #__VA_ARGS__
+ "WHERE " #__VA_ARGS__
-#define MYSQL_UPDATE_OPTION4(...) \
+#define MYSQL_UPDATE_OPTION4_WITH_TAG(...) \
+ MYSQL_UPDATE_OPTION_COMMON(dhcp4, "", s.tag = ? __VA_ARGS__)
+
+#define MYSQL_UPDATE_OPTION4_NO_TAG(...) \
MYSQL_UPDATE_OPTION_COMMON(dhcp4, "", __VA_ARGS__)
-#define MYSQL_UPDATE_OPTION6(...) \
+
+#define MYSQL_UPDATE_OPTION6_WITH_TAG(...) \
+ MYSQL_UPDATE_OPTION_COMMON(dhcp6, ", o.pd_pool_id = ? ", s.tag = ? __VA_ARGS__)
+
+#define MYSQL_UPDATE_OPTION6_NO_TAG(...) \
MYSQL_UPDATE_OPTION_COMMON(dhcp6, ", o.pd_pool_id = ? ", __VA_ARGS__)
#endif
"WHERE s.tag = ? " #__VA_ARGS__
#endif
+#ifndef MYSQL_DELETE_SHARED_NETWORK_SERVER
+#define MYSQL_DELETE_SHARED_NETWORK_SERVER(table_prefix) \
+ "DELETE FROM " #table_prefix "_shared_network_server " \
+ "WHERE shared_network_id = " \
+ "(SELECT id FROM " #table_prefix "_shared_network WHERE name = ?)"
+#endif
+
#ifndef MYSQL_DELETE_OPTION_DEF
#define MYSQL_DELETE_OPTION_DEF(table_prefix, ...) \
"DELETE d FROM " #table_prefix "_option_def AS d " \
#endif
#ifndef MYSQL_DELETE_OPTION
-#define MYSQL_DELETE_OPTION(table_prefix, ...) \
+#define MYSQL_DELETE_OPTION_COMMON(table_prefix, ...) \
"DELETE o FROM " #table_prefix "_options AS o " \
"INNER JOIN " #table_prefix "_options_server AS a" \
" ON o.option_id = a.option_id " \
"INNER JOIN " #table_prefix "_server AS s" \
" ON a.server_id = s.id " \
- "WHERE s.tag = ? " #__VA_ARGS__
+ #__VA_ARGS__
+
+#define MYSQL_DELETE_OPTION_WITH_TAG(table_prefix, ...) \
+ MYSQL_DELETE_OPTION_COMMON(table_prefix, WHERE s.tag = ? __VA_ARGS__)
+
+#define MYSQL_DELETE_OPTION_NO_TAG(table_prefix, ...) \
+ MYSQL_DELETE_OPTION_COMMON(table_prefix, __VA_ARGS__)
#endif
#ifndef MYSQL_DELETE_OPTION_UNASSIGNED
" ON o.option_id = a.option_id " \
"INNER JOIN " #table_prefix "_server AS s" \
" ON a.server_id = s.id " \
- "WHERE s.tag = ? " #__VA_ARGS__ \
+ "WHERE " #__VA_ARGS__ \
" AND o.pool_id = " \
" (SELECT id FROM " #table_prefix "_pool" \
" WHERE start_address = ? AND end_address = ?)"
" ON o.option_id = a.option_id " \
"INNER JOIN dhcp6_server AS s" \
" ON a.server_id = s.id " \
- "WHERE s.tag = ? " #__VA_ARGS__ \
+ "WHERE " #__VA_ARGS__ \
" AND o.pd_pool_id = " \
" (SELECT id FROM dhcp6_pd_pool" \
" WHERE prefix = ? AND prefix_length = ?)"
#endif
+#ifndef MYSQL_DELETE_OPTION_SERVER
+#define MYSQL_DELETE_OPTION_SERVER(table_prefix) \
+ "DELETE os FROM " #table_prefix "_options_server AS os " \
+ "WHERE os.option_id = " \
+ " (SELECT o.option_id FROM " #table_prefix "_options AS o" \
+ " INNER JOIN " #table_prefix "_options_server AS a" \
+ " ON o.option_id = a.option_id " \
+ " INNER JOIN " #table_prefix "_server AS s" \
+ " ON a.server_id = s.id " \
+ " WHERE s.tag = ? AND o.scope_id = ? AND o.code = ? AND o.space = ?)"
+#endif
+
#ifndef MYSQL_DELETE_SERVER
#define MYSQL_DELETE_SERVER(table_prefix) \
"DELETE FROM " #table_prefix "_server " \
// Test that shared network can be inserted, fetched, updated and then
// fetched again.
TEST_F(MySqlConfigBackendDHCPv4Test, getSharedNetwork4) {
- // Insert new shared network.
- SharedNetwork4Ptr shared_network = test_networks_[0];
- cbptr_->createUpdateSharedNetwork4(ServerSelector::ALL(), shared_network);
+ // Insert the server2 into the database.
+ EXPECT_NO_THROW(cbptr_->createUpdateServer4(test_servers_[2]));
+ {
+ SCOPED_TRACE("CREATE audit entry for server");
+ testNewAuditEntry("dhcp4_server",
+ AuditEntry::ModificationType::CREATE,
+ "server set");
+ }
- // Fetch this shared network by name.
- SharedNetwork4Ptr
- returned_network = cbptr_->getSharedNetwork4(ServerSelector::ALL(),
- test_networks_[0]->getName());
- ASSERT_TRUE(returned_network);
+ auto shared_network = test_networks_[0];
+ auto shared_network2 = test_networks_[2];
- EXPECT_GT(returned_network->getId(), 0);
- ASSERT_EQ(1, returned_network->getServerTags().size());
- EXPECT_EQ("all", returned_network->getServerTags()[0].get());
+ // Insert two shared networks, one for all servers, and one for server2.
+ EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork4(ServerSelector::ALL(),
+ shared_network));
+ EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork4(ServerSelector::ONE("server2"),
+ shared_network2));
- // The easiest way to verify whether the returned shared network matches the
- // inserted shared network is to convert both to text.
- EXPECT_EQ(shared_network->toElement()->str(),
- returned_network->toElement()->str());
+ // We are not going to support selection of a single entry for multiple servers.
+ 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,
+ const ServerSelector& server_selector,
+ const std::string& expected_tag = ServerTag::ALL) {
+ SCOPED_TRACE(test_case_name);
+ SharedNetwork4Ptr network;
+ ASSERT_NO_THROW(network = cbptr_->getSharedNetwork4(server_selector,
+ shared_network->getName()));
+ ASSERT_TRUE(network);
+
+ EXPECT_GT(network->getId(), 0);
+ ASSERT_EQ(1, network->getServerTags().size());
+ EXPECT_EQ(expected_tag, network->getServerTags()[0].get());
+
+ // The easiest way to verify whether the returned shared network matches the
+ // inserted shared network is to convert both to text.
+ EXPECT_EQ(shared_network->toElement()->str(), network->toElement()->str());
+ };
+
+ {
+ SCOPED_TRACE("testing various server selectors before update");
+ test_get_network("all servers", ServerSelector::ALL());
+ test_get_network("one server", ServerSelector::ONE("server1"));
+ test_get_network("any server", ServerSelector::ANY());
+ }
{
SCOPED_TRACE("CREATE audit entry for a shared network");
}
// Update shared network in the database.
- SharedNetwork4Ptr shared_network2 = test_networks_[1];
- cbptr_->createUpdateSharedNetwork4(ServerSelector::ALL(), shared_network2);
+ shared_network = test_networks_[1];
+ EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork4(ServerSelector::ALL(),
+ shared_network));
- // Fetch updated shared network and see if it matches.
- returned_network = cbptr_->getSharedNetwork4(ServerSelector::ALL(),
- test_networks_[1]->getName());
- EXPECT_EQ(shared_network2->toElement()->str(),
- returned_network->toElement()->str());
+ {
+ SCOPED_TRACE("testing various server selectors after update");
+ test_get_network("all servers after update", ServerSelector::ALL());
+ test_get_network("one server after update", ServerSelector::ONE("server1"));
+ test_get_network("any server after update", ServerSelector::ANY());
+ }
{
SCOPED_TRACE("UPDATE audit entry for a shared network");
"shared network set");
}
- // Fetching the shared network for an explicitly specified server tag should
- // succeed too.
- returned_network = cbptr_->getSharedNetwork4(ServerSelector::ONE("server1"),
- shared_network2->getName());
- EXPECT_EQ(shared_network2->toElement()->str(),
- returned_network->toElement()->str());
+ // The server2 specific shared network should not be returned if the
+ // server selector is not matching.
+ EXPECT_FALSE(cbptr_->getSharedNetwork4(ServerSelector::ALL(),
+ shared_network2->getName()));
+ EXPECT_FALSE(cbptr_->getSharedNetwork4(ServerSelector::ONE("server1"),
+ shared_network2->getName()));
+
+ {
+ SCOPED_TRACE("testing selectors for server2 specific shared network");
+ shared_network = shared_network2;
+ test_get_network("one server", ServerSelector::ONE("server2"), "server2");
+ test_get_network("any server", ServerSelector::ANY(), "server2");
+ }
+}
+
+// Test that shared network may be created and updated and the server tags
+// are properly assigned to it.
+TEST_F(MySqlConfigBackendDHCPv4Test, createUpdateSharedNetwork4) {
+ // Insert the server1 into 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");
+ }
+
+ // Insert the server2 into the database.
+ 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_network = test_networks_[0];
+
+ EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork4(ServerSelector::ALL(),
+ shared_network));
+ {
+ SCOPED_TRACE("CREATE audit entry for shared network and ALL servers");
+ testNewAuditEntry("dhcp4_shared_network",
+ AuditEntry::ModificationType::CREATE,
+ "shared network set");
+ }
+
+ EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork4(ServerSelector::MULTIPLE({ "server1", "server2" }),
+ shared_network));
+ {
+ SCOPED_TRACE("CREATE audit entry for shared network and MULTIPLE servers");
+ testNewAuditEntry("dhcp4_shared_network",
+ AuditEntry::ModificationType::UPDATE,
+ "shared network set");
+ }
+
+ SharedNetwork4Ptr network;
+ ASSERT_NO_THROW(network = cbptr_->getSharedNetwork4(ServerSelector::ANY(),
+ shared_network->getName()));
+ ASSERT_TRUE(network);
+ EXPECT_TRUE(network->hasServerTag(ServerTag("server1")));
+ EXPECT_TRUE(network->hasServerTag(ServerTag("server2")));
+ EXPECT_FALSE(network->hasServerTag(ServerTag()));
}
// Test that the information about unspecified optional parameters gets
for (auto i = 0; i < networks.size(); ++i) {
EXPECT_EQ(test_networks_[i + 1]->toElement()->str(),
networks[i]->toElement()->str());
+ ASSERT_EQ(1, networks[i]->getServerTags().size());
+ EXPECT_EQ("all", networks[i]->getServerTags()[0].get());
}
// Add some subnets.
"subnet specific option set");
}
- // Deleting an option with explicitly specified server tag should fail.
- EXPECT_EQ(0, cbptr_->deleteOption4(ServerSelector::ONE("server1"),
- subnet->getID(),
- opt_boot_file_name->option_->getType(),
- opt_boot_file_name->space_name_));
-
- // It should succeed for all servers.
- EXPECT_EQ(1, cbptr_->deleteOption4(ServerSelector::ALL(), subnet->getID(),
+ // It should succeed for any server.
+ EXPECT_EQ(1, cbptr_->deleteOption4(ServerSelector::ANY(), subnet->getID(),
opt_boot_file_name->option_->getType(),
opt_boot_file_name->space_name_));
"pool specific option set");
}
- // Deleting an option with explicitly specified server tag should fail.
- EXPECT_EQ(0, cbptr_->deleteOption4(ServerSelector::ONE("server1"),
- pool->getFirstAddress(),
- pool->getLastAddress(),
- opt_boot_file_name->option_->getType(),
- opt_boot_file_name->space_name_));
-
- // Delete option for all servers should succeed.
- EXPECT_EQ(1, cbptr_->deleteOption4(ServerSelector::ALL(),
+ // Delete option for any server should succeed.
+ EXPECT_EQ(1, cbptr_->deleteOption4(ServerSelector::ANY(),
pool->getFirstAddress(),
pool->getLastAddress(),
opt_boot_file_name->option_->getType(),
"shared network specific option set");
}
- // Deleting an option with explicitly specified server tag should fail.
- EXPECT_EQ(0, cbptr_->deleteOption4(ServerSelector::ONE("server1"),
- shared_network->getName(),
- opt_boot_file_name->option_->getType(),
- opt_boot_file_name->space_name_));
-
- // Deleting an option for all servers should succeed.
- EXPECT_EQ(1, cbptr_->deleteOption4(ServerSelector::ALL(),
+ // Deleting an option for any server should succeed.
+ EXPECT_EQ(1, cbptr_->deleteOption4(ServerSelector::ANY(),
shared_network->getName(),
opt_boot_file_name->option_->getType(),
opt_boot_file_name->space_name_));
// Test that shared network can be inserted, fetched, updated and then
// fetched again.
TEST_F(MySqlConfigBackendDHCPv6Test, getSharedNetwork6) {
- // Insert new shared network.
- SharedNetwork6Ptr shared_network = test_networks_[0];
- cbptr_->createUpdateSharedNetwork6(ServerSelector::ALL(), shared_network);
+ // Insert the server2 into the database.
+ EXPECT_NO_THROW(cbptr_->createUpdateServer6(test_servers_[2]));
+ {
+ SCOPED_TRACE("CREATE audit entry for server");
+ testNewAuditEntry("dhcp6_server",
+ AuditEntry::ModificationType::CREATE,
+ "server set");
+ }
- // Fetch this shared network by name.
- SharedNetwork6Ptr
- returned_network = cbptr_->getSharedNetwork6(ServerSelector::ALL(),
- test_networks_[0]->getName());
- ASSERT_TRUE(returned_network);
+ auto shared_network = test_networks_[0];
+ auto shared_network2 = test_networks_[2];
- EXPECT_GT(returned_network->getId(), 0);
- ASSERT_EQ(1, returned_network->getServerTags().size());
- EXPECT_EQ("all", returned_network->getServerTags()[0].get());
+ // Insert two shared networks, one for all servers, and one for server2.
+ EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork6(ServerSelector::ALL(),
+ shared_network));
+ EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork6(ServerSelector::ONE("server2"),
+ shared_network2));
- // The easiest way to verify whether the returned shared network matches the
- // inserted shared network is to convert both to text.
- EXPECT_EQ(shared_network->toElement()->str(),
- returned_network->toElement()->str());
+ // We are not going to support selection of a single entry for multiple servers.
+ 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,
+ const ServerSelector& server_selector,
+ const std::string& expected_tag = ServerTag::ALL) {
+ SCOPED_TRACE(test_case_name);
+ SharedNetwork6Ptr network;
+ ASSERT_NO_THROW(network = cbptr_->getSharedNetwork6(server_selector,
+ shared_network->getName()));
+ ASSERT_TRUE(network);
+
+ EXPECT_GT(network->getId(), 0);
+ ASSERT_EQ(1, network->getServerTags().size());
+ EXPECT_EQ(expected_tag, network->getServerTags()[0].get());
+
+ // The easiest way to verify whether the returned shared network matches the
+ // inserted shared network is to convert both to text.
+ EXPECT_EQ(shared_network->toElement()->str(), network->toElement()->str());
+ };
+
+ {
+ SCOPED_TRACE("testing various server selectors before update");
+ test_get_network("all servers", ServerSelector::ALL());
+ test_get_network("one server", ServerSelector::ONE("server1"));
+ test_get_network("any server", ServerSelector::ANY());
+ }
{
SCOPED_TRACE("CREATE audit entry for a shared network");
}
// Update shared network in the database.
- SharedNetwork6Ptr shared_network2 = test_networks_[1];
- cbptr_->createUpdateSharedNetwork6(ServerSelector::ALL(), shared_network2);
+ shared_network = test_networks_[1];
+ EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork6(ServerSelector::ALL(),
+ shared_network));
- // Fetch updated shared network and see if it matches.
- returned_network = cbptr_->getSharedNetwork6(ServerSelector::ALL(),
- test_networks_[1]->getName());
- EXPECT_EQ(shared_network2->toElement()->str(),
- returned_network->toElement()->str());
+ {
+ SCOPED_TRACE("testing various server selectors after update");
+ test_get_network("all servers after update", ServerSelector::ALL());
+ test_get_network("one server after update", ServerSelector::ONE("server1"));
+ test_get_network("any server after update", ServerSelector::ANY());
+ }
{
SCOPED_TRACE("UPDATE audit entry for a shared network");
"shared network set");
}
- // Fetching the shared network for an explicitly specified server tag should
- // succeed too.
- returned_network = cbptr_->getSharedNetwork6(ServerSelector::ONE("server1"),
- shared_network2->getName());
- EXPECT_EQ(shared_network2->toElement()->str(),
- returned_network->toElement()->str());
+ // The server2 specific shared network should not be returned if the
+ // server selector is not matching.
+ EXPECT_FALSE(cbptr_->getSharedNetwork6(ServerSelector::ALL(),
+ shared_network2->getName()));
+ EXPECT_FALSE(cbptr_->getSharedNetwork6(ServerSelector::ONE("server1"),
+ shared_network2->getName()));
+
+ {
+ SCOPED_TRACE("testing selectors for server2 specific shared network");
+ shared_network = shared_network2;
+ test_get_network("one server", ServerSelector::ONE("server2"), "server2");
+ test_get_network("any server", ServerSelector::ANY(), "server2");
+ }
+}
+
+// Test that shared network may be created and updated and the server tags
+// are properly assigned to it.
+TEST_F(MySqlConfigBackendDHCPv6Test, createUpdateSharedNetwork6) {
+ // Insert the server1 into 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");
+ }
+
+ // Insert the server2 into the database.
+ 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_network = test_networks_[0];
+
+ EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork6(ServerSelector::ALL(),
+ shared_network));
+ {
+ SCOPED_TRACE("CREATE audit entry for shared network and ALL servers");
+ testNewAuditEntry("dhcp6_shared_network",
+ AuditEntry::ModificationType::CREATE,
+ "shared network set");
+ }
+
+ EXPECT_NO_THROW(cbptr_->createUpdateSharedNetwork6(ServerSelector::MULTIPLE({ "server1", "server2" }),
+ shared_network));
+ {
+ SCOPED_TRACE("UPDATE audit entry for shared network and MULTIPLE servers");
+ testNewAuditEntry("dhcp6_shared_network",
+ AuditEntry::ModificationType::UPDATE,
+ "shared network set");
+ }
+
+ SharedNetwork6Ptr network;
+ ASSERT_NO_THROW(network = cbptr_->getSharedNetwork6(ServerSelector::ANY(),
+ shared_network->getName()));
+ ASSERT_TRUE(network);
+ EXPECT_TRUE(network->hasServerTag(ServerTag("server1")));
+ EXPECT_TRUE(network->hasServerTag(ServerTag("server2")));
+ EXPECT_FALSE(network->hasServerTag(ServerTag()));
}
// Test that the information about unspecified optional parameters gets
"subnet specific option set");
}
- // Deleting an option with explicitly specified server tag should fail.
- EXPECT_EQ(0, cbptr_->deleteOption6(ServerSelector::ONE("server1"),
- subnet->getID(),
- opt_posix_timezone->option_->getType(),
- opt_posix_timezone->space_name_));
-
- // It should succeed for all servers.
- EXPECT_EQ(1, cbptr_->deleteOption6(ServerSelector::ALL(), subnet->getID(),
+ // It should succeed for any server.
+ EXPECT_EQ(1, cbptr_->deleteOption6(ServerSelector::ANY(), subnet->getID(),
opt_posix_timezone->option_->getType(),
opt_posix_timezone->space_name_));
"address pool specific option set");
}
- // Deleting an option with explicitly specified server tag should fail.
- EXPECT_EQ(0, cbptr_->deleteOption6(ServerSelector::ONE("server1"),
- pool->getFirstAddress(),
- pool->getLastAddress(),
- opt_posix_timezone->option_->getType(),
- opt_posix_timezone->space_name_));
-
- // Delete option for all servers should succeed.
- EXPECT_EQ(1, cbptr_->deleteOption6(ServerSelector::ALL(),
+ // Delete option for any server should succeed.
+ EXPECT_EQ(1, cbptr_->deleteOption6(ServerSelector::ANY(),
pool->getFirstAddress(),
pool->getLastAddress(),
opt_posix_timezone->option_->getType(),
"prefix delegation pool specific option set");
}
- // Deleting an option with explicitly specified server tag should fail.
- EXPECT_EQ(0, cbptr_->deleteOption6(ServerSelector::ONE("server1"),
- pd_pool->getFirstAddress(),
- static_cast<uint8_t>(pd_pool_len),
- opt_posix_timezone->option_->getType(),
- opt_posix_timezone->space_name_));
-
- // Delete option for all servers should succeed.
- EXPECT_EQ(1, cbptr_->deleteOption6(ServerSelector::ALL(),
+ // Delete option for any server should succeed.
+ EXPECT_EQ(1, cbptr_->deleteOption6(ServerSelector::ANY(),
pd_pool->getFirstAddress(),
static_cast<uint8_t>(pd_pool_len),
opt_posix_timezone->option_->getType(),
"shared network specific option set");
}
- // Deleting an option with explicitly specified server tag should fail.
- EXPECT_EQ(0, cbptr_->deleteOption6(ServerSelector::ONE("server1"),
- shared_network->getName(),
- opt_posix_timezone->option_->getType(),
- opt_posix_timezone->space_name_));
-
- // Deleting an option for all servers should succeed.
- EXPECT_EQ(1, cbptr_->deleteOption6(ServerSelector::ALL(),
+ // Deleting an option for any server should succeed.
+ EXPECT_EQ(1, cbptr_->deleteOption6(ServerSelector::ANY(),
shared_network->getName(),
opt_posix_timezone->option_->getType(),
opt_posix_timezone->space_name_));
enum class Type {
UNASSIGNED,
ALL,
- SUBSET
+ SUBSET,
+ ANY
};
/// @brief Factory returning "unassigned" server selector.
/// @throw InvalidOperation if no server tags provided.
static ServerSelector MULTIPLE(const std::set<std::string>& server_tags);
+ /// @brief Factory returning "any server" selector.
+ static ServerSelector ANY() {
+ ServerSelector selector(Type::ANY);
+ return (selector);
+ }
+
/// @brief Returns type of the selector.
Type getType() const {
return (type_);
return (getType() == Type::UNASSIGNED);
}
+ /// @brief Convenience method checking if the server selector is "any".
+ ///
+ /// @return true if the selector is "any", false otherwise.
+ bool amAny() const {
+ return (getType() == Type::ANY);
+ }
+
/// @brief Convenience method checking if the server selector has multiple tags.
///
/// @return true if it has multiple tags, false otherwise.
EXPECT_TRUE(selector.hasMultipleTags());
}
+// Check that server selector can be set to ALL.
+TEST(ServerSelectorTest, any) {
+ ServerSelector selector = ServerSelector::ANY();
+ EXPECT_EQ(ServerSelector::Type::ANY, selector.getType());
+ EXPECT_FALSE(selector.amUnassigned());
+
+ auto tags = selector.getTags();
+ EXPECT_EQ(0, tags.size());
+}
+
}