Commit e38e8d97 authored by Francis Dupont's avatar Francis Dupont

[102b] rebased

parent 3188ae9a
...@@ -113,6 +113,22 @@ will be sent to Kea and the responses received from Kea printed to standard outp ...@@ -113,6 +113,22 @@ will be sent to Kea and the responses received from Kea printed to standard outp
<section id="commands-common"> <section id="commands-common">
<title>Commands Supported by Both the DHCPv4 and DHCPv6 Servers</title> <title>Commands Supported by Both the DHCPv4 and DHCPv6 Servers</title>
<section id="command-build-report">
<title>build-report</title>
<para>
The <emphasis>build-report</emphasis> command returns
on the control channel what the command line
<command>-W</command> argument displays, i.e. the embedded
content of the <filename>config.report</filename> file.
This command does not take any parameters.
</para>
<screen>
{
"command": "build-report"
}
</screen>
</section> <!-- end of command-build-report -->
<section id="command-config-get"> <section id="command-config-get">
<title>config-get</title> <title>config-get</title>
...@@ -315,7 +331,21 @@ will be sent to Kea and the responses received from Kea printed to standard outp ...@@ -315,7 +331,21 @@ will be sent to Kea and the responses received from Kea printed to standard outp
</para> </para>
</section> <!-- end of command-shutdown --> </section> <!-- end of command-shutdown -->
<section id="command-version-get">
<title>version-get</title>
<para>
The <emphasis>version-get</emphasis> command returns on the control
channel what the command line <command>-v</command> argument
displays with in arguments the extended version, i.e., what
the command line <command>-V</command> argument displays. This command
does not take any parameters.
</para>
<screen>
{
"command": "version-get"
}
</screen>
</section> <!-- end of command-version-get -->
</section> <!-- end of commands supported by both servers --> </section> <!-- end of commands supported by both servers -->
......
...@@ -195,7 +195,7 @@ opening curly bracket (or brace). Each configuration consists of ...@@ -195,7 +195,7 @@ opening curly bracket (or brace). Each configuration consists of
one or more objects. In this specific example, we have only one one or more objects. In this specific example, we have only one
object, called Dhcp4. This is a simplified configuration, as usually object, called Dhcp4. This is a simplified configuration, as usually
there will be additional objects, like <command>Logging</command> or there will be additional objects, like <command>Logging</command> or
<command>DhcpDns</command>, but we omit them now for clarity. The Dhcp4 <command>DhcpDdns</command>, but we omit them now for clarity. The Dhcp4
configuration starts with the <command>"Dhcp4": {</command> line configuration starts with the <command>"Dhcp4": {</command> line
and ends with the corresponding closing brace (in the above example, and ends with the corresponding closing brace (in the above example,
the brace after the last comment). Everything defined between those the brace after the last comment). Everything defined between those
...@@ -2475,7 +2475,7 @@ It is merely echoed by the server ...@@ -2475,7 +2475,7 @@ It is merely echoed by the server
indicates that the server will use the "client identifier" for lease indicates that the server will use the "client identifier" for lease
lookups and "chaddr" if the first lookup returns no results. The lookups and "chaddr" if the first lookup returns no results. The
<command>false</command> means that the server will only <command>false</command> means that the server will only
use the "chaddr" to search for client"s lease. Whether the DHCID for use the "chaddr" to search for client's lease. Whether the DHCID for
DNS updates is generated from the "client identifier" or "chaddr" is DNS updates is generated from the "client identifier" or "chaddr" is
controlled through the same parameter accordingly.</para> controlled through the same parameter accordingly.</para>
...@@ -3723,12 +3723,14 @@ src/lib/dhcpsrv/cfg_host_operations.cc --> ...@@ -3723,12 +3723,14 @@ src/lib/dhcpsrv/cfg_host_operations.cc -->
<para>The DHCPv4 server supports the following operational commands: <para>The DHCPv4 server supports the following operational commands:
<itemizedlist> <itemizedlist>
<listitem>build-report</listitem>
<listitem>config-get</listitem> <listitem>config-get</listitem>
<listitem>config-write</listitem> <listitem>config-write</listitem>
<listitem>leases-reclaim</listitem> <listitem>leases-reclaim</listitem>
<listitem>list-commands</listitem> <listitem>list-commands</listitem>
<listitem>set-config</listitem> <listitem>set-config</listitem>
<listitem>shutdown</listitem> <listitem>shutdown</listitem>
<listitem>version-get</listitem>
</itemizedlist> </itemizedlist>
as described in <xref linkend="commands-common"/>. In addition, as described in <xref linkend="commands-common"/>. In addition,
it supports the following statistics related commands: it supports the following statistics related commands:
......
...@@ -196,7 +196,7 @@ opening curly bracket (or brace). Each configuration consists of ...@@ -196,7 +196,7 @@ opening curly bracket (or brace). Each configuration consists of
one or more objects. In this specific example, we have only one one or more objects. In this specific example, we have only one
object, called Dhcp6. This is a simplified configuration, as usually object, called Dhcp6. This is a simplified configuration, as usually
there will be additional objects, like <command>Logging</command> or there will be additional objects, like <command>Logging</command> or
<command>DhcpDns</command>, but we omit them now for clarity. The Dhcp6 <command>DhcpDdns</command>, but we omit them now for clarity. The Dhcp6
configuration starts with the <command>"Dhcp6": {</command> line configuration starts with the <command>"Dhcp6": {</command> line
and ends with the corresponding closing brace (in the above example, and ends with the corresponding closing brace (in the above example,
the brace after the last comment). Everything defined between those the brace after the last comment). Everything defined between those
...@@ -2892,7 +2892,7 @@ should include options from the isc option space: ...@@ -2892,7 +2892,7 @@ should include options from the isc option space:
<userinput>"option-data": [ <userinput>"option-data": [
{ {
"name": "vendor-opts", "name": "vendor-opts",
"data": 4491" "data": 4491
}, },
{ {
"name": "tftp-servers", "name": "tftp-servers",
...@@ -4131,12 +4131,14 @@ If not specified, the default value is: ...@@ -4131,12 +4131,14 @@ If not specified, the default value is:
<para>The DHCPv6 server supports the following operational commands: <para>The DHCPv6 server supports the following operational commands:
<itemizedlist> <itemizedlist>
<listitem>build-report</listitem>
<listitem>config-get</listitem> <listitem>config-get</listitem>
<listitem>config-write</listitem> <listitem>config-write</listitem>
<listitem>leases-reclaim</listitem> <listitem>leases-reclaim</listitem>
<listitem>list-commands</listitem> <listitem>list-commands</listitem>
<listitem>set-config</listitem> <listitem>set-config</listitem>
<listitem>shutdown</listitem> <listitem>shutdown</listitem>
<listitem>version-get</listitem>
</itemizedlist> </itemizedlist>
as described in <xref linkend="commands-common"/>. In addition, as described in <xref linkend="commands-common"/>. In addition,
it supports the following statistics related commands: it supports the following statistics related commands:
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <agent/ca_controller.h> #include <agent/ca_controller.h>
#include <agent/ca_process.h> #include <agent/ca_process.h>
#include <agent/ca_command_mgr.h>
#include <agent/parser_context.h> #include <agent/parser_context.h>
using namespace isc::process; using namespace isc::process;
...@@ -47,6 +48,25 @@ CtrlAgentController::parseFile(const std::string& name) { ...@@ -47,6 +48,25 @@ CtrlAgentController::parseFile(const std::string& name) {
return (parser.parseFile(name, ParserContext::PARSER_AGENT)); return (parser.parseFile(name, ParserContext::PARSER_AGENT));
} }
void
CtrlAgentController::registerCommands() {
CtrlAgentCommandMgr::instance().registerCommand(VERSION_GET_COMMAND,
boost::bind(&DControllerBase::versionGetHandler, this, _1, _2));
CtrlAgentCommandMgr::instance().registerCommand(BUILD_REPORT_COMMAND,
boost::bind(&DControllerBase::buildReportHandler, this, _1, _2));
CtrlAgentCommandMgr::instance().registerCommand(SHUT_DOWN_COMMAND,
boost::bind(&DControllerBase::shutdownHandler, this, _1, _2));
}
void
CtrlAgentController::deregisterCommands() {
CtrlAgentCommandMgr::instance().deregisterCommand(VERSION_GET_COMMAND);
CtrlAgentCommandMgr::instance().deregisterCommand(BUILD_REPORT_COMMAND);
CtrlAgentCommandMgr::instance().deregisterCommand(SHUT_DOWN_COMMAND);
}
CtrlAgentController::CtrlAgentController() CtrlAgentController::CtrlAgentController()
: DControllerBase(agent_app_name_, agent_bin_name_) { : DControllerBase(agent_app_name_, agent_bin_name_) {
} }
......
// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // 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 // License, v. 2.0. If a copy of the MPL was not distributed with this
...@@ -47,6 +47,19 @@ public: ...@@ -47,6 +47,19 @@ public:
isc::data::ConstElementPtr isc::data::ConstElementPtr
parseFile(const std::string& name); parseFile(const std::string& name);
/// @brief Register commands.
///
/// For all commands in the commands_ set at the exception of
/// list-commands register the command with the generic
/// @ref isc::process::DControllerBase::executeCommand() handler.
void registerCommands();
/// @brief Deregister commands.
///
/// For all commands in the commands_ set at the exception of
/// list-commands deregister the command.
void deregisterCommands();
private: private:
/// @brief Creates an instance of the Control Agent application /// @brief Creates an instance of the Control Agent application
...@@ -64,9 +77,11 @@ private: ...@@ -64,9 +77,11 @@ private:
/// @brief Constructor is declared private to maintain the integrity of /// @brief Constructor is declared private to maintain the integrity of
/// the singleton instance. /// the singleton instance.
CtrlAgentController(); CtrlAgentController();
}; };
// @Defines a shared pointer to CtrlAgentController
typedef boost::shared_ptr<CtrlAgentController> CtrlAgentControllerPtr;
} // namespace isc::agent } // namespace isc::agent
} // namespace isc } // namespace isc
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <config.h> #include <config.h>
#include <agent/ca_process.h> #include <agent/ca_process.h>
#include <agent/ca_controller.h>
#include <agent/ca_response_creator_factory.h> #include <agent/ca_response_creator_factory.h>
#include <agent/ca_log.h> #include <agent/ca_log.h>
#include <asiolink/io_address.h> #include <asiolink/io_address.h>
...@@ -47,13 +48,20 @@ CtrlAgentProcess::run() { ...@@ -47,13 +48,20 @@ CtrlAgentProcess::run() {
try { try {
// Register commands.
CtrlAgentControllerPtr controller =
boost::dynamic_pointer_cast<CtrlAgentController>(
CtrlAgentController::instance());
controller->registerCommands();
// Create response creator factory first. It will be used to generate // Create response creator factory first. It will be used to generate
// response creators. Each response creator will be used to generate // response creators. Each response creator will be used to generate
// answer to specific request. // answer to specific request.
HttpResponseCreatorFactoryPtr rcf(new CtrlAgentResponseCreatorFactory()); HttpResponseCreatorFactoryPtr rcf(new CtrlAgentResponseCreatorFactory());
DCfgContextBasePtr base_ctx = getCfgMgr()->getContext(); DCfgContextBasePtr base_ctx = getCfgMgr()->getContext();
CtrlAgentCfgContextPtr ctx = boost::dynamic_pointer_cast<CtrlAgentCfgContext>(base_ctx); CtrlAgentCfgContextPtr ctx =
boost::dynamic_pointer_cast<CtrlAgentCfgContext>(base_ctx);
if (!ctx) { if (!ctx) {
isc_throw(Unexpected, "Interal logic error: bad context type"); isc_throw(Unexpected, "Interal logic error: bad context type");
} }
...@@ -99,6 +107,16 @@ CtrlAgentProcess::run() { ...@@ -99,6 +107,16 @@ CtrlAgentProcess::run() {
"Process run method failed: " << ex.what()); "Process run method failed: " << ex.what());
} }
try {
// Deregister commands.
CtrlAgentControllerPtr controller =
boost::dynamic_pointer_cast<CtrlAgentController>(
CtrlAgentController::instance());
controller->deregisterCommands();
} catch (const std::exception&) {
// What to do? Simply ignore...
}
LOG_DEBUG(agent_logger, DBGLVL_START_SHUT, CTRL_AGENT_RUN_EXIT); LOG_DEBUG(agent_logger, DBGLVL_START_SHUT, CTRL_AGENT_RUN_EXIT);
} }
...@@ -118,13 +136,6 @@ CtrlAgentProcess::configure(isc::data::ConstElementPtr config_set, ...@@ -118,13 +136,6 @@ CtrlAgentProcess::configure(isc::data::ConstElementPtr config_set,
return (answer); return (answer);
} }
isc::data::ConstElementPtr
CtrlAgentProcess::command(const std::string& command,
isc::data::ConstElementPtr /*args*/) {
return (isc::config::createAnswer(COMMAND_INVALID, "Unrecognized command: "
+ command));
}
CtrlAgentCfgMgrPtr CtrlAgentCfgMgrPtr
CtrlAgentProcess::getCtrlAgentCfgMgr() { CtrlAgentProcess::getCtrlAgentCfgMgr() {
......
...@@ -87,26 +87,6 @@ public: ...@@ -87,26 +87,6 @@ public:
configure(isc::data::ConstElementPtr config_set, configure(isc::data::ConstElementPtr config_set,
bool check_only = false); bool check_only = false);
/// @brief Processes the given command.
///
/// This method is called to execute any custom commands supported by the
/// process. This method must not throw, it should catch any processing
/// errors and return a success or failure answer as described below.
///
/// @param command is a string label representing the command to execute.
/// @param args is a set of arguments (if any) required for the given
/// command.
/// @return an Element that contains the results of command composed
/// of an integer status value:
///
/// - COMMAND_SUCCESS indicates a command was successful.
/// - COMMAND_ERROR indicates a valid command failed execute.
/// - COMMAND_INVALID indicates a command is not valid.
///
/// and a string explanation of the outcome.
virtual isc::data::ConstElementPtr
command(const std::string& command, isc::data::ConstElementPtr args);
/// @brief Returns a pointer to the configuration manager. /// @brief Returns a pointer to the configuration manager.
CtrlAgentCfgMgrPtr getCtrlAgentCfgMgr(); CtrlAgentCfgMgrPtr getCtrlAgentCfgMgr();
}; };
......
...@@ -362,19 +362,6 @@ D2Process::reconfigureQueueMgr() { ...@@ -362,19 +362,6 @@ D2Process::reconfigureQueueMgr() {
} }
} }
isc::data::ConstElementPtr
D2Process::command(const std::string& command,
isc::data::ConstElementPtr args) {
// @todo This is the initial implementation. If and when D2 is extended
// to support its own commands, this implementation must change. Otherwise
// it should reject all commands as it does now.
LOG_DEBUG(d2_logger, DBGLVL_TRACE_BASIC, DHCP_DDNS_COMMAND)
.arg(command).arg(args ? args->str() : "(no args)");
return (isc::config::createAnswer(COMMAND_INVALID, "Unrecognized command: "
+ command));
}
D2Process::~D2Process() { D2Process::~D2Process() {
}; };
......
...@@ -161,20 +161,6 @@ public: ...@@ -161,20 +161,6 @@ public:
configure(isc::data::ConstElementPtr config_set, configure(isc::data::ConstElementPtr config_set,
bool check_only = false); bool check_only = false);
/// @brief Processes the given command.
///
/// This method is called to execute any custom commands supported by the
/// process. This method must not throw, it should catch any processing
/// errors and return a success or failure answer as described below.
///
/// @param command is a string label representing the command to execute.
/// @param args is a set of arguments (if any) required for the given
/// command. It can be a NULL pointer if no arguments exist for a command.
/// @return an Element that contains the results of command composed
/// of an integer status value (0 means successful, non-zero means failure),
/// and a string explanation of the outcome.
virtual isc::data::ConstElementPtr command(const std::string& command,
isc::data::ConstElementPtr args);
/// @brief Destructor /// @brief Destructor
virtual ~D2Process(); virtual ~D2Process();
......
...@@ -199,35 +199,6 @@ TEST_F(D2ControllerTest, configUpdateTests) { ...@@ -199,35 +199,6 @@ TEST_F(D2ControllerTest, configUpdateTests) {
EXPECT_EQ(1, rcode); EXPECT_EQ(1, rcode);
} }
/// @brief Command execution tests.
/// This really tests just the ability of the handler to invoke the necessary
/// chain of methods and to handle error conditions.
/// This test verifies that:
/// 1. That an unrecognized command is detected and returns a status of
/// d2::COMMAND_INVALID.
/// 2. Shutdown command is recognized and returns a d2::COMMAND_SUCCESS status.
TEST_F(D2ControllerTest, executeCommandTests) {
int rcode = -1;
isc::data::ConstElementPtr answer;
isc::data::ElementPtr arg_set;
// Initialize the application process.
ASSERT_NO_THROW(initProcess());
EXPECT_TRUE(checkProcess());
// Verify that an unknown command returns an COMMAND_INVALID response.
std::string bogus_command("bogus");
answer = executeCommand(bogus_command, arg_set);
isc::config::parseAnswer(rcode, answer);
EXPECT_EQ(COMMAND_INVALID, rcode);
// Verify that shutdown command returns COMMAND_SUCCESS response.
//answer = executeCommand(SHUT_DOWN_COMMAND, isc::data::ElementPtr());
answer = executeCommand(SHUT_DOWN_COMMAND, arg_set);
isc::config::parseAnswer(rcode, answer);
EXPECT_EQ(COMMAND_SUCCESS, rcode);
}
// Tests that the original configuration is retained after a SIGHUP triggered // Tests that the original configuration is retained after a SIGHUP triggered
// reconfiguration fails due to invalid config content. // reconfiguration fails due to invalid config content.
TEST_F(D2ControllerTest, invalidConfigReload) { TEST_F(D2ControllerTest, invalidConfigReload) {
......
...@@ -394,20 +394,6 @@ TEST_F(D2ProcessTest, badConfigureRecovery) { ...@@ -394,20 +394,6 @@ TEST_F(D2ProcessTest, badConfigureRecovery) {
EXPECT_FALSE(getReconfQueueFlag()); EXPECT_FALSE(getReconfQueueFlag());
} }
/// @brief Verifies basic command method behavior.
/// @TODO IF the D2Process is extended to support extra commands this testing
/// will need to augmented accordingly.
TEST_F(D2ProcessTest, command) {
// Verify that the process will process unsupported command and
// return a failure response.
int rcode = -1;
string args = "{ \"arg1\": 77 } ";
isc::data::ElementPtr json = isc::data::Element::fromJSON(args);
isc::data::ConstElementPtr answer = command("bogus_command", json);
parseAnswer(rcode, answer);
EXPECT_EQ(COMMAND_INVALID, rcode);
}
/// @brief Tests shutdown command argument parsing /// @brief Tests shutdown command argument parsing
/// The shutdown command supports an optional "type" argument. This test /// The shutdown command supports an optional "type" argument. This test
/// checks that for valid values, the shutdown() method: sets the shutdown /// checks that for valid values, the shutdown() method: sets the shutdown
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <dhcpsrv/cfg_db_access.h> #include <dhcpsrv/cfg_db_access.h>
#include <config/command_mgr.h> #include <config/command_mgr.h>
#include <stats/stats_mgr.h> #include <stats/stats_mgr.h>
#include <cfgrpt/config_report.h>
using namespace isc::data; using namespace isc::data;
using namespace isc::hooks; using namespace isc::hooks;
...@@ -205,6 +206,25 @@ ControlledDhcpv4Srv::commandSetConfigHandler(const string&, ...@@ -205,6 +206,25 @@ ControlledDhcpv4Srv::commandSetConfigHandler(const string&,
return (result); return (result);
} }
ConstElementPtr
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,
Dhcpv4Srv::getVersion(false),
arguments);
return (answer);
}
ConstElementPtr
ControlledDhcpv4Srv::commandBuildReportHandler(const string&,
ConstElementPtr) {
ConstElementPtr answer =
isc::config::createAnswer(0, isc::detail::getConfigReport());
return (answer);
}
ConstElementPtr ConstElementPtr
ControlledDhcpv4Srv::commandLeasesReclaimHandler(const string&, ControlledDhcpv4Srv::commandLeasesReclaimHandler(const string&,
ConstElementPtr args) { ConstElementPtr args) {
...@@ -262,6 +282,12 @@ ControlledDhcpv4Srv::processCommand(const string& command, ...@@ -262,6 +282,12 @@ ControlledDhcpv4Srv::processCommand(const string& command,
} else if (command == "config-get") { } else if (command == "config-get") {
return (srv->commandConfigGetHandler(command, args)); return (srv->commandConfigGetHandler(command, args));
} else if (command == "version-get") {
return (srv->commandVersionGetHandler(command, args));
} else if (command == "build-report") {
return (srv->commandBuildReportHandler(command, args));
} else if (command == "leases-reclaim") { } else if (command == "leases-reclaim") {
return (srv->commandLeasesReclaimHandler(command, args)); return (srv->commandLeasesReclaimHandler(command, args));
...@@ -398,6 +424,9 @@ ControlledDhcpv4Srv::ControlledDhcpv4Srv(uint16_t port /*= DHCP4_SERVER_PORT*/) ...@@ -398,6 +424,9 @@ ControlledDhcpv4Srv::ControlledDhcpv4Srv(uint16_t port /*= DHCP4_SERVER_PORT*/)
// These are the commands always supported by the DHCPv4 server. // These are the commands always supported by the DHCPv4 server.
// Please keep the list in alphabetic order. // Please keep the list in alphabetic order.
CommandMgr::instance().registerCommand("build-report",
boost::bind(&ControlledDhcpv4Srv::commandBuildReportHandler, this, _1, _2));
CommandMgr::instance().registerCommand("config-get", CommandMgr::instance().registerCommand("config-get",
boost::bind(&ControlledDhcpv4Srv::commandConfigGetHandler, this, _1, _2)); boost::bind(&ControlledDhcpv4Srv::commandConfigGetHandler, this, _1, _2));
...@@ -418,6 +447,9 @@ ControlledDhcpv4Srv::ControlledDhcpv4Srv(uint16_t port /*= DHCP4_SERVER_PORT*/) ...@@ -418,6 +447,9 @@ ControlledDhcpv4Srv::ControlledDhcpv4Srv(uint16_t port /*= DHCP4_SERVER_PORT*/)
CommandMgr::instance().registerCommand("shutdown", CommandMgr::instance().registerCommand("shutdown",
boost::bind(&ControlledDhcpv4Srv::commandShutdownHandler, this, _1, _2)); boost::bind(&ControlledDhcpv4Srv::commandShutdownHandler, this, _1, _2));
CommandMgr::instance().registerCommand("version-get",
boost::bind(&ControlledDhcpv4Srv::commandVersionGetHandler, this, _1, _2));
// Register statistic related commands // Register statistic related commands
CommandMgr::instance().registerCommand("statistic-get", CommandMgr::instance().registerCommand("statistic-get",
boost::bind(&StatsMgr::statisticGetHandler, _1, _2)); boost::bind(&StatsMgr::statisticGetHandler, _1, _2));
...@@ -457,6 +489,7 @@ ControlledDhcpv4Srv::~ControlledDhcpv4Srv() { ...@@ -457,6 +489,7 @@ ControlledDhcpv4Srv::~ControlledDhcpv4Srv() {
CommandMgr::instance().closeCommandSocket(); CommandMgr::instance().closeCommandSocket();
// Deregister any registered commands (please keep in alphabetic order) // Deregister any registered commands (please keep in alphabetic order)
CommandMgr::instance().deregisterCommand("build-report");
CommandMgr::instance().deregisterCommand("config-get"); CommandMgr::instance().deregisterCommand("config-get");
CommandMgr::instance().deregisterCommand("config-write"); CommandMgr::instance().deregisterCommand("config-write");
CommandMgr::instance().deregisterCommand("leases-reclaim"); CommandMgr::instance().deregisterCommand("leases-reclaim");
...@@ -469,6 +502,7 @@ ControlledDhcpv4Srv::~ControlledDhcpv4Srv() { ...@@ -469,6 +502,7 @@ ControlledDhcpv4Srv::~ControlledDhcpv4Srv() {
CommandMgr::instance().deregisterCommand("statistic-remove-all"); CommandMgr::instance().deregisterCommand("statistic-remove-all");
CommandMgr::instance().deregisterCommand("statistic-reset"); CommandMgr::instance().deregisterCommand("statistic-reset");
CommandMgr::instance().deregisterCommand("statistic-reset-all"); CommandMgr::instance().deregisterCommand("statistic-reset-all");
CommandMgr::instance().deregisterCommand("version-get");
} catch (...) { } catch (...) {
// Don't want to throw exceptions from the destructor. The server // Don't want to throw exceptions from the destructor. The server
......
...@@ -187,6 +187,31 @@ private: ...@@ -187,6 +187,31 @@ private:
commandSetConfigHandler(const std::string& command, commandSetConfigHandler(const std::string& command,
isc::data::ConstElementPtr args); isc::data::ConstElementPtr args);
/// @brief handler for processing 'version-get' command
///
/// This handler processes version-get command, which returns