Commit d7e1e2f0 authored by Thomas Markwalder's avatar Thomas Markwalder

[master] kea-dhcp4 server now opens configuration backends

    Merge branch '101-cb-add-two-step-configuration-to-the-dhcpv4-server-2'
parents 2338a92b 619abfd9
......@@ -411,6 +411,11 @@ This warning message is issued when current server configuration specifies
no interfaces that server should listen on, or specified interfaces are not
configured to receive the traffic.
% DHCP4_OPEN_CONFIG_DB Opening configuration database: %1
This message is printed when the DHCPv4 server is attempting to open a
configuration database. The database access string with password redacted
is logged.
% DHCP4_OPEN_SOCKET opening sockets on port %1
A debug message issued during startup, this indicates that the DHCPv4
server is about to open sockets on the specified port.
......
......@@ -10,11 +10,12 @@
#include <database/dbaccess_parser.h>
#include <dhcp4/dhcp4_log.h>
#include <dhcp4/dhcp4_srv.h>
#include <dhcp4/json_config_parser.h>
#include <dhcp/libdhcp++.h>
#include <dhcp/option_definition.h>
#include <dhcpsrv/cfg_option.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcp4/json_config_parser.h>
#include <dhcpsrv/config_backend_dhcp4_mgr.h>
#include <dhcpsrv/db_type.h>
#include <dhcpsrv/parsers/client_class_def_parser.h>
#include <dhcpsrv/parsers/dhcp_parsers.h>
......@@ -50,6 +51,8 @@ using namespace isc::dhcp;
using namespace isc::data;
using namespace isc::asiolink;
using namespace isc::hooks;
using namespace isc::process;
using namespace isc::config;
namespace {
......@@ -282,7 +285,7 @@ isc::data::ConstElementPtr
configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
bool check_only) {
if (!config_set) {
ConstElementPtr answer = isc::config::createAnswer(1,
ConstElementPtr answer = isc::config::createAnswer(CONTROL_RESULT_ERROR,
string("Can't parse NULL config"));
return (answer);
}
......@@ -318,9 +321,11 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
// the parsers. It is declared outside the loops so in case of an error,
// the name of the failing parser can be retrieved in the "catch" clause.
ConfigPair config_pair;
ElementPtr mutable_cfg;
SrvConfigPtr srv_cfg;
try {
SrvConfigPtr srv_cfg = CfgMgr::instance().getStagingCfg();
// Get the staging configuration
srv_cfg = CfgMgr::instance().getStagingCfg();
// Preserve all scalar global parameters
srv_cfg->extractConfiguredGlobals(config_set);
......@@ -328,7 +333,7 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
// This is a way to convert ConstElementPtr to ElementPtr.
// We need a config that can be edited, because we will insert
// default values and will insert derived values as well.
ElementPtr mutable_cfg = boost::const_pointer_cast<Element>(config_set);
mutable_cfg = boost::const_pointer_cast<Element>(config_set);
// Set all default values if not specified by the user.
SimpleParser4::setAllDefaults(mutable_cfg);
......@@ -464,7 +469,6 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
}
if (config_pair.first == "subnet4") {
SrvConfigPtr srv_cfg = CfgMgr::instance().getStagingCfg();
Subnets4ListConfigParser subnets_parser;
// parse() returns number of subnets parsed. We may log it one day.
subnets_parser.parse(srv_cfg, config_pair.second);
......@@ -500,8 +504,8 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
}
if (config_pair.first == "config-control") {
process::ConfigControlParser parser;
process::ConfigControlInfoPtr config_ctl_info = parser.parse(config_pair.second);
ConfigControlParser parser;
ConfigControlInfoPtr config_ctl_info = parser.parse(config_pair.second);
CfgMgr::instance().getStagingCfg()->setConfigControlInfo(config_ctl_info);
continue;
}
......@@ -544,7 +548,7 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
} catch (const isc::Exception& ex) {
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_FAIL)
.arg(config_pair.first).arg(ex.what());
answer = isc::config::createAnswer(1, ex.what());
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, ex.what());
// An error occurred, so make sure that we restore original data.
rollback = true;
......@@ -552,7 +556,7 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
} catch (...) {
// For things like bad_cast in boost::lexical_cast
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_EXCEPTION).arg(config_pair.first);
answer = isc::config::createAnswer(1, "undefined configuration"
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, "undefined configuration"
" processing error");
// An error occurred, so make sure that we restore original data.
......@@ -562,7 +566,7 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
if (check_only) {
rollback = true;
if (!answer) {
answer = isc::config::createAnswer(0,
answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS,
"Configuration seems sane. Control-socket, hook-libraries, and D2 "
"configuration were sanity checked, but not applied.");
}
......@@ -574,9 +578,6 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
// This operation should be exception safe but let's make sure.
if (!rollback) {
try {
// if we have config-control DBs attempt to create them here,
// if that fails, rollback?
// Setup the command channel.
configureCommandChannel();
......@@ -595,17 +596,17 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
CfgMgr::instance().getStagingCfg()->getHooksConfig();
libraries.loadLibraries();
// now that we have config-db and hooks, merge in config from DB
// databaseConfigFetch(srv_config, mutable_cfg);
// If there are config backends, fetch and merge into staging config
databaseConfigFetch(srv_cfg, mutable_cfg);
}
catch (const isc::Exception& ex) {
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_FAIL).arg(ex.what());
answer = isc::config::createAnswer(2, ex.what());
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, ex.what());
rollback = true;
} catch (...) {
// For things like bad_cast in boost::lexical_cast
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_EXCEPTION);
answer = isc::config::createAnswer(2, "undefined configuration"
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, "undefined configuration"
" parsing error");
rollback = true;
}
......@@ -625,9 +626,53 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
getConfigSummary(SrvConfig::CFGSEL_ALL4));
// Everything was fine. Configuration is successful.
answer = isc::config::createAnswer(0, "Configuration successful.");
answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS, "Configuration successful.");
return (answer);
}
bool databaseConfigConnect(const SrvConfigPtr& srv_cfg) {
// We need to get rid of any existing backends. These would be any
// opened by previous configuration cycle.
ConfigBackendDHCPv4Mgr& mgr = ConfigBackendDHCPv4Mgr::instance();
mgr.delAllBackends();
// Fetch the config-control info.
ConstConfigControlInfoPtr config_ctl = srv_cfg->getConfigControlInfo();
if (!config_ctl || config_ctl->getConfigDatabases().empty()) {
// No config dbs, nothing to do.
return (false);
}
// Iterate over the configured DBs and instantiate them.
for (auto db : config_ctl->getConfigDatabases()) {
LOG_INFO(dhcp4_logger, DHCP4_OPEN_CONFIG_DB)
.arg(db.redactedAccessString());
mgr.addBackend(db.getAccessString());
}
// Let the caller know we have opened DBs.
return (true);
}
void databaseConfigFetch(const SrvConfigPtr& srv_cfg, ElementPtr /* mutable_cfg */) {
// Close any existing CB databasess, then open all in srv_cfg (if any)
if (!databaseConfigConnect(srv_cfg)) {
// There are no CB databases so we're done
return;
}
// @todo Fetching and merging the configuration falls under #99
// ConfigBackendDHCPv4Mgr& mgr = ConfigBackendDHCPv4Mgr::instance();
// Next we have to fetch the pieces we care about it and merge them
// probably in this order?
// globals
// option defs
// options
// shared networks
// subnets
}
}; // end of isc::dhcp namespace
}; // end of isc namespace
......@@ -59,6 +59,35 @@ configureDhcp4Server(Dhcpv4Srv&,
isc::data::ConstElementPtr config_set,
bool check_only = false);
/// @brief Attempts to connect to configured CB databases
///
/// First, this function will close all existing CB backends. It
/// will then attempt to connect to all of the CB backends defined
/// in the given SrvConfig (if any).
///
/// It will return true if there are configured CB databases,
/// and false otherwise. Any errors encountered along the way
/// should generate throws.
///
/// @param srv_cfg Server configuration from which to get
/// the config-control information to use.
///
/// @return True if there are configured CB databases, false if not.
bool
databaseConfigConnect(const SrvConfigPtr& srv_cfg);
/// @brief Fetch configuration from CB databases and merge it into the given configuration
///
/// It will call @c databaseConfigConnect, passing in the given server configuration. If
/// that call results in open CB databases, the function will then proceed to fetch
/// configuration components from said databases and merge them into the given server
/// configuration.
///
/// @param srv_cfg Server configuration into which database configuration should be merged
/// @param mutable_cfg parsed configuration from the configuration file plus default values
void
databaseConfigFetch(const SrvConfigPtr& srv_cfg, isc::data::ElementPtr /* mutable_cfg */);
}; // end of isc::dhcp namespace
}; // end of isc namespace
......
......@@ -25,6 +25,7 @@
#include <dhcpsrv/cfg_hosts.h>
#include <dhcpsrv/cfg_subnets4.h>
#include <dhcpsrv/testutils/config_result_check.h>
#include <dhcpsrv/testutils/test_config_backend_dhcp4.h>
#include <process/config_ctl_info.h>
#include <hooks/hooks_manager.h>
......@@ -6258,10 +6259,27 @@ TEST_F(Dhcp4ParserTest, globalReservations) {
EXPECT_FALSE(hosts_cfg->get4(542, Host::IDENT_DUID, &duid[0], duid.size()));
}
// This test verifies that configuration control with unsupported type fails
TEST_F(Dhcp4ParserTest, configControlInfoNoFactory) {
string config = PARSER_CONFIGS[6];
extractConfig(config);
// Should fail because "type=mysql" has no factories.
configure(config, CONTROL_RESULT_ERROR,
"The type of the configuration backend: 'mysql' is not supported");
}
// This test verifies that configuration control info gets populated.
TEST_F(Dhcp4ParserTest, configControlInfo) {
string config = PARSER_CONFIGS[6];
extractConfig(config);
// Should be able to register a backend factory for "mysql".
ASSERT_TRUE(TestConfigBackendDHCPv4::
registerBackendType(ConfigBackendDHCPv4Mgr::instance(),
"mysql"));
// Should parse ok, now that the factory has been registered.
configure(config, CONTROL_RESULT_SUCCESS, "");
// Make sure the config control info is there.
......@@ -6273,12 +6291,12 @@ TEST_F(Dhcp4ParserTest, configControlInfo) {
const process::ConfigDbInfoList& dblist = info->getConfigDatabases();
ASSERT_EQ(2, dblist.size());
// Make sure the entries are what we expect and in the right order.
// (DbAccessParser creates access strings with the keywords in
// Make sure the entries are what we expect and in the right order.
// (DbAccessParser creates access strings with the keywords in
// alphabetical order).
EXPECT_EQ("name=keatest1 password=keatest type=mysql user=keatest",
EXPECT_EQ("name=keatest1 password=keatest type=mysql user=keatest",
dblist.front().getAccessString());
EXPECT_EQ("name=keatest2 password=keatest type=mysql user=keatest",
EXPECT_EQ("name=keatest2 password=keatest type=mysql user=keatest",
dblist.back().getAccessString());
}
......
......@@ -19,6 +19,8 @@ libdhcpsrvtest_la_SOURCES += memory_host_data_source.cc memory_host_data_source.
libdhcpsrvtest_la_SOURCES += generic_backend_unittest.cc generic_backend_unittest.h
libdhcpsrvtest_la_SOURCES += generic_host_data_source_unittest.cc generic_host_data_source_unittest.h
libdhcpsrvtest_la_SOURCES += lease_file_io.cc lease_file_io.h
libdhcpsrvtest_la_SOURCES += test_config_backend.h
libdhcpsrvtest_la_SOURCES += test_config_backend_dhcp4.cc test_config_backend_dhcp4.h
libdhcpsrvtest_la_CXXFLAGS = $(AM_CXXFLAGS)
libdhcpsrvtest_la_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
......
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef TEST_CONFIG_BACKEND_H
#define TEST_CONFIG_BACKEND_H
#include <config.h>
#include <database/database_connection.h>
#include <dhcpsrv/config_backend_dhcp4_mgr.h>
#include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
namespace isc {
namespace dhcp {
namespace test {
/// @brief Base class for implementing fake backends
template<typename ConfigBackendType>
class TestConfigBackend : public ConfigBackendType {
public:
/// @brief Constructor
///
/// @param params database connection parameters
/// @throw BadValue if parameters do not include "type"
TestConfigBackend(const db::DatabaseConnection::ParameterMap& params)
: connection_(params) {
try {
db_type_ = connection_.getParameter("type");
} catch (...) {
isc_throw(BadValue, "Backend parameters must include \"type\"");
}
try {
db_type_ = connection_.getParameter("host");
} catch (...) {
host_ = "default_host";
}
try {
port_ = boost::lexical_cast<uint16_t>(connection_.getParameter("host"));
} catch (...) {
port_ = 0;
}
}
/// @brief virtual Destructor.
virtual ~TestConfigBackend(){};
/// @brief Returns backend type.
///
/// @return string db_type name
virtual std::string getType() const { return (db_type_);
}
/// @brief Returns backend host.
///
/// @return string host
virtual std::string getHost() const {
return (host_);
}
/// @brief Returns backend port.
///
/// @return uint16_t port
virtual uint16_t getPort() const {
return (port_);
}
/// @brief Fake database connection
db::DatabaseConnection connection_;
/// @brief Back end type
std::string db_type_;
/// @brief Back end host
std::string host_;
/// @brief Back end port
uint16_t port_;
};
} // namespace test
} // namespace dhcp
} // namespace isc
#endif // TEST_CONFIG_BACKEND_H
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
#include <database/database_connection.h>
#include <test_config_backend_dhcp4.h>
namespace isc {
namespace dhcp {
namespace test {
bool
TestConfigBackendDHCPv4::registerBackendType(ConfigBackendDHCPv4Mgr& mgr,
const std::string& db_type) {
return(mgr.registerBackendFactory(db_type,
[](const db::DatabaseConnection::ParameterMap& params)
-> dhcp::ConfigBackendDHCPv4Ptr {
return (TestConfigBackendDHCPv4Ptr(new TestConfigBackendDHCPv4(params)));
})
);
}
void
TestConfigBackendDHCPv4::unregisterBackendType(ConfigBackendDHCPv4Mgr& mgr,
const std::string& db_type) {
mgr.unregisterBackendFactory(db_type);
}
Subnet4Ptr
TestConfigBackendDHCPv4::getSubnet4(const db::ServerSelector& /* server_selector */,
const std::string& /* subnet_prefix */) const{
return (Subnet4Ptr());
}
Subnet4Ptr
TestConfigBackendDHCPv4::getSubnet4(const db::ServerSelector& /* server_selector */,
const SubnetID& /* subnet_id */) const {
return (Subnet4Ptr());
}
Subnet4Collection
TestConfigBackendDHCPv4::getAllSubnets4(const db::ServerSelector& /* server_selector */) const {
return(subnets_);
}
Subnet4Collection
TestConfigBackendDHCPv4::getModifiedSubnets4(const db::ServerSelector& /* server_selector */,
const boost::posix_time::ptime& /* modification_time */) const {
return(subnets_);
}
SharedNetwork4Ptr
TestConfigBackendDHCPv4::getSharedNetwork4(const db::ServerSelector& /* server_selector */,
const std::string& /* name */) const {
return(SharedNetwork4Ptr());
}
SharedNetwork4Collection
TestConfigBackendDHCPv4::getAllSharedNetworks4(const db::ServerSelector& /* server_selector */) const{
return(shared_networks_);
}
SharedNetwork4Collection
TestConfigBackendDHCPv4::getModifiedSharedNetworks4(const db::ServerSelector& /* server_selector */,
const boost::posix_time::ptime& /* modification_time */) const {
return(shared_networks_);
}
OptionDefinitionPtr
TestConfigBackendDHCPv4::getOptionDef4(const db::ServerSelector& /* server_selector */,
const uint16_t /* code */,
const std::string& /* space */) const {
return (OptionDefinitionPtr());
}
OptionDefContainer
TestConfigBackendDHCPv4::getAllOptionDefs4(const db::ServerSelector& /* server_selector */) const {
return (option_defs_);
}
OptionDefContainer
TestConfigBackendDHCPv4::getModifiedOptionDefs4(const db::ServerSelector& /* server_selector */,
const boost::posix_time::ptime& /* modification_time */) const {
return (option_defs_);
}
OptionDescriptorPtr
TestConfigBackendDHCPv4::getOption4(const db::ServerSelector& /* server_selector */,
const uint16_t /* code */,
const std::string& /* space */) const {
return (OptionDescriptorPtr());
}
OptionContainer
TestConfigBackendDHCPv4::getAllOptions4(const db::ServerSelector& /* server_selector */) const {
return (options_);
}
OptionContainer
TestConfigBackendDHCPv4::getModifiedOptions4(const db::ServerSelector& /* server_selector */,
const boost::posix_time::ptime& /* modification_time */) const {
return (options_);
}
data::StampedValuePtr
TestConfigBackendDHCPv4::getGlobalParameter4(const db::ServerSelector& /* server_selector */,
const std::string& /* name */) const {
return(data::StampedValuePtr());
}
data::StampedValueCollection
TestConfigBackendDHCPv4::getAllGlobalParameters4(const db::ServerSelector& /* server_selector */) const {
return (globals_);
}
data::StampedValueCollection
TestConfigBackendDHCPv4::getModifiedGlobalParameters4(const db::ServerSelector& /* server_selector */,
const boost::posix_time::ptime& /* modification_time */) const {
return (globals_);
}
void
TestConfigBackendDHCPv4::createUpdateSubnet4(const db::ServerSelector& /* server_selector */,
const Subnet4Ptr& /* subnet */) {
}
void
TestConfigBackendDHCPv4::createUpdateSharedNetwork4(const db::ServerSelector& /* server_selector */,
const SharedNetwork4Ptr& /* shared_network */) {
}
void
TestConfigBackendDHCPv4::createUpdateOptionDef4(const db::ServerSelector& /* server_selector */,
const OptionDefinitionPtr& /* option_def */) {
}
void
TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& /* server_selector */,
const OptionDescriptorPtr& /* option */) {
}
void
TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& /* server_selector */,
const std::string& /* shared_network_name */,
const OptionDescriptorPtr& /* option */) {
}
void
TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& /* server_selector */,
const SubnetID& /* subnet_id */,
const OptionDescriptorPtr& /* option */) {
}
void
TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& /* server_selector */,
const asiolink::IOAddress& /* pool_start_address */,
const asiolink::IOAddress& /* pool_end_address */,
const OptionDescriptorPtr& /* option */) {
}
void
TestConfigBackendDHCPv4::createUpdateGlobalParameter4(const db::ServerSelector& /* server_selector */,
const data::StampedValuePtr& /* value */) {
}
uint64_t
TestConfigBackendDHCPv4::deleteSubnet4(const db::ServerSelector& /* server_selector */,
const std::string& /* subnet_prefix */) {
return (0);
}
uint64_t
TestConfigBackendDHCPv4::deleteSubnet4(const db::ServerSelector& /* server_selector */,
const SubnetID& /* subnet_id */) {
return (0);
}
uint64_t
TestConfigBackendDHCPv4::deleteAllSubnets4(const db::ServerSelector& /* server_selector */) {
return (0);
}
uint64_t
TestConfigBackendDHCPv4::deleteSharedNetwork4(const db::ServerSelector& /* server_selector */,
const std::string& /* name */) {
return (0);
}
uint64_t
TestConfigBackendDHCPv4::deleteAllSharedNetworks4(const db::ServerSelector& /* server_selector */) {
return (0);
}
uint64_t
TestConfigBackendDHCPv4::deleteOptionDef4(const db::ServerSelector& /* server_selector */,
const uint16_t /* code */,
const std::string& /* space */) {
return (0);
}
uint64_t
TestConfigBackendDHCPv4::deleteAllOptionDefs4(const db::ServerSelector& /* server_selector */) {
return (0);
}
uint64_t
TestConfigBackendDHCPv4::deleteOption4(const db::ServerSelector& /* server_selector */,
const uint16_t /* code */,
const std::string& /* space */) {
return (0);
}
uint64_t
TestConfigBackendDHCPv4::deleteOption4(const db::ServerSelector& /* server_selector */,
const std::string& /* shared_network_name */,
const uint16_t /* code */,
const std::string& /* space */) {
return (0);
}
uint64_t
TestConfigBackendDHCPv4::deleteOption4(const db::ServerSelector& /* server_selector */,
const SubnetID& /* subnet_id */,
const uint16_t /* code */,
const std::string& /* space */) {
return (0);
}
uint64_t
TestConfigBackendDHCPv4::deleteOption4(const db::ServerSelector& /* server_selector */,
const asiolink::IOAddress& /* pool_start_address */,
const asiolink::IOAddress& /* pool_end_address */,
const uint16_t /* code */,
const std::string& /* space */) {
return (0);
}
uint64_t
TestConfigBackendDHCPv4::deleteGlobalParameter4(const db::ServerSelector& /* server_selector */,
const std::string& /* name */) {
return (0);
}
uint64_t
TestConfigBackendDHCPv4::deleteAllGlobalParameters4(const db::ServerSelector& /* server_selector */) {
return (0);
}
} // namespace test
} // namespace dhcp
} // namespace isc
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef TEST_CONFIG_BACKEND_DHCP4
#define TEST_CONFIG_BACKEND_DHCP4
#include <config.h>
#include <database/database_connection.h>
#include <dhcpsrv/config_backend_dhcp4_mgr.h>
#include <dhcpsrv/testutils/test_config_backend.h>
#include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
namespace isc {
namespace dhcp {
namespace test {
/// @brief Test backend that implements all of the DHCPv4 API calls
///
/// Currently all API get calls which return a single entry, will return an
/// empty pointer of appropriate type. API calls which return a collection of
/// entires will return an empty collection of the appropriate type.
///
/// In addition provides static register and unregister methods so it may be
/// registered with a configuration backend manager.
class TestConfigBackendDHCPv4 : public TestConfigBackend<ConfigBackendDHCPv4> {
public:
/// @brief Constructor
///
///
TestConfigBackendDHCPv4(const db::DatabaseConnection::ParameterMap& params)
: TestConfigBackend(params) {
}
/// @brief virtual Destructor.
virtual ~TestConfigBackendDHCPv4(){};
/// @brief Registers the backend type with the given backend manager
///
/// @param mgr configuration manager to register with
/// @brief db_type back end type - Note you will need to
/// use the same value here as you do when creating backend instances.
static bool registerBackendType(ConfigBackendDHCPv4Mgr& mgr,
const std::string& db_type);
/// @brief Unregisters the backend from the given backend manager
///
/// @param mgr configuration manager to unregister from
/// @brief db_type back end type - Note you will need to
/// use the same value here as you do when registering the backend type
static void unregisterBackendType(ConfigBackendDHCPv4Mgr& mgr,
const std::string& db_type);
/// @brief Retrieves a single subnet by subnet_prefix.
///
/// @param server_selector Server selector.
/// @param subnet_prefix Prefix of the subnet to be retrieved.
/// @return Pointer to the retrieved subnet or NULL if not found.
virtual Subnet4Ptr
getSubnet4(const db::ServerSelector& server_selector,
const std::string& subnet_prefix) const;
/// @brief Retrieves a single subnet by subnet identifier.
///
/// @param server_selector Server selector.
/// @param subnet_id Identifier of a subnet to be retrieved.
/// @return Pointer to the retrieved subnet or NULL if not found.
virtual Subnet4Ptr
getSubnet4(const db::ServerSelector& server_selector, const SubnetID& subnet_id) const;
/// @brief Retrieves all subnets.
///
/// @param server_selector Server selector.
/// @return Collection of subnets or empty collection if no subnet found.