From: Marcin Siodelski Date: Thu, 12 Oct 2017 13:55:29 +0000 (+0200) Subject: [5331] Extended hooks developer guide with section about control commands. X-Git-Tag: trac5389_base~5^2~1 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=30b20b89af33546f2fd99b166ffced6bff95fb81;p=thirdparty%2Fkea.git [5331] Extended hooks developer guide with section about control commands. --- diff --git a/src/bin/dhcp4/dhcp4_hooks.dox b/src/bin/dhcp4/dhcp4_hooks.dox index e59f1f3b3d..9c87a66c2d 100644 --- a/src/bin/dhcp4/dhcp4_hooks.dox +++ b/src/bin/dhcp4/dhcp4_hooks.dox @@ -11,8 +11,10 @@ Kea features an API (the "Hooks" API) that allows user-written code to be integrated into Kea and called at specific points in its processing. An overview of the API and a tutorial for writing such code can be found in - the @ref hooksdgDevelopersGuide. Information for Kea maintainers can be - found in the @ref hooksComponentDeveloperGuide. + the @ref hooksdgDevelopersGuide. It also includes information how hooks + framework can be used to implement additional control commands for the + DHCPv4 server. Information for Kea maintainers can be found in the + @ref hooksComponentDeveloperGuide. This manual is more specialized and is aimed at developers of hook code for the DHCPv4 server. It describes each hook point, what the callouts diff --git a/src/bin/dhcp6/dhcp6_hooks.dox b/src/bin/dhcp6/dhcp6_hooks.dox index 1b0e19e7f4..6dc1fde806 100644 --- a/src/bin/dhcp6/dhcp6_hooks.dox +++ b/src/bin/dhcp6/dhcp6_hooks.dox @@ -11,8 +11,10 @@ Kea features an API (the "Hooks" API) that allows user-written code to be integrated into Kea and called at specific points in its processing. An overview of the API and a tutorial for writing such code can be found in - the @ref hooksdgDevelopersGuide. Information for Kea maintainers can be - found in the @ref hooksComponentDeveloperGuide. + the @ref hooksdgDevelopersGuide. It also includes information how hooks + framework can be used to implement additional control commands for the + DHCPv6 server. Information for Kea maintainers can be found in the + @ref hooksComponentDeveloperGuide. This manual is more specialized and is aimed at developers of hook code for the DHCPv6 server. It describes each hook point, what the callouts diff --git a/src/lib/config/command-socket.dox b/src/lib/config/command-socket.dox index bbe94e83c9..4c3a23f051 100644 --- a/src/lib/config/command-socket.dox +++ b/src/lib/config/command-socket.dox @@ -158,6 +158,11 @@ or HTTPS connection): - @ref isc::config::CommandMgr::closeCommandSocket() - it is used to close the socket. +Kea servers use @c CommandMgr to register handlers for various commands they +support natively. However, it is possible extend a set of supported commands +using hooks framework. See @ref hooksdgCommandHandlers how to implement support +for your own control commands in Kea. + @section ctrlSocketConnections Accepting connections The @ref isc::config::CommandMgr is implemented using boost ASIO and uses diff --git a/src/lib/hooks/hooks_user.dox b/src/lib/hooks/hooks_user.dox index 0ac119ffc3..d4607aeb32 100644 --- a/src/lib/hooks/hooks_user.dox +++ b/src/lib/hooks/hooks_user.dox @@ -1020,6 +1020,94 @@ It is possible for a library to contain callouts with both standard and non-standard names: ones with standard names will be registered automatically, ones with non-standard names need to be registered manually. +@subsubsection hooksdgCommandHandlers Using Callouts as Command handlers + +Kea servers natively support a set of control commands to retrieve and update +runtime information, e.g. server configuration, basic statistics etc. In +many cases, however, DHCP deployments require support for additional commands +or the natively supported commands don't exactly fulfil one's requirements. + +Taking advantage of Kea's modularity and hooks framework, it is now possible +to easily extend the pool of supported commands by implementing additional +(non-standard) commands within hook libraries. + +A hook library needs to register command handlers for control commands within +its @c load function as follows: + +@code +int load(LibraryHandle& handle) { + handle.registerCommandCallout("diagnostics-enable", diagnostics_enable); + handle.registerCommandCallout("diagnostics-dump", diagnostics_dump); + return (0); +} +@endcode + +Internally, the @c LibraryHandle associates command handlers @c diagnostics_enable +and @c diagnostics_dump with dedicated hook points. These hook points are +given names after the command names, i.e. "$diagnostics_enable" and +"$diagnostics_dump". The dollar sign before the hook point name indicates +that the hook point is dedicated for a command handler, i.e. is not one of +the standard hook points used by the Kea servers. This is just a naming convention, +usually invisible to the hook library implementation and is mainly aimed at +minimizing a risk of collision between names of the hook points registered with +command handlers and standard hook points. + +Once the hook library is loaded and the command handlers supported by the +library are registered, the Kea servers will be able to recognize that those +specific commands are supported and will dispatch commands with the corresponding +names to the hook library (or multiple hook libraries) for processing. See the +documentation of the @ref isc::config::HookedCommandMgr for more details how +it uses @c HooksManager::commandHandlersPresent to determine if the received +command should be dispatched to a hook library for processing. + +The @c diagnostics_enable and @c diagnostics_dump command +handlers must be implemented within the hook library in analogous way to +regular callouts: + +@code +int diagnostics_enable(CalloutHandle& handle) { + ConstElementPtr response; + + try { + ConstElementPtr command; + handle.getArgument("command", command); + ConstElementPtr args; + static_cast(isc::config::parseCommand(args, command)); + + // ... + // handle command here. + // ... + + response = createAnswer(CONTROL_RESULT_SUCCESS, "successful"); + + } catch (const std::exception& ex) { + response = createAnswer(CONTROL_RESULT_ERROR, ex.what()); + } + + handle.setArgument("response", response); + + return (0); +} +@endcode + +The sample code above retrieves the "command" argument which is always provided. +It represents the control command as sent by the controlling client. It includes +command name and command specific arguments. The generic @ref isc::config::parseCommand +can be used to retrieve arguments included in the command. The callout then interprets +these arguments, takes appropriate action and creates a response to the client. +Care should be taken to catch any non-fatal exceptions that may arise during the callout +that should be reported as a failure to the controlling client. In such case, the response +with @c CONTROL_RESULT_ERROR is returned and the callout should return the value of 0. +The non-zero result should only be returned by the callout in case of fatal errors, i.e. +errors which result in inability to generate a response to the client. If the response +is generated, the command handler must set it as "response" argument prior to return. + +It is uncommon but valid scenario to have multiple hook libraries providing command +handlers for the same command. They are invoked sequentially and each of them +can freely modify a response set by a previous callout. This includes entirely +replacing the response provided by previous callouts, if neccessary. + + @subsubsection hooksdgMultipleCallouts Multiple Callouts on a Hook The Kea hooks framework allows multiple callouts to be attached to