From: Marcin Siodelski Date: Sun, 7 Oct 2018 11:27:41 +0000 (+0200) Subject: [#93,!56] Updated MySQL config backend to manage global parameters. X-Git-Tag: 5-netconf-extend-syntax_base~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=52dad7c3ae7300da3b12466d548aacdf6ea76d9d;p=thirdparty%2Fkea.git [#93,!56] Updated MySQL config backend to manage global parameters. --- diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc index c3c2713732..0ae0ee0cd6 100644 --- a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc @@ -49,6 +49,9 @@ public: /// reading the database are less than those of statements modifying the /// database. enum StatementIndex { + GET_GLOBAL_PARAMETER4, + GET_ALL_GLOBAL_PARAMETERS4, + GET_MODIFIED_GLOBAL_PARAMETERS4, GET_SUBNET4_ID, GET_SUBNET4_PREFIX, GET_ALL_SUBNETS4, @@ -66,11 +69,13 @@ public: GET_OPTION4_SUBNET_ID_CODE_SPACE, GET_OPTION4_POOL_ID_CODE_SPACE, GET_OPTION4_SHARED_NETWORK_CODE_SPACE, + INSERT_GLOBAL_PARAMETER4, INSERT_SUBNET4, INSERT_POOL4, INSERT_SHARED_NETWORK4, INSERT_OPTION_DEF4, INSERT_OPTION4, + UPDATE_GLOBAL_PARAMETER4, UPDATE_SUBNET4, UPDATE_SHARED_NETWORK4, UPDATE_OPTION_DEF4, @@ -78,6 +83,8 @@ public: UPDATE_OPTION4_SUBNET_ID, UPDATE_OPTION4_POOL_ID, UPDATE_OPTION4_SHARED_NETWORK, + DELETE_GLOBAL_PARAMETER4, + DELETE_ALL_GLOBAL_PARAMETERS4, DELETE_SUBNET4_ID, DELETE_SUBNET4_PREFIX, DELETE_ALL_SUBNETS4, @@ -102,6 +109,82 @@ public: explicit MySqlConfigBackendDHCPv4Impl(const DatabaseConnection::ParameterMap& parameters); + /// @brief Sends query to retrieve multiple global parameters. + /// + /// @param index Index of the query to be used. + /// @param in_bindings Input bindings specifying selection criteria. The + /// size of the bindings collection must match the number of placeholders + /// in the prepared statement. The input bindings collection must be empty + /// if the query contains no WHERE clause. + /// @param [out] subnets Reference to the container where fetched parameters + /// will be inserted. + void getGlobalParameters4(const StatementIndex& index, + const MySqlBindingCollection& in_bindings, + StampedValueCollection& parameters) { + MySqlBindingCollection out_bindings = { + MySqlBinding::createInteger(), + MySqlBinding::createString(128), + MySqlBinding::createString(65536), + MySqlBinding::createTimestamp() + }; + + conn_.selectQuery(index, in_bindings, out_bindings, + [¶meters] + (MySqlBindingCollection& out_bindings) { + if (!out_bindings[1]->getString().empty()) { + StampedValuePtr stamped_value(new StampedValue(out_bindings[1]->getString(), + out_bindings[2]->getString())); + stamped_value->setModificationTime(out_bindings[3]->getTimestamp()); + parameters.push_back(stamped_value); + } + }); + } + + /// @brief Sends query to retrieve global parameter. + /// + /// @param server_selector Server selector. + /// @param name Name of the parameter to be retrieved. + /// + /// @return Pointer to the retrieved value or null if such parameter + /// doesn't exist. + StampedValuePtr getGlobalParameter4(const ServerSelector& server_selector, + const std::string& name) { + MySqlBindingCollection in_bindings = { + MySqlBinding::createString(name) + }; + + StampedValueCollection parameters; + getGlobalParameters4(GET_GLOBAL_PARAMETER4, in_bindings, parameters); + + return (parameters.empty() ? StampedValuePtr() : *parameters.begin()); + } + + /// @brief Sends query to insert or update global parameter. + /// + /// @param server_selector Server selector. + /// @param name Name of the global parameter. + /// @param value Value of the global parameter. + void createUpdateGlobalParameter4(const db::ServerSelector& server_selector, + const StampedValuePtr& value) { + MySqlBindingCollection in_bindings = { + MySqlBinding::createString(value->getName()), + MySqlBinding::createString(value->getValue()), + MySqlBinding::createTimestamp(value->getModificationTime()), + MySqlBinding::createString(value->getName()) + }; + + // Try to update the existing row. + if (conn_.updateDeleteQuery(MySqlConfigBackendDHCPv4Impl::UPDATE_GLOBAL_PARAMETER4, + in_bindings) == 0) { + + // No such parameter found, so let's insert it. We have to adjust the + // bindings collection to match the prepared statement for insert. + in_bindings.pop_back(); + conn_.insertQuery(MySqlConfigBackendDHCPv4Impl::INSERT_GLOBAL_PARAMETER4, + in_bindings); + } + } + /// @brief Sends query to the database to retrieve multiple subnets. /// /// Query should order subnets by subnet_id. @@ -580,7 +663,7 @@ public: /// @param server_selector Server selector. /// @param pool Pointer to the pool to be inserted. /// @param subnet Pointer to the subnet that this pool belongs to. - void createPool4(const ServerSelector& selector, const Pool4Ptr& pool, + void createPool4(const ServerSelector& server_selector, const Pool4Ptr& pool, const Subnet4Ptr& subnet) { MySqlBindingCollection in_bindings = { MySqlBinding::createInteger(pool->getFirstAddress().toUint32()), @@ -599,7 +682,7 @@ public: for (auto desc = options->begin(); desc != options->end(); ++desc) { OptionDescriptorPtr desc_copy(new OptionDescriptor(*desc)); desc_copy->space_name_ = option_space; - createUpdateOption4(selector, pool_id, desc_copy); + createUpdateOption4(server_selector, pool_id, desc_copy); } } } @@ -858,9 +941,9 @@ public: /// @brief Sends query to insert or update global DHCP option. /// - /// @param selector Server selector. + /// @param server_selector Server selector. /// @param option Pointer to the option descriptor encapsulating the option. - void createUpdateOption4(const ServerSelector& selector, + void createUpdateOption4(const ServerSelector& server_selector, const OptionDescriptorPtr& option) { MySqlBindingCollection in_bindings = { @@ -879,8 +962,7 @@ public: }; MySqlTransaction transaction(conn_); - - OptionDescriptorPtr existing_option = getOption4(selector, + OptionDescriptorPtr existing_option = getOption4(server_selector, option->option_->getType(), option->space_name_); if (existing_option) { @@ -899,10 +981,10 @@ public: /// @brief Sends query to insert or update DHCP option in a subnet. /// - /// @param selector Server selector. + /// @param server_selector Server selector. /// @param subnet_id Identifier of the subnet the option belongs to. /// @param option Pointer to the option descriptor encapsulating the option. - void createUpdateOption4(const ServerSelector& selector, + void createUpdateOption4(const ServerSelector& server_selector, const SubnetID& subnet_id, const OptionDescriptorPtr& option) { @@ -924,7 +1006,7 @@ public: MySqlTransaction transaction(conn_); - OptionDescriptorPtr existing_option = getOption4(selector, subnet_id, + OptionDescriptorPtr existing_option = getOption4(server_selector, subnet_id, option->option_->getType(), option->space_name_); if (existing_option) { @@ -942,12 +1024,12 @@ public: transaction.commit(); } - void createUpdateOption4(const ServerSelector& selector, + void createUpdateOption4(const ServerSelector& server_selector, const IOAddress& pool_start_address, const IOAddress& pool_end_address, const OptionDescriptorPtr& option) { uint64_t pool_id = 0; - Pool4Ptr pool = getPool4(selector, pool_start_address, pool_end_address, + Pool4Ptr pool = getPool4(server_selector, pool_start_address, pool_end_address, pool_id); if (!pool) { isc_throw(BadValue, "no pool found for range of " @@ -955,7 +1037,7 @@ public: << pool_end_address); } - createUpdateOption4(selector, pool_id, option); + createUpdateOption4(server_selector, pool_id, option); } @@ -964,7 +1046,7 @@ public: /// @param selector Server selector. /// @param pool_id Identifier of the pool the option belongs to. /// @param option Pointer to the option descriptor encapsulating the option. - void createUpdateOption4(const ServerSelector& selector, + void createUpdateOption4(const ServerSelector& server_selector, const uint64_t pool_id, const OptionDescriptorPtr& option) { @@ -984,8 +1066,7 @@ public: }; MySqlTransaction transaction(conn_); - - OptionDescriptorPtr existing_option = getOption4(selector, pool_id, + OptionDescriptorPtr existing_option = getOption4(server_selector, pool_id, option->option_->getType(), option->space_name_); if (existing_option) { @@ -1009,7 +1090,7 @@ public: /// @param shared_network_name Name of the shared network the option /// belongs to. /// @param option Pointer to the option descriptor encapsulating the option. - void createUpdateOption4(const ServerSelector& selector, + void createUpdateOption4(const ServerSelector& server_selector, const std::string& shared_network_name, const OptionDescriptorPtr& option) { MySqlBindingCollection in_bindings = { @@ -1029,7 +1110,7 @@ public: MySqlTransaction transaction(conn_); - OptionDescriptorPtr existing_option = getOption4(selector, shared_network_name, + OptionDescriptorPtr existing_option = getOption4(server_selector, shared_network_name, option->option_->getType(), option->space_name_); if (existing_option) { @@ -1107,7 +1188,7 @@ public: /// @return Pointer to the returned option or NULL if such option /// doesn't exist. OptionDescriptorPtr - getOption4(const ServerSelector& selector, const uint16_t code, + getOption4(const ServerSelector& server_selector, const uint16_t code, const std::string& space) { OptionContainer options; MySqlBindingCollection in_bindings = { @@ -1124,7 +1205,7 @@ public: /// @param selector Server selector. /// @return Container holding returned options. OptionContainer - getAllOptions4(const ServerSelector& selector) { + getAllOptions4(const ServerSelector& server_selector) { OptionContainer options; MySqlBindingCollection in_bindings; getOptions(MySqlConfigBackendDHCPv4Impl::GET_ALL_OPTIONS4, @@ -1138,7 +1219,7 @@ public: /// @param selector Server selector. /// @return Container holding returned options. OptionContainer - getModifiedOptions4(const ServerSelector& selector, + getModifiedOptions4(const ServerSelector& server_selector, const boost::posix_time::ptime& modification_time) { OptionContainer options; MySqlBindingCollection in_bindings = { @@ -1428,6 +1509,41 @@ TaggedStatementArray; /// @brief Prepared MySQL statements used by the backend to insert and /// retrieve data from the database. TaggedStatementArray tagged_statements = { { + // Select global parameter by name. + { MySqlConfigBackendDHCPv4Impl::GET_GLOBAL_PARAMETER4, + "SELECT" + " id," + " name," + " value," + " modification_ts " + "FROM dhcp4_global_parameter " + "WHERE name = ? " + "ORDER BY id" + }, + + // Select all global parameters. + { MySqlConfigBackendDHCPv4Impl::GET_ALL_GLOBAL_PARAMETERS4, + "SELECT" + " id," + " name," + " value," + " modification_ts " + "FROM dhcp4_global_parameter " + "ORDER BY id" + }, + + // Select modified global parameters. + { MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_GLOBAL_PARAMETERS4, + "SELECT" + " id," + " name," + " value," + " modification_ts " + "FROM dhcp4_global_parameter " + "WHERE modification_ts > ? " + "ORDER BY id" + }, + // Select subnet by id. { MySqlConfigBackendDHCPv4Impl::GET_SUBNET4_ID, "SELECT" @@ -1957,6 +2073,14 @@ TaggedStatementArray tagged_statements = { { " code = ? AND space = ? " "ORDER BY option_id" }, + // Insert global parameter. + { MySqlConfigBackendDHCPv4Impl::INSERT_GLOBAL_PARAMETER4, + "INSERT INTO dhcp4_global_parameter(" + " name," + " value," + " modification_ts" + ") VALUES (?, ?, ?)" }, + // Insert a subnet. { MySqlConfigBackendDHCPv4Impl::INSERT_SUBNET4, "INSERT INTO dhcp4_subnet(" @@ -2040,6 +2164,14 @@ TaggedStatementArray tagged_statements = { { "modification_ts" ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" }, + // Update existing global parameter. + { MySqlConfigBackendDHCPv4Impl::UPDATE_GLOBAL_PARAMETER4, + "UPDATE dhcp4_global_parameter SET" + " name = ?," + " value = ?," + " modification_ts = ? " + "WHERE name = ?" }, + // Update existing subnet. { MySqlConfigBackendDHCPv4Impl::UPDATE_SUBNET4, "UPDATE dhcp4_subnet SET" @@ -2168,6 +2300,17 @@ TaggedStatementArray tagged_statements = { { "WHERE scope_id = 4 AND shared_network_name = ? AND code = ? AND space = ?" }, + // Delete global parameter by name. + { MySqlConfigBackendDHCPv4Impl::DELETE_GLOBAL_PARAMETER4, + "DELETE FROM dhcp4_global_parameter " + "WHERE name = ?" + }, + + // Delete all global parameters. + { MySqlConfigBackendDHCPv4Impl::DELETE_ALL_GLOBAL_PARAMETERS4, + "DELETE FROM dhcp4_global_parameter" + }, + // Delete subnet by id. { MySqlConfigBackendDHCPv4Impl::DELETE_SUBNET4_ID, "DELETE FROM dhcp4_subnet " @@ -2338,39 +2481,50 @@ getModifiedOptionDefs4(const ServerSelector& server_selector, } OptionDescriptorPtr -MySqlConfigBackendDHCPv4::getOption4(const ServerSelector& selector, +MySqlConfigBackendDHCPv4::getOption4(const ServerSelector& server_selector, const uint16_t code, const std::string& space) const { - return (impl_->getOption4(selector, code, space)); + return (impl_->getOption4(server_selector, code, space)); } OptionContainer -MySqlConfigBackendDHCPv4::getAllOptions4(const ServerSelector& selector) const { - return (impl_->getAllOptions4(selector)); +MySqlConfigBackendDHCPv4::getAllOptions4(const ServerSelector& server_selector) const { + return (impl_->getAllOptions4(server_selector)); } OptionContainer MySqlConfigBackendDHCPv4:: -getModifiedOptions4(const ServerSelector& selector, +getModifiedOptions4(const ServerSelector& server_selector, const boost::posix_time::ptime& modification_time) const { - return (impl_->getModifiedOptions4(selector, modification_time)); + return (impl_->getModifiedOptions4(server_selector, modification_time)); } -util::OptionalValue -MySqlConfigBackendDHCPv4::getGlobalStringParameter4(const ServerSelector& /* server_selector */, - const std::string& /* name */) const { - isc_throw(NotImplemented, "not implemented"); +StampedValuePtr +MySqlConfigBackendDHCPv4::getGlobalParameter4(const ServerSelector& server_selector, + const std::string& name) const { + return (impl_->getGlobalParameter4(server_selector, name)); } -util::OptionalValue -MySqlConfigBackendDHCPv4::getGlobalNumberParameter4(const ServerSelector& /* server_selector */, - const std::string& /* name */) const { - isc_throw(NotImplemented, "not implemented"); +StampedValueCollection +MySqlConfigBackendDHCPv4::getAllGlobalParameters4(const ServerSelector& server_selector) const { + MySqlBindingCollection in_bindings; + StampedValueCollection parameters; + impl_->getGlobalParameters4(MySqlConfigBackendDHCPv4Impl::GET_ALL_GLOBAL_PARAMETERS4, + in_bindings, parameters); + return (parameters); } -std::map -MySqlConfigBackendDHCPv4::getAllGlobalParameters4(const ServerSelector& /* server_selector */) const { - isc_throw(NotImplemented, "not implemented"); +StampedValueCollection +MySqlConfigBackendDHCPv4:: +getModifiedGlobalParameters4(const db::ServerSelector& server_selector, + const boost::posix_time::ptime& modification_time) const { + MySqlBindingCollection in_bindings = { + MySqlBinding::createTimestamp(modification_time) + }; + StampedValueCollection parameters; + impl_->getGlobalParameters4(MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_GLOBAL_PARAMETERS4, + in_bindings, parameters); + return (parameters); } void @@ -2392,9 +2546,9 @@ MySqlConfigBackendDHCPv4::createUpdateOptionDef4(const ServerSelector& server_se } void -MySqlConfigBackendDHCPv4::createUpdateOption4(const ServerSelector& selector, +MySqlConfigBackendDHCPv4::createUpdateOption4(const ServerSelector& server_selector, const OptionDescriptorPtr& option) { - impl_->createUpdateOption4(selector, option); + impl_->createUpdateOption4(server_selector, option); } void @@ -2405,31 +2559,25 @@ MySqlConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& server_s } void -MySqlConfigBackendDHCPv4::createUpdateOption4(const ServerSelector& selector, +MySqlConfigBackendDHCPv4::createUpdateOption4(const ServerSelector& server_selector, const SubnetID& subnet_id, const OptionDescriptorPtr& option) { - impl_->createUpdateOption4(selector, subnet_id, option); + impl_->createUpdateOption4(server_selector, subnet_id, option); } void -MySqlConfigBackendDHCPv4::createUpdateOption4(const ServerSelector& selector, +MySqlConfigBackendDHCPv4::createUpdateOption4(const ServerSelector& server_selector, const asiolink::IOAddress& pool_start_address, const asiolink::IOAddress& pool_end_address, const OptionDescriptorPtr& option) { - impl_->createUpdateOption4(selector, pool_start_address, pool_end_address, + impl_->createUpdateOption4(server_selector, pool_start_address, pool_end_address, option); } void -MySqlConfigBackendDHCPv4::createUpdateGlobalParameter4(const ServerSelector& /* server_selector */, - const std::string& /* name */, - const std::string& /* value */) { -} - -void -MySqlConfigBackendDHCPv4::createUpdateGlobalParameter4(const ServerSelector& /* server_selector */, - const std::string& /* name */, - const int64_t /* value */) { +MySqlConfigBackendDHCPv4::createUpdateGlobalParameter4(const ServerSelector& server_selector, + const StampedValuePtr& value) { + impl_->createUpdateGlobalParameter4(server_selector, value); } uint64_t @@ -2491,32 +2639,33 @@ MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& server_selector, } uint64_t -MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& selector, +MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& server_selector, const SubnetID& subnet_id, const uint16_t code, const std::string& space) { - return (impl_->deleteOption4(selector, subnet_id, code, space)); + return (impl_->deleteOption4(server_selector, subnet_id, code, space)); } uint64_t -MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& 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) { - return (impl_->deleteOption4(selector, pool_start_address, pool_end_address, + return (impl_->deleteOption4(server_selector, pool_start_address, pool_end_address, code, space)); } uint64_t -MySqlConfigBackendDHCPv4::deleteGlobalParameter4(const ServerSelector& /* server_selector */, - const std::string& /* name */) { - return (0); +MySqlConfigBackendDHCPv4::deleteGlobalParameter4(const ServerSelector& server_selector, + const std::string& name) { + impl_->deleteFromTable(MySqlConfigBackendDHCPv4Impl::DELETE_GLOBAL_PARAMETER4, + name); } uint64_t -MySqlConfigBackendDHCPv4::deleteAllGlobalParameters4(const ServerSelector& /* server_selector */) { - return (0); +MySqlConfigBackendDHCPv4::deleteAllGlobalParameters4(const ServerSelector& selector) { + impl_->deleteFromTable(MySqlConfigBackendDHCPv4Impl::DELETE_ALL_GLOBAL_PARAMETERS4); } std::string diff --git a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.h b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.h index e2af4e3d2c..1820768cb6 100644 --- a/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.h +++ b/src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.h @@ -118,53 +118,53 @@ public: /// @brief Retrieves single option by code and space. /// - /// @param selector Server selector. + /// @param server_selector Server selector. /// @return Pointer to the retrieved option descriptor or null if /// no option was found. virtual OptionDescriptorPtr - getOption4(const db::ServerSelector& selector, const uint16_t code, + getOption4(const db::ServerSelector& server_selector, const uint16_t code, const std::string& space) const; /// @brief Retrieves all global options. /// - /// @param selector Server selector. + /// @param server_selector Server selector. /// @return Collection of global options or empty collection if no /// option found. virtual OptionContainer - getAllOptions4(const db::ServerSelector& selector) const; + getAllOptions4(const db::ServerSelector& server_selector) const; /// @brief Retrieves option modified after specified time. /// - /// @param selector Server selector. + /// @param server_selector Server selector. /// @param modification_time Lower bound option modification time. /// @return Collection of global options or empty collection if no /// option found. virtual OptionContainer - getModifiedOptions4(const db::ServerSelector& selector, + getModifiedOptions4(const db::ServerSelector& server_selector, const boost::posix_time::ptime& modification_time) const; - /// @brief Retrieves global string parameter value. + /// @brief Retrieves global parameter value. /// /// @param server_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& server_selector, - const std::string& name) const; + /// @return Value of the global parameter. + virtual data::StampedValuePtr + getGlobalParameter4(const db::ServerSelector& server_selector, + const std::string& name) const; - /// @brief Retrieves global number parameter. + /// @brief Retrieves all global parameters. /// /// @param server_selector Server selector. - /// @param name Name of the parameter to be retrieved. - virtual util::OptionalValue - getGlobalNumberParameter4(const db::ServerSelector& server_selector, - const std::string& name) const; + virtual data::StampedValueCollection + getAllGlobalParameters4(const db::ServerSelector& server_selector) const; - /// @brief Retrieves all global parameters as strings. + /// @brief Retrieves global parameters modified after specified time. /// - /// @param server_selector Server selector. - virtual std::map - getAllGlobalParameters4(const db::ServerSelector& server_selector) const; + /// @param modification_time Lower bound modification time. + /// @return Collection of modified global parameters. + virtual data::StampedValueCollection + getModifiedGlobalParameters4(const db::ServerSelector& server_selector, + const boost::posix_time::ptime& modification_time) const; /// @brief Creates or updates a subnet. /// @@ -200,12 +200,12 @@ public: /// @brief Creates or updates shared network level option. /// - /// @param selector Server selector. + /// @param server_selector Server selector. /// @param shared_network_name Name of a shared network to which option /// belongs. /// @param option Option to be added or updated. virtual void - createUpdateOption4(const db::ServerSelector& selector, + createUpdateOption4(const db::ServerSelector& server_selector, const std::string& shared_network_name, const OptionDescriptorPtr& option); @@ -233,25 +233,14 @@ public: const asiolink::IOAddress& pool_end_address, const OptionDescriptorPtr& option); - /// @brief Creates or updates global string parameter. + /// @brief Creates or updates global parameter. /// /// @param server_selector Server selector. /// @param name Name of the global parameter. /// @param value Value of the global parameter. virtual void createUpdateGlobalParameter4(const db::ServerSelector& server_selector, - const std::string& name, - const std::string& value); - - /// @brief Creates or updates global number parameter. - /// - /// @param server_selector Server selector. - /// @param name Name of the global parameter. - /// @param value Value of the global parameter. - virtual void - createUpdateGlobalParameter4(const db::ServerSelector& server_selector, - const std::string& name, - const int64_t value); + const data::StampedValuePtr& value); /// @brief Deletes subnet by prefix. /// @@ -322,13 +311,13 @@ public: /// @brief Deletes shared network level option. /// - /// @param selector Server selector. + /// @param server_selector Server selector. /// @param shared_network_name Name of the shared network which deleted /// option belongs to /// @param code Code of the deleted option. /// @param space Option space of the deleted option. virtual uint64_t - deleteOption4(const db::ServerSelector& selector, + deleteOption4(const db::ServerSelector& server_selector, const std::string& shared_network_name, const uint16_t code, const std::string& space); diff --git a/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc b/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc index abc5e341d6..edfadc1dc8 100644 --- a/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc +++ b/src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc @@ -302,6 +302,99 @@ public: boost::shared_ptr cbptr_; }; +// This test verifies that the global parameter can be added, updated and +// deleted. +TEST_F(MySqlConfigBackendDHCPv4Test, createUpdateDeleteGlobalParameter4) { + StampedValuePtr server_tag = StampedValue::create("server-tag", "whale"); + // Explicitly set modification time to make sure that the time + // returned from the database is correct. + server_tag->setModificationTime(timestamps_["yesterday"]); + cbptr_->createUpdateGlobalParameter4(ServerSelector::UNASSIGNED(), + server_tag); + + // Verify returned parameter and the modification time. + StampedValuePtr returned_server_tag = + cbptr_->getGlobalParameter4(ServerSelector::UNASSIGNED(), "server-tag"); + ASSERT_TRUE(returned_server_tag); + EXPECT_EQ("server-tag", returned_server_tag->getName()); + EXPECT_EQ("whale", returned_server_tag->getValue()); + EXPECT_TRUE(returned_server_tag->getModificationTime() == + server_tag->getModificationTime()); + + // Check that the parameter is udpated when it already exists in + // the database. + server_tag = StampedValue::create("server-tag", "fish"); + cbptr_->createUpdateGlobalParameter4(ServerSelector::UNASSIGNED(), + server_tag); + returned_server_tag = cbptr_->getGlobalParameter4(ServerSelector::UNASSIGNED(), + "server-tag"); + ASSERT_TRUE(returned_server_tag); + EXPECT_EQ("server-tag", returned_server_tag->getName()); + EXPECT_EQ("fish", returned_server_tag->getValue()); + EXPECT_TRUE(returned_server_tag->getModificationTime() == + server_tag->getModificationTime()); + + // Delete parameter and make sure it is gone. + cbptr_->deleteGlobalParameter4(ServerSelector::UNASSIGNED(), "server-tag"); + returned_server_tag = cbptr_->getGlobalParameter4(ServerSelector::UNASSIGNED(), + "server-tag"); + EXPECT_FALSE(returned_server_tag); +} + +// This test verifies that all global parameters can be retrieved and deleted. +TEST_F(MySqlConfigBackendDHCPv4Test, getAllGlobalParameters4) { + // Create 3 parameters and put them into the database. + cbptr_->createUpdateGlobalParameter4(ServerSelector::UNASSIGNED(), + StampedValue::create("name1", "value1")); + cbptr_->createUpdateGlobalParameter4(ServerSelector::UNASSIGNED(), + StampedValue::create("name2", 65)); + cbptr_->createUpdateGlobalParameter4(ServerSelector::UNASSIGNED(), + StampedValue::create("name3", "value3")); + + // Fetch all parameters. + auto parameters = cbptr_->getAllGlobalParameters4(ServerSelector::UNASSIGNED()); + ASSERT_EQ(3, parameters.size()); + + // Verify their values. + EXPECT_EQ("value1", parameters[0]->getValue()); + EXPECT_EQ(65, parameters[1]->getSignedIntegerValue()); + EXPECT_EQ("value3", parameters[2]->getValue()); + + // Delete all parameters and make sure they are gone. + cbptr_->deleteAllGlobalParameters4(ServerSelector::UNASSIGNED()); + parameters = cbptr_->getAllGlobalParameters4(ServerSelector::UNASSIGNED()); + EXPECT_TRUE(parameters.empty()); +} + +// This test verifies that modified global parameters can be retrieved. +TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedGlobalParameters4) { + // Create 3 global parameters and assign modification times: + // "yesterday", "today" and "tomorrow" respectively. + StampedValuePtr value = StampedValue::create("name1", "value1"); + value->setModificationTime(timestamps_["yesterday"]); + cbptr_->createUpdateGlobalParameter4(ServerSelector::UNASSIGNED(), + value); + + value = StampedValue::create("name2", 65); + value->setModificationTime(timestamps_["today"]); + cbptr_->createUpdateGlobalParameter4(ServerSelector::UNASSIGNED(), + value); + + value = StampedValue::create("name3", "value3"); + value->setModificationTime(timestamps_["tomorrow"]); + cbptr_->createUpdateGlobalParameter4(ServerSelector::UNASSIGNED(), + value); + + // Get parameters modified after "today". + auto parameters = cbptr_->getModifiedGlobalParameters4(ServerSelector::UNASSIGNED(), + timestamps_["today"]); + + // It should be the one modified "tomorrow". + ASSERT_EQ(1, parameters.size()); + ASSERT_TRUE(parameters[0]); + EXPECT_EQ("value3", parameters[0]->getValue()); +} + // Test that subnet can be inserted, fetched, updated and then fetched again. TEST_F(MySqlConfigBackendDHCPv4Test, getSubnet4) { // Insert new subnet. diff --git a/src/lib/cc/stamped_value.cc b/src/lib/cc/stamped_value.cc index a5204c2f46..38ab82b615 100644 --- a/src/lib/cc/stamped_value.cc +++ b/src/lib/cc/stamped_value.cc @@ -11,12 +11,15 @@ namespace isc { namespace data { -StampedValue::StampedValue(const std::string& value) - : StampedElement(), value_(value) { +StampedValue::StampedValue(const std::string& name, + const std::string& value) + : StampedElement(), name_(name), value_(value) { } -StampedValue::StampedValue(const int64_t value) - : StampedElement(), value_() { +StampedValue::StampedValue(const std::string& name, + const int64_t value) + : StampedElement(), name_(name), value_() { + try { value_ = boost::lexical_cast(value); } catch (...) { @@ -25,6 +28,19 @@ StampedValue::StampedValue(const int64_t value) } } +StampedValuePtr +StampedValue::create(const std::string& name, + const std::string& value) { + return (StampedValuePtr(new StampedValue(name, value))); +} + +StampedValuePtr +StampedValue::create(const std::string& name, + const int64_t value) { + return (StampedValuePtr(new StampedValue(name, value))); +} + + int64_t StampedValue::getSignedIntegerValue() const { if (!value_.empty()) { diff --git a/src/lib/cc/stamped_value.h b/src/lib/cc/stamped_value.h index c6168a6ed2..d8a406fb9c 100644 --- a/src/lib/cc/stamped_value.h +++ b/src/lib/cc/stamped_value.h @@ -15,6 +15,14 @@ namespace isc { namespace data { +class StampedValue; + +/// @brief Pointer to the stamped value. +typedef boost::shared_ptr StampedValuePtr; + +/// @brief Collection of pointers to values. +typedef std::vector StampedValueCollection; + /// @brief This class represents string or signed integer configuration /// element associated with the modification timestamp. /// @@ -33,17 +41,38 @@ public: /// /// Creates stamped value from a string. /// + /// @param name Name of the value. /// @param value Value to be set. - explicit StampedValue(const std::string& value); + StampedValue(const std::string& name, const std::string& value); /// @brief Constructor. /// /// Creates stamped value from the signed integer. /// + /// @param name Name of the value. /// @param value Value to be set. - explicit StampedValue(const int64_t value); + explicit StampedValue(const std::string& name, const int64_t value); + + /// @brief Convenience function creating shared pointer to the object. + /// + /// @param name Name of the value. + /// @param value String value to be encapsulated by this object. + static StampedValuePtr create(const std::string& name, + const std::string& value); + + /// @brief Convenience function creating shared Pointer to the object. + /// + /// @param name Name of the value. + /// @param value Integer value to be encapsulated by this object. + static StampedValuePtr create(const std::string& name, + const int64_t value); - /// @brief Returns value as string. + /// @brief Returns value name. + std::string getName() const { + return (name_); + } + + /// @Brief Returns value as string. std::string getValue() const { return (value_); } @@ -55,6 +84,9 @@ public: private: + /// @brief Name of the value. + std::string name_; + /// @brief Holds value as a string. std::string value_; }; diff --git a/src/lib/cc/tests/stamped_value_unittest.cc b/src/lib/cc/tests/stamped_value_unittest.cc index 6d5651a994..4419a5f7f8 100644 --- a/src/lib/cc/tests/stamped_value_unittest.cc +++ b/src/lib/cc/tests/stamped_value_unittest.cc @@ -19,7 +19,8 @@ namespace { // Tests that stamped value from string can be created. TEST(StampedValueTest, createFromString) { boost::scoped_ptr value; - ASSERT_NO_THROW(value.reset(new StampedValue("foo"))); + ASSERT_NO_THROW(value.reset(new StampedValue("bar", "foo"))); + EXPECT_EQ("bar", value->getName()); EXPECT_EQ("foo", value->getValue()); EXPECT_THROW(value->getSignedIntegerValue(), BadValue); } @@ -27,7 +28,8 @@ TEST(StampedValueTest, createFromString) { // Tests that stamped value from integer can be created. TEST(StampedValueTest, createFromInteger) { boost::scoped_ptr value; - ASSERT_NO_THROW(value.reset(new StampedValue(5))); + ASSERT_NO_THROW(value.reset(new StampedValue("bar", 5))); + EXPECT_EQ("bar", value->getName()); EXPECT_EQ("5", value->getValue()); int64_t signed_integer; ASSERT_NO_THROW(signed_integer = value->getSignedIntegerValue()); diff --git a/src/lib/config_backend/base_config_backend_pool.h b/src/lib/config_backend/base_config_backend_pool.h index 93ad080cff..a74f2f66a5 100644 --- a/src/lib/config_backend/base_config_backend_pool.h +++ b/src/lib/config_backend/base_config_backend_pool.h @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -147,87 +146,6 @@ protected: } } - /// @brief Retrieve a single value encapsulated in the @c OptionalValue - /// template. - /// - /// This is common method for retrieving a single configuration property - /// from the databases. The property is encapsulated in the @c OptionalValue - /// class. The value is set to "unspecified" if it is null in the database. - /// The following is the example implementation of the method retrieving - /// global conifguration value: - /// - /// @code - /// OptionalValue - /// getGlobalParameter4(const std::string& parameter_name, - /// const BackendSelector& backend_selector, - /// const ServerSelector& server_selector) const { - /// std::string parameter; - /// getOptionalPropertyConst - /// (&ConfigBackendDHCPv4::getGlobalParameter4, backend_selector, - /// server_selector, parameter, parameter_name); - /// return (parameter); - /// } - /// @endcode - /// - /// where @c ConfigBackendDHCPv4::getGlobalParameter has the following signature: - /// - /// @code - /// std::string getGlobalParameter4(const ServerSelector&, const std::string&) const; - /// @endcode - /// - /// - /// @tparam PropertyType Type of the object returned by the backend call. - /// @tparam FnPtrArgs Parameter pack holding argument types of the backend - /// method to be invoked. - /// @tparam Args Parameter pack holding types of the arguments provided - /// in the call to this method. - /// - /// @param MethodPointer Pointer to the backend method to be called. - /// @param backend_selector Backend selector. - /// @param server_selector Server selector. - /// @param [out] property Reference to the shared pointer where retrieved - /// property should be assigned. - /// @param input Values to be used as input to the backend call. - /// - /// @throw db::NoSuchDatabase if no database matching the given selector - /// was found. - template - void getOptionalPropertyConst(util::OptionalValue - (ConfigBackendType::*MethodPointer) - (const db::ServerSelector&, FnPtrArgs...) const, - const db::BackendSelector& backend_selector, - const db::ServerSelector& server_selector, - util::OptionalValue& property, - Args... input) const { - - // If no particular backend is selected, call each backend and return - // the first non-null (non zero) value. - if (backend_selector.amUnspecified()) { - for (auto backend : backends_) { - property = ((*backend).*MethodPointer)(server_selector, input...); - if (property.isSpecified()) { - break; - } - } - - } else { - // Backend selected, find the one that matches selection. - auto backends = selectBackends(backend_selector); - if (!backends.empty()) { - for (auto backend : backends) { - property = ((*backend).*MethodPointer)(server_selector, input...); - if (property.isSpecified()) { - break; - } - } - - } else { - isc_throw(db::NoSuchDatabase, "no such database found for selector: " - << backend_selector.toText()); - } - } - } - /// @brief Retrieve multiple configuration properties from the pool. /// /// This is a common method for retrieving multiple configuration properties diff --git a/src/lib/dhcpsrv/config_backend_dhcp4.h b/src/lib/dhcpsrv/config_backend_dhcp4.h index 25fa180b4f..7ce80d19c5 100644 --- a/src/lib/dhcpsrv/config_backend_dhcp4.h +++ b/src/lib/dhcpsrv/config_backend_dhcp4.h @@ -7,6 +7,7 @@ #ifndef CONFIG_BACKEND_DHCP4_H #define CONFIG_BACKEND_DHCP4_H +#include #include #include #include @@ -14,9 +15,7 @@ #include #include #include -#include #include -#include #include namespace isc { @@ -120,20 +119,20 @@ public: /// @brief Retrieves single option by code and space. /// - /// @param selector Server selector. + /// @param server_selector Server selector. /// @return Pointer to the retrieved option descriptor or null if /// no option was found. virtual OptionDescriptorPtr - getOption4(const db::ServerSelector& selector, const uint16_t code, + getOption4(const db::ServerSelector& server_selector, const uint16_t code, const std::string& space) const = 0; /// @brief Retrieves all global options. /// - /// @param selector Server selector. + /// @param server_selector Server selector. /// @return Collection of global options or empty collection if no /// option found. virtual OptionContainer - getAllOptions4(const db::ServerSelector& selector) const = 0; + getAllOptions4(const db::ServerSelector& server_selector) const = 0; /// @brief Retrieves option modified after specified time. /// @@ -145,28 +144,27 @@ public: getModifiedOptions4(const db::ServerSelector& selector, const boost::posix_time::ptime& modification_time) const = 0; - /// @brief Retrieves global string parameter value. + /// @brief Retrieves global parameter value. /// /// @param server_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& server_selector, - const std::string& name) const = 0; + /// @return Value of the global parameter or null if parameter doesn't + /// exist. + virtual data::StampedValuePtr + getGlobalParameter4(const db::ServerSelector& selector, + const std::string& name) const = 0; - /// @brief Retrieves global number parameter. - /// - /// @param server_selector Server selector. - /// @param name Name of the parameter to be retrieved. - virtual util::OptionalValue - getGlobalNumberParameter4(const db::ServerSelector& server_selector, - const std::string& name) const = 0; + /// @return Collection of global parameters. + virtual data::StampedValueCollection + getAllGlobalParameters4(const db::ServerSelector& selector) const = 0; - /// @brief Retrieves all global parameters as strings. + /// @brief Retrieves global parameters modified after specified time. /// - /// @param server_selector Server selector. - virtual std::map - getAllGlobalParameters4(const db::ServerSelector& server_selector) const = 0; + /// @param selector Server selector. + /// @return Collection of modified global parameters. + virtual data::StampedValueCollection + getModifiedGlobalParameters4(const db::ServerSelector& selector, + const boost::posix_time::ptime& modification_time) const = 0; /// @brief Creates or updates a subnet. /// @@ -235,26 +233,14 @@ public: const asiolink::IOAddress& pool_end_address, const OptionDescriptorPtr& option) = 0; - /// @brief Creates or updates global string parameter. + /// @brief Creates or updates global parameter. /// /// @param server_selector Server selector. - /// @param name Name of the global parameter. /// @param value Value of the global parameter. virtual void createUpdateGlobalParameter4(const db::ServerSelector& server_selector, - const std::string& name, - const std::string& value) = 0; + const data::StampedValuePtr& value) = 0; - /// @brief Creates or updates global number parameter. - /// - /// @param server_selector Server selector. - /// @param name Name of the global parameter. - /// @param value Value of the global parameter. - virtual void - createUpdateGlobalParameter4(const db::ServerSelector& server_selector, - const std::string& name, - const int64_t value) = 0; - /// @brief Deletes subnet by prefix. /// /// @param server_selector Server selector. diff --git a/src/lib/dhcpsrv/config_backend_pool_dhcp4.cc b/src/lib/dhcpsrv/config_backend_pool_dhcp4.cc index a01f757d98..192c85cb3c 100644 --- a/src/lib/dhcpsrv/config_backend_pool_dhcp4.cc +++ b/src/lib/dhcpsrv/config_backend_pool_dhcp4.cc @@ -8,8 +8,8 @@ #include using namespace isc::asiolink; +using namespace isc::data; using namespace isc::db; -using namespace isc::util; namespace isc { namespace dhcp { @@ -156,38 +156,39 @@ ConfigBackendPoolDHCPv4::getModifiedOptions4(const BackendSelector& backend_sele return (options); } -util::OptionalValue -ConfigBackendPoolDHCPv4::getGlobalStringParameter4(const BackendSelector& backend_selector, - const ServerSelector& server_selector, - const std::string& name) const { - OptionalValue parameter; - getOptionalPropertyConst - (&ConfigBackendDHCPv4::getGlobalStringParameter4, backend_selector, - server_selector, parameter, name); - return (parameter); -} - -util::OptionalValue -ConfigBackendPoolDHCPv4::getGlobalNumberParameter4(const BackendSelector& backend_selector, - const ServerSelector& server_selector, - const std::string& name) const { - OptionalValue parameter; - getOptionalPropertyConst - (&ConfigBackendDHCPv4::getGlobalNumberParameter4, backend_selector, - server_selector, parameter, name); - return (parameter); +StampedValuePtr +ConfigBackendPoolDHCPv4::getGlobalParameter4(const BackendSelector& backend_selector, + const ServerSelector& server_selector, + const std::string& name) const { + StampedValuePtr parameter; + getPropertyPtrConst + (&ConfigBackendDHCPv4::getGlobalParameter4, backend_selector, + server_selector, parameter, name); + return (parameter); } -std::map +StampedValueCollection ConfigBackendPoolDHCPv4::getAllGlobalParameters4(const BackendSelector& backend_selector, const ServerSelector& server_selector) const { - std::map parameters; - getAllPropertiesConst > + StampedValueCollection parameters; + getAllPropertiesConst (&ConfigBackendDHCPv4::getAllGlobalParameters4, backend_selector, server_selector, parameters); return (parameters); } +StampedValueCollection +ConfigBackendPoolDHCPv4:: +getModifiedGlobalParameters4(const db::BackendSelector& backend_selector, + const db::ServerSelector& server_selector, + const boost::posix_time::ptime& modification_time) const { + StampedValueCollection parameters; + getMultiplePropertiesConst + (&ConfigBackendDHCPv4::getModifiedGlobalParameters4, backend_selector, + server_selector, parameters, modification_time); + return (parameters); +} + void ConfigBackendPoolDHCPv4::createUpdateSubnet4(const BackendSelector& backend_selector, const ServerSelector& server_selector, @@ -260,23 +261,12 @@ ConfigBackendPoolDHCPv4::createUpdateOption4(const BackendSelector& backend_sele void ConfigBackendPoolDHCPv4::createUpdateGlobalParameter4(const BackendSelector& backend_selector, const ServerSelector& server_selector, - const std::string& name, - const std::string& value) { - createUpdateDeleteProperty + const StampedValuePtr& value) { + createUpdateDeleteProperty (&ConfigBackendDHCPv4::createUpdateGlobalParameter4, backend_selector, - server_selector, name, value); + server_selector, value); } -void -ConfigBackendPoolDHCPv4::createUpdateGlobalParameter4(const BackendSelector& backend_selector, - const ServerSelector& server_selector, - const std::string& name, - const int64_t value) { - createUpdateDeleteProperty - (&ConfigBackendDHCPv4::createUpdateGlobalParameter4, backend_selector, - server_selector, name, value); -} - uint64_t ConfigBackendPoolDHCPv4::deleteSubnet4(const BackendSelector& backend_selector, const ServerSelector& server_selector, diff --git a/src/lib/dhcpsrv/config_backend_pool_dhcp4.h b/src/lib/dhcpsrv/config_backend_pool_dhcp4.h index 87816993dc..057d29d775 100644 --- a/src/lib/dhcpsrv/config_backend_pool_dhcp4.h +++ b/src/lib/dhcpsrv/config_backend_pool_dhcp4.h @@ -7,6 +7,7 @@ #ifndef CONFIG_BACKEND_POOL_DHCP4_H #define CONFIG_BACKEND_POOL_DHCP4_H +#include #include #include #include @@ -16,7 +17,6 @@ #include #include #include -#include #include #include @@ -172,34 +172,35 @@ public: const db::ServerSelector& server_selector, const boost::posix_time::ptime& modification_time) const; - /// @brief Retrieves global string parameter value. + /// @brief Retrieves global parameter value. /// /// @param backend_selector Backend selector. /// @param server_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::BackendSelector& backend_selector, - const db::ServerSelector& server_selector, - const std::string& name) const; + /// @return Value of the global parameter. + virtual data::StampedValuePtr + getGlobalParameter4(const db::BackendSelector& backend_selector, + const db::ServerSelector& server_selector, + const std::string& name) const; - /// @brief Retrieves global number parameter. + /// @brief Retrieves all global parameters. /// /// @param backend_selector Backend selector. /// @param server_selector Server selector. - /// @param name Name of the parameter to be retrieved. - virtual util::OptionalValue - getGlobalNumberParameter4(const db::BackendSelector& backend_selector, - const db::ServerSelector& server_selector, - const std::string& name) const; + virtual data::StampedValueCollection + getAllGlobalParameters4(const db::BackendSelector& backend_selector, + const db::ServerSelector& server_selector) const; - /// @brief Retrieves all global parameters as strings. + /// @brief Retrieves global parameters modified after specified time. /// /// @param backend_selector Backend selector. /// @param server_selector Server selector. - virtual std::map - getAllGlobalParameters4(const db::BackendSelector& backend_selector, - const db::ServerSelector& server_selector) const; + /// @param modification_time Lower bound subnet modification time. + /// @return Collection of modified global parameters. + virtual data::StampedValueCollection + getModifiedGlobalParameters4(const db::BackendSelector& backend_selector, + const db::ServerSelector& server_selector, + const boost::posix_time::ptime& modification_time) const; /// @brief Creates or updates a subnet. /// @@ -291,21 +292,8 @@ public: virtual void createUpdateGlobalParameter4(const db::BackendSelector& backend_selector, const db::ServerSelector& server_selector, - const std::string& name, - const std::string& value); + const data::StampedValuePtr& value); - /// @brief Creates or updates global number parameter. - /// - /// @param backend_selector Backend selector. - /// @param server_selector Server selector. - /// @param name Name of the global parameter. - /// @param value Value of the global parameter. - virtual void - createUpdateGlobalParameter4(const db::BackendSelector& backend_selector, - const db::ServerSelector& server_selector, - const std::string& name, - const int64_t value); - /// @brief Deletes subnet by prefix. /// /// @param backend_selector Backend selector. @@ -395,14 +383,14 @@ public: /// @brief Deletes shared network level option. /// /// @param backend_selector Backend selector. - /// @param selector Server selector. + /// @param server_selector Server selector. /// @param shared_network_name Name of the shared network which option /// belongs to. /// @param code Code of the option to be deleted. /// @param space Option space of the option to be deleted. virtual uint64_t deleteOption4(const db::BackendSelector& backend_selector, - const db::ServerSelector& selector, + const db::ServerSelector& server_selector, const std::string& shared_network_name, const uint16_t code, const std::string& space) = 0; diff --git a/src/share/database/scripts/mysql/dhcpdb_create.mysql.orig b/src/share/database/scripts/mysql/dhcpdb_create.mysql.orig new file mode 100644 index 0000000000..90e03cf26b --- /dev/null +++ b/src/share/database/scripts/mysql/dhcpdb_create.mysql.orig @@ -0,0 +1,1359 @@ +# Copyright (C) 2012-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/. + +# This is the Kea schema specification for MySQL. +# +# The schema is reasonably portable (with the exception of the engine +# specification, which is MySQL-specific). Minor changes might be needed for +# other databases. + +# To create the schema, either type the command: +# +# mysql -u -p < dhcpdb_create.mysql +# +# ... at the command prompt, or log in to the MySQL database and at the 'mysql>' +# prompt, issue the command: +# +# source dhcpdb_create.mysql +# +# This script is also called from kea-admin, see kea-admin lease-init mysql +# +# Over time, Kea database schema will evolve. Each version is marked with +# major.minor version. This file is organized sequentially, i.e. database +# is initialized to 1.0, then upgraded to 2.0 etc. This may be somewhat +# sub-optimal, but it ensues consistency with upgrade scripts. (It is much +# easier to maintain init and upgrade scripts if they look the same). +# Since initialization is done only once, it's performance is not an issue. + +# This line starts database initialization to 1.0. + +# Holds the IPv4 leases. +CREATE TABLE lease4 ( + address INT UNSIGNED PRIMARY KEY NOT NULL, # IPv4 address + hwaddr VARBINARY(20), # Hardware address + client_id VARBINARY(128), # Client ID + valid_lifetime INT UNSIGNED, # Length of the lease (seconds) + expire TIMESTAMP, # Expiration time of the lease + subnet_id INT UNSIGNED, # Subnet identification + fqdn_fwd BOOL, # Has forward DNS update been performed by a server + fqdn_rev BOOL, # Has reverse DNS update been performed by a server + hostname VARCHAR(255) # The FQDN of the client + ) ENGINE = INNODB; + + +# Create search indexes for lease4 table +# index by hwaddr and subnet_id +CREATE INDEX lease4_by_hwaddr_subnet_id ON lease4 (hwaddr, subnet_id); + +# index by client_id and subnet_id +CREATE INDEX lease4_by_client_id_subnet_id ON lease4 (client_id, subnet_id); + +# Holds the IPv6 leases. +# N.B. The use of a VARCHAR for the address is temporary for development: +# it will eventually be replaced by BINARY(16). +CREATE TABLE lease6 ( + address VARCHAR(39) PRIMARY KEY NOT NULL, # IPv6 address + duid VARBINARY(128), # DUID + valid_lifetime INT UNSIGNED, # Length of the lease (seconds) + expire TIMESTAMP, # Expiration time of the lease + subnet_id INT UNSIGNED, # Subnet identification + pref_lifetime INT UNSIGNED, # Preferred lifetime + lease_type TINYINT, # Lease type (see lease6_types + # table for possible values) + iaid INT UNSIGNED, # See Section 10 of RFC 3315 + prefix_len TINYINT UNSIGNED, # For IA_PD only + fqdn_fwd BOOL, # Has forward DNS update been performed by a server + fqdn_rev BOOL, # Has reverse DNS update been performed by a server + hostname VARCHAR(255) # The FQDN of the client + + ) ENGINE = INNODB; + +# Create search indexes for lease4 table +# index by iaid, subnet_id, and duid +CREATE INDEX lease6_by_iaid_subnet_id_duid ON lease6 (iaid, subnet_id, duid); + +# ... and a definition of lease6 types. This table is a convenience for +# users of the database - if they want to view the lease table and use the +# type names, they can join this table with the lease6 table. +# Make sure those values match Lease6::LeaseType enum (see src/bin/dhcpsrv/ +# lease_mgr.h) +CREATE TABLE lease6_types ( + lease_type TINYINT PRIMARY KEY NOT NULL, # Lease type code. + name VARCHAR(5) # Name of the lease type + ) ENGINE = INNODB; + +START TRANSACTION; +INSERT INTO lease6_types VALUES (0, 'IA_NA'); # Non-temporary v6 addresses +INSERT INTO lease6_types VALUES (1, 'IA_TA'); # Temporary v6 addresses +INSERT INTO lease6_types VALUES (2, 'IA_PD'); # Prefix delegations +COMMIT; + +# Finally, the version of the schema. We start at 1.0 during development. +# This table is only modified during schema upgrades. For historical reasons +# (related to the names of the columns in the BIND 10 DNS database file), the +# first column is called 'version' and not 'major'. +CREATE TABLE schema_version ( + version INT PRIMARY KEY NOT NULL, # Major version number + minor INT # Minor version number + ) ENGINE = INNODB; +START TRANSACTION; +INSERT INTO schema_version VALUES (1, 0); +COMMIT; + +# This line concludes database initialization to version 1.0. + +# This line starts database upgrade to version 2.0. +ALTER TABLE lease6 + ADD COLUMN hwaddr varbinary(20), # Hardware/MAC address, typically only 6 + # bytes is used, but some hardware (e.g. + # Infiniband) use up to 20. + ADD COLUMN hwtype smallint unsigned, # hardware type (16 bits) + ADD COLUMN hwaddr_source int unsigned; # Hardware source. See description + # of lease_hwaddr_source below. + +# Kea keeps track of the hardware/MAC address source, i.e. how the address +# was obtained. Depending on the technique and your network topology, it may +# be more or less trustworthy. This table is a convenience for +# users of the database - if they want to view the lease table and use the +# type names, they can join this table with the lease6 table. For details, +# see constants defined in src/lib/dhcp/dhcp/pkt.h for detailed explanation. +CREATE TABLE lease_hwaddr_source ( + hwaddr_source INT PRIMARY KEY NOT NULL, + name VARCHAR(40) +) ENGINE = INNODB; + +# Hardware address obtained from raw sockets +INSERT INTO lease_hwaddr_source VALUES (1, 'HWADDR_SOURCE_RAW'); + +# Hardware address converted from IPv6 link-local address with EUI-64 +INSERT INTO lease_hwaddr_source VALUES (2, 'HWADDR_SOURCE_IPV6_LINK_LOCAL'); + +# Hardware address extracted from client-id (duid) +INSERT INTO lease_hwaddr_source VALUES (4, 'HWADDR_SOURCE_DUID'); + +# Hardware address extracted from client address relay option (RFC6939) +INSERT INTO lease_hwaddr_source VALUES (8, 'HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION'); + +# Hardware address extracted from remote-id option (RFC4649) +INSERT INTO lease_hwaddr_source VALUES (16, 'HWADDR_SOURCE_REMOTE_ID'); + +# Hardware address extracted from subscriber-id option (RFC4580) +INSERT INTO lease_hwaddr_source VALUES (32, 'HWADDR_SOURCE_SUBSCRIBER_ID'); + +# Hardware address extracted from docsis options +INSERT INTO lease_hwaddr_source VALUES (64, 'HWADDR_SOURCE_DOCSIS'); + +UPDATE schema_version SET version='2', minor='0'; + +# This line concludes database upgrade to version 2.0. + +# This line starts database upgrade to version 3.0. +# Upgrade extending MySQL schema with the ability to store hosts. + +CREATE TABLE IF NOT EXISTS hosts ( + host_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + dhcp_identifier VARBINARY(128) NOT NULL, + dhcp_identifier_type TINYINT NOT NULL, + dhcp4_subnet_id INT UNSIGNED NULL, + dhcp6_subnet_id INT UNSIGNED NULL, + ipv4_address INT UNSIGNED NULL, + hostname VARCHAR(255) NULL, + dhcp4_client_classes VARCHAR(255) NULL, + dhcp6_client_classes VARCHAR(255) NULL, + PRIMARY KEY (host_id), + INDEX key_dhcp4_identifier_subnet_id (dhcp_identifier ASC , dhcp_identifier_type ASC), + INDEX key_dhcp6_identifier_subnet_id (dhcp_identifier ASC , dhcp_identifier_type ASC , dhcp6_subnet_id ASC) +) ENGINE=INNODB; +-- ----------------------------------------------------- +-- Table `ipv6_reservations` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS ipv6_reservations ( + reservation_id INT NOT NULL AUTO_INCREMENT, + address VARCHAR(39) NOT NULL, + prefix_len TINYINT(3) UNSIGNED NOT NULL DEFAULT 128, + type TINYINT(4) UNSIGNED NOT NULL DEFAULT 0, + dhcp6_iaid INT UNSIGNED NULL, + host_id INT UNSIGNED NOT NULL, + PRIMARY KEY (reservation_id), + INDEX fk_ipv6_reservations_host_idx (host_id ASC), + CONSTRAINT fk_ipv6_reservations_Host FOREIGN KEY (host_id) + REFERENCES hosts (host_id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=INNODB; +-- ----------------------------------------------------- +-- Table `dhcp4_options` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp4_options ( + option_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + code TINYINT UNSIGNED NOT NULL, + value BLOB NULL, + formatted_value TEXT NULL, + space VARCHAR(128) NULL, + persistent TINYINT(1) NOT NULL DEFAULT 0, + dhcp_client_class VARCHAR(128) NULL, + dhcp4_subnet_id INT NULL, + host_id INT UNSIGNED NULL, + PRIMARY KEY (option_id), + UNIQUE INDEX option_id_UNIQUE (option_id ASC), + INDEX fk_options_host1_idx (host_id ASC), + CONSTRAINT fk_options_host1 FOREIGN KEY (host_id) + REFERENCES hosts (host_id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=INNODB; +-- ----------------------------------------------------- +-- Table `dhcp6_options` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp6_options ( + option_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + code INT UNSIGNED NOT NULL, + value BLOB NULL, + formatted_value TEXT NULL, + space VARCHAR(128) NULL, + persistent TINYINT(1) NOT NULL DEFAULT 0, + dhcp_client_class VARCHAR(128) NULL, + dhcp6_subnet_id INT NULL, + host_id INT UNSIGNED NULL, + PRIMARY KEY (option_id), + UNIQUE INDEX option_id_UNIQUE (option_id ASC), + INDEX fk_options_host1_idx (host_id ASC), + CONSTRAINT fk_options_host10 FOREIGN KEY (host_id) + REFERENCES hosts (host_id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=INNODB; + +DELIMITER $$ +CREATE TRIGGER host_BDEL BEFORE DELETE ON hosts FOR EACH ROW +-- Edit trigger body code below this line. Do not edit lines above this one +BEGIN +DELETE FROM ipv6_reservations WHERE ipv6_reservations.host_id = OLD.host_id; +END +$$ +DELIMITER ; + +UPDATE schema_version +SET version = '3', minor = '0'; +# This line concludes database upgrade to version 3.0. + +# This line starts database upgrade to version 4.0. +# Upgrade extending MySQL schema with the state columns for lease tables. + +# Add state column to the lease4 table. +ALTER TABLE lease4 + ADD COLUMN state INT UNSIGNED DEFAULT 0; + +# Add state column to the lease6 table. +ALTER TABLE lease6 + ADD COLUMN state INT UNSIGNED DEFAULT 0; + +# Create indexes for querying leases in a given state and segregated +# by the expiration time. One of the applications is to retrieve all +# expired leases. However, these indexes can be also used to retrieve +# leases in a given state regardless of the expiration time. +CREATE INDEX lease4_by_state_expire ON lease4 (state ASC, expire ASC); +CREATE INDEX lease6_by_state_expire ON lease6 (state ASC, expire ASC); + +# Create table holding mapping of the lease states to their names. +# This is not used in queries from the DHCP server but rather in +# direct queries from the lease database management tools. +CREATE TABLE IF NOT EXISTS lease_state ( + state INT UNSIGNED PRIMARY KEY NOT NULL, + name VARCHAR(64) NOT NULL +) ENGINE=INNODB; + +# Insert currently defined state names. +INSERT INTO lease_state VALUES (0, 'default'); +INSERT INTO lease_state VALUES (1, 'declined'); +INSERT INTO lease_state VALUES (2, 'expired-reclaimed'); + +# Add a constraint that any state value added to the lease4 must +# map to a value in the lease_state table. +ALTER TABLE lease4 + ADD CONSTRAINT fk_lease4_state FOREIGN KEY (state) + REFERENCES lease_state (state); + +# Add a constraint that any state value added to the lease6 must +# map to a value in the lease_state table. +ALTER TABLE lease6 + ADD CONSTRAINT fk_lease6_state FOREIGN KEY (state) + REFERENCES lease_state (state); + +# Add a constraint that lease type in the lease6 table must map +# to a lease type defined in the lease6_types table. +ALTER TABLE lease6 + ADD CONSTRAINT fk_lease6_type FOREIGN KEY (lease_type) + REFERENCES lease6_types (lease_type); + +# Modify the name of one of the HW address sources, and add a new one. +UPDATE lease_hwaddr_source + SET name = 'HWADDR_SOURCE_DOCSIS_CMTS' + WHERE hwaddr_source = 64; + +INSERT INTO lease_hwaddr_source VALUES (128, 'HWADDR_SOURCE_DOCSIS_MODEM'); + +# Add UNSIGNED to match with the lease6. +ALTER TABLE lease_hwaddr_source + MODIFY COLUMN hwaddr_source INT UNSIGNED NOT NULL; + +# Add a constraint that non-null hwaddr_source in the lease6 table +# must map to an entry in the lease_hwaddr_source. +ALTER TABLE lease6 + ADD CONSTRAINT fk_lease6_hwaddr_source FOREIGN KEY (hwaddr_source) + REFERENCES lease_hwaddr_source (hwaddr_source); + +# FUNCTION that returns a result set containing the column names for lease4 dumps +DROP PROCEDURE IF EXISTS lease4DumpHeader; +DELIMITER $$ +CREATE PROCEDURE lease4DumpHeader() +BEGIN +SELECT 'address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state'; +END $$ +DELIMITER ; + +# FUNCTION that returns a result set containing the data for lease4 dumps +DROP PROCEDURE IF EXISTS lease4DumpData; +DELIMITER $$ +CREATE PROCEDURE lease4DumpData() +BEGIN +SELECT + INET_NTOA(l.address), + IFNULL(HEX(l.hwaddr), ''), + IFNULL(HEX(l.client_id), ''), + l.valid_lifetime, + l.expire, + l.subnet_id, + l.fqdn_fwd, + l.fqdn_rev, + l.hostname, + s.name +FROM + lease4 l + LEFT OUTER JOIN lease_state s on (l.state = s.state) +ORDER BY l.address; +END $$ +DELIMITER ; + +# FUNCTION that returns a result set containing the column names for lease6 dumps +DROP PROCEDURE IF EXISTS lease6DumpHeader; +DELIMITER $$ +CREATE PROCEDURE lease6DumpHeader() +BEGIN +SELECT 'address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,hwtype,hwaddr_source,state'; +END $$ +DELIMITER ; + +# FUNCTION that returns a result set containing the data for lease6 dumps +DROP PROCEDURE IF EXISTS lease6DumpData; +DELIMITER $$ +CREATE PROCEDURE lease6DumpData() +BEGIN +SELECT + l.address, + IFNULL(HEX(l.duid), ''), + l.valid_lifetime, + l.expire, + l.subnet_id, + l.pref_lifetime, + IFNULL(t.name, ''), + l.iaid, + l.prefix_len, + l.fqdn_fwd, + l.fqdn_rev, + l.hostname, + IFNULL(HEX(l.hwaddr), ''), + IFNULL(l.hwtype, ''), + IFNULL(h.name, ''), + IFNULL(s.name, '') +FROM lease6 l + left outer join lease6_types t on (l.lease_type = t.lease_type) + left outer join lease_state s on (l.state = s.state) + left outer join lease_hwaddr_source h on (l.hwaddr_source = h.hwaddr_source) +ORDER BY l.address; +END $$ +DELIMITER ; + +# Update the schema version number +UPDATE schema_version +SET version = '4', minor = '0'; + +# This line concludes database upgrade to version 4.0. + +# In the event hardware address cannot be determined, we need to satisfy +# foreign key constraint between lease6 and lease_hardware_source +INSERT INTO lease_hwaddr_source VALUES (0, 'HWADDR_SOURCE_UNKNOWN'); + +# Update the schema version number +UPDATE schema_version +SET version = '4', minor = '1'; + +# This line concludes database upgrade to version 4.1. + +# Update index used for searching DHCPv4 reservations by identifier and subnet id. +# This index is now unique (to prevent duplicates) and includes DHCPv4 subnet +# identifier. +DROP INDEX key_dhcp4_identifier_subnet_id ON hosts; +CREATE UNIQUE INDEX key_dhcp4_identifier_subnet_id ON hosts (dhcp_identifier ASC , dhcp_identifier_type ASC , dhcp4_subnet_id ASC); + +# Update index used for searching DHCPv6 reservations by identifier and subnet id. +# This index is now unique to prevent duplicates. +DROP INDEX key_dhcp6_identifier_subnet_id ON hosts; +CREATE UNIQUE INDEX key_dhcp6_identifier_subnet_id ON hosts (dhcp_identifier ASC , dhcp_identifier_type ASC , dhcp6_subnet_id ASC); + +# Create index to search for reservations using IP address and subnet id. +# This unique index guarantees that there is only one occurrence of the +# particular IPv4 address for a given subnet. +CREATE UNIQUE INDEX key_dhcp4_ipv4_address_subnet_id ON hosts (ipv4_address ASC , dhcp4_subnet_id ASC); + +# Create index to search for reservations using address/prefix and prefix +# length. +CREATE UNIQUE INDEX key_dhcp6_address_prefix_len ON ipv6_reservations (address ASC , prefix_len ASC); + +# Create a table mapping host identifiers to their names. Values in this +# table are used as a foreign key in hosts table to guarantee that only +# identifiers present in host_identifier_type table are used in hosts +# table. +CREATE TABLE IF NOT EXISTS host_identifier_type ( + type TINYINT PRIMARY KEY NOT NULL, # Lease type code. + name VARCHAR(32) # Name of the lease type +) ENGINE = INNODB; + +START TRANSACTION; +INSERT INTO host_identifier_type VALUES (0, 'hw-address'); +INSERT INTO host_identifier_type VALUES (1, 'duid'); +INSERT INTO host_identifier_type VALUES (2, 'circuit-id'); +COMMIT; + +# Add a constraint that any identifier type value added to the hosts +# must map to a value in the host_identifier_type table. +ALTER TABLE hosts + ADD CONSTRAINT fk_host_identifier_type FOREIGN KEY (dhcp_identifier_type) + REFERENCES host_identifier_type (type); + +# Store DHCPv6 option code as 16-bit unsigned integer. +ALTER TABLE dhcp6_options MODIFY code SMALLINT UNSIGNED NOT NULL; + +# Subnet identifier is unsigned. +ALTER TABLE dhcp4_options MODIFY dhcp4_subnet_id INT UNSIGNED NULL; +ALTER TABLE dhcp6_options MODIFY dhcp6_subnet_id INT UNSIGNED NULL; + +# Scopes associate DHCP options stored in dhcp4_options and +# dhcp6_options tables with hosts, subnets, classes or indicate +# that they are global options. +CREATE TABLE IF NOT EXISTS dhcp_option_scope ( + scope_id TINYINT UNSIGNED PRIMARY KEY NOT NULL, + scope_name VARCHAR(32) +) ENGINE = INNODB; + +START TRANSACTION; +INSERT INTO dhcp_option_scope VALUES (0, 'global'); +INSERT INTO dhcp_option_scope VALUES (1, 'subnet'); +INSERT INTO dhcp_option_scope VALUES (2, 'client-class'); +INSERT INTO dhcp_option_scope VALUES (3, 'host'); +COMMIT; + +# Add scopes into table holding DHCPv4 options +ALTER TABLE dhcp4_options ADD COLUMN scope_id TINYINT UNSIGNED NOT NULL; +ALTER TABLE dhcp4_options + ADD CONSTRAINT fk_dhcp4_option_scope FOREIGN KEY (scope_id) + REFERENCES dhcp_option_scope (scope_id); + +# Add scopes into table holding DHCPv6 options +ALTER TABLE dhcp6_options ADD COLUMN scope_id TINYINT UNSIGNED NOT NULL; +ALTER TABLE dhcp6_options + ADD CONSTRAINT fk_dhcp6_option_scope FOREIGN KEY (scope_id) + REFERENCES dhcp_option_scope (scope_id); + +# Add UNSIGNED to reservation_id +ALTER TABLE ipv6_reservations + MODIFY reservation_id INT UNSIGNED NOT NULL AUTO_INCREMENT; + +# This line concludes database upgrade to version 7.0. + +# Add columns holding reservations for siaddr, sname and file fields +# carried within DHCPv4 message. +ALTER TABLE hosts ADD COLUMN dhcp4_next_server INT UNSIGNED NULL; +ALTER TABLE hosts ADD COLUMN dhcp4_server_hostname VARCHAR(64) NULL; +ALTER TABLE hosts ADD COLUMN dhcp4_boot_file_name VARCHAR(128) NULL; + +# Update the schema version number +UPDATE schema_version +SET version = '5', minor = '0'; +# This line concludes database upgrade to version 5.0. + +# Add missing 'client-id' and new 'flex-id' host identifier types. +INSERT INTO host_identifier_type VALUES (3, 'client-id'); +INSERT INTO host_identifier_type VALUES (4, 'flex-id'); + +# Recreate the trigger removing dependent host entries. +DROP TRIGGER host_BDEL; + +DELIMITER $$ +CREATE TRIGGER host_BDEL BEFORE DELETE ON hosts FOR EACH ROW +-- Edit trigger body code below this line. Do not edit lines above this one +BEGIN +DELETE FROM ipv6_reservations WHERE ipv6_reservations.host_id = OLD.host_id; +DELETE FROM dhcp4_options WHERE dhcp4_options.host_id = OLD.host_id; +DELETE FROM dhcp6_options WHERE dhcp6_options.host_id = OLD.host_id; +END +$$ +DELIMITER ; + +# Update the schema version number +UPDATE schema_version +SET version = '5', minor = '1'; +# This line concludes database upgrade to version 5.1. + +# Make subnet_id column types consistent with lease table columns +ALTER TABLE dhcp4_options MODIFY dhcp4_subnet_id INT UNSIGNED; +ALTER TABLE dhcp6_options MODIFY dhcp6_subnet_id INT UNSIGNED; + +# Update the schema version number +UPDATE schema_version +SET version = '5', minor = '2'; + +# This line concludes database upgrade to version 5.2. + +# Add user context into table holding hosts +ALTER TABLE hosts ADD COLUMN user_context TEXT NULL; + +# Add user contexts into tables holding DHCP options +ALTER TABLE dhcp4_options ADD COLUMN user_context TEXT NULL; +ALTER TABLE dhcp6_options ADD COLUMN user_context TEXT NULL; + +# Create index for searching leases by subnet identifier. +CREATE INDEX lease4_by_subnet_id ON lease4 (subnet_id); + +# Create for searching leases by subnet identifier and lease type. +CREATE INDEX lease6_by_subnet_id_lease_type ON lease6 (subnet_id, lease_type); + +# The index by iaid_subnet_id_duid is not the best choice because there are +# cases when we don't specify subnet identifier while searching leases. The +# index will be universal if the subnet_id is the right most column in the +# index. +DROP INDEX lease6_by_iaid_subnet_id_duid on lease6; +CREATE INDEX lease6_by_duid_iaid_subnet_id ON lease6 (duid, iaid, subnet_id); + +# Create lease4_stat table +CREATE TABLE lease4_stat ( + subnet_id INT UNSIGNED NOT NULL, + state INT UNSIGNED NOT NULL, + leases BIGINT, + PRIMARY KEY (subnet_id, state) +) ENGINE = INNODB; + +# Create stat_lease4_insert trigger +DELIMITER $$ +CREATE TRIGGER stat_lease4_insert AFTER INSERT ON lease4 + FOR EACH ROW + BEGIN + IF NEW.state = 0 OR NEW.state = 1 THEN + # Update the state count if it exists + UPDATE lease4_stat SET leases = leases + 1 + WHERE subnet_id = NEW.subnet_id AND state = NEW.state; + + # Insert the state count record if it does not exist + IF ROW_COUNT() <= 0 THEN + INSERT INTO lease4_stat VALUES (NEW.subnet_id, NEW.state, 1); + END IF; + END IF; + END $$ +DELIMITER ; + +# Create stat_lease4_update trigger +DELIMITER $$ +CREATE TRIGGER stat_lease4_update AFTER UPDATE ON lease4 + FOR EACH ROW + BEGIN + IF OLD.state != NEW.state THEN + IF OLD.state = 0 OR OLD.state = 1 THEN + # Decrement the old state count if record exists + UPDATE lease4_stat SET leases = leases - 1 + WHERE subnet_id = OLD.subnet_id AND state = OLD.state; + END IF; + + IF NEW.state = 0 OR NEW.state = 1 THEN + # Increment the new state count if record exists + UPDATE lease4_stat SET leases = leases + 1 + WHERE subnet_id = NEW.subnet_id AND state = NEW.state; + + # Insert new state record if it does not exist + IF ROW_COUNT() <= 0 THEN + INSERT INTO lease4_stat VALUES (NEW.subnet_id, NEW.state, 1); + END IF; + END IF; + END IF; + END $$ +DELIMITER ; + +# Create stat_lease4_delete trigger +DELIMITER $$ +CREATE TRIGGER stat_lease4_delete AFTER DELETE ON lease4 + FOR EACH ROW + BEGIN + IF OLD.state = 0 OR OLD.state = 1 THEN + # Decrement the state count if record exists + UPDATE lease4_stat SET leases = leases - 1 + WHERE subnet_id = OLD.subnet_id AND OLD.state = state; + END IF; + END $$ +DELIMITER ; + +# Create lease6_stat table +CREATE TABLE lease6_stat ( + subnet_id INT UNSIGNED NOT NULL, + lease_type INT UNSIGNED NOT NULL, + state INT UNSIGNED NOT NULL, + leases BIGINT, + PRIMARY KEY (subnet_id, lease_type, state) +) ENGINE = INNODB; + +# Create stat_lease6_insert trigger +DELIMITER $$ +CREATE TRIGGER stat_lease6_insert AFTER INSERT ON lease6 + FOR EACH ROW + BEGIN + IF NEW.state = 0 OR NEW.state = 1 THEN + # Update the state count if it exists + UPDATE lease6_stat SET leases = leases + 1 + WHERE + subnet_id = NEW.subnet_id AND lease_type = NEW.lease_type + AND state = NEW.state; + + # Insert the state count record if it does not exist + IF ROW_COUNT() <= 0 THEN + INSERT INTO lease6_stat + VALUES (NEW.subnet_id, NEW.lease_type, NEW.state, 1); + END IF; + END IF; + END $$ +DELIMITER ; + +# Create stat_lease6_update trigger +DELIMITER $$ +CREATE TRIGGER stat_lease6_update AFTER UPDATE ON lease6 + FOR EACH ROW + BEGIN + IF OLD.state != NEW.state THEN + IF OLD.state = 0 OR OLD.state = 1 THEN + # Decrement the old state count if record exists + UPDATE lease6_stat SET leases = leases - 1 + WHERE subnet_id = OLD.subnet_id AND lease_type = OLD.lease_type + AND state = OLD.state; + END IF; + + IF NEW.state = 0 OR NEW.state = 1 THEN + # Increment the new state count if record exists + UPDATE lease6_stat SET leases = leases + 1 + WHERE subnet_id = NEW.subnet_id AND lease_type = NEW.lease_type + AND state = NEW.state; + + # Insert new state record if it does not exist + IF ROW_COUNT() <= 0 THEN + INSERT INTO lease6_stat + VALUES (NEW.subnet_id, NEW.lease_type, NEW.state, 1); + END IF; + END IF; + END IF; + END $$ +DELIMITER ; + +# Create stat_lease6_delete trigger +DELIMITER $$ +CREATE TRIGGER stat_lease6_delete AFTER DELETE ON lease6 + FOR EACH ROW + BEGIN + IF OLD.state = 0 OR OLD.state = 1 THEN + # Decrement the state count if record exists + UPDATE lease6_stat SET leases = leases - 1 + WHERE subnet_id = OLD.subnet_id AND lease_type = OLD.lease_type + AND state = OLD.state; + END IF; + END $$ +DELIMITER ; + +# Update the schema version number +UPDATE schema_version +SET version = '6', minor = '0'; + +# This line concludes database upgrade to version 6.0. + +# Add user context into tables holding leases +ALTER TABLE lease4 ADD COLUMN user_context TEXT NULL; +ALTER TABLE lease6 ADD COLUMN user_context TEXT NULL; + +DROP PROCEDURE IF EXISTS lease4DumpHeader; +DELIMITER $$ +CREATE PROCEDURE lease4DumpHeader() +BEGIN +SELECT 'address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context'; +END $$ +DELIMITER ; + +# FUNCTION that returns a result set containing the data for lease4 dumps +DROP PROCEDURE IF EXISTS lease4DumpData; +DELIMITER $$ +CREATE PROCEDURE lease4DumpData() +BEGIN +SELECT + INET_NTOA(l.address), + IFNULL(HEX(l.hwaddr), ''), + IFNULL(HEX(l.client_id), ''), + l.valid_lifetime, + l.expire, + l.subnet_id, + l.fqdn_fwd, + l.fqdn_rev, + l.hostname, + s.name, + IFNULL(l.user_context, '') +FROM + lease4 l + LEFT OUTER JOIN lease_state s on (l.state = s.state) +ORDER BY l.address; +END $$ +DELIMITER ; + +DROP PROCEDURE IF EXISTS lease6DumpHeader; +DELIMITER $$ +CREATE PROCEDURE lease6DumpHeader() +BEGIN +SELECT 'address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,hwtype,hwaddr_source,state,user_context'; +END $$ +DELIMITER ; + +# FUNCTION that returns a result set containing the data for lease6 dumps +DROP PROCEDURE IF EXISTS lease6DumpData; +DELIMITER $$ +CREATE PROCEDURE lease6DumpData() +BEGIN +SELECT + l.address, + IFNULL(HEX(l.duid), ''), + l.valid_lifetime, + l.expire, + l.subnet_id, + l.pref_lifetime, + IFNULL(t.name, ''), + l.iaid, + l.prefix_len, + l.fqdn_fwd, + l.fqdn_rev, + l.hostname, + IFNULL(HEX(l.hwaddr), ''), + IFNULL(l.hwtype, ''), + IFNULL(h.name, ''), + IFNULL(s.name, ''), + IFNULL(l.user_context, '') +FROM lease6 l + left outer join lease6_types t on (l.lease_type = t.lease_type) + left outer join lease_state s on (l.state = s.state) + left outer join lease_hwaddr_source h on (l.hwaddr_source = h.hwaddr_source) +ORDER BY l.address; +END $$ +DELIMITER ; + +# Create logs table (logs table is used by forensic logging hook library) +CREATE TABLE logs ( + timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, # creation timestamp + address VARCHAR(43) NULL, # address or prefix + log TEXT NOT NULL # the log itself + ) ENGINE = INNODB; + +# Create search index +CREATE INDEX timestamp_index ON logs (timestamp); + +#add auth key for reconfiguration +ALTER TABLE hosts + ADD COLUMN auth_key VARCHAR(16) NULL; + + +# Add scope for shared network specific options. +INSERT INTO dhcp_option_scope (scope_id, scope_name) + VALUES(4, "shared-network"); + +<<<<<<< HEAD +# Add scope for pool specific options. +INSERT INTO dhcp_option_scope (scope_id, scope_name) + VALUES(5, "pool"); + +# Add scope for PD pool specific options. +INSERT INTO dhcp_option_scope (scope_id, scope_name) + VALUES(6, "pd-pool"); + +======= +>>>>>>> [#93,!51] Added options management in MySQL DHCPv4 config backend. +-- ----------------------------------------------------- +-- Table `modification` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS modification ( + id TINYINT(3) NOT NULL, + modification_type VARCHAR(32) NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +INSERT INTO modification(id, modification_type) + VALUES(0, "create"); + +INSERT INTO modification(id, modification_type) + VALUES(1, "update"); + +INSERT INTO modification(id, modification_type) + VALUES(2, "delete"); + +-- ----------------------------------------------------- +-- Table `dhcp4_server` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp4_server ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + tag VARCHAR(256) NOT NULL, + description TEXT, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY dhcp4_server_tag_UNIQUE (tag), + KEY key_dhcp4_server_modification_ts (modification_ts) +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp4_audit` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp4_audit ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + object_type VARCHAR(256) NOT NULL, + object_id BIGINT(20) UNSIGNED NOT NULL, + modification_type TINYINT(1) NOT NULL, + modification_ts TIMESTAMP NOT NULL, + log_message TEXT, + PRIMARY KEY (id), + KEY key_dhcp4_audit_by_modification_ts (modification_ts), + KEY fk_dhcp4_audit_modification_type (modification_type), + CONSTRAINT fk_dhcp4_audit_modification_type FOREIGN KEY (modification_type) + REFERENCES modification (id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + + +-- ----------------------------------------------------- +-- Table `dhcp4_global_parameter` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp4_global_parameter ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + name VARCHAR(128) NOT NULL, + value LONGTEXT NOT NULL, + modification_ts timestamp NOT NULL, + PRIMARY KEY (id), + KEY key_dhcp4_global_parameter_modification_ts (modification_ts), + KEY key_dhcp4_global_parameter_name (name) +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp4_global_parameter_server` +-- M-to-M cross-reference between global parameters and +-- servers +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp4_global_parameter_server ( + parameter_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (parameter_id, server_id), + KEY fk_dhcp4_global_parameter_server_server_id (server_id), + KEY key_dhcp4_global_parameter_server (modification_ts), + CONSTRAINT fk_dhcp4_global_parameter_server_parameter_id FOREIGN KEY (parameter_id) + REFERENCES dhcp4_global_parameter (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp4_global_parameter_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp4_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp4_option_def` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp4_option_def ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + code SMALLINT UNSIGNED NOT NULL, + name VARCHAR(128) NOT NULL, + space VARCHAR(128) NOT NULL, + type TINYINT UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + array TINYINT(1) NOT NULL, + encapsulate VARCHAR(128) NOT NULL, + record_types VARCHAR(512) DEFAULT NULL, + user_context LONGTEXT, + PRIMARY KEY (id), + KEY key_dhcp4_option_def_modification_ts (modification_ts), + KEY key_dhcp4_option_def_code_space (code, space) +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp4_option_def_server` +-- M-to-M cross-reference between option definitions and +-- servers +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp4_option_def_server ( + option_def_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (option_def_id, server_id), + KEY fk_dhcp4_option_def_server_server_id_idx (server_id), + KEY key_dhcp4_option_def_server_modification_ts (modification_ts), + CONSTRAINT fk_dhcp4_option_def_server_option_def_id FOREIGN KEY (option_def_id) + REFERENCES dhcp4_option_def (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp4_option_def_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp4_server (id) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp4_shared_network` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp4_shared_network ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + name VARCHAR(128) NOT NULL, + client_class VARCHAR(128) DEFAULT NULL, + interface VARCHAR(128) DEFAULT NULL, + match_client_id TINYINT(1) NOT NULL DEFAULT '1', + modification_ts TIMESTAMP NOT NULL, + rebind_timer INT(10) DEFAULT NULL, + relay LONGTEXT, + renew_timer INT(10) DEFAULT NULL, + require_client_classes LONGTEXT DEFAULT NULL, + reservation_mode TINYINT(3) NOT NULL DEFAULT '3', + user_context LONGTEXT, + valid_lifetime INT(10) DEFAULT NULL, + PRIMARY KEY (id), + UNIQUE KEY name_UNIQUE (name), + KEY key_dhcp4_shared_network_modification_ts (modification_ts) +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp4_shared_network_server` +-- M-to-M cross-reference between shared networks and +-- servers +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp4_shared_network_server ( + shared_network_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (shared_network_id, server_id), + KEY key_dhcp4_shared_network_server_modification_ts (modification_ts), + KEY fk_dhcp4_shared_network_server_server_id (server_id), + CONSTRAINT fk_dhcp4_shared_network_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp4_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp4_shared_network_server_shared_network_id FOREIGN KEY (shared_network_id) + REFERENCES dhcp4_shared_network (id) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp4_subnet` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp4_subnet ( + subnet_id INT(10) UNSIGNED NOT NULL, + subnet_prefix VARCHAR(32) NOT NULL, + 4o6_interface VARCHAR(128) DEFAULT NULL, + 4o6_interface_id VARCHAR(128) DEFAULT NULL, + 4o6_subnet VARCHAR(64) DEFAULT NULL, + boot_file_name VARCHAR(512) DEFAULT NULL, + client_class VARCHAR(128) DEFAULT NULL, + interface VARCHAR(128) DEFAULT NULL, + match_client_id TINYINT(1) NOT NULL DEFAULT '1', + modification_ts TIMESTAMP NOT NULL, + next_server INT(10) UNSIGNED DEFAULT NULL, + rebind_timer INT(10) DEFAULT NULL, + relay LONGTEXT, + renew_timer INT(10) DEFAULT NULL, + require_client_classes LONGTEXT DEFAULT NULL, + reservation_mode TINYINT(3) NOT NULL DEFAULT '3', + server_hostname VARCHAR(512) DEFAULT NULL, + shared_network_name VARCHAR(128) DEFAULT NULL, + user_context LONGTEXT, + valid_lifetime INT(10) DEFAULT NULL, + PRIMARY KEY (subnet_id), + UNIQUE KEY subnet4_subnet_prefix (subnet_prefix), + KEY fk_dhcp4_subnet_shared_network (shared_network_name), + KEY key_dhcp4_subnet_modification_ts (modification_ts), + CONSTRAINT fk_dhcp4_subnet_shared_network FOREIGN KEY (shared_network_name) + REFERENCES dhcp4_shared_network (name) + ON DELETE SET NULL ON UPDATE NO ACTION +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp4_pool` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp4_pool ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + start_address INT(10) UNSIGNED NOT NULL, + end_address INT(10) UNSIGNED NOT NULL, + subnet_id INT(10) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (id), + KEY key_dhcp4_pool_modification_ts (modification_ts), + KEY fk_dhcp4_pool_subnet_id (subnet_id), + CONSTRAINT fk_dhcp4_pool_subnet_id FOREIGN KEY (subnet_id) + REFERENCES dhcp4_subnet (subnet_id) + ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp4_subnet_server` +-- M-to-M cross-reference between subnets and servers +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp4_subnet_server ( + subnet_id INT(10) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (subnet_id,server_id), + KEY fk_dhcp4_subnet_server_server_id_idx (server_id), + KEY key_dhcp4_subnet_server_modification_ts (modification_ts), + CONSTRAINT fk_dhcp4_subnet_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp4_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp4_subnet_server_subnet_id FOREIGN KEY (subnet_id) + REFERENCES dhcp4_subnet (subnet_id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + + +# Modify the primary key to BINGINT as other tables have. +ALTER TABLE dhcp4_options MODIFY option_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT; + +# Add conifguration backend specific columns. +ALTER TABLE dhcp4_options + ADD COLUMN shared_network_name VARCHAR(128) DEFAULT NULL, + ADD COLUMN pool_id BIGINT(20) UNSIGNED DEFAULT NULL, + ADD COLUMN modification_ts TIMESTAMP NOT NULL; + +-- ----------------------------------------------------- +-- Table `dhcp4_options_server` +-- M-to-M cross-reference between options and servers +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp4_options_server ( + option_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (option_id, server_id), + KEY fk_dhcp4_options_server_server_id (server_id), + KEY key_dhcp4_options_server_modification_ts (modification_ts), + CONSTRAINT fk_dhcp4_options_server_option_id FOREIGN KEY (option_id) + REFERENCES dhcp4_options (option_id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp4_options_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp4_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create trigger which removes pool specific options upon removal of +# the pool. +DELIMITER $$ +CREATE TRIGGER dhcp4_pool_BDEL BEFORE DELETE ON dhcp4_pool FOR EACH ROW +-- Edit trigger body code below this line. Do not edit lines above this one +BEGIN +DELETE FROM dhcp4_options WHERE scope_id = 5 AND pool_id = OLD.id; +END +$$ +DELIMITER ; + +-- ----------------------------------------------------- +-- Table `dhcp6_server` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp6_server ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + tag VARCHAR(256) NOT NULL, + description TEXT, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY dhcp6_server_tag_UNIQUE (tag), + KEY key_dhcp6_server_modification_ts (modification_ts) +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp6_audit` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp6_audit ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + object_type VARCHAR(256) NOT NULL, + object_id BIGINT(20) UNSIGNED NOT NULL, + modification_type TINYINT(1) NOT NULL, + modification_ts TIMESTAMP NOT NULL, + log_message TEXT, + PRIMARY KEY (id), + KEY key_dhcp6_audit_modification_ts (modification_ts), + KEY fk_dhcp6_audit_modification_type (modification_type), + CONSTRAINT fk_dhcp6_audit_modification_type FOREIGN KEY (modification_type) + REFERENCES modification (id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp6_global_parameter` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp6_global_parameter ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + name VARCHAR(128) NOT NULL, + value LONGTEXT NOT NULL, + modification_ts timestamp NOT NULL, + PRIMARY KEY (id), + KEY key_dhcp6_global_parameter_modification_ts (modification_ts), + KEY key_dhcp6_global_parameter_name (name) +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp6_global_parameter_server` +-- M-to-M cross-reference between global parameters and +-- servers +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp6_global_parameter_server ( + parameter_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (parameter_id, server_id), + KEY fk_dhcp6_global_parameter_server_server_id (server_id), + KEY key_dhcp6_global_parameter_server (modification_ts), + CONSTRAINT fk_dhcp6_global_parameter_server_parameter_id FOREIGN KEY (parameter_id) + REFERENCES dhcp6_global_parameter (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp6_global_parameter_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp6_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp6_option_def` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp6_option_def ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + code SMALLINT UNSIGNED NOT NULL, + name VARCHAR(128) NOT NULL, + space VARCHAR(128) NOT NULL, + type TINYINT UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + array TINYINT(1) NOT NULL, + encapsulate VARCHAR(128) NOT NULL, + record_types VARCHAR(512) DEFAULT NULL, + user_context LONGTEXT, + PRIMARY KEY (id), + KEY key_dhcp6_option_def_modification_ts (modification_ts), + KEY key_dhcp6_option_def_code_space (code, space) +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp6_option_def_server` +-- M-to-M cross-reference between option definitions and +-- servers +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp6_option_def_server ( + option_def_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (option_def_id, server_id), + KEY fk_dhcp6_option_def_server_server_id_idx (server_id), + KEY key_dhcp6_option_def_server_modification_ts (modification_ts), + CONSTRAINT fk_dhcp6_option_def_server_option_def_id FOREIGN KEY (option_def_id) + REFERENCES dhcp6_option_def (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp6_option_def_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp6_server (id) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp6_shared_network` +-- ----------------------------------------------------- +CREATE TABLE dhcp6_shared_network ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + name VARCHAR(128) NOT NULL, + client_class VARCHAR(128) DEFAULT NULL, + interface VARCHAR(128) DEFAULT NULL, + modification_ts TIMESTAMP NOT NULL, + preferred_lifetime INT(10) DEFAULT NULL, + rapid_commit TINYINT(1) NOT NULL DEFAULT '1', + rebind_timer INT(10) DEFAULT NULL, + relay LONGTEXT DEFAULT NULL, + renew_timer INT(10) DEFAULT NULL, + require_client_classes LONGTEXT, + reservation_mode TINYINT(3) NOT NULL DEFAULT '3', + user_context LONGTEXT, + valid_lifetime INT(10) DEFAULT NULL, + PRIMARY KEY (id), + UNIQUE KEY name_UNIQUE (name), + KEY key_dhcp6_shared_network_modification_ts (modification_ts) +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp6_shared_network_server` +-- M-to-M cross-reference between shared networks and +-- servers +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp6_shared_network_server ( + shared_network_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + KEY key_dhcp6_shared_network_server_modification_ts (modification_ts), + KEY fk_dhcp6_shared_network_server_server_id_idx (server_id), + KEY fk_dhcp6_shared_network_server_shared_network_id (shared_network_id), + CONSTRAINT fk_dhcp6_shared_network_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp6_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp6_shared_network_server_shared_network_id FOREIGN KEY (shared_network_id) + REFERENCES dhcp6_shared_network (id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp6_subnet` +-- ----------------------------------------------------- +CREATE TABLE dhcp6_subnet ( + subnet_id INT(10) UNSIGNED NOT NULL, + subnet_prefix VARCHAR(64) NOT NULL, + client_class VARCHAR(128) DEFAULT NULL, + interface VARCHAR(128) DEFAULT NULL, + modification_ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + preferred_lifetime INT(10) DEFAULT NULL, + rapid_commit TINYINT(1) NOT NULL DEFAULT '1', + rebind_timer INT(10) DEFAULT NULL, + relay LONGTEXT DEFAULT NULL, + renew_timer INT(10) DEFAULT NULL, + require_client_classes LONGTEXT, + reservation_mode TINYINT(3) NOT NULL DEFAULT '3', + shared_network_name VARCHAR(128) DEFAULT NULL, + user_context LONGTEXT, + valid_lifetime INT(10) DEFAULT NULL, + PRIMARY KEY (subnet_id), + UNIQUE KEY subnet_prefix_UNIQUE (subnet_prefix), + KEY subnet6_subnet_prefix (subnet_prefix), + KEY fk_dhcp6_subnet_shared_network (shared_network_name), + KEY key_dhcp6_subnet_modification_ts (modification_ts), + CONSTRAINT fk_dhcp6_subnet_shared_network FOREIGN KEY (shared_network_name) + REFERENCES dhcp6_shared_network (name) + ON DELETE SET NULL ON UPDATE NO ACTION +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp6_subnet_server` +-- M-to-M cross-reference between subnets and servers +-- ----------------------------------------------------- +CREATE TABLE dhcp6_subnet_server ( + subnet_id INT(10) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (subnet_id, server_id), + KEY fk_dhcp6_subnet_server_server_id (server_id), + KEY key_dhcp6_subnet_server_modification_ts (modification_ts), + CONSTRAINT fk_dhcp6_subnet_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp6_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp6_subnet_server_subnet_id FOREIGN KEY (subnet_id) + REFERENCES dhcp6_subnet (subnet_id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp6_pd_pool` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp6_pd_pool ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + prefix VARCHAR(45) NOT NULL, + prefix_length TINYINT(3) NOT NULL, + delegated_prefix_length TINYINT(3) NOT NULL, + dhcp6_subnet_id INT(10) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (id), + KEY fk_dhcp6_pd_pool_subnet_id (dhcp6_subnet_id), + KEY key_dhcp6_pd_pool_modification_ts (modification_ts), + CONSTRAINT fk_dhcp6_pd_pool_subnet_id FOREIGN KEY (dhcp6_subnet_id) + REFERENCES dhcp6_subnet (subnet_id) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +-- ----------------------------------------------------- +-- Table `dhcp6_pool` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp6_pool ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + start_address VARCHAR(45) NOT NULL, + end_address VARCHAR(45) NOT NULL, + dhcp6_subnet_id INT(10) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (id), + KEY fk_dhcp6_pool_subnet_id (dhcp6_subnet_id), + KEY key_dhcp6_pool_modification_ts (modification_ts), + CONSTRAINT fk_dhcp6_pool_subnet_id FOREIGN KEY (dhcp6_subnet_id) + REFERENCES dhcp6_subnet (subnet_id) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +# Modify the primary key to BINGINT as other tables have. +ALTER TABLE dhcp6_options MODIFY option_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT; + +# Add conifguration backend specific columns. +ALTER TABLE dhcp6_options + ADD COLUMN shared_network_name VARCHAR(128) DEFAULT NULL, + ADD COLUMN pool_id BIGINT(20) UNSIGNED DEFAULT NULL, + ADD COLUMN pd_pool_id BIGINT(20) UNSIGNED DEFAULT NULL, + ADD COLUMN modification_ts TIMESTAMP NOT NULL; + +-- ----------------------------------------------------- +-- Table `dhcp6_options_server` +-- M-to-M cross-reference between options and servers +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS dhcp6_options_server ( + option_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (option_id, server_id), + KEY fk_dhcp6_options_server_server_id_idx (server_id), + KEY key_dhcp6_options_server_modification_ts (modification_ts), + CONSTRAINT fk_dhcp6_options_server_option_id FOREIGN KEY (option_id) + REFERENCES dhcp6_options (option_id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp6_options_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp6_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create trigger which removes pool specific options upon removal of +# the pool. +DELIMITER $$ +CREATE TRIGGER dhcp6_pool_BDEL BEFORE DELETE ON dhcp6_pool FOR EACH ROW +-- Edit trigger body code below this line. Do not edit lines above this one +BEGIN +DELETE FROM dhcp6_options WHERE scope_id = 5 AND pool_id = OLD.id; +END +$$ +DELIMITER ; + +# Update the schema version number +UPDATE schema_version +SET version = '7', minor = '0'; + +# This line concludes database upgrade to version 7.0. + +# Notes: +# +# Indexes +# ======= +# It is likely that additional indexes will be needed. However, the +# increase in lookup performance from these will come at the expense +# of a decrease in performance during insert operations due to the need +# to update the indexes. For this reason, the need for additional indexes +# will be determined by experiment during performance tests. +# +# The most likely additional indexes will cover the following columns: +# +# hwaddr and client_id +# For lease stability: if a client requests a new lease, try to find an +# existing or recently expired lease for it so that it can keep using the +# same IP address. +# +# Field Sizes +# =========== +# If any of the VARxxx field sizes are altered, the lengths in the MySQL +# backend source file (mysql_lease_mgr.cc) must be correspondingly changed. +# +# Portability +# =========== +# The 'ENGINE = INNODB' on some tables is not portable to another database +# and will need to be removed. +# +# Some columns contain binary data so are stored as VARBINARY instead of +# VARCHAR. This may be non-portable between databases: in this case, the +# definition should be changed to VARCHAR. diff --git a/src/share/database/scripts/mysql/upgrade_6.0_to_7.0.sh.in.orig b/src/share/database/scripts/mysql/upgrade_6.0_to_7.0.sh.in.orig new file mode 100644 index 0000000000..d6871eaf49 --- /dev/null +++ b/src/share/database/scripts/mysql/upgrade_6.0_to_7.0.sh.in.orig @@ -0,0 +1,643 @@ +#!/bin/sh + +# Include utilities. Use installed version if available and +# use build version if it isn't. +if [ -e @datarootdir@/@PACKAGE_NAME@/scripts/admin-utils.sh ]; then + . @datarootdir@/@PACKAGE_NAME@/scripts/admin-utils.sh +else + . @abs_top_builddir@/src/bin/admin/admin-utils.sh +fi + +VERSION=`mysql_version "$@"` + +if [ "$VERSION" != "6.0" ]; then + printf "This script upgrades 6.0 to 7.0. Reported version is $VERSION. Skipping upgrade.\n" + exit 0 +fi + +mysql "$@" <>>>>>> [#93,!51] Added options management in MySQL DHCPv4 config backend. +# Create table modification +CREATE TABLE IF NOT EXISTS modification ( + id TINYINT(3) NOT NULL, + modification_type VARCHAR(32) NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +INSERT INTO modification(id, modification_type) + VALUES(0, "create"); + +INSERT INTO modification(id, modification_type) + VALUES(1, "update"); + +INSERT INTO modification(id, modification_type) + VALUES(2, "delete"); + +# Create table dhcp4_server +# +CREATE TABLE IF NOT EXISTS dhcp4_server ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + tag VARCHAR(256) NOT NULL, + description TEXT, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY dhcp4_server_tag_UNIQUE (tag), + KEY key_dhcp4_server_modification_ts (modification_ts) +) ENGINE=InnoDB; + +# Create table dhcp4_audit +# +CREATE TABLE IF NOT EXISTS dhcp4_audit ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + object_type VARCHAR(256) NOT NULL, + object_id BIGINT(2) UNSIGNED NOT NULL, + modification_type TINYINT(1) NOT NULL, + modification_ts TIMESTAMP NOT NULL, + log_message TEXT, + PRIMARY KEY (id), + KEY key_dhcp4_audit_by_modification_ts (modification_ts), + KEY fk_dhcp4_audit_modification_type (modification_type), + CONSTRAINT fk_dhcp4_audit_modification_type FOREIGN KEY (modification_type) + REFERENCES modification (id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create table dhcp4_global_parameter +# +CREATE TABLE IF NOT EXISTS dhcp4_global_parameter ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + name VARCHAR(128) NOT NULL, + value LONGTEXT NOT NULL, + modification_ts timestamp NOT NULL, + PRIMARY KEY (id), + KEY key_dhcp4_global_parameter_modification_ts (modification_ts), + KEY key_dhcp4_global_parameter_name (name) +) ENGINE=InnoDB; + +# Create table dhcp4_global_parameter_server +# M-to-M cross-reference between global parameters and servers +# +CREATE TABLE IF NOT EXISTS dhcp4_global_parameter_server ( + parameter_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (parameter_id, server_id), + KEY fk_dhcp4_global_parameter_server_server_id (server_id), + KEY key_dhcp4_global_parameter_server (modification_ts), + CONSTRAINT fk_dhcp4_global_parameter_server_parameter_id FOREIGN KEY (parameter_id) + REFERENCES dhcp4_global_parameter (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp4_global_parameter_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp4_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create table dhcp4_option_def +# +CREATE TABLE IF NOT EXISTS dhcp4_option_def ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + code SMALLINT UNSIGNED NOT NULL, + name VARCHAR(128) NOT NULL, + space VARCHAR(128) NOT NULL, + type TINYINT UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + array TINYINT(1) NOT NULL, + encapsulate VARCHAR(128) NOT NULL, + record_types VARCHAR(512) DEFAULT NULL, + user_context LONGTEXT, + PRIMARY KEY (id), + KEY key_dhcp4_option_def_modification_ts (modification_ts), + KEY key_dhcp4_option_def_code_space (code, space) +) ENGINE=InnoDB; + +# Create table dhcp4_option_def_server +# M-to-M cross-reference between option definitions and servers +# +CREATE TABLE IF NOT EXISTS dhcp4_option_def_server ( + option_def_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (option_def_id, server_id), + KEY fk_dhcp4_option_def_server_server_id_idx (server_id), + KEY key_dhcp4_option_def_server_modification_ts (modification_ts), + CONSTRAINT fk_dhcp4_option_def_server_option_def_id FOREIGN KEY (option_def_id) + REFERENCES dhcp4_option_def (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp4_option_def_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp4_server (id) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create table dhcp4_shared_network +# +CREATE TABLE IF NOT EXISTS dhcp4_shared_network ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + name VARCHAR(128) NOT NULL, + client_class VARCHAR(128) DEFAULT NULL, + interface VARCHAR(128) DEFAULT NULL, + match_client_id TINYINT(1) NOT NULL DEFAULT '1', + modification_ts TIMESTAMP NOT NULL, + rebind_timer INT(10) DEFAULT NULL, + relay LONGTEXT, + renew_timer INT(10) DEFAULT NULL, + require_client_classes LONGTEXT DEFAULT NULL, + reservation_mode TINYINT(3) NOT NULL DEFAULT '3', + user_context LONGTEXT, + valid_lifetime INT(10) DEFAULT NULL, + PRIMARY KEY (id), + UNIQUE KEY name_UNIQUE (name), + KEY key_dhcp4_shared_network_modification_ts (modification_ts) +) ENGINE=InnoDB; + +# Create table dhcp4_shared_network_server +# M-to-M cross-reference between shared networks and servers +# +CREATE TABLE IF NOT EXISTS dhcp4_shared_network_server ( + shared_network_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (shared_network_id, server_id), + KEY key_dhcp4_shared_network_server_modification_ts (modification_ts), + KEY fk_dhcp4_shared_network_server_server_id (server_id), + CONSTRAINT fk_dhcp4_shared_network_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp4_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp4_shared_network_server_shared_network_id FOREIGN KEY (shared_network_id) + REFERENCES dhcp4_shared_network (id) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create table dhcp4_subnet +# +CREATE TABLE IF NOT EXISTS dhcp4_subnet ( + subnet_id INT(10) UNSIGNED NOT NULL, + subnet_prefix VARCHAR(32) NOT NULL, + 4o6_interface VARCHAR(128) DEFAULT NULL, + 4o6_interface_id VARCHAR(128) DEFAULT NULL, + 4o6_subnet VARCHAR(64) DEFAULT NULL, + boot_file_name VARCHAR(512) DEFAULT NULL, + client_class VARCHAR(128) DEFAULT NULL, + interface VARCHAR(128) DEFAULT NULL, + match_client_id TINYINT(1) NOT NULL DEFAULT '1', + modification_ts TIMESTAMP NOT NULL, + next_server INT(10) UNSIGNED DEFAULT NULL, + rebind_timer INT(10) DEFAULT NULL, + relay LONGTEXT, + renew_timer INT(10) DEFAULT NULL, + require_client_classes LONGTEXT DEFAULT NULL, + reservation_mode TINYINT(3) NOT NULL DEFAULT '3', + server_hostname VARCHAR(512) DEFAULT NULL, + shared_network_name VARCHAR(128) DEFAULT NULL, + user_context LONGTEXT, + valid_lifetime INT(10) DEFAULT NULL, + PRIMARY KEY (subnet_id), + UNIQUE KEY subnet4_subnet_prefix (subnet_prefix), + KEY fk_dhcp4_subnet_shared_network (shared_network_name), + KEY key_dhcp4_subnet_modification_ts (modification_ts), + CONSTRAINT fk_dhcp4_subnet_shared_network FOREIGN KEY (shared_network_name) + REFERENCES dhcp4_shared_network (name) + ON DELETE SET NULL ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create table dhcp4_pool +# +CREATE TABLE IF NOT EXISTS dhcp4_pool ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + start_address INT(10) UNSIGNED NOT NULL, + end_address INT(10) UNSIGNED NOT NULL, + subnet_id INT(10) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (id), + KEY key_dhcp4_pool_modification_ts (modification_ts), + KEY fk_dhcp4_pool_subnet_id (subnet_id), + CONSTRAINT fk_dhcp4_pool_subnet_id FOREIGN KEY (subnet_id) + REFERENCES dhcp4_subnet (subnet_id) + ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +# Create table dhcp4_subnet_server +# M-to-M cross-reference between subnets and servers +# +CREATE TABLE IF NOT EXISTS dhcp4_subnet_server ( + subnet_id INT(10) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (subnet_id,server_id), + KEY fk_dhcp4_subnet_server_server_id_idx (server_id), + KEY key_dhcp4_subnet_server_modification_ts (modification_ts), + CONSTRAINT fk_dhcp4_subnet_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp4_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp4_subnet_server_subnet_id FOREIGN KEY (subnet_id) + REFERENCES dhcp4_subnet (subnet_id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + + +# Modify the primary key to BINGINT as other tables have. +# +ALTER TABLE dhcp4_options MODIFY option_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT; + +# Add conifguration backend specific columns. +ALTER TABLE dhcp4_options + ADD COLUMN shared_network_name VARCHAR(128) DEFAULT NULL, + ADD COLUMN pool_id BIGINT(20) UNSIGNED DEFAULT NULL, + ADD COLUMN modification_ts TIMESTAMP NOT NULL; + +# Create table dhcp4_options_server +# M-to-M cross-reference between options and servers +# +CREATE TABLE IF NOT EXISTS dhcp4_options_server ( + option_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (option_id, server_id), + KEY fk_dhcp4_options_server_server_id (server_id), + KEY key_dhcp4_options_server_modification_ts (modification_ts), + CONSTRAINT fk_dhcp4_options_server_option_id FOREIGN KEY (option_id) + REFERENCES dhcp4_options (option_id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp4_options_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp4_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create trigger which removes pool specific options upon removal of +# the pool. +DELIMITER $$ +CREATE TRIGGER dhcp4_pool_BDEL BEFORE DELETE ON dhcp4_pool FOR EACH ROW +-- Edit trigger body code below this line. Do not edit lines above this one +BEGIN +DELETE FROM dhcp4_options WHERE scope_id = 5 AND pool_id = OLD.id; +END +$$ +DELIMITER ; + +# Create table dhcp6_server +# +CREATE TABLE IF NOT EXISTS dhcp6_server ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + tag VARCHAR(256) NOT NULL, + description TEXT, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY dhcp6_server_tag_UNIQUE (tag), + KEY key_dhcp6_server_modification_ts (modification_ts) +) ENGINE=InnoDB; + +# Create table dhcp6_audit +# +CREATE TABLE IF NOT EXISTS dhcp6_audit ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + object_type VARCHAR(256) NOT NULL, + object_id BIGINT(20) UNSIGNED NOT NULL, + modification_type TINYINT(1) NOT NULL, + modification_ts TIMESTAMP NOT NULL, + log_message TEXT, + PRIMARY KEY (id), + KEY key_dhcp6_audit_modification_ts (modification_ts), + KEY fk_dhcp6_audit_modification_type (modification_type), + CONSTRAINT fk_dhcp6_audit_modification_type FOREIGN KEY (modification_type) + REFERENCES modification (id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create table dhcp6_global_parameter +# +CREATE TABLE IF NOT EXISTS dhcp6_global_parameter ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + name VARCHAR(128) NOT NULL, + value LONGTEXT NOT NULL, + modification_ts timestamp NOT NULL, + PRIMARY KEY (id), + KEY key_dhcp6_global_parameter_modification_ts (modification_ts), + KEY key_dhcp6_global_parameter_name (name) +) ENGINE=InnoDB; + +# Create table dhcp6_global_parameter_server +# M-to-M cross-reference between global parameters and servers +# +CREATE TABLE IF NOT EXISTS dhcp6_global_parameter_server ( + parameter_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (parameter_id, server_id), + KEY fk_dhcp6_global_parameter_server_server_id (server_id), + KEY key_dhcp6_global_parameter_server (modification_ts), + CONSTRAINT fk_dhcp6_global_parameter_server_parameter_id FOREIGN KEY (parameter_id) + REFERENCES dhcp6_global_parameter (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp6_global_parameter_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp6_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create table dhcp6_option_def +# +CREATE TABLE IF NOT EXISTS dhcp6_option_def ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + code SMALLINT UNSIGNED NOT NULL, + name VARCHAR(128) NOT NULL, + space VARCHAR(128) NOT NULL, + type TINYINT UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + array TINYINT(1) NOT NULL, + encapsulate VARCHAR(128) NOT NULL, + record_types VARCHAR(512) DEFAULT NULL, + user_context LONGTEXT, + PRIMARY KEY (id), + KEY key_dhcp6_option_def_modification_ts (modification_ts), + KEY key_dhcp6_option_def_code_space (code, space) +) ENGINE=InnoDB; + +# Create table dhcp6_option_def_server +# M-to-M cross-reference between option definitions and servers +# +CREATE TABLE IF NOT EXISTS dhcp6_option_def_server ( + option_def_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (option_def_id, server_id), + KEY fk_dhcp6_option_def_server_server_id_idx (server_id), + KEY key_dhcp6_option_def_server_modification_ts (modification_ts), + CONSTRAINT fk_dhcp6_option_def_server_option_def_id FOREIGN KEY (option_def_id) + REFERENCES dhcp6_option_def (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp6_option_def_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp6_server (id) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create table dhcp6_shared_network +# +CREATE TABLE dhcp6_shared_network ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + name VARCHAR(128) NOT NULL, + client_class VARCHAR(128) DEFAULT NULL, + interface VARCHAR(128) DEFAULT NULL, + modification_ts TIMESTAMP NOT NULL, + preferred_lifetime INT(10) DEFAULT NULL, + rapid_commit TINYINT(1) NOT NULL DEFAULT '1', + rebind_timer INT(10) DEFAULT NULL, + relay LONGTEXT DEFAULT NULL, + renew_timer INT(10) DEFAULT NULL, + require_client_classes LONGTEXT, + reservation_mode TINYINT(3) NOT NULL DEFAULT '3', + user_context LONGTEXT, + valid_lifetime INT(10) DEFAULT NULL, + PRIMARY KEY (id), + UNIQUE KEY name_UNIQUE (name), + KEY key_dhcp6_shared_network_modification_ts (modification_ts) +) ENGINE=InnoDB; + +# Create table dhcp6_shared_network_server +# M-to-M cross-reference between shared networks and servers +# +CREATE TABLE IF NOT EXISTS dhcp6_shared_network_server ( + shared_network_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + KEY key_dhcp6_shared_network_server_modification_ts (modification_ts), + KEY fk_dhcp6_shared_network_server_server_id_idx (server_id), + KEY fk_dhcp6_shared_network_server_shared_network_id (shared_network_id), + CONSTRAINT fk_dhcp6_shared_network_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp6_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp6_shared_network_server_shared_network_id FOREIGN KEY (shared_network_id) + REFERENCES dhcp6_shared_network (id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create table dhcp6_subnet +# +CREATE TABLE dhcp6_subnet ( + subnet_id int(10) UNSIGNED NOT NULL, + subnet_prefix VARCHAR(64) NOT NULL, + client_class VARCHAR(128) DEFAULT NULL, + interface VARCHAR(128) DEFAULT NULL, + modification_ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + preferred_lifetime INT(10) DEFAULT NULL, + rapid_commit TINYINT(1) NOT NULL DEFAULT '1', + rebind_timer INT(10) DEFAULT NULL, + relay LONGTEXT DEFAULT NULL, + renew_timer INT(10) DEFAULT NULL, + require_client_classes LONGTEXT, + reservation_mode TINYINT(3) NOT NULL DEFAULT '3', + shared_network_name VARCHAR(128) DEFAULT NULL, + user_context LONGTEXT, + valid_lifetime INT(10) DEFAULT NULL, + PRIMARY KEY (subnet_id), + UNIQUE KEY subnet6_subnet_prefix (subnet_prefix), + KEY fk_dhcp6_subnet_shared_network (shared_network_name), + KEY key_dhcp6_subnet_modification_ts (modification_ts), + CONSTRAINT fk_dhcp6_subnet_shared_network FOREIGN KEY (shared_network_name) + REFERENCES dhcp6_shared_network (name) + ON DELETE SET NULL ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create table dhcp6_subnet_server +# M-to-M cross-reference between subnets and servers +# +CREATE TABLE dhcp6_subnet_server ( + subnet_id INT(10) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (subnet_id, server_id), + KEY fk_dhcp6_subnet_server_server_id (server_id), + KEY key_dhcp6_subnet_server_modification_ts (modification_ts), + CONSTRAINT fk_dhcp6_subnet_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp6_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp6_subnet_server_subnet_id FOREIGN KEY (subnet_id) + REFERENCES dhcp6_subnet (subnet_id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create table dhcp6_pd_pool +# +CREATE TABLE IF NOT EXISTS dhcp6_pd_pool ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + prefix VARCHAR(45) NOT NULL, + prefix_length TINYINT(3) NOT NULL, + delegated_prefix_length TINYINT(3) NOT NULL, + dhcp6_subnet_id INT(10) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (id), + KEY fk_dhcp6_pd_pool_subnet_id (dhcp6_subnet_id), + KEY key_dhcp6_pd_pool_modification_ts (modification_ts), + CONSTRAINT fk_dhcp6_pd_pool_subnet_id FOREIGN KEY (dhcp6_subnet_id) + REFERENCES dhcp6_subnet (subnet_id) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +# Create table dhcp6_pool +# +CREATE TABLE IF NOT EXISTS dhcp6_pool ( + id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + start_address VARCHAR(45) NOT NULL, + end_address VARCHAR(45) NOT NULL, + dhcp6_subnet_id INT(10) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (id), + KEY fk_dhcp6_pool_subnet_id (dhcp6_subnet_id), + KEY key_dhcp6_pool_modification_ts (modification_ts), + CONSTRAINT fk_dhcp6_pool_subnet_id FOREIGN KEY (dhcp6_subnet_id) + REFERENCES dhcp6_subnet (subnet_id) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +# Modify the primary key to BINGINT as other tables have. +ALTER TABLE dhcp6_options MODIFY option_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT; + +# Add conifguration backend specific columns. +ALTER TABLE dhcp6_options + ADD COLUMN shared_network_name VARCHAR(128) DEFAULT NULL, + ADD COLUMN pool_id BIGINT(20) UNSIGNED DEFAULT NULL, + ADD COLUMN pd_pool_id BIGINT(20) UNSIGNED DEFAULT NULL, + ADD COLUMN modification_ts TIMESTAMP NOT NULL; + +# Create table dhcp6_options_server +# M-to-M cross-reference between options and servers +# +CREATE TABLE IF NOT EXISTS dhcp6_options_server ( + option_id BIGINT(20) UNSIGNED NOT NULL, + server_id BIGINT(20) UNSIGNED NOT NULL, + modification_ts TIMESTAMP NOT NULL, + PRIMARY KEY (option_id, server_id), + KEY fk_dhcp6_options_server_server_id_idx (server_id), + KEY key_dhcp6_options_server_modification_ts (modification_ts), + CONSTRAINT fk_dhcp6_options_server_option_id FOREIGN KEY (option_id) + REFERENCES dhcp6_options (option_id) + ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dhcp6_options_server_server_id FOREIGN KEY (server_id) + REFERENCES dhcp6_server (id) + ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +# Create trigger which removes pool specific options upon removal of +# the pool. +DELIMITER $$ +CREATE TRIGGER dhcp6_pool_BDEL BEFORE DELETE ON dhcp6_pool FOR EACH ROW +-- Edit trigger body code below this line. Do not edit lines above this one +BEGIN +DELETE FROM dhcp6_options WHERE scope_id = 5 AND pool_id = OLD.id; +END +$$ +DELIMITER ; + +# Update the schema version number +UPDATE schema_version +SET version = '7', minor = '0'; + +# This line concludes database upgrade to version 7.0. + +EOF + +RESULT=$? + +exit $?