Kea  1.9.9-git
hooked_command_mgr.cc
Go to the documentation of this file.
1 // Copyright (C) 2017-2018 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 
11 #include <config/config_log.h>
12 #include <hooks/callout_handle.h>
13 #include <hooks/hooks_manager.h>
14 #include <hooks/server_hooks.h>
15 #include <boost/pointer_cast.hpp>
16 #include <vector>
17 
18 using namespace isc::data;
19 using namespace isc::hooks;
20 
21 namespace isc {
22 namespace config {
23 
24 HookedCommandMgr::HookedCommandMgr()
25  : BaseCommandMgr() {
26 }
27 
28 bool
30  const ConstElementPtr& params,
31  const ConstElementPtr& original_cmd,
32  ElementPtr& answer) {
33 
34  ConstElementPtr hook_response;
35  if (HooksManager::commandHandlersPresent(cmd_name)) {
36 
37  CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
38 
39  // Set status to normal.
40  callout_handle->setStatus(CalloutHandle::NEXT_STEP_CONTINUE);
41 
42  // Delete previously set arguments.
43  callout_handle->deleteAllArguments();
44 
45  ConstElementPtr command = original_cmd ? original_cmd :
46  createCommand(cmd_name, params);
47 
48  // And pass it to the hook library.
49  callout_handle->setArgument("command", command);
50  callout_handle->setArgument("response", hook_response);
51 
52  HooksManager::callCommandHandlers(cmd_name, *callout_handle);
53 
54  // The callouts should set the response.
55  callout_handle->getArgument("response", hook_response);
56 
57  answer = boost::const_pointer_cast<Element>(hook_response);
58 
59  return (true);
60  }
61 
62  return (false);
63 }
64 
66 HookedCommandMgr::handleCommand(const std::string& cmd_name,
67  const ConstElementPtr& params,
68  const ConstElementPtr& original_cmd) {
69 
70  // The 'list-commands' is a special case. Hook libraries do not implement
71  // this command. We determine what commands are supported by the hook
72  // libraries by checking what hook points are present that have callouts
73  // registered.
74  if ((cmd_name != "list-commands")) {
75  ElementPtr hook_response;
76  // Check if there are any hooks libraries to process this command.
77  if (delegateCommandToHookLibrary(cmd_name, params, original_cmd,
78  hook_response)) {
79  // Hooks libraries processed this command so simply return a
80  // result.
81  return (hook_response);
82  }
83 
84  }
85 
86  // If we're here it means that the callouts weren't called. We need
87  // to handle the command using local Command Mananger.
89  params,
90  original_cmd);
91 
92  // If we're processing 'list-commands' command we may need to include
93  // commands supported by hooks libraries in the response.
94  if (cmd_name == "list-commands") {
95  // Hooks names can be used to decode what commands are supported.
96  const std::vector<std::string>& hooks =
97  ServerHooks::getServerHooksPtr()->getHookNames();
98 
99  // Only update the response if there are any hooks present.
100  if (!hooks.empty()) {
101  ElementPtr hooks_commands = Element::createList();
102  for (auto h = hooks.cbegin(); h != hooks.end(); ++h) {
103  // Try to convert hook name to command name. If non-empty
104  // string is returned it means that the hook point may have
105  // command handlers associated with it. Otherwise, it means that
106  // existing hook points are not for command handlers but for
107  // regular callouts.
108  std::string command_name = ServerHooks::hookToCommandName(*h);
109  if (!command_name.empty()) {
110  // Final check: are command handlers registered for this
111  // hook point? If there are no command handlers associated,
112  // it means that the hook library was already unloaded.
113  if (HooksManager::commandHandlersPresent(command_name)) {
114  hooks_commands->add(Element::create(command_name));
115  }
116  }
117  }
118 
119  // If there is at least one hook point with command handlers
120  // registered
121  // for it, combine the lists of commands.
122  if (!hooks_commands->empty()) {
123  response = combineCommandsLists(response, createAnswer(0, hooks_commands));
124  }
125  }
126  }
127 
128  return (response);
129 }
130 
131 
132 } // end of namespace isc::config
133 } // end of namespace isc
ConstElementPtr createAnswer(const int status_code, const std::string &text, const ConstElementPtr &arg)
virtual isc::data::ConstElementPtr handleCommand(const std::string &cmd_name, const isc::data::ConstElementPtr &params, const isc::data::ConstElementPtr &original_cmd)
Handles the command having a given name and arguments.
boost::shared_ptr< Element > ElementPtr
Definition: data.h:20
ConstElementPtr createCommand(const std::string &command)
Creates a standard command message with no argument (of the form { "command": "my_command" }) ...
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:23
Commands Manager, responsible for processing external commands.
bool delegateCommandToHookLibrary(const std::string &cmd_name, const isc::data::ConstElementPtr &params, const isc::data::ConstElementPtr &original_cmd, isc::data::ElementPtr &answer)
Handles the command within the hooks libraries.
Defines the logger used by the top-level component of kea-dhcp-ddns.
boost::shared_ptr< CalloutHandle > CalloutHandlePtr
A shared pointer to a CalloutHandle object.
This file contains several functions and constants that are used for handling commands and responses ...
virtual isc::data::ConstElementPtr handleCommand(const std::string &cmd_name, const isc::data::ConstElementPtr &params, const isc::data::ConstElementPtr &original_cmd)
Handles the command having a given name and arguments.
ConstElementPtr combineCommandsLists(const ConstElementPtr &response1, const ConstElementPtr &response2)
The Element class represents a piece of data, used by the command channel and configuration parts...
Definition: data.h:66