From: Francis Dupont Date: Sat, 13 Apr 2019 16:11:59 +0000 (+0200) Subject: [397-cb-implement-mysqlconfigbackenddhcpv6] Shared body of createUpdateOptionDef[46] X-Git-Tag: Kea-1.6.0-beta~242 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d56ea6f1d0688931857ec02ab45d1e78ced3136b;p=thirdparty%2Fkea.git [397-cb-implement-mysqlconfigbackenddhcpv6] Shared body of createUpdateOptionDef[46] --- diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc index bd3e2c5cb4..d16da2b1ea 100644 --- a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc @@ -1664,87 +1664,13 @@ public: void createUpdateOptionDef4(const ServerSelector& server_selector, const OptionDefinitionPtr& option_def) { - if (server_selector.amUnassigned()) { - isc_throw(NotImplemented, "managing configuration for no particular server" - " (unassigned) is unsupported at the moment"); - } - - auto tag = getServerTag(server_selector, "creating or updating option definition"); - - ElementPtr record_types = Element::createList(); - for (auto field : option_def->getRecordFields()) { - record_types->add(Element::create(static_cast(field))); - } - MySqlBindingPtr record_types_binding = record_types->empty() ? - MySqlBinding::createNull() : MySqlBinding::createString(record_types->str()); - - MySqlBindingCollection in_bindings = { - MySqlBinding::createInteger(static_cast(option_def->getCode())), - MySqlBinding::createString(option_def->getName()), - MySqlBinding::createString(option_def->getOptionSpaceName().empty() ? - "dhcp4" : option_def->getOptionSpaceName()), - MySqlBinding::createInteger(static_cast(option_def->getType())), - MySqlBinding::createTimestamp(option_def->getModificationTime()), - MySqlBinding::createBool(option_def->getArrayType()), - MySqlBinding::createString(option_def->getEncapsulatedSpace()), - record_types_binding, - createInputContextBinding(option_def) - }; - - MySqlTransaction transaction(conn_); - - // Need to check if this definition already exists. We can't follow - // the same pattern as for shared networks and subnets, to try to insert - // the definition first and fall back to update if the DuplicateEntry - // exception is thrown, because the option code/space is not unique - // within the dhcp4_option_def table. Inserting another option definition - // with existing option code/name would not violate the key and the - // option definition instance would be inserted successfully. Therefore, - // we first fetch the option definition for the given server, code and - // space name. If it exists, we simply update it. - OptionDefinitionPtr existing_definition = - getOptionDef(GET_OPTION_DEF4_CODE_SPACE, - server_selector, - option_def->getCode(), - option_def->getOptionSpaceName()); - - // Create scoped audit revision. As long as this instance exists - // no new audit revisions are created in any subsequent calls. - ScopedAuditRevision - audit_revision(this, - MySqlConfigBackendDHCPv4Impl::CREATE_AUDIT_REVISION, - server_selector, "option definition set", - true); - - if (existing_definition) { - // Need to add three more bindings for WHERE clause. - in_bindings.push_back(MySqlBinding::createString(tag)); - in_bindings.push_back(MySqlBinding::createInteger(existing_definition->getCode())); - in_bindings.push_back(MySqlBinding::createString(existing_definition->getOptionSpaceName())); - conn_.updateDeleteQuery(MySqlConfigBackendDHCPv4Impl::UPDATE_OPTION_DEF4, - in_bindings); - - } else { - // If the option definition doesn't exist, let's insert it. - conn_.insertQuery(MySqlConfigBackendDHCPv4Impl::INSERT_OPTION_DEF4, - in_bindings); - - // Fetch unique identifier of the inserted option definition and use it - // as input to the next query. - uint64_t id = mysql_insert_id(conn_.mysql_); - - MySqlBindingCollection in_server_bindings = { - MySqlBinding::createInteger(id), // option_def_id - MySqlBinding::createString(tag), // tag used to obtain server_id - MySqlBinding::createTimestamp(option_def->getModificationTime()), // modification_ts - }; - - // Insert association. - conn_.insertQuery(MySqlConfigBackendDHCPv4Impl::INSERT_OPTION_DEF4_SERVER, - in_server_bindings); - } - - transaction.commit(); + createUpdateOptionDef + (server_selector, option_def, "dhcp4", + MySqlConfigBackendDHCPv4Impl::GET_OPTION_DEF4_CODE_SPACE, + MySqlConfigBackendDHCPv4Impl::INSERT_OPTION_DEF4, + MySqlConfigBackendDHCPv4Impl::UPDATE_OPTION_DEF4, + MySqlConfigBackendDHCPv4Impl::CREATE_AUDIT_REVISION, + MySqlConfigBackendDHCPv4Impl::INSERT_OPTION_DEF4_SERVER); } /// @brief Sends query to delete option definition by code and diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp6.cc b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp6.cc index 9ccbc91d02..63ca0bd0ab 100644 --- a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp6.cc +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp6.cc @@ -1206,7 +1206,7 @@ public: last_network_id = out_bindings[0]->getInteger(); last_network.reset(new SharedNetwork6(out_bindings[1]->getString())); - last_network->setId(last_network_id); + last_network->setId(last_network_id); // client_class if (!out_bindings[2]->amNull()) { @@ -1889,87 +1889,13 @@ public: void createUpdateOptionDef6(const ServerSelector& server_selector, const OptionDefinitionPtr& option_def) { - if (server_selector.amUnassigned()) { - isc_throw(NotImplemented, "managing configuration for no particular server" - " (unassigned) is unsupported at the moment"); - } - - auto tag = getServerTag(server_selector, "creating or updating option definition"); - - ElementPtr record_types = Element::createList(); - for (auto field : option_def->getRecordFields()) { - record_types->add(Element::create(static_cast(field))); - } - MySqlBindingPtr record_types_binding = record_types->empty() ? - MySqlBinding::createNull() : MySqlBinding::createString(record_types->str()); - - MySqlBindingCollection in_bindings = { - MySqlBinding::createInteger(option_def->getCode()), - MySqlBinding::createString(option_def->getName()), - MySqlBinding::createString(option_def->getOptionSpaceName().empty() ? - "dhcp6" : option_def->getOptionSpaceName()), - MySqlBinding::createInteger(static_cast(option_def->getType())), - MySqlBinding::createTimestamp(option_def->getModificationTime()), - MySqlBinding::createBool(option_def->getArrayType()), - MySqlBinding::createString(option_def->getEncapsulatedSpace()), - record_types_binding, - createInputContextBinding(option_def) - }; - - MySqlTransaction transaction(conn_); - - // Need to check if this definition already exists. We can't follow - // the same pattern as for shared networks and subnets, to try to insert - // the definition first and fall back to update if the DuplicateEntry - // exception is thrown, because the option code/space is not unique - // within the dhcp6_option_def table. Inserting another option definition - // with existing option code/name would not violate the key and the - // option definition instance would be inserted successfully. Therefore, - // we first fetch the option definition for the given server, code and - // space name. If it exists, we simply update it. - OptionDefinitionPtr existing_definition = - getOptionDef(GET_OPTION_DEF6_CODE_SPACE, - server_selector, - option_def->getCode(), - option_def->getOptionSpaceName()); - - // Create scoped audit revision. As long as this instance exists - // no new audit revisions are created in any subsequent calls. - ScopedAuditRevision - audit_revision(this, - MySqlConfigBackendDHCPv6Impl::CREATE_AUDIT_REVISION, - server_selector, "option definition set", - true); - - if (existing_definition) { - // Need to add three more bindings for WHERE clause. - in_bindings.push_back(MySqlBinding::createString(tag)); - in_bindings.push_back(MySqlBinding::createInteger(existing_definition->getCode())); - in_bindings.push_back(MySqlBinding::createString(existing_definition->getOptionSpaceName())); - conn_.updateDeleteQuery(MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION_DEF6, - in_bindings); - - } else { - // If the option definition doesn't exist, let's insert it. - conn_.insertQuery(MySqlConfigBackendDHCPv6Impl::INSERT_OPTION_DEF6, - in_bindings); - - // Fetch unique identifier of the inserted option definition and use it - // as input to the next query. - uint64_t id = mysql_insert_id(conn_.mysql_); - - MySqlBindingCollection in_server_bindings = { - MySqlBinding::createInteger(id), // option_def_id - MySqlBinding::createString(tag), // tag used to obtain server_id - MySqlBinding::createTimestamp(option_def->getModificationTime()), // modification_ts - }; - - // Insert association. - conn_.insertQuery(MySqlConfigBackendDHCPv6Impl::INSERT_OPTION_DEF6_SERVER, - in_server_bindings); - } - - transaction.commit(); + createUpdateOptionDef + (server_selector, option_def, "dhcp6", + MySqlConfigBackendDHCPv6Impl::GET_OPTION_DEF6_CODE_SPACE, + MySqlConfigBackendDHCPv6Impl::INSERT_OPTION_DEF6, + MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION_DEF6, + MySqlConfigBackendDHCPv6Impl::CREATE_AUDIT_REVISION, + MySqlConfigBackendDHCPv6Impl::INSERT_OPTION_DEF6_SERVER); } /// @brief Sends query to delete option definition by code and diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_impl.cc b/src/hooks/dhcp/mysql_cb/mysql_cb_impl.cc index 7ed30a279c..f5fa19d3ed 100644 --- a/src/hooks/dhcp/mysql_cb/mysql_cb_impl.cc +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_impl.cc @@ -365,6 +365,97 @@ MySqlConfigBackendImpl::getOptionDefs(const int index, }); } +void MySqlConfigBackendImpl::createUpdateOptionDef + (const db::ServerSelector& server_selector, + const OptionDefinitionPtr& option_def, + const std::string& space, + const int& get_option_def_code_space, + const int& insert_option_def, + const int& update_option_def, + const int& create_audit_revision, + const int& insert_option_def_server) +{ + + if (server_selector.amUnassigned()) { + isc_throw(NotImplemented, "managing configuration for no particular server" + " (unassigned) is unsupported at the moment"); + } + + auto tag = getServerTag(server_selector, "creating or updating option definition"); + + ElementPtr record_types = Element::createList(); + for (auto field : option_def->getRecordFields()) { + record_types->add(Element::create(static_cast(field))); + } + MySqlBindingPtr record_types_binding = record_types->empty() ? + MySqlBinding::createNull() : MySqlBinding::createString(record_types->str()); + + MySqlBindingCollection in_bindings = { + MySqlBinding::createInteger(option_def->getCode()), + MySqlBinding::createString(option_def->getName()), + MySqlBinding::createString(option_def->getOptionSpaceName().empty() ? + space : option_def->getOptionSpaceName()), + MySqlBinding::createInteger(static_cast(option_def->getType())), + MySqlBinding::createTimestamp(option_def->getModificationTime()), + MySqlBinding::createBool(option_def->getArrayType()), + MySqlBinding::createString(option_def->getEncapsulatedSpace()), + record_types_binding, + createInputContextBinding(option_def) + }; + + MySqlTransaction transaction(conn_); + + // Need to check if this definition already exists. We can't follow + // the same pattern as for shared networks and subnets, to try to insert + // the definition first and fall back to update if the DuplicateEntry + // exception is thrown, because the option code/space is not unique + // within the dhcpX_option_def table. Inserting another option definition + // with existing option code/name would not violate the key and the + // option definition instance would be inserted successfully. Therefore, + // we first fetch the option definition for the given server, code and + // space name. If it exists, we simply update it. + OptionDefinitionPtr existing_definition = + getOptionDef(get_option_def_code_space, + server_selector, + option_def->getCode(), + option_def->getOptionSpaceName()); + + // Create scoped audit revision. As long as this instance exists + // no new audit revisions are created in any subsequent calls. + ScopedAuditRevision audit_revision(this, + create_audit_revision, + server_selector, + "option definition set", + true); + + if (existing_definition) { + // Need to add three more bindings for WHERE clause. + in_bindings.push_back(MySqlBinding::createString(tag)); + in_bindings.push_back(MySqlBinding::createInteger(existing_definition->getCode())); + in_bindings.push_back(MySqlBinding::createString(existing_definition->getOptionSpaceName())); + conn_.updateDeleteQuery(update_option_def, in_bindings); + + } else { + // If the option definition doesn't exist, let's insert it. + conn_.insertQuery(insert_option_def, in_bindings); + + // Fetch unique identifier of the inserted option definition and use it + // as input to the next query. + uint64_t id = mysql_insert_id(conn_.mysql_); + + MySqlBindingCollection in_server_bindings = { + MySqlBinding::createInteger(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); + } + + transaction.commit(); +} + OptionDescriptorPtr MySqlConfigBackendImpl::getOption(const int index, const Option::Universe& universe, diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_impl.h b/src/hooks/dhcp/mysql_cb/mysql_cb_impl.h index 96fc3d05ae..ebeccec458 100644 --- a/src/hooks/dhcp/mysql_cb/mysql_cb_impl.h +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_impl.h @@ -366,6 +366,28 @@ public: const db::MySqlBindingCollection& in_bindings, OptionDefContainer& option_defs); + /// @brief Creates or updates an option definition. + /// + /// @param server_selector Server selector. + /// @param option_def Option definition to be added or updated. + /// @param space Default option space + /// @param get_option_def_code_space Statement getting option + /// definition by code and space. + /// @param insert_option_def Statement inserting option definition. + /// @param update_option_def Statement updating option definition. + /// @param create_audit_revision Statement creating audit revision. + /// @param insert_option_def_server Statement inserting option + /// definition in the server table. + /// @throw NotImplemented if server selector is "unassigned". + void createUpdateOptionDef(const db::ServerSelector& server_selector, + const OptionDefinitionPtr& option_def, + const std::string& space, + const int& get_option_def_code_space, + const int& insert_option_def, + const int& update_option_def, + const int& create_audit_revision, + const int& insert_option_def_server); + /// @brief Sends query to retrieve single global option by code and /// option space. ///