mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 05:55:28 +00:00
[#1671] the -t parameter now loads and checks hook libraries config
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <database/dbaccess_parser.h>
|
||||
#include <database/backend_selector.h>
|
||||
#include <database/server_selector.h>
|
||||
#include <dhcp4/ctrl_dhcp4_srv.h>
|
||||
#include <dhcp4/dhcp4_log.h>
|
||||
#include <dhcp4/dhcp4_srv.h>
|
||||
#include <dhcp4/json_config_parser.h>
|
||||
@@ -738,7 +739,7 @@ processDhcp4Config(isc::data::ConstElementPtr config_set) {
|
||||
|
||||
isc::data::ConstElementPtr
|
||||
configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
bool check_only) {
|
||||
bool check_only, bool extra_checks) {
|
||||
if (!config_set) {
|
||||
ConstElementPtr answer = isc::config::createAnswer(CONTROL_RESULT_ERROR,
|
||||
"Can't parse NULL config");
|
||||
@@ -748,21 +749,14 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_COMMAND, DHCP4_CONFIG_START)
|
||||
.arg(server.redactConfig(config_set)->str());
|
||||
|
||||
// Rollback informs whether error occurred and original data
|
||||
// have to be restored to global storages.
|
||||
bool rollback = false;
|
||||
|
||||
auto answer = processDhcp4Config(config_set);
|
||||
|
||||
int status_code = 0;
|
||||
int status_code = CONTROL_RESULT_SUCCESS;
|
||||
isc::config::parseAnswer(status_code, answer);
|
||||
if (status_code != CONTROL_RESULT_SUCCESS) {
|
||||
rollback = true;
|
||||
}
|
||||
|
||||
SrvConfigPtr srv_config;
|
||||
|
||||
if (!rollback) {
|
||||
if (status_code == CONTROL_RESULT_SUCCESS) {
|
||||
if (!check_only) {
|
||||
string parameter_name;
|
||||
ElementPtr mutable_cfg;
|
||||
@@ -803,20 +797,33 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_FAIL)
|
||||
.arg(parameter_name).arg(ex.what());
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, ex.what());
|
||||
|
||||
// An error occurred, so make sure that we restore original data.
|
||||
rollback = true;
|
||||
status_code = CONTROL_RESULT_ERROR;
|
||||
} catch (...) {
|
||||
// For things like bad_cast in boost::lexical_cast
|
||||
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_EXCEPTION).arg(parameter_name);
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, "undefined configuration"
|
||||
" processing error");
|
||||
|
||||
// An error occurred, so make sure that we restore original data.
|
||||
rollback = true;
|
||||
status_code = CONTROL_RESULT_ERROR;
|
||||
}
|
||||
} else {
|
||||
rollback = true;
|
||||
if (extra_checks) {
|
||||
// Re-open lease and host database with new parameters.
|
||||
try {
|
||||
// Get the staging configuration.
|
||||
srv_config = CfgMgr::instance().getStagingCfg();
|
||||
|
||||
CfgDbAccessPtr cfg_db = CfgMgr::instance().getStagingCfg()->getCfgDbAccess();
|
||||
string params = "universe=4 persist=false";
|
||||
if (cfg_db->getExtendedInfoTablesEnabled()) {
|
||||
params += " extended-info-tables=true";
|
||||
}
|
||||
cfg_db->setAppendedParameters(params);
|
||||
cfg_db->createManagers();
|
||||
} catch (const std::exception& ex) {
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, ex.what());
|
||||
status_code = CONTROL_RESULT_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -824,12 +831,26 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
// configuration. This will add created subnets and option values into
|
||||
// the server's configuration.
|
||||
// This operation should be exception safe but let's make sure.
|
||||
if (!rollback) {
|
||||
if (status_code == CONTROL_RESULT_SUCCESS && !check_only) {
|
||||
try {
|
||||
|
||||
// Setup the command channel.
|
||||
configureCommandChannel();
|
||||
} catch (const isc::Exception& ex) {
|
||||
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_FAIL).arg(ex.what());
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, ex.what());
|
||||
status_code = CONTROL_RESULT_ERROR;
|
||||
} catch (...) {
|
||||
// For things like bad_cast in boost::lexical_cast
|
||||
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_EXCEPTION);
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, "undefined configuration"
|
||||
" parsing error");
|
||||
status_code = CONTROL_RESULT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) {
|
||||
try {
|
||||
// No need to commit interface names as this is handled by the
|
||||
// CfgMgr::commit() function.
|
||||
|
||||
@@ -837,7 +858,21 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
D2ClientConfigPtr cfg;
|
||||
cfg = CfgMgr::instance().getStagingCfg()->getD2ClientConfig();
|
||||
CfgMgr::instance().setD2ClientConfig(cfg);
|
||||
} catch (const isc::Exception& ex) {
|
||||
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_FAIL).arg(ex.what());
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, ex.what());
|
||||
status_code = CONTROL_RESULT_ERROR;
|
||||
} catch (...) {
|
||||
// For things like bad_cast in boost::lexical_cast
|
||||
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_EXCEPTION);
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, "undefined configuration"
|
||||
" parsing error");
|
||||
status_code = CONTROL_RESULT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) {
|
||||
try {
|
||||
// This occurs last as if it succeeds, there is no easy way to
|
||||
// revert it. As a result, the failure to commit a subsequent
|
||||
// change causes problems when trying to roll back.
|
||||
@@ -849,35 +884,32 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
} catch (const isc::Exception& ex) {
|
||||
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_FAIL).arg(ex.what());
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, ex.what());
|
||||
|
||||
// An error occurred, so make sure to restore the original data.
|
||||
rollback = true;
|
||||
status_code = CONTROL_RESULT_ERROR;
|
||||
} catch (...) {
|
||||
// For things like bad_cast in boost::lexical_cast
|
||||
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_EXCEPTION);
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, "undefined configuration"
|
||||
" parsing error");
|
||||
|
||||
// An error occurred, so make sure to restore the original data.
|
||||
rollback = true;
|
||||
status_code = CONTROL_RESULT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// Moved from the commit block to add the config backend indication.
|
||||
if (!rollback) {
|
||||
if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) {
|
||||
try {
|
||||
|
||||
// If there are config backends, fetch and merge into staging config
|
||||
server.getCBControl()->databaseConfigFetch(srv_config,
|
||||
CBControlDHCPv4::FetchMode::FETCH_ALL);
|
||||
if (extra_checks) {
|
||||
server.getCBControl()->databaseConfigConnect(srv_config);
|
||||
} else {
|
||||
// If there are config backends, fetch and merge into staging config
|
||||
server.getCBControl()->databaseConfigFetch(srv_config,
|
||||
CBControlDHCPv4::FetchMode::FETCH_ALL);
|
||||
}
|
||||
} catch (const isc::Exception& ex) {
|
||||
std::ostringstream err;
|
||||
err << "during update from config backend database: " << ex.what();
|
||||
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_FAIL).arg(err.str());
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str());
|
||||
|
||||
// An error occurred, so make sure to restore the original data.
|
||||
rollback = true;
|
||||
status_code = CONTROL_RESULT_ERROR;
|
||||
} catch (...) {
|
||||
// For things like bad_cast in boost::lexical_cast
|
||||
std::ostringstream err;
|
||||
@@ -885,17 +917,23 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
<< "undefined configuration parsing error";
|
||||
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_FAIL).arg(err.str());
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str());
|
||||
|
||||
// An error occurred, so make sure to restore the original data.
|
||||
rollback = true;
|
||||
status_code = CONTROL_RESULT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// Rollback changes as the configuration parsing failed.
|
||||
if (rollback) {
|
||||
if (check_only || status_code != CONTROL_RESULT_SUCCESS) {
|
||||
// Revert to original configuration of runtime option definitions
|
||||
// in the libdhcp++.
|
||||
LibDHCP::revertRuntimeOptionDefs();
|
||||
|
||||
if (status_code == CONTROL_RESULT_SUCCESS && extra_checks) {
|
||||
auto notify_libraries = ControlledDhcpv4Srv::finishConfigHookLibraries(config_set);
|
||||
if (notify_libraries) {
|
||||
return (notify_libraries);
|
||||
}
|
||||
}
|
||||
|
||||
return (answer);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user