From: Marcin Siodelski Date: Fri, 14 Sep 2018 07:37:47 +0000 (+0200) Subject: [#93] Added mysql_cb hooks library. X-Git-Tag: 5-netconf-extend-syntax_base~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9994f64b54e568eb8c249505458a4db0721eb009;p=thirdparty%2Fkea.git [#93] Added mysql_cb hooks library. --- diff --git a/src/hooks/dhcp/Makefile.am b/src/hooks/dhcp/Makefile.am index d8e33e26c8..0bb9b878e3 100644 --- a/src/hooks/dhcp/Makefile.am +++ b/src/hooks/dhcp/Makefile.am @@ -1 +1,7 @@ -SUBDIRS = high_availability lease_cmds stat_cmds user_chk +SUBDIRS = high_availability lease_cmds + +if HAVE_MYSQL +SUBDIRS += mysql_cb +endif + +SUBDIRS += stat_cmds user_chk diff --git a/src/hooks/dhcp/mysql_cb/.gitignore b/src/hooks/dhcp/mysql_cb/.gitignore new file mode 100644 index 0000000000..2b15432f05 --- /dev/null +++ b/src/hooks/dhcp/mysql_cb/.gitignore @@ -0,0 +1,3 @@ +/mysql_cb_messages.cc +/mysql_cb_messages.h +/s-messages diff --git a/src/hooks/dhcp/mysql_cb/Makefile.am b/src/hooks/dhcp/mysql_cb/Makefile.am new file mode 100644 index 0000000000..ae7aef442f --- /dev/null +++ b/src/hooks/dhcp/mysql_cb/Makefile.am @@ -0,0 +1,61 @@ +SUBDIRS = . tests + +AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib +AM_CPPFLAGS += $(BOOST_INCLUDES) $(MYSQL_CPPFLAGS) +AM_CXXFLAGS = $(KEA_CXXFLAGS) + +# Define rule to build logging source files from message file +mysql_cb_messages.h mysql_cb_messages.cc: s-messages +s-messages: mysql_cb_messages.mes + $(top_builddir)/src/lib/log/compiler/kea-msg-compiler $(top_srcdir)/src/hooks/dhcp/mysql_cb/mysql_cb_messages.mes + touch $@ + +# Tell automake that the message files are built as part of the build process +# (so that they are built before the main library is built). +BUILT_SOURCES = mysql_cb_messages.h mysql_cb_messages.cc + +# Ensure that the message file is included in the distribution +EXTRA_DIST = mysql_cb_messages.mes +EXTRA_DIST += ha.dox + +# Get rid of generated message files on a clean +CLEANFILES = *.gcno *.gcda mysql_cb_messages.h mysql_cb_messages.cc s-messages + +# convenience archive + +noinst_LTLIBRARIES = libmysqlcb.la + +libmysqlcb_la_SOURCES = mysql_cb_callouts.cc +libmysqlcb_la_SOURCES += mysql_cb_dhcp4.cc mysql_cb_dhcp4.h +libmysqlcb_la_SOURCES += version.cc + +nodist_libmysqlcb_la_SOURCES = mysql_cb_messages.cc mysql_cb_messages.h + +libmysqlcb_la_CXXFLAGS = $(AM_CXXFLAGS) +libmysqlcb_la_CPPFLAGS = $(AM_CPPFLAGS) + +# install the shared object into $(libdir)/hooks +lib_hooksdir = $(libdir)/hooks +lib_hooks_LTLIBRARIES = libdhcp_mysql_cb.la + +libdhcp_mysql_cb_la_SOURCES = +libdhcp_mysql_cb_la_LDFLAGS = $(AM_LDFLAGS) $(MYSQL_LIBS)o +libdhcp_mysql_cb_la_LDFLAGS += -avoid-version -export-dynamic -module + +libdhcp_mysql_cb_la_LIBADD = libmysqlcb.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/eval/libkea-eval.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/stats/libkea-stats.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/mysql/libkea-mysql.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/database/libkea-database.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/cc/libkea-cc.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/dns/libkea-dns++.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/log/libkea-log.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/util/threads/libkea-threads.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/util/libkea-util.la +libdhcp_mysql_cb_la_LIBADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_callouts.cc b/src/hooks/dhcp/mysql_cb/mysql_cb_callouts.cc new file mode 100644 index 0000000000..44df1e9676 --- /dev/null +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_callouts.cc @@ -0,0 +1,34 @@ +// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Functions accessed by the hooks framework use C linkage to avoid the name +// mangling that accompanies use of the C++ compiler as well as to avoid +// issues related to namespaces. + +#include +#include + +using namespace isc::hooks; + +extern "C" { + +/// @brief This function is called when the library is loaded. +/// +/// @param handle library handle +/// @return 0 when initialization is successful, 1 otherwise +int load(LibraryHandle& handle) { + return (0); +} + +/// @brief This function is called when the library is unloaded. +/// +/// @return 0 if deregistration was successful, 1 otherwise +int unload() { + return (0); +} + + +} // end extern "C" diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc new file mode 100644 index 0000000000..faa84244f4 --- /dev/null +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc @@ -0,0 +1,438 @@ +// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace isc::db; + +namespace { + +class Binding; + +typedef boost::shared_ptr BindingPtr; + +class Binding { +public: + + enum_field_types getType() const { + return (bind_.buffer_type); + } + + MYSQL_BIND& getMySqlBinding() { + return (bind_); + } + + void setBufferValue(const std::string& value) { + buffer_.assign(value.begin(), value.end()); + bind_.buffer = &buffer_[0]; + bind_.buffer_length = value.size(); + } + + template + T getValue() const { + const T* value = reinterpret_cast(&buffer_[0]); + return (*value); + } + + bool amNull() const { + return (null_value_ == MLM_TRUE); + } + + static BindingPtr createString(const unsigned long length = 512) { + BindingPtr binding(new Binding(MYSQL_TYPE_STRING)); + binding->setBufferLength(length); + return (binding); + } + + static BindingPtr createString(const std::string& value) { + BindingPtr binding(new Binding(MYSQL_TYPE_STRING)); + binding->setBufferValue(value); + return (binding); + } + + static BindingPtr createTimestamp() { + BindingPtr binding(new Binding(MYSQL_TYPE_TIMESTAMP)); + binding->setBufferLength(sizeof(MYSQL_TIME)); + return (binding); + } + +private: + + Binding(enum_field_types buffer_type) + : buffer_(), length_(0), null_value_(MLM_FALSE) { + bind_.buffer_type = buffer_type; + bind_.length = &length_; + bind_.is_null = &null_value_; + } + + void setBufferLength(const unsigned long length) { + length_ = length; + buffer_.resize(length_); + bind_.buffer = &buffer_[0]; + bind_.buffer_length = length_; + } + + std::vector buffer_; + + unsigned long length_; + + my_bool null_value_; + + MYSQL_BIND bind_; +}; + +typedef std::vector BindingCollection; + +class DatabaseExchange { +public: + + typedef std::function ConsumeResultFun; + + void selectQuery(MYSQL_STMT* statement, + const BindingCollection& in_bindings, + BindingCollection& out_bindings, + ConsumeResultFun process_result) { + std::vector in_bind_vec; + for (BindingPtr in_binding : in_bindings) { + in_bind_vec.push_back(in_binding->getMySqlBinding()); + } + + int status = 0; + + if (!in_bind_vec.empty()) { + status = mysql_stmt_bind_param(statement, &in_bind_vec[0]); + } + + std::vector out_bind_vec; + for (BindingPtr out_binding : out_bindings) { + out_bind_vec.push_back(out_binding->getMySqlBinding()); + } + + if (!out_bind_vec.empty()) { + status = mysql_stmt_bind_result(statement, &out_bind_vec[0]); + } + + status = mysql_stmt_execute(statement); + + status = mysql_stmt_store_result(statement); + + MySqlFreeResult fetch_release(statement); + while ((status = mysql_stmt_fetch(statement)) == + MLM_MYSQL_FETCH_SUCCESS) { + try { + process_result(); + } catch (...) { + throw; + } + } + } + +}; + +} + +namespace isc { +namespace dhcp { + +/// @brief Implementation of the MySQL Configuration Backend. +class MySqlConfigBackendDHCPv4Impl { +public: + + /// @brief Statement tags. + /// + /// The contents of the enum are indexes into the list of SQL statements. + /// It is assumed that the order is such that the indices of statements + /// reading the database are less than those of statements modifying the + /// database. + enum StatementIndex { + GET_SUBNET4_ID, + NUM_STATEMENTS + }; + + /// @brief Constructor. + /// + /// @param parameters A data structure relating keywords and values + /// concerned with the database. + MySqlConfigBackendDHCPv4Impl(const DatabaseConnection::ParameterMap& parameters); + + /// @brief Destructor. + ~MySqlConfigBackendDHCPv4Impl(); + + /// @brief Represents connection to the MySQL database. + MySqlConnection conn_; +}; + +/// @brief Array of tagged statements. +typedef std::array +TaggedStatementArray; + +/// @brief Prepared MySQL statements used by the backend to insert and +/// retrieve data from the database. +TaggedStatementArray tagged_statements = { { + { MySqlConfigBackendDHCPv4Impl::GET_SUBNET4_ID, + "SELECT hostname FROM hosts WHERE dhcp4_subnet_id = ?" } +} +}; + +MySqlConfigBackendDHCPv4Impl:: +MySqlConfigBackendDHCPv4Impl(const DatabaseConnection::ParameterMap& parameters) + : conn_(parameters) { + // Open the database. + conn_.openDatabase(); + + // Test schema version before we try to prepare statements. + std::pair code_version(MYSQL_SCHEMA_VERSION_MAJOR, + MYSQL_SCHEMA_VERSION_MINOR); +/* std::pair db_version = getVersion(); + if (code_version != db_version) { + isc_throw(DbOpenError, "MySQL schema version mismatch: need version: " + << code_version.first << "." << code_version.second + << " found version: " << db_version.first << "." + << db_version.second); + } */ + + // Enable autocommit. In case transaction is explicitly used, this + // setting will be overwritten for the transaction. However, there are + // cases when lack of autocommit could cause transactions to hang + // until commit or rollback is explicitly called. This already + // caused issues for some unit tests which were unable to cleanup + // the database after the test because of pending transactions. + // Use of autocommit will eliminate this problem. + my_bool result = mysql_autocommit(conn_.mysql_, 1); + if (result != 0) { + isc_throw(DbOperationError, mysql_error(conn_.mysql_)); + } + + // Prepare query statements. Those are will be only used to retrieve + // information from the database, so they can be used even if the + // database is read only for the current user. + conn_.prepareStatements(tagged_statements.begin(), + tagged_statements.end()); +// tagged_statements.begin() + WRITE_STMTS_BEGIN); +} + +MySqlConfigBackendDHCPv4Impl::~MySqlConfigBackendDHCPv4Impl() { + // Free up the prepared statements, ignoring errors. (What would we do + // about them? We're destroying this object and are not really concerned + // with errors on a database connection that is about to go away.) + for (int i = 0; i < conn_.statements_.size(); ++i) { + if (conn_.statements_[i] != NULL) { + (void) mysql_stmt_close(conn_.statements_[i]); + conn_.statements_[i] = NULL; + } + } +} + +MySqlConfigBackendDHCPv4:: +MySqlConfigBackendDHCPv4(const DatabaseConnection::ParameterMap& parameters) + : impl_(new MySqlConfigBackendDHCPv4Impl(parameters)) { +} + +Subnet4Ptr +MySqlConfigBackendDHCPv4::getSubnet4(const ServerSelector& selector, + const std::string& subnet_prefix) const { +} + +Subnet4Ptr +MySqlConfigBackendDHCPv4::getSubnet4(const ServerSelector& selector, + const SubnetID& subnet_id) const { + BindingCollection in_bindings; + in_bindings.push_back(Binding::createString("1024")); + + BindingCollection out_bindings; + out_bindings.push_back(Binding::createString()); + + DatabaseExchange xchg; + xchg.selectQuery(impl_->conn_.statements_[MySqlConfigBackendDHCPv4Impl::GET_SUBNET4_ID], + in_bindings, out_bindings, + [&out_bindings]() { + uint32_t hostname = out_bindings[0]->getValue(); + }); + + return (Subnet4Ptr()); +} + +Subnet4Collection +MySqlConfigBackendDHCPv4::getAllSubnets4(const ServerSelector& selector) const { +} + +Subnet4Collection +MySqlConfigBackendDHCPv4::getModifiedSubnets4(const ServerSelector& selector, + const boost::posix_time::ptime& modification_time) const { +} + +SharedNetwork4Ptr +MySqlConfigBackendDHCPv4::getSharedNetwork4(const ServerSelector& selector, + const std::string& name) const { +} + +SharedNetwork4Collection +MySqlConfigBackendDHCPv4::getAllSharedNetworks4(const ServerSelector& selector) const { +} + +SharedNetwork4Collection +MySqlConfigBackendDHCPv4::getModifiedSharedNetworks4(const ServerSelector& selector, + const boost::posix_time::ptime& modification_time) const { +} + +OptionDefinitionPtr +MySqlConfigBackendDHCPv4::getOptionDef4(const ServerSelector& selector, + const uint16_t code, + const std::string& space) const { +} + +OptionDefContainer +MySqlConfigBackendDHCPv4::getAllOptionDefs4(const ServerSelector& selector) const { +} + +OptionDefContainer +MySqlConfigBackendDHCPv4::getModifiedOptionDefs4(const ServerSelector& selector, + const boost::posix_time::ptime& modification_time) const { +} + +util::OptionalValue +MySqlConfigBackendDHCPv4::getGlobalStringParameter4(const ServerSelector& selector, + const std::string& name) const { +} +util::OptionalValue +MySqlConfigBackendDHCPv4::getGlobalNumberParameter4(const ServerSelector& selector, + const std::string& name) const { +} + +std::map +MySqlConfigBackendDHCPv4::getAllGlobalParameters4(const ServerSelector& selector) const { +} + +void +MySqlConfigBackendDHCPv4::createUpdateSubnet4(const ServerSelector& selector, + const Subnet4Ptr& subnet) { +} + +void +MySqlConfigBackendDHCPv4::createUpdateSharedNetwork4(const ServerSelector& selector, + const SharedNetwork4Ptr& shared_network) { +} + +void +MySqlConfigBackendDHCPv4::createUpdateOptionDef4(const ServerSelector& selector, + const OptionDefinitionPtr& option_def) { +} + +void +MySqlConfigBackendDHCPv4::createUpdateOption4(const ServerSelector& selector, + const OptionPtr& option) { +} + +void +MySqlConfigBackendDHCPv4::createUpdateOption4(const ServerSelector& selector, + const SubnetID& subnet_id, + const OptionPtr& option) { +} + +void +MySqlConfigBackendDHCPv4::createUpdateOption4(const ServerSelector& selector, + const asiolink::IOAddress& pool_start_address, + const asiolink::IOAddress& pool_end_address, + const OptionPtr& option) { +} + +void +MySqlConfigBackendDHCPv4::createUpdateGlobalParameter4(const ServerSelector& selector, + const std::string& name, + const std::string& value) { +} + +void +MySqlConfigBackendDHCPv4::createUpdateGlobalParameter4(const ServerSelector& selector, + const std::string& name, + const int64_t value) { +} + +void +MySqlConfigBackendDHCPv4::deleteSubnet4(const ServerSelector& selector, + const std::string& subnet_prefix) { +} + +void +MySqlConfigBackendDHCPv4::deleteSubnet4(const ServerSelector& selector, + const SubnetID& subnet_id) { +} + +void +MySqlConfigBackendDHCPv4::deleteAllSubnets4(const ServerSelector& selector) { +} + +void +MySqlConfigBackendDHCPv4::deleteSharedNetwork4(const ServerSelector& selector, + const std::string& name) { +} + +void +MySqlConfigBackendDHCPv4::deleteAllSharedNetworks4(const ServerSelector& selector) { +} + +void +MySqlConfigBackendDHCPv4::deleteOptionDef4(const ServerSelector& selector, + const uint16_t code, + const std::string& space) { +} + +void +MySqlConfigBackendDHCPv4::deleteAllOptionDefs4(const ServerSelector& selector) { +} + +void +MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& selector, + const uint16_t code, + const std::string& space) { +} + +void +MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& selector, + const SubnetID& subnet_id, + const uint16_t code, + const std::string& space) { +} + +void +MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& selector, + const asiolink::IOAddress& pool_start_address, + const asiolink::IOAddress& pool_end_address, + const uint16_t code, + const std::string& space) { +} + +void +MySqlConfigBackendDHCPv4::deleteGlobalParameter4(const ServerSelector& selector, + const std::string& name) { +} + +void +MySqlConfigBackendDHCPv4::deleteAllGlobalParameters4(const ServerSelector& selector) { +} + +std::string +MySqlConfigBackendDHCPv4::getType() const { + return ("mysql"); +} + +std::string +MySqlConfigBackendDHCPv4::getHost() const { +} + +uint16_t +MySqlConfigBackendDHCPv4::getPort() const { +} + +} // end of namespace isc::dhcp +} // end of namespace isc diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.h b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.h new file mode 100644 index 0000000000..f0bf2d2a18 --- /dev/null +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.h @@ -0,0 +1,353 @@ +// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef MYSQL_CONFIG_BACKEND_DHCP4_H +#define MYSQL_CONFIG_BACKEND_DHCP4_H + +#include +#include +#include + +namespace isc { +namespace dhcp { + +class MySqlConfigBackendDHCPv4Impl; + +/// @brief Implementation of the MySql Configuration Backend for +/// Kea DHCPv4 server. +class MySqlConfigBackendDHCPv4 : public ConfigBackendDHCPv4 { +public: + + /// @brief Constructor. + /// + /// @param parameters A data structure relating keywords and values + /// concerned with the database. + explicit MySqlConfigBackendDHCPv4(const db::DatabaseConnection::ParameterMap& parameters); + + /// @brief Retrieves a single subnet by subnet_prefix. + /// + /// @param selector Server selector. + /// @param subnet_prefix Prefix of the subnet to be retrieved. + /// @return Pointer to the retrieved subnet or NULL if not found. + virtual Subnet4Ptr + getSubnet4(const db::ServerSelector& selector, + const std::string& subnet_prefix) const; + + /// @brief Retrieves a single subnet by subnet identifier. + /// + /// @param selector Server selector. + /// @param subnet_id Identifier of a subnet to be retrieved. + /// @return Pointer to the retrieved subnet or NULL if not found. + virtual Subnet4Ptr + getSubnet4(const db::ServerSelector& selector, const SubnetID& subnet_id) const; + + /// @brief Retrieves all subnets. + /// + /// @param selector Server selector. + /// @return Collection of subnets or empty collection if no subnet found. + virtual Subnet4Collection + getAllSubnets4(const db::ServerSelector& selector) const; + + /// @brief Retrieves subnets modified after specified time. + /// + /// @param selector Server selector. + /// @param modification_time Lower bound subnet modification time. + /// @return Collection of subnets or empty collection if no subnet found. + virtual Subnet4Collection + getModifiedSubnets4(const db::ServerSelector& selector, + const boost::posix_time::ptime& modification_time) const; + + /// @brief Retrieves shared network by name. + /// + /// @param selector Server selector. + /// @param name Name of the shared network to be retrieved. + /// @return Pointer to the shared network or NULL if not found. + virtual SharedNetwork4Ptr + getSharedNetwork4(const db::ServerSelector& selector, + const std::string& name) const; + + /// @brief Retrieves all shared networks. + /// + /// @param selector Server selector. + /// @return Collection of shared network or empty collection if + /// no shared network found. + virtual SharedNetwork4Collection + getAllSharedNetworks4(const db::ServerSelector& selector) const; + + /// @brief Retrieves shared networks modified after specified time. + /// + /// @param selector Server selector. + /// @param modification_time Lower bound shared network modification time. + /// @return Collection of shared network or empty collection if + /// no shared network found. + virtual SharedNetwork4Collection + getModifiedSharedNetworks4(const db::ServerSelector& selector, + const boost::posix_time::ptime& modification_time) const; + + /// @brief Retrieves single option definition by code and space. + /// + /// @param selector Server selector. + /// @param code Code of the option to be retrieved. + /// @param space Option space of the option to be retrieved. + /// @return Pointer to the option definition or NULL if not found. + virtual OptionDefinitionPtr + getOptionDef4(const db::ServerSelector& selector, const uint16_t code, + const std::string& space) const; + + /// @brief Retrieves all option definitions. + /// + /// @param selector Server selector. + /// @return Collection of option definitions or empty collection if + /// no option definition found. + virtual OptionDefContainer + getAllOptionDefs4(const db::ServerSelector& selector) const; + + /// @brief Retrieves option definitions modified after specified time. + /// + /// @param selector Server selector. + /// @param modification_time Lower bound option definition modification + /// time. + /// @return Collection of option definitions or empty collection if + /// no option definition found. + virtual OptionDefContainer + getModifiedOptionDefs4(const db::ServerSelector& selector, + const boost::posix_time::ptime& modification_time) const; + + /// @brief Retrieves global string parameter value. + /// + /// @param selector Server selector. + /// @param name Name of the global parameter to be retrieved. + /// @return Value of the global string parameter. + virtual util::OptionalValue + getGlobalStringParameter4(const db::ServerSelector& selector, + const std::string& name) const; + + /// @brief Retrieves global number parameter. + /// + /// @param selector Server selector. + /// @param name Name of the parameter to be retrieved. + virtual util::OptionalValue + getGlobalNumberParameter4(const db::ServerSelector& selector, + const std::string& name) const; + + /// @brief Retrieves all global parameters as strings. + /// + /// @param selector Server selector. + virtual std::map + getAllGlobalParameters4(const db::ServerSelector& selector) const; + + /// @brief Creates or updates a subnet. + /// + /// @param selector Server selector. + /// @param subnet Subnet to be added or updated. + virtual void + createUpdateSubnet4(const db::ServerSelector& selector, + const Subnet4Ptr& subnet); + + /// @brief Creates or updates a shared network. + /// + /// @param selector Server selector. + /// @param shared_network Shared network to be added or updated. + virtual void + createUpdateSharedNetwork4(const db::ServerSelector& selector, + const SharedNetwork4Ptr& shared_network); + + /// @brief Creates or updates an option definition. + /// + /// @param selector Server selector. + /// @param option_def Option definition to be added or updated. + virtual void + createUpdateOptionDef4(const db::ServerSelector& selector, + const OptionDefinitionPtr& option_def); + + /// @brief Creates or updates global option. + /// + /// @param selector Server selector. + /// @param option Option to be added or updated. + virtual void + createUpdateOption4(const db::ServerSelector& selector, + const OptionPtr& option); + + /// @brief Creates or updates subnet level option. + /// + /// @param selector Server selector. + /// @param subnet_id Identifier of a subnet to which option belongs. + /// @param option Option to be added or updated. + virtual void + createUpdateOption4(const db::ServerSelector& selector, + const SubnetID& subnet_id, + const OptionPtr& option); + + /// @brief Creates or updates pool level option. + /// + /// @param selector Server selector. + /// @param pool_start_address Lower bound address of the pool to which + /// the option belongs. + /// @param pool_end_address Upper bound address of the pool to which the + /// option belongs. + /// @param option Option to be added or updated. + virtual void + createUpdateOption4(const db::ServerSelector& selector, + const asiolink::IOAddress& pool_start_address, + const asiolink::IOAddress& pool_end_address, + const OptionPtr& option); + + /// @brief Creates or updates global string parameter. + /// + /// @param selector Server selector. + /// @param name Name of the global parameter. + /// @param value Value of the global parameter. + virtual void + createUpdateGlobalParameter4(const db::ServerSelector& selector, + const std::string& name, + const std::string& value); + + /// @brief Creates or updates global number parameter. + /// + /// @param selector Server selector. + /// @param name Name of the global parameter. + /// @param value Value of the global parameter. + virtual void + createUpdateGlobalParameter4(const db::ServerSelector& selector, + const std::string& name, + const int64_t value); + + /// @brief Deletes subnet by prefix. + /// + /// @param selector Server selector. + /// @param subnet_prefix Prefix of the subnet to be deleted. + virtual void + deleteSubnet4(const db::ServerSelector& selector, + const std::string& subnet_prefix); + + /// @brief Deletes subnet by identifier. + /// + /// @param selector Server selector. + /// @param subnet_id Identifier of the subnet to be deleted. + virtual void + deleteSubnet4(const db::ServerSelector& selector, const SubnetID& subnet_id); + + /// @brief Deletes all subnets. + /// + /// @param selector Server selector. + virtual void + deleteAllSubnets4(const db::ServerSelector& selector); + + /// @brief Deletes shared network by name. + /// + /// @param selector Server selector. + /// @param name Name of the shared network to be deleted. + virtual void + deleteSharedNetwork4(const db::ServerSelector& selector, + const std::string& name); + + /// @brief Deletes all shared networks. + /// + /// @param selector Server selector. + virtual void + deleteAllSharedNetworks4(const db::ServerSelector& selector); + + /// @brief Deletes option definition. + /// + /// @param selector Server selector. + /// @param code Code of the option to be deleted. + /// @param space Option space of the option to be deleted. + virtual void + deleteOptionDef4(const db::ServerSelector& selector, const uint16_t code, + const std::string& space); + + /// @brief Deletes all option definitions. + /// + /// @param selector Server selector. + virtual void + deleteAllOptionDefs4(const db::ServerSelector& selector); + + /// @brief Deletes global option. + /// + /// @param selector Server selector. + /// @param code Code of the option to be deleted. + /// @param space Option space of the option to be deleted. + virtual void + deleteOption4(const db::ServerSelector& selector, const uint16_t code, + const std::string& space); + + /// @brief Deletes subnet level option. + /// + /// @param selector Server selector. + /// @param subnet_id Identifier of the subnet to which deleted option + /// belongs. + /// @param code Code of the deleted option. + /// @param space Option space of the deleted option. + virtual void + deleteOption4(const db::ServerSelector& selector, const SubnetID& subnet_id, + const uint16_t code, const std::string& space); + + /// @brief Deletes pool level option. + /// + /// @param selector Server selector. + /// @param pool_start_address Lower bound address of the pool to which + /// deleted option belongs. + /// @param pool_end_address Upper bound address of the pool to which the + /// deleted option belongs. + /// @param code Code of the deleted option. + /// @param space Option space of the deleted option. + virtual void + deleteOption4(const db::ServerSelector& selector, + const asiolink::IOAddress& pool_start_address, + const asiolink::IOAddress& pool_end_address, + const uint16_t code, + const std::string& space); + + /// @brief Deletes global parameter. + /// + /// @param selector Server selector. + /// @param name Name of the global parameter to be deleted. + virtual void + deleteGlobalParameter4(const db::ServerSelector& selector, + const std::string& name); + + /// @brief Deletes all global parameters. + /// + /// @param selector Server selector. + virtual void + deleteAllGlobalParameters4(const db::ServerSelector& selector); + + /// @brief Returns backend type in the textual format. + /// + /// @return "mysql". + virtual std::string getType() const; + + /// @brief Returns backend host. + /// + /// This is used by the @c BaseConfigBackendPool to select backend + /// when @c BackendSelector is specified. + /// + /// @return host on which the database is located. + virtual std::string getHost() const; + + /// @brief Returns backend port number. + /// + /// This is used by the @c BaseConfigBackendPool to select backend + /// when @c BackendSelector is specified. + /// + /// @return Port number on which database service is available. + virtual uint16_t getPort() const; + +private: + + /// @brief Pointer to the implementation of the @c MySqlConfigBackendDHCPv4 + /// class. + boost::shared_ptr impl_; + +}; + +/// @brief Pointer to the @c MySqlConfigBackendDHCPv4 class. +typedef boost::shared_ptr MySqlConfigBackendDHCPv4Ptr; + +} // end of namespace isc::cb +} // end of namespace isc + +#endif // MYSQL_CONFIG_BACKEND_DHCP4_H diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_messages.mes b/src/hooks/dhcp/mysql_cb/mysql_cb_messages.mes new file mode 100644 index 0000000000..b03f62a1e1 --- /dev/null +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_messages.mes @@ -0,0 +1,3 @@ +# Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC") + +$NAMESPACE isc::cb diff --git a/src/hooks/dhcp/mysql_cb/tests/.gitignore b/src/hooks/dhcp/mysql_cb/tests/.gitignore new file mode 100644 index 0000000000..98266a2b26 --- /dev/null +++ b/src/hooks/dhcp/mysql_cb/tests/.gitignore @@ -0,0 +1 @@ +/mysql_cb_unittests \ No newline at end of file diff --git a/src/hooks/dhcp/mysql_cb/tests/Makefile.am b/src/hooks/dhcp/mysql_cb/tests/Makefile.am new file mode 100644 index 0000000000..5546b734dd --- /dev/null +++ b/src/hooks/dhcp/mysql_cb/tests/Makefile.am @@ -0,0 +1,58 @@ +SUBDIRS = . + +AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib +AM_CPPFLAGS += -I$(top_builddir)/src/hooks/dhcp/mysql_cb -I$(top_srcdir)/src/hooks/dhcp/mysql_cb +AM_CPPFLAGS += $(BOOST_INCLUDES) +AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\" + +AM_CXXFLAGS = $(KEA_CXXFLAGS) + +if USE_STATIC_LINK +AM_LDFLAGS = -static +endif + +# Unit test data files need to get installed. +EXTRA_DIST = + +CLEANFILES = *.gcno *.gcda + +TESTS_ENVIRONMENT = \ + $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND) + +TESTS = +if HAVE_GTEST +TESTS += mysql_cb_unittests + +mysql_cb_unittests_SOURCES = mysql_cb_dhcp4_unittest.cc +mysql_cb_unittests_SOURCES += run_unittests.cc + +mysql_cb_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES) + +mysql_cb_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS) + +mysql_cb_unittests_CXXFLAGS = $(AM_CXXFLAGS) + +mysql_cb_unittests_LDADD = $(top_builddir)/src/hooks/dhcp/mysql_cb/libmysqlcb.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/eval/libkea-eval.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/mysql/testutils/libmysqltest.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/mysql/libkea-mysql.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/database/libkea-database.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/util/threads/libkea-threads.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la +mysql_cb_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la +mysql_cb_unittests_LDADD += $(LOG4CPLUS_LIBS) +mysql_cb_unittests_LDADD += $(CRYPTO_LIBS) +mysql_cb_unittests_LDADD += $(BOOST_LIBS) +mysql_cb_unittests_LDADD += $(GTEST_LDADD) +endif +noinst_PROGRAMS = $(TESTS) 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 new file mode 100644 index 0000000000..feb191bfab --- /dev/null +++ b/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc @@ -0,0 +1,53 @@ +// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include + +using namespace isc::db; +using namespace isc::db::test; +using namespace isc::dhcp; + +namespace { + +class MySqlConfigBackendDHCPv4Test : public ::testing::Test { +public: + + MySqlConfigBackendDHCPv4Test() { + destroyMySQLSchema(); + createMySQLSchema(); + + try { + DatabaseConnection::ParameterMap params = + DatabaseConnection::parse(validMySQLConnectionString()); + cbptr_.reset(new MySqlConfigBackendDHCPv4(params)); + + } catch (...) { + std::cerr << "*** ERROR: unable to open database. The test\n" + "*** environment is broken and must be fixed before\n" + "*** the MySQL tests will run correctly.\n" + "*** The reason for the problem is described in the\n" + "*** accompanying exception output.\n"; + throw; + } + } + + virtual ~MySqlConfigBackendDHCPv4Test() { + cbptr_.reset(); + destroyMySQLSchema(); + } + + MySqlConfigBackendDHCPv4Ptr cbptr_; +}; + +TEST_F(MySqlConfigBackendDHCPv4Test, getSubnet4) { + cbptr_->getSubnet4(ServerSelector::UNASSIGNED(), SubnetID(1)); +} + + +} diff --git a/src/hooks/dhcp/mysql_cb/tests/run_unittests.cc b/src/hooks/dhcp/mysql_cb/tests/run_unittests.cc new file mode 100644 index 0000000000..3b1baf9e98 --- /dev/null +++ b/src/hooks/dhcp/mysql_cb/tests/run_unittests.cc @@ -0,0 +1,19 @@ +// Copyright (C) 2017-2018 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include +#include + +int +main(int argc, char* argv[]) { + ::testing::InitGoogleTest(&argc, argv); + isc::log::initLogger(); + int result = RUN_ALL_TESTS(); + + return (result); +} diff --git a/src/hooks/dhcp/mysql_cb/version.cc b/src/hooks/dhcp/mysql_cb/version.cc new file mode 100644 index 0000000000..32834cec8b --- /dev/null +++ b/src/hooks/dhcp/mysql_cb/version.cc @@ -0,0 +1,17 @@ +// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include + +extern "C" { + +/// @brief returns Kea hooks version. +int version() { + return (KEA_HOOKS_VERSION); +} + +}