22 #include <boost/pointer_cast.hpp>
38 CtrlAgentCommandMgr::instance() {
43 CtrlAgentCommandMgr::CtrlAgentCommandMgr()
54 if (answer->getType() == Element::list) {
57 ElementPtr answer_list = Element::createList();
58 answer_list->add(boost::const_pointer_cast<Element>(answer));
72 if (original_cmd && original_cmd->contains(
"service")) {
73 services = original_cmd->get(
"service");
76 if (services->getType() != Element::list) {
85 if (services->empty()) {
100 (HookedCommandMgr::handleCommand(cmd_name, params, original_cmd));
112 std::ostringstream s;
113 s << text->stringValue();
114 s <<
" You did not include \"service\" parameter in the command,"
115 " which indicates that Kea Control Agent should process this"
116 " command rather than forward it to one or more Kea servers. If you"
117 " aimed to send this command to one of the Kea servers you"
118 " should include the \"service\" parameter in your request, e.g."
119 " \"service\": [ \"dhcp4\" ] to forward the command to the DHCPv4"
120 " server, or \"service\": [ \"dhcp4\", \"dhcp6\", \"d2\" ] to forward it to"
121 " DHCPv4, DHCPv6 and D2 servers etc.";
134 ElementPtr answer_list = Element::createList();
138 if (HookedCommandMgr::delegateCommandToHookLibrary(cmd_name, params, original_cmd,
141 return (answer_list);
146 answer_list = Element::createList();
149 for (
unsigned i = 0; i < services->size(); ++i) {
155 .arg(cmd_name).arg(services->get(i)->stringValue());
157 answer = forwardCommand(services->get(i)->stringValue(),
158 cmd_name, original_cmd);
163 .arg(cmd_name).arg(ex.
what());
167 answer_list->add(boost::const_pointer_cast<Element>(answer));
171 return (answer_list);
175 CtrlAgentCommandMgr::forwardCommand(
const std::string& service,
176 const std::string& cmd_name,
185 boost::shared_ptr<CtrlAgentController> controller =
192 ctx = cfgmgr->getCtrlAgentCfgContext();
200 isc_throw(CommandForwardingError,
"internal server error: unable to retrieve"
201 " Control Agent configuration information");
209 isc_throw(CommandForwardingError,
"forwarding socket is not configured"
210 " for the server type " << service);
215 std::string socket_name = socket_info->get(
"socket-name")->stringValue();
220 boost::system::error_code received_ec;
224 [&io_service, &received_ec, &received_feed]
228 received_feed = feed;
231 io_service->stopWork();
236 isc_throw(CommandForwardingError,
"unable to forward command to the "
237 << service <<
" service: " << received_ec.message()
238 <<
". The server is likely to be offline");
244 if (!received_feed) {
245 isc_throw(CommandForwardingError,
"internal server error: empty response"
246 " received from the unix domain socket");
251 answer = received_feed->toElement();
254 .arg(cmd_name).arg(service);
256 }
catch (
const std::exception& ex) {
257 isc_throw(CommandForwardingError,
"internal server error: unable to parse"
258 " server's answer to the forwarded message: " << ex.what());
const isc::log::MessageID CTRL_AGENT_COMMAND_FORWARD_BEGIN
Exception thrown when an error occurred during control command forwarding.
virtual isc::data::ConstElementPtr processCommand(const isc::data::ConstElementPtr &cmd)
Triggers command processing.
const isc::log::MessageID CTRL_AGENT_COMMAND_FORWARD_FAILED
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
ConstElementPtr createAnswer(const int status_code, const std::string &text, const ConstElementPtr &arg)
static process::DControllerBasePtr & instance()
Static singleton instance method.
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
boost::shared_ptr< Element > ElementPtr
boost::shared_ptr< CtrlAgentCfgMgr > CtrlAgentCfgMgrPtr
Defines a shared pointer to CtrlAgentCfgMgr.
Represents client side connection over the unix domain socket.
boost::shared_ptr< CtrlAgentProcess > CtrlAgentProcessPtr
Defines a shared pointer to CtrlAgentProcess.
The IOService class is a wrapper for the ASIO io_service class.
isc::log::Logger agent_logger("ctrl-agent")
Control Agent logger.
Command Manager which can delegate commands to a hook library.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
CtrlAgentProcessPtr getCtrlAgentProcess()
Returns pointer to an instance of the underlying process object.
Command Manager for Control Agent.
virtual isc::data::ConstElementPtr handleCommand(const std::string &cmd_name, const isc::data::ConstElementPtr ¶ms, const isc::data::ConstElementPtr &original_cmd)
Handles the command having a given name and arguments.
const char * CONTROL_TEXT
String used for storing textual description ("text")
Process Controller for Control Agent Process.
boost::shared_ptr< const Element > ConstElementPtr
constexpr long TIMEOUT_AGENT_FORWARD_COMMAND
Timeout for the Control Agent to forward command to a Kea server, e.g.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
ConstElementPtr parseAnswer(int &rcode, const ConstElementPtr &msg)
Defines the logger used by the top-level component of kea-dhcp-ddns.
boost::shared_ptr< const JSONFeed > ConstJSONFeedPtr
Pointer to the const JSONFeed.
const isc::log::MessageID CTRL_AGENT_COMMAND_FORWARDED
This file contains several functions and constants that are used for handling commands and responses ...
const int DBGLVL_COMMAND
This debug level is reserved for logging the exchange of messages/commands between processes...
The Element class represents a piece of data, used by the command channel and configuration parts...
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Encapsulates socket path.
boost::shared_ptr< CtrlAgentCfgContext > CtrlAgentCfgContextPtr
Pointer to a configuration context.
Encapsulates timeout value.
Encapsulates control command.
const int CONTROL_RESULT_COMMAND_UNSUPPORTED
Status code indicating that the specified command is not supported.