From: Francis Dupont Date: Fri, 14 Jun 2019 23:05:07 +0000 (+0200) Subject: [470-server-tag-get-command] Added server-tag-get and prepared server-tag-set X-Git-Tag: Kea-1.6.1~10^2~107^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d4a8accc16bf4dd69892bed3964bce880d62eab4;p=thirdparty%2Fkea.git [470-server-tag-get-command] Added server-tag-get and prepared server-tag-set --- diff --git a/src/bin/dhcp4/ctrl_dhcp4_srv.cc b/src/bin/dhcp4/ctrl_dhcp4_srv.cc index 3964a1a3fb..7eb7a8377a 100644 --- a/src/bin/dhcp4/ctrl_dhcp4_srv.cc +++ b/src/bin/dhcp4/ctrl_dhcp4_srv.cc @@ -538,6 +538,44 @@ ControlledDhcpv4Srv::commandLeasesReclaimHandler(const string&, return (answer); } +ConstElementPtr +ControlledDhcpv4Srv::commandServerTagGetHandler(const std::string&, + ConstElementPtr) { + const std::string& tag = + CfgMgr::instance().getCurrentCfg()->getServerTag(); + ElementPtr response = Element::createMap(); + response->set("server-tag", Element::create(tag)); + + return (createAnswer(CONTROL_RESULT_SUCCESS, response)); +} + +ConstElementPtr +ControlledDhcpv4Srv::commandServerTagSetHandler(const std::string&, + ConstElementPtr args) { + std::string message; + ConstElementPtr tag; + if (!args) { + message = "Missing mandatory 'arguments' parameter."; + } else { + tag = args->get("server-tag"); + if (!tag) { + message = "Missing mandatory 'server-tag' parameter."; + } else if (tag->getType() != Element::string) { + message = "'server-tag' parameter expected to be a string."; + } + } + + if (!message.empty()) { + // Something is amiss with arguments, return a failure response. + return (createAnswer(CONTROL_RESULT_ERROR, message)); + } + + CfgMgr::instance().getCurrentCfg()->setServerTag(tag->stringValue()); + CfgMgr::instance().getCurrentCfg()->addConfiguredGlobal("server-tag", tag); + message = "'server-tag' successfully updated."; + return (createAnswer(CONTROL_RESULT_SUCCESS, message)); +} + ConstElementPtr ControlledDhcpv4Srv::processCommand(const string& command, ConstElementPtr args) { @@ -592,7 +630,11 @@ ControlledDhcpv4Srv::processCommand(const string& command, } else if (command == "config-write") { return (srv->commandConfigWriteHandler(command, args)); + } else if (command == "server-tag-get") { + return (srv->commandServerTagGetHandler(command, args)); + } + // not yet server-tag-set ConstElementPtr answer = isc::config::createAnswer(1, "Unrecognized command:" + command); return (answer); @@ -822,6 +864,11 @@ ControlledDhcpv4Srv::ControlledDhcpv4Srv(uint16_t server_port /*= DHCP4_SERVER_P CommandMgr::instance().registerCommand("leases-reclaim", boost::bind(&ControlledDhcpv4Srv::commandLeasesReclaimHandler, this, _1, _2)); + CommandMgr::instance().registerCommand("server-tag-get", + boost::bind(&ControlledDhcpv4Srv::commandServerTagGetHandler, this, _1, _2)); + + // not yet server-tag-set + CommandMgr::instance().registerCommand("shutdown", boost::bind(&ControlledDhcpv4Srv::commandShutdownHandler, this, _1, _2)); @@ -878,6 +925,8 @@ ControlledDhcpv4Srv::~ControlledDhcpv4Srv() { CommandMgr::instance().deregisterCommand("config-set"); CommandMgr::instance().deregisterCommand("dhcp-disable"); CommandMgr::instance().deregisterCommand("dhcp-enable"); + CommandMgr::instance().deregisterCommand("server-tag-get"); + // not yet server-tag-set CommandMgr::instance().deregisterCommand("shutdown"); CommandMgr::instance().deregisterCommand("statistic-get"); CommandMgr::instance().deregisterCommand("statistic-get-all"); diff --git a/src/bin/dhcp4/ctrl_dhcp4_srv.h b/src/bin/dhcp4/ctrl_dhcp4_srv.h index 0b2a471fac..6913a21e9d 100644 --- a/src/bin/dhcp4/ctrl_dhcp4_srv.h +++ b/src/bin/dhcp4/ctrl_dhcp4_srv.h @@ -292,6 +292,32 @@ private: commandLeasesReclaimHandler(const std::string& command, isc::data::ConstElementPtr args); + /// @brief Handler for processing 'server-tag-get' command + /// + /// This handler processes server-tag-get command, which retrieves + /// the current server tag and returns it in response. + /// + /// @param command (parameter ignored) + /// @param args { "server-tag": "" } argument map. + /// + /// @return status of the command + isc::data::ConstElementPtr + commandServerTagGetHandler(const std::string& command, + isc::data::ConstElementPtr args); + + /// @brief Handler for processing 'server-tag-set' command + /// + /// This handler processes server-tag-set command, which sets + /// the server tag to the specified value. + /// + /// @param command (parameter ignored) + /// @param args { "server-tag": "" } argument map. + /// + /// @return status of the command + isc::data::ConstElementPtr + commandServerTagSetHandler(const std::string& command, + isc::data::ConstElementPtr args); + /// @brief Reclaims expired IPv4 leases and reschedules timer. /// /// This is a wrapper method for @c AllocEngine::reclaimExpiredLeases4. diff --git a/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc index 78a04cdc07..d56f40e35d 100644 --- a/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc @@ -483,6 +483,8 @@ TEST_F(CtrlChannelDhcpv4SrvTest, commandsRegistration) { EXPECT_TRUE(command_list.find("\"config-write\"") != string::npos); EXPECT_TRUE(command_list.find("\"leases-reclaim\"") != string::npos); EXPECT_TRUE(command_list.find("\"libreload\"") != string::npos); + EXPECT_TRUE(command_list.find("\"server-tag-get\"") != string::npos); + EXPECT_FALSE(command_list.find("\"server-tag-set\"") != string::npos); EXPECT_TRUE(command_list.find("\"shutdown\"") != string::npos); EXPECT_TRUE(command_list.find("\"statistic-get\"") != string::npos); EXPECT_TRUE(command_list.find("\"statistic-get-all\"") != string::npos); @@ -604,6 +606,39 @@ TEST_F(CtrlChannelDhcpv4SrvTest, getversion) { EXPECT_TRUE(response.find("GTEST_VERSION") != string::npos); } +// This test verifies that the DHCP server handles server-tag-get command +TEST_F(CtrlChannelDhcpv4SrvTest, serverTagGet) { + createUnixChannelServer(); + + std::string response; + std::string expected; + + // Send the server-tag-get command + sendUnixCommand("{ \"command\": \"server-tag-get\" }", response); + expected = "{ \"arguments\": { \"server-tag\": \"\" }, \"result\": 0 }"; + EXPECT_EQ(expected, response); + + // Set a value to the server tag + CfgMgr::instance().getCurrentCfg()->setServerTag("foobar"); + + // Retry... + sendUnixCommand("{ \"command\": \"server-tag-get\" }", response); + expected = "{ \"arguments\": { \"server-tag\": \"foobar\" }, \"result\": 0 }"; +} + +// This test verifies that the DHCP server does not handles server-tag-set command +TEST_F(CtrlChannelDhcpv4SrvTest, serverTagSet) { + createUnixChannelServer(); + + std::string response; + + // Send the server-tag-set command + sendUnixCommand("{ \"command\": \"server-tag-set\" }", response); + std::string expected = "{ \"result\": 2, " + "\"text\": \"'server-tag-set' command not supported.\" }"; + EXPECT_EQ(expected, response); +} + // This test verifies that the DHCP server immediately removed expired // This test verifies that the DHCP server immediately removed expired // leases on leases-reclaim command with remove = true @@ -854,6 +889,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, listCommands) { checkListCommands(rsp, "list-commands"); checkListCommands(rsp, "leases-reclaim"); checkListCommands(rsp, "libreload"); + checkListCommands(rsp, "server-tag-get"); checkListCommands(rsp, "shutdown"); checkListCommands(rsp, "statistic-get"); checkListCommands(rsp, "statistic-get-all"); diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.cc b/src/bin/dhcp6/ctrl_dhcp6_srv.cc index 8cb2737cce..c9cd6873bc 100644 --- a/src/bin/dhcp6/ctrl_dhcp6_srv.cc +++ b/src/bin/dhcp6/ctrl_dhcp6_srv.cc @@ -539,6 +539,44 @@ ControlledDhcpv6Srv::commandLeasesReclaimHandler(const string&, return (answer); } +ConstElementPtr +ControlledDhcpv6Srv::commandServerTagGetHandler(const std::string&, + ConstElementPtr) { + const std::string& tag = + CfgMgr::instance().getCurrentCfg()->getServerTag(); + ElementPtr response = Element::createMap(); + response->set("server-tag", Element::create(tag)); + + return (createAnswer(CONTROL_RESULT_SUCCESS, response)); +} + +ConstElementPtr +ControlledDhcpv6Srv::commandServerTagSetHandler(const std::string&, + ConstElementPtr args) { + std::string message; + ConstElementPtr tag; + if (!args) { + message = "Missing mandatory 'arguments' parameter."; + } else { + tag = args->get("server-tag"); + if (!tag) { + message = "Missing mandatory 'server-tag' parameter."; + } else if (tag->getType() != Element::string) { + message = "'server-tag' parameter expected to be a string."; + } + } + + if (!message.empty()) { + // Something is amiss with arguments, return a failure response. + return (createAnswer(CONTROL_RESULT_ERROR, message)); + } + + CfgMgr::instance().getCurrentCfg()->setServerTag(tag->stringValue()); + CfgMgr::instance().getCurrentCfg()->addConfiguredGlobal("server-tag", tag); + message = "'server-tag' successfully updated."; + return (createAnswer(CONTROL_RESULT_SUCCESS, message)); +} + isc::data::ConstElementPtr ControlledDhcpv6Srv::processCommand(const std::string& command, isc::data::ConstElementPtr args) { @@ -593,7 +631,11 @@ ControlledDhcpv6Srv::processCommand(const std::string& command, } else if (command == "config-write") { return (srv->commandConfigWriteHandler(command, args)); + } else if (command == "server-tag-get") { + return (srv->commandServerTagGetHandler(command, args)); + } + // not yet server-tag-set return (isc::config::createAnswer(1, "Unrecognized command:" + command)); @@ -840,6 +882,11 @@ ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t server_port, CommandMgr::instance().registerCommand("leases-reclaim", boost::bind(&ControlledDhcpv6Srv::commandLeasesReclaimHandler, this, _1, _2)); + CommandMgr::instance().registerCommand("server-tag-get", + boost::bind(&ControlledDhcpv6Srv::commandServerTagGetHandler, this, _1, _2)); + + // not yet server-tag-set + CommandMgr::instance().registerCommand("libreload", boost::bind(&ControlledDhcpv6Srv::commandLibReloadHandler, this, _1, _2)); @@ -901,6 +948,8 @@ ControlledDhcpv6Srv::~ControlledDhcpv6Srv() { CommandMgr::instance().deregisterCommand("dhcp-enable"); CommandMgr::instance().deregisterCommand("leases-reclaim"); CommandMgr::instance().deregisterCommand("libreload"); + CommandMgr::instance().deregisterCommand("server-tag-get"); + // not yet server-tag-set CommandMgr::instance().deregisterCommand("shutdown"); CommandMgr::instance().deregisterCommand("statistic-get"); CommandMgr::instance().deregisterCommand("statistic-get-all"); diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.h b/src/bin/dhcp6/ctrl_dhcp6_srv.h index c859115aa6..2ef57278a5 100644 --- a/src/bin/dhcp6/ctrl_dhcp6_srv.h +++ b/src/bin/dhcp6/ctrl_dhcp6_srv.h @@ -291,6 +291,32 @@ private: commandLeasesReclaimHandler(const std::string& command, isc::data::ConstElementPtr args); + /// @brief Handler for processing 'server-tag-get' command + /// + /// This handler processes server-tag-get command, which retrieves + /// the current server tag and returns it in response. + /// + /// @param command (parameter ignored) + /// @param args { "server-tag": "" } argument map. + /// + /// @return status of the command + isc::data::ConstElementPtr + commandServerTagGetHandler(const std::string& command, + isc::data::ConstElementPtr args); + + /// @brief Handler for processing 'server-tag-set' command + /// + /// This handler processes server-tag-set command, which sets + /// the server tag to the specified value. + /// + /// @param command (parameter ignored) + /// @param args { "server-tag": "" } argument map. + /// + /// @return status of the command + isc::data::ConstElementPtr + commandServerTagSetHandler(const std::string& command, + isc::data::ConstElementPtr args); + /// @brief Reclaims expired IPv6 leases and reschedules timer. /// /// This is a wrapper method for @c AllocEngine::reclaimExpiredLeases6. diff --git a/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc index 7b1eb0e0ae..2169ef6477 100644 --- a/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc @@ -790,6 +790,8 @@ TEST_F(CtrlDhcpv6SrvTest, commandsRegistration) { EXPECT_TRUE(command_list.find("\"leases-reclaim\"") != string::npos); EXPECT_TRUE(command_list.find("\"libreload\"") != string::npos); EXPECT_TRUE(command_list.find("\"config-set\"") != string::npos); + EXPECT_TRUE(command_list.find("\"server-tag-get\"") != string::npos); + EXPECT_FALSE(command_list.find("\"server-tag-set\"") != string::npos); EXPECT_TRUE(command_list.find("\"shutdown\"") != string::npos); EXPECT_TRUE(command_list.find("\"statistic-get\"") != string::npos); EXPECT_TRUE(command_list.find("\"statistic-get-all\"") != string::npos); @@ -853,6 +855,39 @@ TEST_F(CtrlChannelDhcpv6SrvTest, getversion) { EXPECT_TRUE(response.find("GTEST_VERSION") != string::npos); } +// This test verifies that the DHCP server handles server-tag-get command +TEST_F(CtrlChannelDhcpv6SrvTest, serverTagGet) { + createUnixChannelServer(); + + std::string response; + std::string expected; + + // Send the server-tag-get command + sendUnixCommand("{ \"command\": \"server-tag-get\" }", response); + expected = "{ \"arguments\": { \"server-tag\": \"\" }, \"result\": 0 }"; + EXPECT_EQ(expected, response); + + // Set a value to the server tag + CfgMgr::instance().getCurrentCfg()->setServerTag("foobar"); + + // Retry... + sendUnixCommand("{ \"command\": \"server-tag-get\" }", response); + expected = "{ \"arguments\": { \"server-tag\": \"foobar\" }, \"result\": 0 }"; +} + +// This test verifies that the DHCP server does not handles server-tag-set command +TEST_F(CtrlChannelDhcpv6SrvTest, serverTagSet) { + createUnixChannelServer(); + + std::string response; + + // Send the server-tag-set command + sendUnixCommand("{ \"command\": \"server-tag-set\" }", response); + std::string expected = "{ \"result\": 2, " + "\"text\": \"'server-tag-set' command not supported.\" }"; + EXPECT_EQ(expected, response); +} + // This test verifies that the DHCP server immediately reclaims expired // leases on leases-reclaim command TEST_F(CtrlChannelDhcpv6SrvTest, controlLeasesReclaim) { @@ -1025,6 +1060,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, commandsList) { checkListCommands(rsp, "leases-reclaim"); checkListCommands(rsp, "libreload"); checkListCommands(rsp, "version-get"); + checkListCommands(rsp, "server-tag-get"); checkListCommands(rsp, "shutdown"); checkListCommands(rsp, "statistic-get"); checkListCommands(rsp, "statistic-get-all"); diff --git a/src/lib/process/d_controller.cc b/src/lib/process/d_controller.cc index df746080cd..23340f48ab 100644 --- a/src/lib/process/d_controller.cc +++ b/src/lib/process/d_controller.cc @@ -627,6 +627,40 @@ DControllerBase::configSetHandler(const std::string&, ConstElementPtr args) { } } +ConstElementPtr +DControllerBase::serverTagGetHandler(const std::string&, ConstElementPtr) { + const std::string& tag = process_->getCfgMgr()->getContext()->getServerTag(); + ElementPtr response = Element::createMap(); + response->set("server-tag", Element::create(tag)); + + return (createAnswer(COMMAND_SUCCESS, response)); +} + +ConstElementPtr +DControllerBase::serverTagSetHandler(const std::string&, ConstElementPtr args) { + std::string message; + ConstElementPtr tag; + if (!args) { + message = "Missing mandatory 'arguments' parameter."; + } else { + tag = args->get("server-tag"); + if (!tag) { + message = "Missing mandatory 'server-tag' parameter."; + } else if (tag->getType() != Element::string) { + message = "'server-tag' parameter expected to be a string."; + } + } + + if (!message.empty()) { + // Failure cases. + return (createAnswer(COMMAND_ERROR, message)); + } + + process_->getCfgMgr()->getContext()->setServerTag(tag->stringValue()); + message = "'server-tag' successfully updated."; + return (createAnswer(COMMAND_SUCCESS, message)); +} + ConstElementPtr DControllerBase::versionGetHandler(const std::string&, ConstElementPtr) { ConstElementPtr answer; diff --git a/src/lib/process/d_controller.h b/src/lib/process/d_controller.h index 339845f591..54e4303e34 100644 --- a/src/lib/process/d_controller.h +++ b/src/lib/process/d_controller.h @@ -307,7 +307,7 @@ public: /// @brief handler for config-set command /// - /// This method handles the config-set command, which checks + /// This method handles the config-set command, which loads /// configuration specified in args parameter. /// /// @param command (ignored) @@ -328,6 +328,30 @@ public: shutdownHandler(const std::string& command, isc::data::ConstElementPtr args); + /// @brief handler for server-tag-get command + /// + /// This method handles the server-tag-get command, which retrieves + /// the current server tag and returns it in response. + /// + /// @param command (ignored) + /// @param args (ignored) + /// @return current configuration wrapped in a response + isc::data::ConstElementPtr + serverTagGetHandler(const std::string& command, + isc::data::ConstElementPtr args); + + /// @brief handler for server-tag-set command + /// + /// This method handles the server-tag-set command, which sets + /// the server tag specified in args parameter. + /// + /// @param command (ignored) + /// @param args (ignored) + /// @return current configuration wrapped in a response + isc::data::ConstElementPtr + serverTagSetHandler(const std::string& command, + isc::data::ConstElementPtr args); + protected: /// @brief Virtual method that provides derivations the opportunity to /// support additional command line options. It is invoked during command diff --git a/src/lib/process/d_process.h b/src/lib/process/d_process.h index a408035a08..45b38b9d37 100644 --- a/src/lib/process/d_process.h +++ b/src/lib/process/d_process.h @@ -46,6 +46,12 @@ static const std::string CONFIG_RELOAD_COMMAND("config-reload"); /// @brief String value for the config-set command. static const std::string CONFIG_SET_COMMAND("config-set"); +/// @brief String value for the server-tag-get command. +static const std::string SERVER_TAG_GET_COMMAND("server-tag-get"); + +/// @brief String value for the server-tag-set command. +static const std::string SERVER_TAG_SET_COMMAND("server-tag-set"); + /// @brief String value for the shutdown command. static const std::string SHUT_DOWN_COMMAND("shutdown");