mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 14:05:33 +00:00
[3569] Implemented configuration for host data source.
This commit is contained in:
@@ -438,7 +438,11 @@ DhcpConfigParser* createGlobalDhcp4ConfigParser(const std::string& config_id,
|
||||
parser = new StringParser(config_id,
|
||||
globalContext()->string_values_);
|
||||
} else if (config_id.compare("lease-database") == 0) {
|
||||
parser = new DbAccessParser(config_id, *globalContext());
|
||||
parser = new DbAccessParser(config_id, DbAccessParser::LEASE_DB,
|
||||
*globalContext());
|
||||
} else if (config_id.compare("hosts-database") == 0) {
|
||||
parser = new DbAccessParser(config_id, DbAccessParser::HOSTS_DB,
|
||||
*globalContext());
|
||||
} else if (config_id.compare("hooks-libraries") == 0) {
|
||||
parser = new HooksLibrariesParser(config_id);
|
||||
} else if (config_id.compare("echo-client-id") == 0) {
|
||||
|
@@ -689,7 +689,11 @@ DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id,
|
||||
parser = new StringParser(config_id,
|
||||
globalContext()->string_values_);
|
||||
} else if (config_id.compare("lease-database") == 0) {
|
||||
parser = new DbAccessParser(config_id, *globalContext());
|
||||
parser = new DbAccessParser(config_id, DbAccessParser::LEASE_DB,
|
||||
*globalContext());
|
||||
} else if (config_id.compare("hosts-database") == 0) {
|
||||
parser = new DbAccessParser(config_id, DbAccessParser::HOSTS_DB,
|
||||
*globalContext());
|
||||
} else if (config_id.compare("hooks-libraries") == 0) {
|
||||
parser = new HooksLibrariesParser(config_id);
|
||||
} else if (config_id.compare("dhcp-ddns") == 0) {
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include <dhcp/hwaddr.h>
|
||||
#include <dhcpsrv/host.h>
|
||||
#include <exceptions/exceptions.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace isc {
|
||||
namespace dhcp {
|
||||
@@ -214,6 +215,9 @@ public:
|
||||
virtual void rollback() {};
|
||||
};
|
||||
|
||||
/// @brief HostDataSource pointer
|
||||
typedef boost::shared_ptr<BaseHostDataSource> HostDataSourcePtr;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -207,6 +207,14 @@ public:
|
||||
return (std::string("host_mgr"));
|
||||
}
|
||||
|
||||
/// @brief Returns pointer to the host data source
|
||||
///
|
||||
/// May return NULL
|
||||
/// @return pointer to the host data source (or NULL)
|
||||
HostDataSourcePtr getHostDataSource() const {
|
||||
return (alternate_source);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/// @brief Private default constructor.
|
||||
@@ -215,7 +223,7 @@ private:
|
||||
/// @brief Pointer to an alternate host data source.
|
||||
///
|
||||
/// If this pointer is NULL, the source is not in use.
|
||||
static boost::shared_ptr<BaseHostDataSource> alternate_source;
|
||||
HostDataSourcePtr alternate_source;
|
||||
|
||||
/// @brief Returns a pointer to the currently used instance of the
|
||||
/// @c HostMgr.
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include <dhcp/option.h>
|
||||
#include <dhcpsrv/dhcpsrv_log.h>
|
||||
#include <dhcpsrv/lease_mgr_factory.h>
|
||||
#include <dhcpsrv/host_mgr.h>
|
||||
#include <dhcpsrv/parsers/dbaccess_parser.h>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
@@ -34,8 +35,9 @@ namespace dhcp {
|
||||
|
||||
|
||||
// Factory function to build the parser
|
||||
DbAccessParser::DbAccessParser(const std::string&, const ParserContext& ctx)
|
||||
: values_(), ctx_(ctx)
|
||||
DbAccessParser::DbAccessParser(const std::string&, DBType db_type,
|
||||
const ParserContext& ctx)
|
||||
: values_(), type_(db_type), ctx_(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -139,11 +141,29 @@ DbAccessParser::getDbAccessString() const {
|
||||
// Commit the changes - reopen the database with the new parameters
|
||||
void
|
||||
DbAccessParser::commit() {
|
||||
// Close current lease manager database.
|
||||
LeaseMgrFactory::destroy();
|
||||
|
||||
// ... and open the new database using the access string.
|
||||
LeaseMgrFactory::create(getDbAccessString());
|
||||
switch (type_) {
|
||||
case LEASE_DB:
|
||||
{
|
||||
// Close current lease manager database.
|
||||
LeaseMgrFactory::destroy();
|
||||
|
||||
// ... and open the new database using the access string.
|
||||
LeaseMgrFactory::create(getDbAccessString());
|
||||
break;
|
||||
}
|
||||
case HOSTS_DB:
|
||||
{
|
||||
// Let's instantiate HostMgr with new parameters. Note that HostMgr's
|
||||
// constructor will call HostDataSourceFactory::create() with appropriate
|
||||
// parameters.
|
||||
HostMgr::create(getDbAccessString());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
isc_throw(BadValue, "Incorrect type specified in DbAccessParser: "
|
||||
<< type_);
|
||||
};
|
||||
}
|
||||
|
||||
}; // namespace dhcp
|
||||
|
@@ -45,6 +45,13 @@ public:
|
||||
/// depend on the database chosen.
|
||||
class DbAccessParser: public DhcpConfigParser {
|
||||
public:
|
||||
|
||||
/// @brief Specifies the database type
|
||||
typedef enum {
|
||||
LEASE_DB = 1,
|
||||
HOSTS_DB = 2
|
||||
} DBType;
|
||||
|
||||
/// @brief Keyword and associated value
|
||||
typedef std::pair<std::string, std::string> StringPair;
|
||||
|
||||
@@ -55,8 +62,10 @@ public:
|
||||
///
|
||||
/// @param param_name Name of the parameter under which the database
|
||||
/// access details are held.
|
||||
/// @param db_type Specifies database type (lease or hosts)
|
||||
/// @param ctx Parser context.
|
||||
DbAccessParser(const std::string& param_name, const ParserContext& ctx);
|
||||
DbAccessParser(const std::string& param_name, DBType db_type,
|
||||
const ParserContext& ctx);
|
||||
|
||||
/// The destructor.
|
||||
virtual ~DbAccessParser()
|
||||
@@ -103,7 +112,14 @@ public:
|
||||
/// destroying the parser after use.
|
||||
static DhcpConfigParser* factory(const std::string& param_name,
|
||||
const ParserContext& ctx) {
|
||||
return (new DbAccessParser(param_name, ctx));
|
||||
if (param_name == "lease-database") {
|
||||
return (new DbAccessParser(param_name, DbAccessParser::LEASE_DB, ctx));
|
||||
} else if (param_name == "hosts-database") {
|
||||
return (new DbAccessParser(param_name, DbAccessParser::HOSTS_DB, ctx));
|
||||
} else {
|
||||
isc_throw(BadValue, "Unexpected parameter name (" << param_name
|
||||
<< ") passed to DbAccessParser::factory");
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -130,6 +146,8 @@ private:
|
||||
|
||||
std::map<std::string, std::string> values_; ///< Stored parameter values
|
||||
|
||||
DBType type_; ///< Database type (leases or hosts)
|
||||
|
||||
ParserContext ctx_; ///< Parser context
|
||||
};
|
||||
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include <cc/command_interpreter.h>
|
||||
#include <dhcpsrv/lease_mgr_factory.h>
|
||||
#include <dhcpsrv/parsers/dbaccess_parser.h>
|
||||
#include <dhcpsrv/host_mgr.h>
|
||||
#include <log/logger_support.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
@@ -201,8 +202,9 @@ public:
|
||||
/// @brief Constructor
|
||||
///
|
||||
/// @brief Keyword/value collection of ddatabase access parameters
|
||||
TestDbAccessParser(const std::string& param_name, const ParserContext& ctx)
|
||||
: DbAccessParser(param_name, ctx)
|
||||
TestDbAccessParser(const std::string& param_name, DbAccessParser::DBType type,
|
||||
const ParserContext& ctx)
|
||||
: DbAccessParser(param_name, type, ctx)
|
||||
{}
|
||||
|
||||
/// @brief Destructor
|
||||
@@ -243,7 +245,8 @@ TEST_F(DbAccessParserTest, validTypeMemfile) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB,
|
||||
ParserContext(Option::V4));
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
checkAccessString("Valid memfile", parser.getDbAccessParameters(), config);
|
||||
}
|
||||
@@ -259,7 +262,8 @@ TEST_F(DbAccessParserTest, emptyKeyword) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB,
|
||||
ParserContext(Option::V4));
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
checkAccessString("Valid memfile", parser.getDbAccessParameters(), config);
|
||||
}
|
||||
@@ -276,7 +280,8 @@ TEST_F(DbAccessParserTest, persistV4Memfile) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB,
|
||||
ParserContext(Option::V4));
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
|
||||
checkAccessString("Valid memfile", parser.getDbAccessParameters(),
|
||||
@@ -295,7 +300,8 @@ TEST_F(DbAccessParserTest, persistV6Memfile) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", ParserContext(Option::V6));
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB,
|
||||
ParserContext(Option::V6));
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
|
||||
checkAccessString("Valid memfile", parser.getDbAccessParameters(),
|
||||
@@ -314,7 +320,8 @@ TEST_F(DbAccessParserTest, validLFCInterval) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", ParserContext(Option::V6));
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB,
|
||||
ParserContext(Option::V6));
|
||||
ASSERT_NO_THROW(parser.build(json_elements));
|
||||
checkAccessString("Valid LFC Interval", parser.getDbAccessParameters(),
|
||||
config, Option::V6);
|
||||
@@ -332,7 +339,8 @@ TEST_F(DbAccessParserTest, negativeLFCInterval) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", ParserContext(Option::V6));
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB,
|
||||
ParserContext(Option::V6));
|
||||
EXPECT_THROW(parser.build(json_elements), BadValue);
|
||||
}
|
||||
|
||||
@@ -348,7 +356,8 @@ TEST_F(DbAccessParserTest, largeLFCInterval) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", ParserContext(Option::V6));
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB,
|
||||
ParserContext(Option::V6));
|
||||
EXPECT_THROW(parser.build(json_elements), BadValue);
|
||||
}
|
||||
|
||||
@@ -365,7 +374,8 @@ TEST_F(DbAccessParserTest, validTypeMysql) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB,
|
||||
ParserContext(Option::V4));
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
checkAccessString("Valid mysql", parser.getDbAccessParameters(), config);
|
||||
}
|
||||
@@ -382,7 +392,8 @@ TEST_F(DbAccessParserTest, missingTypeKeyword) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB,
|
||||
ParserContext(Option::V4));
|
||||
EXPECT_THROW(parser.build(json_elements), TypeKeywordMissing);
|
||||
}
|
||||
|
||||
@@ -442,7 +453,8 @@ TEST_F(DbAccessParserTest, incrementalChanges) {
|
||||
"name", "keatest",
|
||||
NULL};
|
||||
|
||||
TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB,
|
||||
ParserContext(Option::V4));
|
||||
|
||||
// First configuration string should cause a representation of that string
|
||||
// to be held.
|
||||
@@ -506,7 +518,8 @@ TEST_F(DbAccessParserTest, getDbAccessString) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB,
|
||||
ParserContext(Option::V4));
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
|
||||
// Get the database access string
|
||||
@@ -518,10 +531,10 @@ TEST_F(DbAccessParserTest, getDbAccessString) {
|
||||
EXPECT_EQ(dbaccess, "name=keatest type=mysql universe=4");
|
||||
}
|
||||
|
||||
// Check that the "commit" function actually opens the database. We will
|
||||
// only do this for the "memfile" database, as that does not assume that the
|
||||
// test has been built with MySQL support.
|
||||
TEST_F(DbAccessParserTest, commit) {
|
||||
// Check that the "commit" function actually opens the database, when type
|
||||
// is set to LEASE_DB. We will only do this for the "memfile" database, as
|
||||
// that does not assume that the test has been built with MySQL support.
|
||||
TEST_F(DbAccessParserTest, commitLeaseDb) {
|
||||
|
||||
// Verify that no lease database is open
|
||||
EXPECT_THROW({
|
||||
@@ -536,7 +549,8 @@ TEST_F(DbAccessParserTest, commit) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", ParserContext(Option::V4));
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB,
|
||||
ParserContext(Option::V4));
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
|
||||
// Ensure that the access string is as expected.
|
||||
@@ -552,4 +566,46 @@ TEST_F(DbAccessParserTest, commit) {
|
||||
EXPECT_EQ(std::string("memfile"), dbtype);
|
||||
}
|
||||
|
||||
// Check that the "commit" function actually opens the database, when type
|
||||
// is set to HOSTS_DB.
|
||||
TEST_F(DbAccessParserTest, commitHostsDb) {
|
||||
|
||||
// Verify that no lease database is open
|
||||
EXPECT_THROW({
|
||||
LeaseMgr& manager = LeaseMgrFactory::instance();
|
||||
manager.getType(); // Never executed but satisfies compiler
|
||||
}, isc::dhcp::NoLeaseManager);
|
||||
|
||||
// Set up the parser to open the memfile database.
|
||||
const char* config[] = {"type", "memfile", "persist", "false", NULL};
|
||||
string json_config = toJson(config);
|
||||
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("hosts-database", DbAccessParser::HOSTS_DB,
|
||||
ParserContext(Option::V4));
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
|
||||
// Ensure that the access string is as expected.
|
||||
EXPECT_EQ("persist=false type=memfile universe=4",
|
||||
parser.getDbAccessString());
|
||||
|
||||
// Destroy lease mgr (if there's any)
|
||||
LeaseMgrFactory::destroy();
|
||||
|
||||
// Committal of the parser changes should not create LeaseMgr.
|
||||
// It should create HostDataSource instead.
|
||||
EXPECT_NO_THROW(parser.commit());
|
||||
|
||||
// Check that LeaseMgr was NOT created (it shouldn't, this is for HOSTS_DB.
|
||||
EXPECT_THROW(LeaseMgrFactory::instance(), NoLeaseManager);
|
||||
|
||||
HostDataSourcePtr hds = HostMgr::instance().getHostDataSource();
|
||||
|
||||
/// @todo: Uncomment this once 3682 is merged. The whole unit-test
|
||||
/// should create MySQL database and be ifdefed appropriately.
|
||||
// ASSERT_TRUE(hds);
|
||||
}
|
||||
|
||||
}; // Anonymous namespace
|
||||
|
Reference in New Issue
Block a user