mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-28 12:37:55 +00:00
[#2722] config set follows the same path as config test and can rollback
This commit is contained in:
parent
66df0bd1d7
commit
db352cc04c
@ -98,7 +98,8 @@ CtrlAgentProcess::runIO() {
|
||||
isc::data::ConstElementPtr
|
||||
CtrlAgentProcess::shutdown(isc::data::ConstElementPtr /*args*/) {
|
||||
setShutdownFlag(true);
|
||||
return (isc::config::createAnswer(0, "Control Agent is shutting down"));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_SUCCESS,
|
||||
"Control Agent is shutting down"));
|
||||
}
|
||||
|
||||
isc::data::ConstElementPtr
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <hooks/hooks.h>
|
||||
#include <hooks/hooks_manager.h>
|
||||
|
||||
using namespace isc::config;
|
||||
using namespace isc::hooks;
|
||||
using namespace isc::process;
|
||||
|
||||
@ -221,16 +222,18 @@ D2Process::shutdown(isc::data::ConstElementPtr args) {
|
||||
shutdown_type_ = SD_NOW;
|
||||
} else {
|
||||
setShutdownFlag(false);
|
||||
return (isc::config::createAnswer(1, "Invalid Shutdown type: "
|
||||
+ type_str));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR,
|
||||
"Invalid Shutdown type: " +
|
||||
type_str));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the base class's shutdown flag.
|
||||
setShutdownFlag(true);
|
||||
return (isc::config::createAnswer(0, "Shutdown initiated, type is: "
|
||||
+ type_str));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_SUCCESS,
|
||||
"Shutdown initiated, type is: " +\
|
||||
type_str));
|
||||
}
|
||||
|
||||
isc::data::ConstElementPtr
|
||||
@ -295,7 +298,7 @@ D2Process::configure(isc::data::ConstElementPtr config_set, bool check_only) {
|
||||
LOG_ERROR(d2_logger, DHCP_DDNS_CONFIGURED_CALLOUT_DROP)
|
||||
.arg(error);
|
||||
reconf_queue_flag_ = false;
|
||||
answer = isc::config::createAnswer(1, error);
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, error);
|
||||
return (answer);
|
||||
}
|
||||
}
|
||||
|
@ -370,7 +370,7 @@ public:
|
||||
// both structures are built using the same order.
|
||||
EXPECT_EQ(Element::fromJSON(expected_command)->str(),
|
||||
entire_command->str());
|
||||
return (createAnswer(0, "long command received ok"));
|
||||
return (createAnswer(CONTROL_RESULT_SUCCESS, "long command received ok"));
|
||||
}
|
||||
|
||||
/// @brief Command handler which generates long response.
|
||||
@ -386,7 +386,7 @@ public:
|
||||
s << std::setw(5) << i;
|
||||
arguments->add(Element::create(s.str()));
|
||||
}
|
||||
return (createAnswer(0, arguments));
|
||||
return (createAnswer(CONTROL_RESULT_SUCCESS, arguments));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -246,12 +246,12 @@ ControlledDhcpv4Srv::commandLibReloadHandler(const string&, ConstElementPtr) {
|
||||
}
|
||||
} catch (const std::exception& ex) {
|
||||
LOG_ERROR(dhcp4_logger, DHCP4_HOOKS_LIBS_RELOAD_FAIL);
|
||||
ConstElementPtr answer = isc::config::createAnswer(1, ex.what());
|
||||
ConstElementPtr answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, ex.what());
|
||||
return (answer);
|
||||
}
|
||||
ConstElementPtr answer = isc::config::createAnswer(0,
|
||||
"Hooks libraries successfully reloaded"
|
||||
" (WARNING: libreload is deprecated).");
|
||||
ConstElementPtr answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS,
|
||||
"Hooks libraries successfully reloaded "
|
||||
"(WARNING: libreload is deprecated).");
|
||||
return (answer);
|
||||
}
|
||||
|
||||
@ -281,7 +281,7 @@ ControlledDhcpv4Srv::commandConfigGetHandler(const string&,
|
||||
ConstElementPtr /*args*/) {
|
||||
ConstElementPtr config = CfgMgr::instance().getCurrentCfg()->toElement();
|
||||
|
||||
return (createAnswer(0, config));
|
||||
return (createAnswer(CONTROL_RESULT_SUCCESS, config));
|
||||
}
|
||||
|
||||
ConstElementPtr
|
||||
@ -391,25 +391,6 @@ ControlledDhcpv4Srv::commandConfigSetHandler(const string&,
|
||||
// configuration attempts.
|
||||
CfgMgr::instance().rollback();
|
||||
|
||||
// Let's first check the config
|
||||
ConstElementPtr result = checkConfig(dhcp4);
|
||||
|
||||
int rcode = 0;
|
||||
isc::config::parseAnswer(rcode, result);
|
||||
if (rcode != CONTROL_RESULT_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
// disable multi-threading (it will be applied by new configuration)
|
||||
// this must be done in order to properly handle MT to ST transition
|
||||
// when 'multi-threading' structure is missing from new config
|
||||
MultiThreadingMgr::instance().apply(false, 0, 0);
|
||||
|
||||
// We are starting the configuration process so we should remove any
|
||||
// staging configuration that has been created during previous
|
||||
// configuration attempts.
|
||||
CfgMgr::instance().rollback();
|
||||
|
||||
// Parse the logger configuration explicitly into the staging config.
|
||||
// Note this does not alter the current loggers, they remain in
|
||||
// effect until we apply the logging config below. If no logging
|
||||
@ -421,11 +402,12 @@ ControlledDhcpv4Srv::commandConfigSetHandler(const string&,
|
||||
CfgMgr::instance().getStagingCfg()->applyLoggingCfg();
|
||||
|
||||
// Now we configure the server proper.
|
||||
result = processConfig(dhcp4);
|
||||
ConstElementPtr result = processConfig(dhcp4);
|
||||
|
||||
// If the configuration parsed successfully, apply the new logger
|
||||
// configuration and the commit the new configuration. We apply
|
||||
// the logging first in case there's a configuration failure.
|
||||
int rcode = 0;
|
||||
isc::config::parseAnswer(rcode, result);
|
||||
if (rcode == CONTROL_RESULT_SUCCESS) {
|
||||
CfgMgr::instance().getStagingCfg()->applyLoggingCfg();
|
||||
@ -645,7 +627,7 @@ ControlledDhcpv4Srv::commandVersionGetHandler(const string&, ConstElementPtr) {
|
||||
ElementPtr extended = Element::create(Dhcpv4Srv::getVersion(true));
|
||||
ElementPtr arguments = Element::createMap();
|
||||
arguments->set("extended", extended);
|
||||
ConstElementPtr answer = isc::config::createAnswer(0,
|
||||
ConstElementPtr answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS,
|
||||
Dhcpv4Srv::getVersion(false),
|
||||
arguments);
|
||||
return (answer);
|
||||
@ -655,7 +637,7 @@ ConstElementPtr
|
||||
ControlledDhcpv4Srv::commandBuildReportHandler(const string&,
|
||||
ConstElementPtr) {
|
||||
ConstElementPtr answer =
|
||||
isc::config::createAnswer(0, isc::detail::getConfigReport());
|
||||
isc::config::createAnswer(CONTROL_RESULT_SUCCESS, isc::detail::getConfigReport());
|
||||
return (answer);
|
||||
}
|
||||
|
||||
@ -791,7 +773,7 @@ ControlledDhcpv4Srv::commandStatusGetHandler(const string&,
|
||||
}
|
||||
status->set("sockets", sockets);
|
||||
|
||||
return (createAnswer(0, status));
|
||||
return (createAnswer(CONTROL_RESULT_SUCCESS, status));
|
||||
}
|
||||
|
||||
ConstElementPtr
|
||||
@ -830,7 +812,7 @@ ControlledDhcpv4Srv::processCommand(const string& command,
|
||||
ControlledDhcpv4Srv* srv = ControlledDhcpv4Srv::getInstance();
|
||||
|
||||
if (!srv) {
|
||||
ConstElementPtr no_srv = isc::config::createAnswer(1,
|
||||
ConstElementPtr no_srv = isc::config::createAnswer(CONTROL_RESULT_ERROR,
|
||||
"Server object not initialized, so can't process command '" +
|
||||
command + "', arguments: '" + txt + "'.");
|
||||
return (no_srv);
|
||||
@ -883,11 +865,11 @@ ControlledDhcpv4Srv::processCommand(const string& command,
|
||||
return (srv->commandStatusGetHandler(command, args));
|
||||
}
|
||||
|
||||
return (isc::config::createAnswer(1, "Unrecognized command:"
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, "Unrecognized command:"
|
||||
+ command));
|
||||
|
||||
} catch (const isc::Exception& ex) {
|
||||
return (isc::config::createAnswer(1, "Error while processing command '"
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, "Error while processing command '"
|
||||
+ command + "': " + ex.what() +
|
||||
", params: '" + txt + "'"));
|
||||
}
|
||||
@ -902,7 +884,7 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
|
||||
if (!srv) {
|
||||
err << "Server object not initialized, can't process config.";
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_COMMAND, DHCP4_CONFIG_RECEIVED)
|
||||
@ -920,7 +902,7 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
}
|
||||
} catch (const std::exception& ex) {
|
||||
err << "Failed to process configuration:" << ex.what();
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
// Re-open lease and host database with new parameters.
|
||||
@ -945,7 +927,7 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
srv->getNetworkState()->reset(NetworkState::Origin::DB_CONNECTION);
|
||||
} catch (const std::exception& ex) {
|
||||
err << "Unable to open database: " << ex.what();
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
// Server will start DDNS communications if its enabled.
|
||||
@ -954,7 +936,7 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
} catch (const std::exception& ex) {
|
||||
err << "Error starting DHCP_DDNS client after server reconfiguration: "
|
||||
<< ex.what();
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
// Setup DHCPv4-over-DHCPv6 IPC
|
||||
@ -963,7 +945,7 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
} catch (const std::exception& ex) {
|
||||
err << "error starting DHCPv4-over-DHCPv6 IPC "
|
||||
" after server reconfiguration: " << ex.what();
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
// Configure DHCP packet queueing
|
||||
@ -978,7 +960,7 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
} catch (const std::exception& ex) {
|
||||
err << "Error setting packet queue controls after server reconfiguration: "
|
||||
<< ex.what();
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
// Configure a callback to shut down the server when the bind socket
|
||||
@ -1008,7 +990,7 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
err << "unable to setup timers for periodically running the"
|
||||
" reclamation of the expired leases: "
|
||||
<< ex.what() << ".";
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
// Setup config backend polling, if configured for it.
|
||||
@ -1094,12 +1076,10 @@ ControlledDhcpv4Srv::checkConfig(isc::data::ConstElementPtr config) {
|
||||
|
||||
ControlledDhcpv4Srv* srv = ControlledDhcpv4Srv::getInstance();
|
||||
|
||||
// Single stream instance used in all error clauses
|
||||
std::ostringstream err;
|
||||
|
||||
if (!srv) {
|
||||
err << "Server object not initialized, can't process config.";
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
ConstElementPtr no_srv = isc::config::createAnswer(CONTROL_RESULT_ERROR,
|
||||
"Server object not initialized, can't process config.");
|
||||
return (no_srv);
|
||||
}
|
||||
|
||||
return (configureDhcp4Server(*srv, config, true));
|
||||
|
@ -321,29 +321,11 @@ void configureCommandChannel() {
|
||||
}
|
||||
|
||||
isc::data::ConstElementPtr
|
||||
configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
bool check_only) {
|
||||
if (!config_set) {
|
||||
ConstElementPtr answer = isc::config::createAnswer(CONTROL_RESULT_ERROR,
|
||||
string("Can't parse NULL config"));
|
||||
return (answer);
|
||||
}
|
||||
|
||||
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_COMMAND, DHCP4_CONFIG_START)
|
||||
.arg(server.redactConfig(config_set)->str());
|
||||
|
||||
processDhcp4Config(isc::data::ConstElementPtr config_set) {
|
||||
// Before starting any subnet operations, let's reset the subnet-id counter,
|
||||
// so newly recreated configuration starts with first subnet-id equal 1.
|
||||
Subnet::resetSubnetID();
|
||||
|
||||
// Close DHCP sockets and remove any existing timers.
|
||||
if (!check_only) {
|
||||
IfaceMgr::instance().closeSockets();
|
||||
TimerMgr::instance()->unregisterTimers();
|
||||
server.discardPackets();
|
||||
server.getCBControl()->reset();
|
||||
}
|
||||
|
||||
// Revert any runtime option definitions configured so far and not committed.
|
||||
LibDHCP::revertRuntimeOptionDefs();
|
||||
// Let's set empty container in case a user hasn't specified any configuration
|
||||
@ -355,9 +337,7 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
|
||||
// Answer will hold the result.
|
||||
ConstElementPtr answer;
|
||||
// Rollback informs whether error occurred and original data
|
||||
// have to be restored to global storages.
|
||||
bool rollback = false;
|
||||
|
||||
// Global parameter name in case of an error.
|
||||
string parameter_name;
|
||||
ElementPtr mutable_cfg;
|
||||
@ -459,7 +439,7 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
ConstElementPtr ifaces_config = mutable_cfg->get("interfaces-config");
|
||||
if (ifaces_config) {
|
||||
parameter_name = "interfaces-config";
|
||||
IfacesConfigParser parser(AF_INET, check_only);
|
||||
IfacesConfigParser parser(AF_INET, true);
|
||||
CfgIfacePtr cfg_iface = srv_config->getCfgIface();
|
||||
parser.parse(cfg_iface, ifaces_config);
|
||||
}
|
||||
@ -740,25 +720,95 @@ 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;
|
||||
} 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");
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, "undefined configuration "
|
||||
"processing error");
|
||||
}
|
||||
|
||||
// An error occurred, so make sure that we restore original data.
|
||||
if (!answer) {
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS, "Configuration seems sane. "
|
||||
"Control-socket, hook-libraries, and D2 configuration "
|
||||
"were sanity checked, but not applied.");
|
||||
}
|
||||
|
||||
return (answer);
|
||||
}
|
||||
|
||||
isc::data::ConstElementPtr
|
||||
configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
bool check_only) {
|
||||
if (!config_set) {
|
||||
ConstElementPtr answer = isc::config::createAnswer(CONTROL_RESULT_ERROR,
|
||||
"Can't parse NULL config");
|
||||
return (answer);
|
||||
}
|
||||
|
||||
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;
|
||||
isc::config::parseAnswer(status_code, answer);
|
||||
if (status_code != CONTROL_RESULT_SUCCESS) {
|
||||
rollback = true;
|
||||
}
|
||||
|
||||
if (check_only) {
|
||||
rollback = true;
|
||||
if (!answer) {
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS,
|
||||
"Configuration seems sane. Control-socket, hook-libraries, and D2 "
|
||||
"configuration were sanity checked, but not applied.");
|
||||
SrvConfigPtr srv_config;
|
||||
|
||||
if (!rollback) {
|
||||
if (!check_only) {
|
||||
string parameter_name;
|
||||
ElementPtr mutable_cfg;
|
||||
|
||||
// Close DHCP sockets and remove any existing timers.
|
||||
IfaceMgr::instance().closeSockets();
|
||||
TimerMgr::instance()->unregisterTimers();
|
||||
server.discardPackets();
|
||||
server.getCBControl()->reset();
|
||||
|
||||
try {
|
||||
|
||||
// Get the staging configuration.
|
||||
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.
|
||||
mutable_cfg = boost::const_pointer_cast<Element>(config_set);
|
||||
|
||||
ConstElementPtr ifaces_config = mutable_cfg->get("interfaces-config");
|
||||
if (ifaces_config) {
|
||||
parameter_name = "interfaces-config";
|
||||
IfacesConfigParser parser(AF_INET, false);
|
||||
CfgIfacePtr cfg_iface = srv_config->getCfgIface();
|
||||
cfg_iface->reset();
|
||||
parser.parse(cfg_iface, ifaces_config);
|
||||
}
|
||||
} catch (const isc::Exception& ex) {
|
||||
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;
|
||||
} 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;
|
||||
}
|
||||
} else {
|
||||
rollback = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -380,7 +380,7 @@ public:
|
||||
// both structures are built using the same order.
|
||||
EXPECT_EQ(Element::fromJSON(expected_command)->str(),
|
||||
entire_command->str());
|
||||
return (createAnswer(0, "long command received ok"));
|
||||
return (createAnswer(CONTROL_RESULT_SUCCESS, "long command received ok"));
|
||||
}
|
||||
|
||||
/// @brief Command handler which generates long response
|
||||
@ -396,7 +396,7 @@ public:
|
||||
s << std::setw(5) << i;
|
||||
arguments->add(Element::create(s.str()));
|
||||
}
|
||||
return (createAnswer(0, arguments));
|
||||
return (createAnswer(CONTROL_RESULT_SUCCESS, arguments));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -249,10 +249,10 @@ ControlledDhcpv6Srv::commandLibReloadHandler(const string&, ConstElementPtr) {
|
||||
}
|
||||
} catch (const std::exception& ex) {
|
||||
LOG_ERROR(dhcp6_logger, DHCP6_HOOKS_LIBS_RELOAD_FAIL);
|
||||
ConstElementPtr answer = isc::config::createAnswer(1, ex.what());
|
||||
ConstElementPtr answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, ex.what());
|
||||
return (answer);
|
||||
}
|
||||
ConstElementPtr answer = isc::config::createAnswer(0,
|
||||
ConstElementPtr answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS,
|
||||
"Hooks libraries successfully reloaded "
|
||||
"(WARNING: libreload is deprecated).");
|
||||
return (answer);
|
||||
@ -284,7 +284,7 @@ ControlledDhcpv6Srv::commandConfigGetHandler(const string&,
|
||||
ConstElementPtr /*args*/) {
|
||||
ConstElementPtr config = CfgMgr::instance().getCurrentCfg()->toElement();
|
||||
|
||||
return (createAnswer(0, config));
|
||||
return (createAnswer(CONTROL_RESULT_SUCCESS, config));
|
||||
}
|
||||
|
||||
ConstElementPtr
|
||||
@ -394,25 +394,6 @@ ControlledDhcpv6Srv::commandConfigSetHandler(const string&,
|
||||
// configuration attempts.
|
||||
CfgMgr::instance().rollback();
|
||||
|
||||
// Let's first check the config
|
||||
ConstElementPtr result = checkConfig(dhcp6);
|
||||
|
||||
int rcode = 0;
|
||||
isc::config::parseAnswer(rcode, result);
|
||||
if (rcode != CONTROL_RESULT_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
// disable multi-threading (it will be applied by new configuration)
|
||||
// this must be done in order to properly handle MT to ST transition
|
||||
// when 'multi-threading' structure is missing from new config
|
||||
MultiThreadingMgr::instance().apply(false, 0, 0);
|
||||
|
||||
// We are starting the configuration process so we should remove any
|
||||
// staging configuration that has been created during previous
|
||||
// configuration attempts.
|
||||
CfgMgr::instance().rollback();
|
||||
|
||||
// Parse the logger configuration explicitly into the staging config.
|
||||
// Note this does not alter the current loggers, they remain in
|
||||
// effect until we apply the logging config below. If no logging
|
||||
@ -424,11 +405,12 @@ ControlledDhcpv6Srv::commandConfigSetHandler(const string&,
|
||||
CfgMgr::instance().getStagingCfg()->applyLoggingCfg();
|
||||
|
||||
// Now we configure the server proper.
|
||||
result = processConfig(dhcp6);
|
||||
ConstElementPtr result = processConfig(dhcp6);
|
||||
|
||||
// If the configuration parsed successfully, apply the new logger
|
||||
// configuration and the commit the new configuration. We apply
|
||||
// the logging first in case there's a configuration failure.
|
||||
int rcode = 0;
|
||||
isc::config::parseAnswer(rcode, result);
|
||||
if (rcode == CONTROL_RESULT_SUCCESS) {
|
||||
CfgMgr::instance().getStagingCfg()->applyLoggingCfg();
|
||||
@ -648,7 +630,7 @@ ControlledDhcpv6Srv::commandVersionGetHandler(const string&, ConstElementPtr) {
|
||||
ElementPtr extended = Element::create(Dhcpv6Srv::getVersion(true));
|
||||
ElementPtr arguments = Element::createMap();
|
||||
arguments->set("extended", extended);
|
||||
ConstElementPtr answer = isc::config::createAnswer(0,
|
||||
ConstElementPtr answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS,
|
||||
Dhcpv6Srv::getVersion(false),
|
||||
arguments);
|
||||
return (answer);
|
||||
@ -658,7 +640,7 @@ ConstElementPtr
|
||||
ControlledDhcpv6Srv::commandBuildReportHandler(const string&,
|
||||
ConstElementPtr) {
|
||||
ConstElementPtr answer =
|
||||
isc::config::createAnswer(0, isc::detail::getConfigReport());
|
||||
isc::config::createAnswer(CONTROL_RESULT_SUCCESS, isc::detail::getConfigReport());
|
||||
return (answer);
|
||||
}
|
||||
|
||||
@ -794,7 +776,7 @@ ControlledDhcpv6Srv::commandStatusGetHandler(const string&,
|
||||
}
|
||||
status->set("sockets", sockets);
|
||||
|
||||
return (createAnswer(0, status));
|
||||
return (createAnswer(CONTROL_RESULT_SUCCESS, status));
|
||||
}
|
||||
|
||||
ConstElementPtr
|
||||
@ -833,7 +815,7 @@ ControlledDhcpv6Srv::processCommand(const string& command,
|
||||
ControlledDhcpv6Srv* srv = ControlledDhcpv6Srv::getInstance();
|
||||
|
||||
if (!srv) {
|
||||
ConstElementPtr no_srv = isc::config::createAnswer(1,
|
||||
ConstElementPtr no_srv = isc::config::createAnswer(CONTROL_RESULT_ERROR,
|
||||
"Server object not initialized, so can't process command '" +
|
||||
command + "', arguments: '" + txt + "'.");
|
||||
return (no_srv);
|
||||
@ -886,11 +868,11 @@ ControlledDhcpv6Srv::processCommand(const string& command,
|
||||
return (srv->commandStatusGetHandler(command, args));
|
||||
}
|
||||
|
||||
return (isc::config::createAnswer(1, "Unrecognized command:"
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, "Unrecognized command:"
|
||||
+ command));
|
||||
|
||||
} catch (const isc::Exception& ex) {
|
||||
return (isc::config::createAnswer(1, "Error while processing command '"
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, "Error while processing command '"
|
||||
+ command + "': " + ex.what() +
|
||||
", params: '" + txt + "'"));
|
||||
}
|
||||
@ -906,7 +888,7 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
|
||||
if (!srv) {
|
||||
err << "Server object not initialized, can't process config.";
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_COMMAND, DHCP6_CONFIG_RECEIVED)
|
||||
@ -924,7 +906,7 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
}
|
||||
} catch (const std::exception& ex) {
|
||||
err << "Failed to process configuration:" << ex.what();
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
// Re-open lease and host database with new parameters.
|
||||
@ -949,7 +931,7 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
srv->getNetworkState()->reset(NetworkState::Origin::DB_CONNECTION);
|
||||
} catch (const std::exception& ex) {
|
||||
err << "Unable to open database: " << ex.what();
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
// Regenerate server identifier if needed.
|
||||
@ -967,7 +949,7 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
|
||||
} catch (const std::exception& ex) {
|
||||
err << "unable to configure server identifier: " << ex.what();
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
// Server will start DDNS communications if its enabled.
|
||||
@ -976,7 +958,7 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
} catch (const std::exception& ex) {
|
||||
err << "Error starting DHCP_DDNS client after server reconfiguration: "
|
||||
<< ex.what();
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
// Setup DHCPv4-over-DHCPv6 IPC
|
||||
@ -985,7 +967,7 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
} catch (const std::exception& ex) {
|
||||
err << "error starting DHCPv4-over-DHCPv6 IPC "
|
||||
" after server reconfiguration: " << ex.what();
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
// Configure DHCP packet queueing
|
||||
@ -1000,7 +982,7 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
} catch (const std::exception& ex) {
|
||||
err << "Error setting packet queue controls after server reconfiguration: "
|
||||
<< ex.what();
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
// Configure a callback to shut down the server when the bind socket
|
||||
@ -1029,7 +1011,7 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
|
||||
err << "unable to setup timers for periodically running the"
|
||||
" reclamation of the expired leases: "
|
||||
<< ex.what() << ".";
|
||||
return (isc::config::createAnswer(1, err.str()));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
|
||||
}
|
||||
|
||||
// Setup config backend polling, if configured for it.
|
||||
@ -1116,7 +1098,7 @@ ControlledDhcpv6Srv::checkConfig(isc::data::ConstElementPtr config) {
|
||||
ControlledDhcpv6Srv* srv = ControlledDhcpv6Srv::getInstance();
|
||||
|
||||
if (!srv) {
|
||||
ConstElementPtr no_srv = isc::config::createAnswer(1,
|
||||
ConstElementPtr no_srv = isc::config::createAnswer(CONTROL_RESULT_ERROR,
|
||||
"Server object not initialized, can't process config.");
|
||||
return (no_srv);
|
||||
}
|
||||
|
@ -424,29 +424,11 @@ void configureCommandChannel() {
|
||||
}
|
||||
|
||||
isc::data::ConstElementPtr
|
||||
configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
|
||||
bool check_only) {
|
||||
if (!config_set) {
|
||||
ConstElementPtr answer = isc::config::createAnswer(CONTROL_RESULT_ERROR,
|
||||
string("Can't parse NULL config"));
|
||||
return (answer);
|
||||
}
|
||||
|
||||
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_COMMAND, DHCP6_CONFIG_START)
|
||||
.arg(server.redactConfig(config_set)->str());
|
||||
|
||||
processDhcp6Config(isc::data::ConstElementPtr config_set) {
|
||||
// Before starting any subnet operations, let's reset the subnet-id counter,
|
||||
// so newly recreated configuration starts with first subnet-id equal 1.
|
||||
Subnet::resetSubnetID();
|
||||
|
||||
// Close DHCP sockets and remove any existing timers.
|
||||
if (!check_only) {
|
||||
IfaceMgr::instance().closeSockets();
|
||||
TimerMgr::instance()->unregisterTimers();
|
||||
server.discardPackets();
|
||||
server.getCBControl()->reset();
|
||||
}
|
||||
|
||||
// Revert any runtime option definitions configured so far and not committed.
|
||||
LibDHCP::revertRuntimeOptionDefs();
|
||||
// Let's set empty container in case a user hasn't specified any configuration
|
||||
@ -458,9 +440,7 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
|
||||
|
||||
// Answer will hold the result.
|
||||
ConstElementPtr answer;
|
||||
// Rollback informs whether error occurred and original data
|
||||
// have to be restored to global storages.
|
||||
bool rollback = false;
|
||||
|
||||
// Global parameter name in case of an error.
|
||||
string parameter_name;
|
||||
ElementPtr mutable_cfg;
|
||||
@ -585,7 +565,7 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
|
||||
ConstElementPtr ifaces_config = mutable_cfg->get("interfaces-config");
|
||||
if (ifaces_config) {
|
||||
parameter_name = "interfaces-config";
|
||||
IfacesConfigParser parser(AF_INET6, check_only);
|
||||
IfacesConfigParser parser(AF_INET6, true);
|
||||
CfgIfacePtr cfg_iface = srv_config->getCfgIface();
|
||||
parser.parse(cfg_iface, ifaces_config);
|
||||
}
|
||||
@ -869,25 +849,95 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
|
||||
LOG_ERROR(dhcp6_logger, DHCP6_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;
|
||||
} catch (...) {
|
||||
// For things like bad_cast in boost::lexical_cast
|
||||
LOG_ERROR(dhcp6_logger, DHCP6_PARSER_EXCEPTION).arg(parameter_name);
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, "undefined configuration"
|
||||
" processing error");
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, "undefined configuration "
|
||||
"processing error");
|
||||
}
|
||||
|
||||
// An error occurred, so make sure that we restore original data.
|
||||
if (!answer) {
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS, "Configuration seems sane. "
|
||||
"Control-socket, hook-libraries, and D2 configuration "
|
||||
"were sanity checked, but not applied.");
|
||||
}
|
||||
|
||||
return (answer);
|
||||
}
|
||||
|
||||
isc::data::ConstElementPtr
|
||||
configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
|
||||
bool check_only) {
|
||||
if (!config_set) {
|
||||
ConstElementPtr answer = isc::config::createAnswer(CONTROL_RESULT_ERROR,
|
||||
"Can't parse NULL config");
|
||||
return (answer);
|
||||
}
|
||||
|
||||
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_COMMAND, DHCP6_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 = processDhcp6Config(config_set);
|
||||
|
||||
int status_code = 0;
|
||||
isc::config::parseAnswer(status_code, answer);
|
||||
if (status_code != CONTROL_RESULT_SUCCESS) {
|
||||
rollback = true;
|
||||
}
|
||||
|
||||
if (check_only) {
|
||||
rollback = true;
|
||||
if (!answer) {
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS,
|
||||
"Configuration seems sane. Control-socket, hook-libraries, and D2 "
|
||||
"configuration were sanity checked, but not applied.");
|
||||
SrvConfigPtr srv_config;
|
||||
|
||||
if (!rollback) {
|
||||
if (!check_only) {
|
||||
string parameter_name;
|
||||
ElementPtr mutable_cfg;
|
||||
|
||||
// Close DHCP sockets and remove any existing timers.
|
||||
IfaceMgr::instance().closeSockets();
|
||||
TimerMgr::instance()->unregisterTimers();
|
||||
server.discardPackets();
|
||||
server.getCBControl()->reset();
|
||||
|
||||
try {
|
||||
|
||||
// Get the staging configuration.
|
||||
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.
|
||||
mutable_cfg = boost::const_pointer_cast<Element>(config_set);
|
||||
|
||||
ConstElementPtr ifaces_config = mutable_cfg->get("interfaces-config");
|
||||
if (ifaces_config) {
|
||||
parameter_name = "interfaces-config";
|
||||
IfacesConfigParser parser(AF_INET6, false);
|
||||
CfgIfacePtr cfg_iface = srv_config->getCfgIface();
|
||||
cfg_iface->reset();
|
||||
parser.parse(cfg_iface, ifaces_config);
|
||||
}
|
||||
} catch (const isc::Exception& ex) {
|
||||
LOG_ERROR(dhcp6_logger, DHCP6_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;
|
||||
} catch (...) {
|
||||
// For things like bad_cast in boost::lexical_cast
|
||||
LOG_ERROR(dhcp6_logger, DHCP6_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;
|
||||
}
|
||||
} else {
|
||||
rollback = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -398,7 +398,7 @@ public:
|
||||
// both structures are built using the same order.
|
||||
EXPECT_EQ(Element::fromJSON(expected_command)->str(),
|
||||
entire_command->str());
|
||||
return (createAnswer(0, "long command received ok"));
|
||||
return (createAnswer(CONTROL_RESULT_SUCCESS, "long command received ok"));
|
||||
}
|
||||
|
||||
/// @brief Command handler which generates long response
|
||||
@ -414,7 +414,7 @@ public:
|
||||
s << std::setw(5) << i;
|
||||
arguments->add(Element::create(s.str()));
|
||||
}
|
||||
return (createAnswer(0, arguments));
|
||||
return (createAnswer(CONTROL_RESULT_SUCCESS, arguments));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -75,7 +75,7 @@ NetconfProcess::runIO() {
|
||||
isc::data::ConstElementPtr
|
||||
NetconfProcess::shutdown(isc::data::ConstElementPtr /*args*/) {
|
||||
setShutdownFlag(true);
|
||||
return (isc::config::createAnswer(0, "Netconf is shutting down"));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_SUCCESS, "Netconf is shutting down"));
|
||||
}
|
||||
|
||||
isc::data::ConstElementPtr
|
||||
|
@ -52,7 +52,7 @@ createAnswer(const int status_code, const std::string& text,
|
||||
|
||||
ConstElementPtr
|
||||
createAnswer() {
|
||||
return (createAnswer(0, string(""), ConstElementPtr()));
|
||||
return (createAnswer(CONTROL_RESULT_SUCCESS, string(""), ConstElementPtr()));
|
||||
}
|
||||
|
||||
ConstElementPtr
|
||||
|
@ -42,17 +42,17 @@ TEST(CommandInterpreterTest, createAnswer) {
|
||||
EXPECT_EQ("{ \"result\": 0 }", answer->str());
|
||||
|
||||
// Let's check if we can generate an error.
|
||||
answer = createAnswer(1, "error");
|
||||
answer = createAnswer(CONTROL_RESULT_ERROR, "error");
|
||||
EXPECT_EQ("{ \"result\": 1, \"text\": \"error\" }", answer->str());
|
||||
|
||||
// This is expected to throw. When status code is non-zero (indicating error),
|
||||
// textual explanation is mandatory.
|
||||
EXPECT_THROW(createAnswer(1, ElementPtr()), CtrlChannelError);
|
||||
EXPECT_THROW(createAnswer(1, Element::create(1)), CtrlChannelError);
|
||||
EXPECT_THROW(createAnswer(CONTROL_RESULT_ERROR, ElementPtr()), CtrlChannelError);
|
||||
EXPECT_THROW(createAnswer(CONTROL_RESULT_ERROR, Element::create(1)), CtrlChannelError);
|
||||
|
||||
// Let's check if answer can be generate with some data in it.
|
||||
ConstElementPtr arg = el("[ \"just\", \"some\", \"data\" ]");
|
||||
answer = createAnswer(0, arg);
|
||||
answer = createAnswer(CONTROL_RESULT_SUCCESS, arg);
|
||||
EXPECT_EQ("{ \"arguments\": [ \"just\", \"some\", \"data\" ], \"result\": 0 }",
|
||||
answer->str());
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ HookedCommandMgr::handleCommand(const std::string& cmd_name,
|
||||
// registered
|
||||
// for it, combine the lists of commands.
|
||||
if (!hooks_commands->empty()) {
|
||||
response = combineCommandsLists(response, createAnswer(0, hooks_commands));
|
||||
response = combineCommandsLists(response, createAnswer(CONTROL_RESULT_SUCCESS, hooks_commands));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ public:
|
||||
// Answer will hold the result.
|
||||
ConstElementPtr answer;
|
||||
if (!config_set) {
|
||||
answer = isc::config::createAnswer(1,
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR,
|
||||
string("Can't parse NULL config"));
|
||||
return (answer);
|
||||
}
|
||||
@ -302,13 +302,13 @@ public:
|
||||
}
|
||||
|
||||
// Everything was fine. Configuration is successful.
|
||||
answer = isc::config::createAnswer(0, "Configuration committed.");
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS, "Configuration committed.");
|
||||
} catch (const isc::Exception& ex) {
|
||||
answer = isc::config::createAnswer(1,
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR,
|
||||
string("Configuration parsing failed: ") + ex.what());
|
||||
|
||||
} catch (...) {
|
||||
answer = isc::config::createAnswer(1,
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR,
|
||||
string("Configuration parsing failed"));
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace isc;
|
||||
using namespace isc::config;
|
||||
using namespace isc::dhcp;
|
||||
using namespace isc::data;
|
||||
using namespace isc::asiolink;
|
||||
@ -76,8 +77,8 @@ DCfgMgrBase::simpleParseConfig(isc::data::ConstElementPtr config_set,
|
||||
bool check_only,
|
||||
const std::function<void()>& post_config_cb) {
|
||||
if (!config_set) {
|
||||
return (isc::config::createAnswer(1,
|
||||
std::string("Can't parse NULL config")));
|
||||
return (isc::config::createAnswer(CONTROL_RESULT_ERROR,
|
||||
std::string("Can't parse NULL config")));
|
||||
}
|
||||
LOG_DEBUG(dctl_logger, isc::log::DBGLVL_COMMAND, DCTL_CONFIG_START)
|
||||
.arg(redactConfig(config_set)->str());
|
||||
@ -122,7 +123,7 @@ DCfgMgrBase::simpleParseConfig(isc::data::ConstElementPtr config_set,
|
||||
}
|
||||
|
||||
// Use the answer provided.
|
||||
//answer = isc::config::createAnswer(0, "Configuration committed.");
|
||||
//answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS, "Configuration committed.");
|
||||
} else {
|
||||
LOG_INFO(dctl_logger, DCTL_CONFIG_CHECK_COMPLETE)
|
||||
.arg(getConfigSummary(0))
|
||||
@ -131,7 +132,7 @@ DCfgMgrBase::simpleParseConfig(isc::data::ConstElementPtr config_set,
|
||||
|
||||
} catch (const std::exception& ex) {
|
||||
LOG_ERROR(dctl_logger, DCTL_PARSER_FAIL).arg(ex.what());
|
||||
answer = isc::config::createAnswer(1, ex.what());
|
||||
answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, ex.what());
|
||||
rollback = true;
|
||||
}
|
||||
|
||||
|
@ -61,15 +61,16 @@ DStubProcess::shutdown(isc::data::ConstElementPtr /* args */) {
|
||||
|
||||
setShutdownFlag(true);
|
||||
stopIOService();
|
||||
return (isc::config::createAnswer(0, "Shutdown initiated."));
|
||||
return (isc::config::createAnswer(isc::config::CONTROL_RESULT_SUCCESS,
|
||||
"Shutdown initiated."));
|
||||
}
|
||||
|
||||
isc::data::ConstElementPtr
|
||||
DStubProcess::configure(isc::data::ConstElementPtr config_set, bool check_only) {
|
||||
if (SimFailure::shouldFailOn(SimFailure::ftProcessConfigure)) {
|
||||
// Simulates a process configure failure.
|
||||
return (isc::config::createAnswer(1,
|
||||
"Simulated process configuration error."));
|
||||
return (isc::config::createAnswer(isc::config::CONTROL_RESULT_ERROR,
|
||||
"Simulated process configuration error."));
|
||||
}
|
||||
|
||||
return (getCfgMgr()->simpleParseConfig(config_set, check_only));
|
||||
@ -329,7 +330,8 @@ DStubCfgMgr::createNewContext() {
|
||||
|
||||
isc::data::ConstElementPtr
|
||||
DStubCfgMgr::parse(isc::data::ConstElementPtr /*config*/, bool /*check_only*/) {
|
||||
return (isc::config::createAnswer(0, "It all went fine. I promise"));
|
||||
return (isc::config::createAnswer(isc::config::CONTROL_RESULT_SUCCESS,
|
||||
"It all went fine. I promise"));
|
||||
}
|
||||
|
||||
} // namespace isc::process
|
||||
|
Loading…
x
Reference in New Issue
Block a user