mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 05:55:28 +00:00
[master] Finishing merge of trac5096 (migrate database config)
This commit is contained in:
@@ -258,13 +258,48 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
|
||||
case isc::dhcp::Parser4Context::LEASE_DATABASE:
|
||||
case isc::dhcp::Parser4Context::HOSTS_DATABASE:
|
||||
case isc::dhcp::Parser4Context::OPTION_DEF:
|
||||
case isc::dhcp::Parser4Context::SERVER_ID:
|
||||
return isc::dhcp::Dhcp4Parser::make_TYPE(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("type", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"memfile\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DATABASE_TYPE:
|
||||
return isc::dhcp::Dhcp4Parser::make_MEMFILE(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("memfile", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"mysql\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DATABASE_TYPE:
|
||||
return isc::dhcp::Dhcp4Parser::make_MYSQL(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("mysql", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"postgresql\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DATABASE_TYPE:
|
||||
return isc::dhcp::Dhcp4Parser::make_POSTGRESQL(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("postgresql", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"cql\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DATABASE_TYPE:
|
||||
return isc::dhcp::Dhcp4Parser::make_CQL(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("cql", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"user\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::LEASE_DATABASE:
|
||||
@@ -299,7 +334,6 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::LEASE_DATABASE:
|
||||
case isc::dhcp::Parser4Context::HOSTS_DATABASE:
|
||||
case isc::dhcp::Parser4Context::SERVER_ID:
|
||||
return isc::dhcp::Dhcp4Parser::make_PERSIST(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("persist", driver.loc_);
|
||||
@@ -316,6 +350,16 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
|
||||
}
|
||||
}
|
||||
|
||||
\"connect-timeout\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::LEASE_DATABASE:
|
||||
case isc::dhcp::Parser4Context::HOSTS_DATABASE:
|
||||
return isc::dhcp::Dhcp4Parser::make_CONNECT_TIMEOUT(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("connect-timeout", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"valid-lifetime\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DHCP4:
|
||||
@@ -737,51 +781,6 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
|
||||
}
|
||||
}
|
||||
|
||||
\"server-id\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DHCP4:
|
||||
return isc::dhcp::Dhcp4Parser::make_SERVER_ID(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("server-id", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"identifier\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::SERVER_ID:
|
||||
return isc::dhcp::Dhcp4Parser::make_IDENTIFIER(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("identifier", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"htype\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::SERVER_ID:
|
||||
return isc::dhcp::Dhcp4Parser::make_HTYPE(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("htype", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"time\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::SERVER_ID:
|
||||
return isc::dhcp::Dhcp4Parser::make_TIME(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("time", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"enterprise-id\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::SERVER_ID:
|
||||
return isc::dhcp::Dhcp4Parser::make_ENTERPRISE_ID(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("enterprise-id", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"expired-leases-processing\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DHCP4:
|
||||
|
@@ -65,12 +65,17 @@ using namespace std;
|
||||
LEASE_DATABASE "lease-database"
|
||||
HOSTS_DATABASE "hosts-database"
|
||||
TYPE "type"
|
||||
MEMFILE "memfile"
|
||||
MYSQL "mysql"
|
||||
POSTGRESQL "postgresql"
|
||||
CQL "cql"
|
||||
USER "user"
|
||||
PASSWORD "password"
|
||||
HOST "host"
|
||||
PERSIST "persist"
|
||||
LFC_INTERVAL "lfc-interval"
|
||||
READONLY "readonly"
|
||||
CONNECT_TIMEOUT "connect-timeout"
|
||||
|
||||
VALID_LIFETIME "valid-lifetime"
|
||||
RENEW_TIMER "renew-timer"
|
||||
@@ -129,12 +134,6 @@ using namespace std;
|
||||
MAX_RECLAIM_TIME "max-reclaim-time"
|
||||
UNWARNED_RECLAIM_CYCLES "unwarned-reclaim-cycles"
|
||||
|
||||
SERVER_ID "server-id"
|
||||
IDENTIFIER "identifier"
|
||||
HTYPE "htype"
|
||||
TIME "time"
|
||||
ENTERPRISE_ID "enterprise-id"
|
||||
|
||||
DHCP4O6_PORT "dhcp4o6-port"
|
||||
|
||||
CONTROL_SOCKET "control-socket"
|
||||
@@ -196,6 +195,7 @@ using namespace std;
|
||||
|
||||
%type <ElementPtr> value
|
||||
%type <ElementPtr> socket_type
|
||||
%type <ElementPtr> db_type
|
||||
%type <ElementPtr> ncr_protocol_value
|
||||
%type <ElementPtr> replace_client_name_value
|
||||
|
||||
@@ -394,7 +394,6 @@ global_param: valid_lifetime
|
||||
| option_data_list
|
||||
| hooks_libraries
|
||||
| expired_leases_processing
|
||||
| server_id
|
||||
| dhcp4o6_port
|
||||
| control_socket
|
||||
| dhcp_ddns
|
||||
@@ -506,7 +505,7 @@ database_map_params: database_map_param
|
||||
| database_map_params COMMA database_map_param
|
||||
;
|
||||
|
||||
database_map_param: type
|
||||
database_map_param: database_type
|
||||
| user
|
||||
| password
|
||||
| host
|
||||
@@ -514,17 +513,23 @@ database_map_param: type
|
||||
| persist
|
||||
| lfc_interval
|
||||
| readonly
|
||||
| connect_timeout
|
||||
| unknown_map_entry
|
||||
;
|
||||
|
||||
type: TYPE {
|
||||
ctx.enter(ctx.NO_KEYWORD);
|
||||
} COLON STRING {
|
||||
ElementPtr prf(new StringElement($4, ctx.loc2pos(@4)));
|
||||
ctx.stack_.back()->set("type", prf);
|
||||
database_type: TYPE {
|
||||
ctx.enter(ctx.DATABASE_TYPE);
|
||||
} COLON db_type {
|
||||
ctx.stack_.back()->set("type", $4);
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
db_type: MEMFILE { $$ = ElementPtr(new StringElement("memfile", ctx.loc2pos(@1))); }
|
||||
| MYSQL { $$ = ElementPtr(new StringElement("mysql", ctx.loc2pos(@1))); }
|
||||
| POSTGRESQL { $$ = ElementPtr(new StringElement("postgresql", ctx.loc2pos(@1))); }
|
||||
| CQL { $$ = ElementPtr(new StringElement("cql", ctx.loc2pos(@1))); }
|
||||
;
|
||||
|
||||
user: USER {
|
||||
ctx.enter(ctx.NO_KEYWORD);
|
||||
} COLON STRING {
|
||||
@@ -572,9 +577,9 @@ readonly: READONLY COLON BOOLEAN {
|
||||
ctx.stack_.back()->set("readonly", n);
|
||||
};
|
||||
|
||||
duid_id : DUID {
|
||||
ElementPtr duid(new StringElement("duid", ctx.loc2pos(@1)));
|
||||
ctx.stack_.back()->add(duid);
|
||||
connect_timeout: CONNECT_TIMEOUT COLON INTEGER {
|
||||
ElementPtr n(new IntElement($3, ctx.loc2pos(@3)));
|
||||
ctx.stack_.back()->set("connect-timeout", n);
|
||||
};
|
||||
|
||||
host_reservation_identifiers: HOST_RESERVATION_IDENTIFIERS {
|
||||
@@ -597,6 +602,11 @@ host_reservation_identifier: duid_id
|
||||
| client_id
|
||||
;
|
||||
|
||||
duid_id : DUID {
|
||||
ElementPtr duid(new StringElement("duid", ctx.loc2pos(@1)));
|
||||
ctx.stack_.back()->add(duid);
|
||||
};
|
||||
|
||||
hw_address_id : HW_ADDRESS {
|
||||
ElementPtr hwaddr(new StringElement("hw-address", ctx.loc2pos(@1)));
|
||||
ctx.stack_.back()->add(hwaddr);
|
||||
@@ -958,7 +968,13 @@ code: CODE COLON INTEGER {
|
||||
|
||||
option_def_code: code;
|
||||
|
||||
option_def_type: type;
|
||||
option_def_type: TYPE {
|
||||
ctx.enter(ctx.NO_KEYWORD);
|
||||
} COLON STRING {
|
||||
ElementPtr prf(new StringElement($4, ctx.loc2pos(@4)));
|
||||
ctx.stack_.back()->set("type", prf);
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
option_def_record_types: RECORD_TYPES {
|
||||
ctx.enter(ctx.NO_KEYWORD);
|
||||
@@ -1354,54 +1370,7 @@ client_class_test: TEST {
|
||||
|
||||
// --- end of client classes ---------------------------------
|
||||
|
||||
// --- server-id ---------------------------------------------
|
||||
server_id: SERVER_ID {
|
||||
ElementPtr m(new MapElement(ctx.loc2pos(@1)));
|
||||
ctx.stack_.back()->set("server-id", m);
|
||||
ctx.stack_.push_back(m);
|
||||
ctx.enter(ctx.SERVER_ID);
|
||||
} COLON LCURLY_BRACKET server_id_params RCURLY_BRACKET {
|
||||
ctx.stack_.pop_back();
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
server_id_params: server_id_param
|
||||
| server_id_params COMMA server_id_param
|
||||
;
|
||||
|
||||
server_id_param: type
|
||||
| identifier
|
||||
| time
|
||||
| htype
|
||||
| enterprise_id
|
||||
| persist
|
||||
| unknown_map_entry
|
||||
;
|
||||
|
||||
htype: HTYPE COLON INTEGER {
|
||||
ElementPtr htype(new IntElement($3, ctx.loc2pos(@3)));
|
||||
ctx.stack_.back()->set("htype", htype);
|
||||
};
|
||||
|
||||
identifier: IDENTIFIER {
|
||||
ctx.enter(ctx.NO_KEYWORD);
|
||||
} COLON STRING {
|
||||
ElementPtr id(new StringElement($4, ctx.loc2pos(@4)));
|
||||
ctx.stack_.back()->set("identifier", id);
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
time: TIME COLON INTEGER {
|
||||
ElementPtr time(new IntElement($3, ctx.loc2pos(@3)));
|
||||
ctx.stack_.back()->set("time", time);
|
||||
};
|
||||
|
||||
enterprise_id: ENTERPRISE_ID COLON INTEGER {
|
||||
ElementPtr time(new IntElement($3, ctx.loc2pos(@3)));
|
||||
ctx.stack_.back()->set("enterprise-id", time);
|
||||
};
|
||||
|
||||
// --- end of server-id --------------------------------------
|
||||
// was server-id but in is DHCPv6-only
|
||||
|
||||
dhcp4o6_port: DHCP4O6_PORT COLON INTEGER {
|
||||
ElementPtr time(new IntElement($3, ctx.loc2pos(@3)));
|
||||
|
@@ -425,12 +425,9 @@ DhcpConfigParser* createGlobalDhcp4ConfigParser(const std::string& config_id,
|
||||
} else if ((config_id.compare("next-server") == 0)) {
|
||||
parser = new StringParser(config_id,
|
||||
globalContext()->string_values_);
|
||||
} else if (config_id.compare("lease-database") == 0) {
|
||||
parser = new DbAccessParser(config_id, DbAccessParser::LEASE_DB);
|
||||
} else if (config_id.compare("hosts-database") == 0) {
|
||||
parser = new DbAccessParser(config_id, DbAccessParser::HOSTS_DB);
|
||||
// hooks-libraries are now migrated to SimpleParser.
|
||||
} else if (config_id.compare("echo-client-id") == 0) {
|
||||
// hooks-libraries are now migrated to SimpleParser.
|
||||
// lease-database and hosts-database have been converted to SimpleParser already.
|
||||
} else if (config_id.compare("echo-client-id") == 0) {
|
||||
parser = new BooleanParser(config_id, globalContext()->boolean_values_);
|
||||
// dhcp-ddns has been converted to SimpleParser.
|
||||
} else if (config_id.compare("match-client-id") == 0) {
|
||||
@@ -566,7 +563,6 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
|
||||
// Please do not change this order!
|
||||
ParserCollection independent_parsers;
|
||||
ParserPtr subnet_parser;
|
||||
ParserPtr leases_parser;
|
||||
|
||||
// Some of the parsers alter the state of the system in a way that can't
|
||||
// easily be undone. (Or alter it in a way such that undoing the change has
|
||||
@@ -593,6 +589,8 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
|
||||
ConfigPair config_pair;
|
||||
try {
|
||||
|
||||
SrvConfigPtr srv_cfg = CfgMgr::instance().getStagingCfg();
|
||||
|
||||
// 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.
|
||||
@@ -605,7 +603,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
|
||||
ConstElementPtr option_defs = mutable_cfg->get("option-def");
|
||||
if (option_defs) {
|
||||
OptionDefListParser parser;
|
||||
CfgOptionDefPtr cfg_option_def = CfgMgr::instance().getStagingCfg()->getCfgOptionDef();
|
||||
CfgOptionDefPtr cfg_option_def = srv_cfg->getCfgOptionDef();
|
||||
parser.parse(cfg_option_def, option_defs);
|
||||
}
|
||||
|
||||
@@ -618,7 +616,6 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
|
||||
// boost, but would make the code less readable. We had serious issues
|
||||
// with the parser code debugability, so I decided to keep it as a
|
||||
// series of independent ifs.
|
||||
|
||||
if (config_pair.first == "option-def") {
|
||||
// This is converted to SimpleParser and is handled already above.
|
||||
continue;
|
||||
@@ -626,14 +623,13 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
|
||||
|
||||
if (config_pair.first == "option-data") {
|
||||
OptionDataListParser parser(AF_INET);
|
||||
CfgOptionPtr cfg_option = CfgMgr::instance().getStagingCfg()->getCfgOption();
|
||||
CfgOptionPtr cfg_option = srv_cfg->getCfgOption();
|
||||
parser.parse(cfg_option, config_pair.second);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config_pair.first == "control-socket") {
|
||||
ControlSocketParser parser;
|
||||
SrvConfigPtr srv_cfg = CfgMgr::instance().getStagingCfg();
|
||||
parser.parse(*srv_cfg, config_pair.second);
|
||||
continue;
|
||||
}
|
||||
@@ -646,7 +642,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
|
||||
|
||||
if (config_pair.first == "interfaces-config") {
|
||||
IfacesConfigParser parser(AF_INET);
|
||||
CfgIfacePtr cfg_iface = CfgMgr::instance().getStagingCfg()->getCfgIface();
|
||||
CfgIfacePtr cfg_iface = srv_cfg->getCfgIface();
|
||||
parser.parse(cfg_iface, config_pair.second);
|
||||
continue;
|
||||
}
|
||||
@@ -671,7 +667,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
|
||||
}
|
||||
D2ClientConfigParser parser;
|
||||
D2ClientConfigPtr cfg = parser.parse(config_pair.second);
|
||||
CfgMgr::instance().getStagingCfg()->setD2ClientConfig(cfg);
|
||||
srv_cfg->setD2ClientConfig(cfg);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -679,7 +675,22 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
|
||||
ClientClassDefListParser parser;
|
||||
ClientClassDictionaryPtr dictionary =
|
||||
parser.parse(config_pair.second, AF_INET);
|
||||
CfgMgr::instance().getStagingCfg()->setClientClassDictionary(dictionary);
|
||||
srv_cfg->setClientClassDictionary(dictionary);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Please move at the end when migration will be finished.
|
||||
if (config_pair.first == "lease-database") {
|
||||
DbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
CfgDbAccessPtr cfg_db_access = srv_cfg->getCfgDbAccess();
|
||||
parser.parse(cfg_db_access, config_pair.second);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config_pair.first == "host-database") {
|
||||
DbAccessParser parser(DbAccessParser::HOSTS_DB);
|
||||
CfgDbAccessPtr cfg_db_access = srv_cfg->getCfgDbAccess();
|
||||
parser.parse(cfg_db_access, config_pair.second);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -689,8 +700,6 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
|
||||
.arg(config_pair.first);
|
||||
if (config_pair.first == "subnet4") {
|
||||
subnet_parser = parser;
|
||||
} else if (config_pair.first == "lease-database") {
|
||||
leases_parser = parser;
|
||||
} else {
|
||||
// Those parsers should be started before other
|
||||
// parsers so we can call build straight away.
|
||||
@@ -714,15 +723,6 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
|
||||
// Setup the command channel.
|
||||
configureCommandChannel();
|
||||
|
||||
// the leases database parser is the last to be run.
|
||||
std::map<std::string, ConstElementPtr>::const_iterator leases_config =
|
||||
values_map.find("lease-database");
|
||||
if (leases_config != values_map.end()) {
|
||||
config_pair.first = "lease-database";
|
||||
leases_parser->build(leases_config->second);
|
||||
leases_parser->commit();
|
||||
}
|
||||
|
||||
} catch (const isc::Exception& ex) {
|
||||
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_FAIL)
|
||||
.arg(config_pair.first).arg(ex.what());
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Generated 201701191339
|
||||
// Generated 201701102039
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Locations for Bison parsers in C++
|
||||
|
@@ -133,6 +133,8 @@ Parser4Context::contextName()
|
||||
return ("lease-database");
|
||||
case HOSTS_DATABASE:
|
||||
return ("hosts-database");
|
||||
case DATABASE_TYPE:
|
||||
return ("database-type");
|
||||
case HOST_RESERVATION_IDENTIFIERS:
|
||||
return ("host-reservation-identifiers");
|
||||
case HOOKS_LIBRARIES:
|
||||
|
@@ -204,6 +204,9 @@ public:
|
||||
/// Used while parsing Dhcp4/hosts-database structures.
|
||||
HOSTS_DATABASE,
|
||||
|
||||
/// Used while parsing Dhcp4/*-database/type.
|
||||
DATABASE_TYPE,
|
||||
|
||||
/// Used while parsing Dhcp4/host-reservation-identifiers.
|
||||
HOST_RESERVATION_IDENTIFIERS,
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Generated 201701191339
|
||||
// Generated 201701102039
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Positions for Bison parsers in C++
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Generated 201701191339
|
||||
// Generated 201701102039
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Stack handling for Bison parsers in C++
|
||||
|
@@ -464,6 +464,42 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
|
||||
}
|
||||
}
|
||||
|
||||
\"memfile\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::DATABASE_TYPE:
|
||||
return isc::dhcp::Dhcp6Parser::make_MEMFILE(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("memfile", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"mysql\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::DATABASE_TYPE:
|
||||
return isc::dhcp::Dhcp6Parser::make_MYSQL(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("mysql", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"postgresql\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::DATABASE_TYPE:
|
||||
return isc::dhcp::Dhcp6Parser::make_POSTGRESQL(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("postgresql", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"cql\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::DATABASE_TYPE:
|
||||
return isc::dhcp::Dhcp6Parser::make_CQL(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("cql", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"user\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::LEASE_DATABASE:
|
||||
@@ -515,6 +551,16 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
|
||||
}
|
||||
}
|
||||
|
||||
\"connect-timeout\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::LEASE_DATABASE:
|
||||
case isc::dhcp::Parser6Context::HOSTS_DATABASE:
|
||||
return isc::dhcp::Dhcp6Parser::make_CONNECT_TIMEOUT(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("connect-timeout", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"preferred-lifetime\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::DHCP6:
|
||||
|
@@ -56,12 +56,17 @@ using namespace std;
|
||||
LEASE_DATABASE "lease-database"
|
||||
HOSTS_DATABASE "hosts-database"
|
||||
TYPE "type"
|
||||
MEMFILE "memfile"
|
||||
MYSQL "mysql"
|
||||
POSTGRESQL "postgresql"
|
||||
CQL "cql"
|
||||
USER "user"
|
||||
PASSWORD "password"
|
||||
HOST "host"
|
||||
PERSIST "persist"
|
||||
LFC_INTERVAL "lfc-interval"
|
||||
READONLY "readonly"
|
||||
CONNECT_TIMEOUT "connect-timeout"
|
||||
|
||||
PREFERRED_LIFETIME "preferred-lifetime"
|
||||
VALID_LIFETIME "valid-lifetime"
|
||||
@@ -197,6 +202,7 @@ using namespace std;
|
||||
%token <bool> BOOLEAN "boolean"
|
||||
|
||||
%type <ElementPtr> value
|
||||
%type <ElementPtr> db_type
|
||||
%type <ElementPtr> duid_type
|
||||
%type <ElementPtr> ncr_protocol_value
|
||||
%type <ElementPtr> replace_client_name_value
|
||||
@@ -492,17 +498,23 @@ database_map_param: database_type
|
||||
| persist
|
||||
| lfc_interval
|
||||
| readonly
|
||||
| connect_timeout
|
||||
| unknown_map_entry
|
||||
;
|
||||
|
||||
database_type: TYPE {
|
||||
ctx.enter(ctx.NO_KEYWORD);
|
||||
} COLON STRING {
|
||||
ElementPtr prf(new StringElement($4, ctx.loc2pos(@4)));
|
||||
ctx.stack_.back()->set("type", prf);
|
||||
ctx.enter(ctx.DATABASE_TYPE);
|
||||
} COLON db_type {
|
||||
ctx.stack_.back()->set("type", $4);
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
db_type: MEMFILE { $$ = ElementPtr(new StringElement("memfile", ctx.loc2pos(@1))); }
|
||||
| MYSQL { $$ = ElementPtr(new StringElement("mysql", ctx.loc2pos(@1))); }
|
||||
| POSTGRESQL { $$ = ElementPtr(new StringElement("postgresql", ctx.loc2pos(@1))); }
|
||||
| CQL { $$ = ElementPtr(new StringElement("cql", ctx.loc2pos(@1))); }
|
||||
;
|
||||
|
||||
user: USER {
|
||||
ctx.enter(ctx.NO_KEYWORD);
|
||||
} COLON STRING {
|
||||
@@ -550,6 +562,11 @@ readonly: READONLY COLON BOOLEAN {
|
||||
ctx.stack_.back()->set("readonly", n);
|
||||
};
|
||||
|
||||
connect_timeout: CONNECT_TIMEOUT COLON INTEGER {
|
||||
ElementPtr n(new IntElement($3, ctx.loc2pos(@3)));
|
||||
ctx.stack_.back()->set("connect-timeout", n);
|
||||
};
|
||||
|
||||
mac_sources: MAC_SOURCES {
|
||||
ElementPtr l(new ListElement(ctx.loc2pos(@1)));
|
||||
ctx.stack_.back()->set("mac-sources", l);
|
||||
|
@@ -705,11 +705,8 @@ DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id,
|
||||
// converted to SimpleParser and are handled in configureDhcp6Server.
|
||||
// interfaces-config has been converted to SimpleParser.
|
||||
// version was removed - it was a leftover from bindctrl.
|
||||
} else if (config_id.compare("lease-database") == 0) {
|
||||
parser = new DbAccessParser(config_id, DbAccessParser::LEASE_DB);
|
||||
} else if (config_id.compare("hosts-database") == 0) {
|
||||
parser = new DbAccessParser(config_id, DbAccessParser::HOSTS_DB);
|
||||
// hooks-libraries is now converted to SimpleParser.
|
||||
// lease-database and hosts-database have been converted to SimpleParser already.
|
||||
// mac-source has been converted to SimpleParser.
|
||||
// dhcp-ddns has been converted to SimpleParser
|
||||
} else if (config_id.compare("relay-supplied-options") == 0) {
|
||||
@@ -835,7 +832,6 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
|
||||
// Please do not change this order!
|
||||
ParserCollection independent_parsers;
|
||||
ParserPtr subnet_parser;
|
||||
ParserPtr leases_parser;
|
||||
|
||||
// Some of the parsers alter state of the system that can't easily
|
||||
// be undone. (Or alter it in a way such that undoing the change
|
||||
@@ -862,6 +858,8 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
|
||||
ConfigPair config_pair;
|
||||
try {
|
||||
|
||||
SrvConfigPtr srv_config = CfgMgr::instance().getStagingCfg();
|
||||
|
||||
// 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.
|
||||
@@ -877,7 +875,7 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
|
||||
ConstElementPtr option_defs = mutable_cfg->get("option-def");
|
||||
if (option_defs) {
|
||||
OptionDefListParser parser;
|
||||
CfgOptionDefPtr cfg_option_def = CfgMgr::instance().getStagingCfg()->getCfgOptionDef();
|
||||
CfgOptionDefPtr cfg_option_def = srv_config->getCfgOptionDef();
|
||||
parser.parse(cfg_option_def, option_defs);
|
||||
}
|
||||
|
||||
@@ -895,21 +893,20 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
|
||||
|
||||
if (config_pair.first == "option-data") {
|
||||
OptionDataListParser parser(AF_INET6);
|
||||
CfgOptionPtr cfg_option = CfgMgr::instance().getStagingCfg()->getCfgOption();
|
||||
CfgOptionPtr cfg_option = srv_config->getCfgOption();
|
||||
parser.parse(cfg_option, config_pair.second);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config_pair.first == "mac-sources") {
|
||||
MACSourcesListConfigParser parser;
|
||||
CfgMACSource& mac_source = CfgMgr::instance().getStagingCfg()->getMACSources();
|
||||
CfgMACSource& mac_source = srv_config->getMACSources();
|
||||
parser.parse(mac_source, config_pair.second);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config_pair.first == "control-socket") {
|
||||
ControlSocketParser parser;
|
||||
SrvConfigPtr srv_config = CfgMgr::instance().getStagingCfg();
|
||||
parser.parse(*srv_config, config_pair.second);
|
||||
continue;
|
||||
}
|
||||
@@ -922,14 +919,14 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
|
||||
|
||||
if (config_pair.first == "server-id") {
|
||||
DUIDConfigParser parser;
|
||||
const CfgDUIDPtr& cfg = CfgMgr::instance().getStagingCfg()->getCfgDUID();
|
||||
const CfgDUIDPtr& cfg = srv_config->getCfgDUID();
|
||||
parser.parse(cfg, config_pair.second);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config_pair.first == "interfaces-config") {
|
||||
IfacesConfigParser parser(AF_INET6);
|
||||
CfgIfacePtr cfg_iface = CfgMgr::instance().getStagingCfg()->getCfgIface();
|
||||
CfgIfacePtr cfg_iface = srv_config->getCfgIface();
|
||||
parser.parse(cfg_iface, config_pair.second);
|
||||
continue;
|
||||
}
|
||||
@@ -953,7 +950,7 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
|
||||
}
|
||||
D2ClientConfigParser parser;
|
||||
D2ClientConfigPtr cfg = parser.parse(config_pair.second);
|
||||
CfgMgr::instance().getStagingCfg()->setD2ClientConfig(cfg);
|
||||
srv_config->setD2ClientConfig(cfg);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -961,7 +958,22 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
|
||||
ClientClassDefListParser parser;
|
||||
ClientClassDictionaryPtr dictionary =
|
||||
parser.parse(config_pair.second, AF_INET6);
|
||||
CfgMgr::instance().getStagingCfg()->setClientClassDictionary(dictionary);
|
||||
srv_config->setClientClassDictionary(dictionary);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Please move at the end when migration will be finished.
|
||||
if (config_pair.first == "lease-database") {
|
||||
DbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
CfgDbAccessPtr cfg_db_access = srv_config->getCfgDbAccess();
|
||||
parser.parse(cfg_db_access, config_pair.second);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config_pair.first == "host-database") {
|
||||
DbAccessParser parser(DbAccessParser::HOSTS_DB);
|
||||
CfgDbAccessPtr cfg_db_access = srv_config->getCfgDbAccess();
|
||||
parser.parse(cfg_db_access, config_pair.second);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -971,8 +983,6 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
|
||||
.arg(config_pair.first);
|
||||
if (config_pair.first == "subnet6") {
|
||||
subnet_parser = parser;
|
||||
} else if (config_pair.first == "lease-database") {
|
||||
leases_parser = parser;
|
||||
} else {
|
||||
// Those parsers should be started before other
|
||||
// parsers so we can call build straight away.
|
||||
@@ -996,15 +1006,6 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
|
||||
// Setup the command channel.
|
||||
configureCommandChannel();
|
||||
|
||||
// The lease database parser is the last to be run.
|
||||
std::map<std::string, ConstElementPtr>::const_iterator leases_config =
|
||||
values_map.find("lease-database");
|
||||
if (leases_config != values_map.end()) {
|
||||
config_pair.first = "lease-database";
|
||||
leases_parser->build(leases_config->second);
|
||||
leases_parser->commit();
|
||||
}
|
||||
|
||||
} catch (const isc::Exception& ex) {
|
||||
LOG_ERROR(dhcp6_logger, DHCP6_PARSER_FAIL)
|
||||
.arg(config_pair.first).arg(ex.what());
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Generated 201701191339
|
||||
// Generated 201701102039
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Locations for Bison parsers in C++
|
||||
|
@@ -131,6 +131,8 @@ Parser6Context::contextName()
|
||||
return ("lease-database");
|
||||
case HOSTS_DATABASE:
|
||||
return ("hosts-database");
|
||||
case DATABASE_TYPE:
|
||||
return ("database-type");
|
||||
case MAC_SOURCES:
|
||||
return ("mac-sources");
|
||||
case HOST_RESERVATION_IDENTIFIERS:
|
||||
|
@@ -204,6 +204,9 @@ public:
|
||||
/// Used while parsing Dhcp6/hosts-database structures.
|
||||
HOSTS_DATABASE,
|
||||
|
||||
/// Used while parsing Dhcp6/*-database/type.
|
||||
DATABASE_TYPE,
|
||||
|
||||
/// Used while parsing Dhcp6/mac-sources structures.
|
||||
MAC_SOURCES,
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Generated 201701191339
|
||||
// Generated 201701102039
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Positions for Bison parsers in C++
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Generated 201701191339
|
||||
// Generated 201701102039
|
||||
// A Bison parser, made by GNU Bison 3.0.4.
|
||||
|
||||
// Stack handling for Bison parsers in C++
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2012-2017 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
|
||||
@@ -28,7 +28,8 @@ const my_bool MLM_TRUE = 1;
|
||||
const int MLM_MYSQL_FETCH_SUCCESS = 0;
|
||||
const int MLM_MYSQL_FETCH_FAILURE = 1;
|
||||
|
||||
const int MYSQL_DEFAULT_CONNECTION_TIMEOUT = 5; // seconds
|
||||
/// @todo: Migrate this default value to src/bin/dhcpX/simple_parserX.cc
|
||||
const int MYSQL_DEFAULT_CONNECTION_TIMEOUT = 5; // seconds
|
||||
|
||||
MySqlTransaction::MySqlTransaction(MySqlConnection& conn)
|
||||
: conn_(conn), committed_(false) {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2012-2017 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
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <dhcpsrv/lease_mgr_factory.h>
|
||||
#include <dhcpsrv/host_mgr.h>
|
||||
#include <dhcpsrv/parsers/dbaccess_parser.h>
|
||||
#include <dhcpsrv/parsers/dhcp_parsers.h>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
@@ -29,13 +30,14 @@ namespace dhcp {
|
||||
|
||||
|
||||
// Factory function to build the parser
|
||||
DbAccessParser::DbAccessParser(const std::string&, DBType db_type)
|
||||
DbAccessParser::DbAccessParser(DBType db_type)
|
||||
: values_(), type_(db_type) {
|
||||
}
|
||||
|
||||
// Parse the configuration and check that the various keywords are consistent.
|
||||
void
|
||||
DbAccessParser::build(isc::data::ConstElementPtr config_value) {
|
||||
DbAccessParser::parse(CfgDbAccessPtr& cfg_db,
|
||||
ConstElementPtr database_config) {
|
||||
|
||||
// To cope with incremental updates, the strategy is:
|
||||
// 1. Take a copy of the stored keyword/value pairs.
|
||||
@@ -45,13 +47,16 @@ DbAccessParser::build(isc::data::ConstElementPtr config_value) {
|
||||
// 5. Save resulting database access string in the Configuration
|
||||
// Manager.
|
||||
|
||||
// Note only range checks can fail with a database_config from
|
||||
// a flex/bison parser.
|
||||
|
||||
// 1. Take a copy of the stored keyword/value pairs.
|
||||
std::map<string, string> values_copy = values_;
|
||||
|
||||
int64_t lfc_interval = 0;
|
||||
int64_t timeout = 0;
|
||||
// 2. Update the copy with the passed keywords.
|
||||
BOOST_FOREACH(ConfigPair param, config_value->mapValue()) {
|
||||
BOOST_FOREACH(ConfigPair param, database_config->mapValue()) {
|
||||
try {
|
||||
if ((param.first == "persist") || (param.first == "readonly")) {
|
||||
values_copy[param.first] = (param.second->boolValue() ?
|
||||
@@ -72,7 +77,7 @@ DbAccessParser::build(isc::data::ConstElementPtr config_value) {
|
||||
}
|
||||
} catch (const isc::data::TypeError& ex) {
|
||||
// Append position of the element.
|
||||
isc_throw(BadValue, "invalid value type specified for "
|
||||
isc_throw(DhcpConfigError, "invalid value type specified for "
|
||||
"parameter '" << param.first << "' ("
|
||||
<< param.second->getPosition() << ")");
|
||||
}
|
||||
@@ -83,33 +88,44 @@ DbAccessParser::build(isc::data::ConstElementPtr config_value) {
|
||||
// a. Check if the "type" keyword exists and thrown an exception if not.
|
||||
StringPairMap::const_iterator type_ptr = values_copy.find("type");
|
||||
if (type_ptr == values_copy.end()) {
|
||||
isc_throw(TypeKeywordMissing, (type_ == LEASE_DB ? "lease" : "host")
|
||||
isc_throw(DhcpConfigError, (type_ == LEASE_DB ? "lease" : "host")
|
||||
<< " database access parameters must "
|
||||
"include the keyword 'type' to determine type of database "
|
||||
"to be accessed (" << config_value->getPosition() << ")");
|
||||
"to be accessed (" << database_config->getPosition() << ")");
|
||||
}
|
||||
|
||||
// b. Check if the 'type' keyword known and throw an exception if not.
|
||||
//
|
||||
// Please note when you add a new database backend you have to add
|
||||
// the new type here and in server grammars.
|
||||
string dbtype = type_ptr->second;
|
||||
if ((dbtype != "memfile") && (dbtype != "mysql") && (dbtype != "postgresql") && (dbtype != "cql")) {
|
||||
isc_throw(BadValue, "unknown backend database type: " << dbtype
|
||||
<< " (" << config_value->getPosition() << ")");
|
||||
if ((dbtype != "memfile") &&
|
||||
(dbtype != "mysql") &&
|
||||
(dbtype != "postgresql") &&
|
||||
(dbtype != "cql")) {
|
||||
ConstElementPtr value = database_config->get("type");
|
||||
isc_throw(DhcpConfigError, "unknown backend database type: " << dbtype
|
||||
<< " (" << value->getPosition() << ")");
|
||||
}
|
||||
|
||||
// c. Check that the lfc-interval is a number and it is within a resonable
|
||||
// range.
|
||||
if ((lfc_interval < 0) || (lfc_interval > std::numeric_limits<uint32_t>::max())) {
|
||||
isc_throw(BadValue, "lfc-interval value: " << lfc_interval
|
||||
// c. Check that the lfc-interval is within a reasonable range.
|
||||
if ((lfc_interval < 0) ||
|
||||
(lfc_interval > std::numeric_limits<uint32_t>::max())) {
|
||||
ConstElementPtr value = database_config->get("lfc-interval");
|
||||
isc_throw(DhcpConfigError, "lfc-interval value: " << lfc_interval
|
||||
<< " is out of range, expected value: 0.."
|
||||
<< std::numeric_limits<uint32_t>::max());
|
||||
<< std::numeric_limits<uint32_t>::max()
|
||||
<< " (" << value->getPosition() << ")");
|
||||
}
|
||||
|
||||
// d. Check that the timeout is a number and it is within a resonable
|
||||
// range.
|
||||
if ((timeout < 0) || (timeout > std::numeric_limits<uint32_t>::max())) {
|
||||
isc_throw(BadValue, "timeout value: " << timeout
|
||||
// d. Check that the timeout is within a reasonable range.
|
||||
if ((timeout < 0) ||
|
||||
(timeout > std::numeric_limits<uint32_t>::max())) {
|
||||
ConstElementPtr value = database_config->get("connect-timeout");
|
||||
isc_throw(DhcpConfigError, "connect-timeout value: " << timeout
|
||||
<< " is out of range, expected value: 0.."
|
||||
<< std::numeric_limits<uint32_t>::max());
|
||||
<< std::numeric_limits<uint32_t>::max()
|
||||
<< " (" << value->getPosition() << ")");
|
||||
}
|
||||
|
||||
// 4. If all is OK, update the stored keyword/value pairs. We do this by
|
||||
@@ -119,7 +135,6 @@ DbAccessParser::build(isc::data::ConstElementPtr config_value) {
|
||||
values_.swap(values_copy);
|
||||
|
||||
// 5. Save the database access string in the Configuration Manager.
|
||||
CfgDbAccessPtr cfg_db = CfgMgr::instance().getStagingCfg()->getCfgDbAccess();
|
||||
if (type_ == LEASE_DB) {
|
||||
cfg_db->setLeaseDbAccessString(getDbAccessString());
|
||||
|
||||
@@ -152,11 +167,5 @@ DbAccessParser::getDbAccessString() const {
|
||||
return (dbaccess);
|
||||
}
|
||||
|
||||
// Commit the changes - reopen the database with the new parameters
|
||||
void
|
||||
DbAccessParser::commit() {
|
||||
}
|
||||
|
||||
}; // namespace dhcp
|
||||
}; // namespace isc
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2012-2017 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
|
||||
@@ -8,8 +8,8 @@
|
||||
#define DBACCESS_PARSER_H
|
||||
|
||||
#include <cc/data.h>
|
||||
#include <dhcpsrv/parsers/dhcp_config_parser.h>
|
||||
#include <dhcpsrv/parsers/dhcp_parsers.h>
|
||||
#include <cc/simple_parser.h>
|
||||
#include <dhcpsrv/cfg_db_access.h>
|
||||
#include <exceptions/exceptions.h>
|
||||
|
||||
#include <string>
|
||||
@@ -17,16 +17,6 @@
|
||||
namespace isc {
|
||||
namespace dhcp {
|
||||
|
||||
/// @brief Exception thrown when 'type' keyword is missing from string
|
||||
///
|
||||
/// This condition is checked, but should never occur because 'type' is marked
|
||||
/// as mandatory in the .spec file for the server.
|
||||
class TypeKeywordMissing : public isc::Exception {
|
||||
public:
|
||||
TypeKeywordMissing(const char* file, size_t line, const char* what) :
|
||||
isc::Exception(file, line, what) {}
|
||||
};
|
||||
|
||||
/// @brief Parse Lease Database Parameters
|
||||
///
|
||||
/// This class is the parser for the lease database configuration. This is a
|
||||
@@ -35,7 +25,7 @@ public:
|
||||
///
|
||||
/// Only the "type" sub-element is mandatory: the remaining sub-elements
|
||||
/// depend on the database chosen.
|
||||
class DbAccessParser: public DhcpConfigParser {
|
||||
class DbAccessParser: public isc::data::SimpleParser {
|
||||
public:
|
||||
|
||||
/// @brief Specifies the database type
|
||||
@@ -52,58 +42,36 @@ public:
|
||||
|
||||
/// @brief Constructor
|
||||
///
|
||||
/// @param param_name Name of the parameter under which the database
|
||||
/// access details are held.
|
||||
/// @param db_type Specifies database type (lease or hosts)
|
||||
DbAccessParser(const std::string& param_name, DBType db_type);
|
||||
DbAccessParser(DBType db_type);
|
||||
|
||||
/// The destructor.
|
||||
virtual ~DbAccessParser()
|
||||
{}
|
||||
|
||||
/// @brief Prepare configuration value.
|
||||
/// @brief Parse configuration value.
|
||||
///
|
||||
/// Parses the set of strings forming the database access specification and
|
||||
/// checks that all are OK. In particular it checks:
|
||||
///
|
||||
/// - "type" is "memfile", "mysql" or "postgresql"
|
||||
/// - "lfc-interval" is a number from the range of 0 to 4294967295.
|
||||
/// - "timeout" is a number from the range of 0 to 4294967295.
|
||||
/// - "connect-timeout" is a number from the range of 0 to 4294967295.
|
||||
///
|
||||
/// Once all has been validated, constructs the database access string
|
||||
/// expected by the lease manager.
|
||||
///
|
||||
/// @param config_value The configuration value for the "lease-database"
|
||||
/// @param cfg_db The configuration where the access string will be set
|
||||
/// @param database_config The configuration value for the "*-database"
|
||||
/// identifier.
|
||||
///
|
||||
/// @throw isc::BadValue The 'type' keyword contains an unknown database
|
||||
/// type.
|
||||
/// @throw isc::dhcp::MissingTypeKeyword The 'type' keyword is missing from
|
||||
/// the list of database access keywords.
|
||||
virtual void build(isc::data::ConstElementPtr config_value);
|
||||
void parse(isc::dhcp::CfgDbAccessPtr& cfg_db,
|
||||
isc::data::ConstElementPtr database_config);
|
||||
|
||||
/// @brief This method is no-op.
|
||||
virtual void commit();
|
||||
|
||||
/// @brief Factory method to create parser
|
||||
///
|
||||
/// Creates an instance of this parser.
|
||||
///
|
||||
/// @param param_name Name of the parameter used to access the
|
||||
/// configuration.
|
||||
///
|
||||
/// @return Pointer to a DbAccessParser. The caller is responsible for
|
||||
/// destroying the parser after use.
|
||||
static DhcpConfigParser* factory(const std::string& param_name) {
|
||||
if (param_name == "lease-database") {
|
||||
return (new DbAccessParser(param_name, DbAccessParser::LEASE_DB));
|
||||
} else if (param_name == "hosts-database") {
|
||||
return (new DbAccessParser(param_name, DbAccessParser::HOSTS_DB));
|
||||
} else {
|
||||
isc_throw(BadValue, "Unexpected parameter name (" << param_name
|
||||
<< ") passed to DbAccessParser::factory");
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
/// @brief Get database access parameters
|
||||
@@ -118,6 +86,7 @@ protected:
|
||||
return (values_);
|
||||
}
|
||||
|
||||
|
||||
/// @brief Construct database access string
|
||||
///
|
||||
/// Constructs the database access string from the stored parameters.
|
||||
@@ -125,6 +94,7 @@ protected:
|
||||
/// @return Database access string
|
||||
std::string getDbAccessString() const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
std::map<std::string, std::string> values_; ///< Stored parameter values
|
||||
|
@@ -31,6 +31,8 @@ namespace isc {
|
||||
namespace dhcp {
|
||||
|
||||
// Default connection timeout
|
||||
|
||||
/// @todo: migrate this default timeout to src/bin/dhcpX/simple_parserX.cc
|
||||
const int PGSQL_DEFAULT_CONNECTION_TIMEOUT = 5; // seconds
|
||||
|
||||
const char PgSqlConnection::DUPLICATE_KEY[] = ERRCODE_UNIQUE_VIOLATION;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2012-2017 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
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <cc/command_interpreter.h>
|
||||
#include <dhcpsrv/lease_mgr_factory.h>
|
||||
#include <dhcpsrv/parsers/dhcp_config_parser.h>
|
||||
#include <dhcpsrv/parsers/dbaccess_parser.h>
|
||||
#include <dhcpsrv/testutils/mysql_schema.h>
|
||||
#include <dhcpsrv/host_mgr.h>
|
||||
@@ -43,7 +44,7 @@ public:
|
||||
/// (the last in particular).
|
||||
///
|
||||
/// As some of the tests have the side-effect of altering the logging
|
||||
/// settings (when the parser's "build" method is called), ensure that
|
||||
/// settings (when the parser's "parse" method is called), ensure that
|
||||
/// the logging is reset to the default after each test completes.
|
||||
~DbAccessParserTest() {
|
||||
LeaseMgrFactory::destroy();
|
||||
@@ -194,14 +195,20 @@ public:
|
||||
/// @brief Constructor
|
||||
///
|
||||
/// @brief Keyword/value collection of database access parameters
|
||||
TestDbAccessParser(const std::string& param_name, DbAccessParser::DBType type)
|
||||
: DbAccessParser(param_name, type)
|
||||
TestDbAccessParser(DbAccessParser::DBType type)
|
||||
: DbAccessParser(type)
|
||||
{}
|
||||
|
||||
/// @brief Destructor
|
||||
virtual ~TestDbAccessParser()
|
||||
{}
|
||||
|
||||
/// @brief Parse configuration value
|
||||
void parse(ConstElementPtr database_config) {
|
||||
CfgDbAccessPtr cfg_db(new CfgDbAccess());
|
||||
DbAccessParser::parse(cfg_db, database_config);
|
||||
}
|
||||
|
||||
/// Allow use of superclass's protected functions.
|
||||
using DbAccessParser::getDbAccessParameters;
|
||||
using DbAccessParser::getDbAccessString;
|
||||
@@ -236,8 +243,8 @@ TEST_F(DbAccessParserTest, validTypeMemfile) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.parse(json_elements));
|
||||
checkAccessString("Valid memfile", parser.getDbAccessParameters(), config);
|
||||
}
|
||||
|
||||
@@ -252,8 +259,8 @@ TEST_F(DbAccessParserTest, emptyKeyword) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.parse(json_elements));
|
||||
checkAccessString("Valid memfile", parser.getDbAccessParameters(), config);
|
||||
}
|
||||
|
||||
@@ -269,8 +276,8 @@ TEST_F(DbAccessParserTest, persistV4Memfile) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.parse(json_elements));
|
||||
|
||||
checkAccessString("Valid memfile", parser.getDbAccessParameters(),
|
||||
config);
|
||||
@@ -288,8 +295,8 @@ TEST_F(DbAccessParserTest, persistV6Memfile) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.parse(json_elements));
|
||||
|
||||
checkAccessString("Valid memfile", parser.getDbAccessParameters(),
|
||||
config);
|
||||
@@ -307,8 +314,8 @@ TEST_F(DbAccessParserTest, validLFCInterval) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.parse(json_elements));
|
||||
checkAccessString("Valid LFC Interval", parser.getDbAccessParameters(),
|
||||
config);
|
||||
}
|
||||
@@ -325,8 +332,8 @@ TEST_F(DbAccessParserTest, negativeLFCInterval) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_THROW(parser.build(json_elements), BadValue);
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_THROW(parser.parse(json_elements), DhcpConfigError);
|
||||
}
|
||||
|
||||
// This test checks that the parser rejects the too large (greater than
|
||||
@@ -341,8 +348,8 @@ TEST_F(DbAccessParserTest, largeLFCInterval) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_THROW(parser.build(json_elements), BadValue);
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_THROW(parser.parse(json_elements), DhcpConfigError);
|
||||
}
|
||||
|
||||
// This test checks that the parser accepts the valid value of the
|
||||
@@ -357,8 +364,8 @@ TEST_F(DbAccessParserTest, validTimeout) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.parse(json_elements));
|
||||
checkAccessString("Valid timeout", parser.getDbAccessParameters(),
|
||||
config);
|
||||
}
|
||||
@@ -375,8 +382,8 @@ TEST_F(DbAccessParserTest, negativeTimeout) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_THROW(parser.build(json_elements), BadValue);
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_THROW(parser.parse(json_elements), DhcpConfigError);
|
||||
}
|
||||
|
||||
// This test checks that the parser rejects a too large (greater than
|
||||
@@ -391,8 +398,8 @@ TEST_F(DbAccessParserTest, largeTimeout) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_THROW(parser.build(json_elements), BadValue);
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_THROW(parser.parse(json_elements), DhcpConfigError);
|
||||
}
|
||||
|
||||
// Check that the parser works with a valid MySQL configuration
|
||||
@@ -408,8 +415,8 @@ TEST_F(DbAccessParserTest, validTypeMysql) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.parse(json_elements));
|
||||
checkAccessString("Valid mysql", parser.getDbAccessParameters(), config);
|
||||
}
|
||||
|
||||
@@ -425,20 +432,8 @@ TEST_F(DbAccessParserTest, missingTypeKeyword) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_THROW(parser.build(json_elements), TypeKeywordMissing);
|
||||
}
|
||||
|
||||
// Check that the factory function works.
|
||||
TEST_F(DbAccessParserTest, factory) {
|
||||
|
||||
// Check that the parser is built through the factory.
|
||||
boost::scoped_ptr<DhcpConfigParser> parser(
|
||||
DbAccessParser::factory("lease-database")
|
||||
);
|
||||
EXPECT_TRUE(parser);
|
||||
DbAccessParser* dbap = dynamic_cast<DbAccessParser*>(parser.get());
|
||||
EXPECT_NE(static_cast<DbAccessParser*>(NULL), dbap);
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_THROW(parser.parse(json_elements), DhcpConfigError);
|
||||
}
|
||||
|
||||
// Check reconfiguration. Checks that incremental changes applied to the
|
||||
@@ -485,7 +480,7 @@ TEST_F(DbAccessParserTest, incrementalChanges) {
|
||||
"name", "keatest",
|
||||
NULL};
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
|
||||
// First configuration string should cause a representation of that string
|
||||
// to be held.
|
||||
@@ -493,7 +488,7 @@ TEST_F(DbAccessParserTest, incrementalChanges) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
EXPECT_NO_THROW(parser.parse(json_elements));
|
||||
checkAccessString("Initial configuration", parser.getDbAccessParameters(),
|
||||
config1);
|
||||
|
||||
@@ -503,7 +498,7 @@ TEST_F(DbAccessParserTest, incrementalChanges) {
|
||||
json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
EXPECT_NO_THROW(parser.parse(json_elements));
|
||||
checkAccessString("Subsequent configuration", parser.getDbAccessParameters(),
|
||||
config2);
|
||||
|
||||
@@ -513,7 +508,7 @@ TEST_F(DbAccessParserTest, incrementalChanges) {
|
||||
json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
EXPECT_NO_THROW(parser.parse(json_elements));
|
||||
checkAccessString("Incremental configuration", parser.getDbAccessParameters(),
|
||||
config3);
|
||||
|
||||
@@ -523,7 +518,7 @@ TEST_F(DbAccessParserTest, incrementalChanges) {
|
||||
json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
EXPECT_THROW(parser.build(json_elements), BadValue);
|
||||
EXPECT_THROW(parser.parse(json_elements), DhcpConfigError);
|
||||
checkAccessString("Incompatible incremental change", parser.getDbAccessParameters(),
|
||||
config3);
|
||||
|
||||
@@ -533,7 +528,7 @@ TEST_F(DbAccessParserTest, incrementalChanges) {
|
||||
json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
EXPECT_NO_THROW(parser.parse(json_elements));
|
||||
checkAccessString("Compatible incremental change", parser.getDbAccessParameters(),
|
||||
config4);
|
||||
}
|
||||
@@ -549,8 +544,8 @@ TEST_F(DbAccessParserTest, getDbAccessString) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.parse(json_elements));
|
||||
|
||||
// Get the database access string
|
||||
std::string dbaccess = parser.getDbAccessString();
|
||||
@@ -575,8 +570,8 @@ TEST_F(DbAccessParserTest, validReadOnly) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.build(json_elements));
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_NO_THROW(parser.parse(json_elements));
|
||||
|
||||
checkAccessString("Valid readonly parameter",
|
||||
parser.getDbAccessParameters(),
|
||||
@@ -597,8 +592,8 @@ TEST_F(DbAccessParserTest, invalidReadOnly) {
|
||||
ConstElementPtr json_elements = Element::fromJSON(json_config);
|
||||
EXPECT_TRUE(json_elements);
|
||||
|
||||
TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB);
|
||||
EXPECT_THROW(parser.build(json_elements), BadValue);
|
||||
TestDbAccessParser parser(DbAccessParser::LEASE_DB);
|
||||
EXPECT_THROW(parser.parse(json_elements), DhcpConfigError);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2012-2017 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
|
||||
@@ -116,7 +116,7 @@ TEST(MySqlOpenTest, OpenDatabase) {
|
||||
// Check that lease manager open the database opens correctly with a longer
|
||||
// timeout. If it fails, print the error message.
|
||||
try {
|
||||
string connection_string = validMySQLConnectionString() + string(" ") +
|
||||
string connection_string = validMySQLConnectionString() + string(" ") +
|
||||
string(VALID_TIMEOUT);
|
||||
LeaseMgrFactory::create(connection_string);
|
||||
EXPECT_NO_THROW((void) LeaseMgrFactory::instance());
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2014-2017 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
|
||||
@@ -108,7 +108,7 @@ TEST(PgSqlOpenTest, OpenDatabase) {
|
||||
// Check that lease manager open the database opens correctly with a longer
|
||||
// timeout. If it fails, print the error message.
|
||||
try {
|
||||
string connection_string = validPgSQLConnectionString() + string(" ") +
|
||||
string connection_string = validPgSQLConnectionString() + string(" ") +
|
||||
string(VALID_TIMEOUT);
|
||||
LeaseMgrFactory::create(connection_string);
|
||||
EXPECT_NO_THROW((void) LeaseMgrFactory::instance());
|
||||
|
Reference in New Issue
Block a user