Browse Source

[master] Merge branch 'trac5175'

Marcin Siodelski 8 years ago
parent
commit
abf7887ad6

+ 7 - 1
doc/devel/mainpage.dox

@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-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
@@ -46,6 +46,7 @@
  * - @subpage hooksdgDevelopersGuide
  * - @subpage hooksdgDevelopersGuide
  * - @subpage dhcpv4Hooks
  * - @subpage dhcpv4Hooks
  * - @subpage dhcpv6Hooks
  * - @subpage dhcpv6Hooks
+ * - @subpage agentHooks
  * - @subpage hooksComponentDeveloperGuide
  * - @subpage hooksComponentDeveloperGuide
  * - @subpage hooksmgMaintenanceGuide
  * - @subpage hooksmgMaintenanceGuide
  * - @subpage libdhcp_user_chk
  * - @subpage libdhcp_user_chk
@@ -80,6 +81,11 @@
  *   - @subpage d2TransDetail
  *   - @subpage d2TransDetail
  *   - @subpage d2StateModel
  *   - @subpage d2StateModel
  *   - @subpage d2TransExecExample
  *   - @subpage d2TransExecExample
+ * - @subpage controlAgent
+ *   - @subpage ctrlAgentHttp
+ *   - @subpage ctrlAgentCreatingResponse
+ *   - @subpage ctrlAgentCommandMgr
+ *   - @subpage CtrlAgentSecurity
  * - @subpage lfc
  * - @subpage lfc
  *   - @subpage lfcProcessing
  *   - @subpage lfcProcessing
  *   - @subpage lfcFiles
  *   - @subpage lfcFiles

+ 1 - 1
doc/examples/agent/simple.json

@@ -6,7 +6,7 @@
 	// We need to specify where the agent should listen to incoming HTTP
 	// We need to specify where the agent should listen to incoming HTTP
 	// queries. Note that agent does not provide SSL or TLS protection
 	// queries. Note that agent does not provide SSL or TLS protection
 	// on its own, so limiting the traffic to localhost is a good idea.
 	// on its own, so limiting the traffic to localhost is a good idea.
-	"http-host": "localhost",
+	"http-host": "127.0.0.1",
 
 
 	// Another mandatory parameter is the HTTP port.
 	// Another mandatory parameter is the HTTP port.
 	"http-port": 8000,
 	"http-port": 8000,

+ 206 - 0
doc/guide/agent.xml

@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!ENTITY mdash  "&#x2017;" >
+]>
+
+<chapter id="kea-ctrl-agent">
+  <title>Kea Control Agent</title>
+
+  <section id="agent-overview">
+    <title>Overview</title>
+    <para>Kea Control Agent (CA) is a daemon, first included in Kea 1.2, which
+    exposes a RESTful control interface for managing Kea servers. The daemon
+    can receive control commands over HTTP and either forward these commands
+    to the respective Kea servers or handle these commands on its own. The
+    determination whether the command should be handled by the CA or forwarded
+    is made by checking the value of the 'service' parameter which may be
+    included in the command from the controlling client. The details of the
+    supported commands as well as their structures are provided in
+    <xref linkend="ctrl-channel"/>.</para>
+    <para>Hook libraries can be attached to the CA to provide support for
+    additional commands or custom behavior of existing commands. Such hook
+    libraries must implement callouts for 'control_command_receive' hook point.
+    Details about creating new hook libraries and supported hook points can be
+    found in
+    <ulink url="https://jenkins.isc.org/job/Kea_doc/doxygen/">Kea Developer's Guide</ulink>.
+    </para>
+
+    <para>
+      The CA processes received commands according to the following algorithm:
+      <itemizedlist>
+        <listitem>
+          <simpara>
+            Pass command into any installed hooks (regardless of service value(s)).
+            If the command is handled by a hook, return the response.
+          </simpara>
+        </listitem>
+
+        <listitem>
+          <simpara>
+            If the service specifies one more or services, the CA will forward the
+            command to specified services and return the accumulated responses.
+          </simpara>
+        </listitem>
+
+        <listitem>
+          <simpara>
+            If service is not specified or is an empty list, the CA will handle
+            the command if it supports it.
+          </simpara>
+        </listitem>
+
+      </itemizedlist>
+    </para>
+  </section>
+
+  <section id="agent-configuration">
+    <title>Configuration</title>
+    <para>The following example demonstrates the basic CA configuration.</para>
+    <para>
+<screen>
+{
+    "Control-agent": {
+        "http-host": "10.20.30.40",
+        "http-port": 8080,
+
+        "control-sockets": {
+            "dhcp4-server": {
+                "socket-type": "unix",
+                "socket-name": "/path/to/the/unix/socket-v4"
+            },
+            "dhcp6-server": {
+                "socket-type": "unix",
+                "socket-name": "/path/to/the/unix/socket-v4"
+            }
+        },
+
+        "hooks-libraries": [
+        {
+            "library": "/opt/local/control-agent-commands.so",
+            "parameters": {
+                "param1": "foo"
+            }
+        } ]
+    },
+
+    "Logging": {
+        "loggers": [ {
+            "name": "kea-ctrl-agent",
+            "severity": "INFO"
+        } ]
+    }
+}</screen>
+    </para>
+
+    <warning>
+      <simpara>
+        In the Kea 1.2 beta release the Control Agent configuration can't be
+        specified within the same configuration file as DHCPv4, DHCPv6 and D2
+        configuration. The default configuration file for the CA is installed
+        in the <filename>etc/kea/kea-ca.conf</filename>. In the Kea 1.2 final
+        release the CA configuration will be merged into the default
+        <filename>etc/kea/kea.conf.</filename>
+      </simpara>
+    </warning>
+
+    <para>
+      The <command>http-host</command> and <command>http-port</command>
+      specify an IP address and port to which HTTP service will be bound.
+      In case of the example configuration provided above, the RESTful
+      service will be available under the URL of
+      <command>http://10.20.30.40:8080/</command>. If these parameters
+      are not specified, the default URL is http://127.0.0.1:8000/
+    </para>
+
+    <para>
+      It has been mentioned in the <xref linkend="agent-overview"/> that
+      CA can forward received commands to the specific Kea servers for
+      processing. For example, <command>config-get</command> is sent to
+      retrieve configuration of one of the Kea services. When CA receives
+      this command, including a <command>service</command> parameter
+      indicating that the client desires to retrieve configuration of
+      the DHCPv4 server, the CA will forward this command to this server
+      and then pass the received response back to the client. More about
+      the <command>service</command> parameter and general structure of
+      the commands can be found in <xref linkend="ctrl-channel"/>.
+    </para>
+
+    <para>
+      The CA uses unix domain sockets to forward control commands and receive
+      responses from other Kea services. The <command>dhcp4-server</command>,
+      <command>dhcp6-server</command> and <command>d2-server</command> maps
+      specify the files to which unix domain sockets are bound. In case
+      of the configuration above, the CA will connect to the DHCPv4 server
+      via <filename>/path/to/the/unix/socket-v4</filename> to forward the
+      commands to it. Obviously, the DHCPv4 server must be configured to
+      listen to connections via this same socket. In other words, the command
+      socket configuration for the DHCPv4 server and CA (for this server)
+      must match. Consult the <xref linkend="dhcp4-ctrl-channel"/> and the
+      <xref linkend="dhcp6-ctrl-channel"/> to learn how the socket
+      configuration is specified for the DHCPv4 and DHCPv6 services.
+    </para>
+
+    <para>
+      Hooks libraries can be attached to the Control Agent just like to
+      DHCPv4 and DHCPv6 servers. It currently supports one hook point
+      'control_command_receive' which makes it possible to delegate
+      processing of some commands to the hooks library. The
+      <command>hooks-libraries</command> list contains the list of hooks
+      libraries that should be loaded by the CA, along with their configuration
+      information specified with <command>parameters</command>.
+    </para>
+
+    <para>
+      Please consult <xref linkend="logging"/> for the details how to
+      configure logging. The CA's root logger's name is
+      <command>kea-ctrl-agent</command> as given in the example above.
+    </para>
+  </section>
+
+  <section id="agent-secure-connection">
+    <title>Secure Connections</title>
+    <para>
+      Control Agent doesn't natively support secure HTTP connections like
+      SSL or TLS. In order to setup secure connection please use one
+      of the available third party HTTP servers and configure it to run
+      as a reverse proxy to the Control Agent.
+    </para>
+  </section>
+
+  <section id="agent-limitations">
+    <title>Control Agent Limitations</title>
+    <para>
+      Control Agent is a new component, first released in Kea 1.2 beta. In
+      this release it comes with two notable limitations:
+      <itemizedlist>
+        <listitem>
+          <simpara>
+            CA configuration must be specified in a separate configuration file
+            from the configurations of other components. The default confirguation
+            file for CA is located in <filename>etc/kea/kea-ca.conf</filename>.
+          </simpara>
+        </listitem>
+
+        <listitem>
+          <simpara>
+            keactrl hasn't been updated to manage the Control Agent (start, stop
+            reload). As a result, the CA must be started directly as described in
+            <xref linkend="agent-launch"/>
+          </simpara>
+        </listitem>
+      </itemizedlist>
+    </para>
+  </section>
+
+  <section id="agent-launch">
+    <title>Starting Control Agent</title>
+    <para>
+      The CA is started by running its binary and specifying the configuration file
+      it should use. For example:
+<screen>
+$ ./kea-ctrl-agent -c /usr/local/etc/kea/kea-ca.conf
+</screen>
+    </para>
+  </section>
+</chapter>

+ 168 - 20
doc/guide/ctrl-channel.xml

@@ -24,14 +24,40 @@
     Both servers can be instructed to open control sockets, which
     Both servers can be instructed to open control sockets, which
     is a communication channel. The server is able to receive
     is a communication channel. The server is able to receive
     commands on that channel, act on them and report back status.
     commands on that channel, act on them and report back status.
-    While the set of commands in Kea 1.1.0 is limited,
+    While the set of commands in Kea 1.2.0 is limited,
     the number is expected to grow over time.</para>
     the number is expected to grow over time.</para>
 
 
-    <para>Currently the only supported type of control channel
-    is UNIX stream socket. For details how to configure it, see
-    <xref linkend="dhcp4-ctrl-channel" /> and <xref
-    linkend="dhcp6-ctrl-channel" />. It is likely that support
-    for other control channel types will be added in the future.
+    <para>The DHCPv4 and DHCPv6 servers receive commands over the
+    unix domain sockets. The details how to configure these sockets,
+    see <xref linkend="dhcp4-ctrl-channel" /> and <xref
+    linkend="dhcp6-ctrl-channel" />. While it is possible control
+    the servers directly using unix domain sockets it requires that
+    the controlling client be running on the same machine as
+    the server. In order to connect remotely SSH is usually used to
+    connect to the controlled machine.</para>
+
+    <para>The network administrators usually prefer using some form
+    of a RESTful API to control the servers, rather than using unix
+    domain sockets directly. Therefore, as of Kea 1.2.0 release,
+    Kea includes a new component called Control Agent (or CA) which
+    exposes a RESTful API to the controlling clients and can forward
+    commands to the respective Kea services over the unix domain
+    sockets. The CA configuration has been described in
+    <xref linkend="agent-configuration"/>.</para>
+
+    <para>The HTTP requests received by the CA contain the control
+    commands encapsulated within HTTP requests. Simply speaking,
+    the CA is responsible for stripping the HTTP layer from the
+    received commands and forwarding the commands in a JSON format
+    over the unix domain sockets to respective services. Because the
+    CA receives commands for all services it requires additional
+    "forwarding" information to be included in the client's messages.
+    This "forwarding" information is carried within the
+    <command>service</command> parameter of the received command.
+    If the <command>service</command> parameter is not included or if
+    the parameter is a blank list the CA will assume that the control
+    command is targetted at the CA itself and will try to handle
+    it on its own.
     </para>
     </para>
 
 
     <section id="ctrl-channel-syntax">
     <section id="ctrl-channel-syntax">
@@ -44,6 +70,7 @@
 <screen>
 <screen>
 {
 {
     "command": "foo",
     "command": "foo",
+    "service": [ "dhcp4" ]
     "arguments": {
     "arguments": {
         "param1": "value1",
         "param1": "value1",
         "param2": "value2",
         "param2": "value2",
@@ -52,13 +79,86 @@
 }
 }
 </screen>
 </screen>
 
 
+    The same command sent over the RESTful interface to the CA will have
+    the following structure.
+
+<screen>
+    POST / HTTP/1.1\r\n
+    Content-Type: application/json\r\n
+    Content-Length: 147\r\n\r\n
+    {
+        "command": "foo",
+        "service": [ "dhcp4" ]
+        "arguments": {
+            "param1": "value1",
+            "param2": "value2",
+            ...
+        }
+    }
+</screen>
+
     <command>command</command> is the name of command to execute and
     <command>command</command> is the name of command to execute and
     is mandatory. <command>arguments</command> is a map of parameters
     is mandatory. <command>arguments</command> is a map of parameters
     required to carry out the given command.  The exact content and
     required to carry out the given command.  The exact content and
     format of the map is command specific.</para>
     format of the map is command specific.</para>
 
 
-    <para>The server will process the incoming command and then send a
-    response of the form:
+    <para>
+      <command>service</command> is a list of the servers at which the control
+      command is targetted. In the example above, the control command is
+      targetted at the DHCPv4 server. In most cases, the CA will simply forward this
+      command to the DHCPv4 server for processing via unix domain socket.
+      Sometimes, the command including a service value may also be processed by the
+      CA, if the CA is running a hooks library which handles such command for the
+      given server. As an example, the hooks library attached to the CA
+      may perform some operations on the database (like adding host reservations,
+      modifying leases etc.). An advantage of performing DHCPv4 specific
+      administrative operations in the CA rather than forwarding it to
+      the DHCPv4 server is the ability to perform these operations without
+      disrupting the DHCPv4 service (DHCPv4 server doesn't have to stop
+      processing DHCP messages to apply changes to the database). Nevetheless,
+      these situations are rather rare and, in most cases, when the
+      <command>service</command> parameter contains a name of the service
+      the commands are simply forwarded by the CA. The forwarded command
+      includes the <command>service</command> parameter but this parameter
+      is ignored by the receiving server. This parameter is only meaningful
+      to the CA.
+    </para>
+
+    <para>
+      If the command received by the CA does not include a <command>service</command>
+      parameter or this list is empty, the CA will simply process this message
+      on its own. For example, the <command>config-get</command> command which
+      doesn't include service parameter will return Control Agent's own
+      configuration. The <command>config-get</command> including a service
+      value "dhcp4" will be forwarded to the DHCPv4 server and will return
+      DHCPv4 server's configuration and so on.
+    </para>
+
+    <para>
+      The following list contains a mapping of the values carried within the
+      <command>service</command> parameter to the servers to which the commands
+      are forwarded:
+
+      <itemizedlist>
+        <listitem>
+          <simpara><command>dhcp4</command> - the command is forwarded to the
+          <command>kea-dhcp4</command> server,</simpara>
+        </listitem>
+
+        <listitem>
+          <simpara><command>dhcp6</command> - the command is forwarded to the
+          <command>kea-dhcp6</command> server,</simpara>
+        </listitem>
+
+        <listitem>
+          <simpara><command>d2</command> - the command is forwarded to the
+          <command>kea-d2</command> server.</simpara>
+        </listitem>
+      </itemizedlist>
+    </para>
+
+    <para>The server processing the incoming command will send a response of
+    the form:
 <screen>
 <screen>
 {
 {
     "result": 0|1,
     "result": 0|1,
@@ -79,23 +179,29 @@
     <command>arguments</command> is a map of additional data values returned by
     <command>arguments</command> is a map of additional data values returned by
     the server which is specific to the command issued. The map is always present, even
     the server which is specific to the command issued. The map is always present, even
     if it contains no data values.</para>
     if it contains no data values.</para>
+
+    <note>
+      <simpara>
+        When sending commands via Control Agent, it is possible to specify
+        multiple services at which the command is targetted. CA will forward this
+        command to each service individually. Thus, the CA response to the
+        controlling client will contain an array of individual responses.
+      </simpara>
+    </note>
+
     </section>
     </section>
 
 
     <section id="ctrl-channel-client">
     <section id="ctrl-channel-client">
     <title>Using the Control Channel</title>
     <title>Using the Control Channel</title>
 
 
-    <para>Kea does not currently provide a client for using the control channel.  The primary
-    reason for this is the expectation is that the entity using the control channel
-    is typically an IPAM or similar network management/monitoring software which
-    may have quite varied expectations regarding the client and is even likely to
-    be written in languages different than C or C++. Therefore only examples are provided to show
-    how one can take advantage of the API.</para>
-
-    <para>The easiest way is to use a tool called <command>socat</command>,
-    a tool available from <ulink url="http://www.dest-unreach.org/socat/">socat
-    homepage</ulink>, but it is also widely available in Linux and BSD
-    distributions. Once Kea is started, one could connect to the control
-    interface using the following command:
+    <para>Kea development team is actively working on providing client applications
+    which can be used to control the servers. These applications are, however, in the
+    early stages of development and as of Kea 1.2.0 release have certain limitatins.
+    The easiest way to start playing with the control API is to use common Unix/Linux tools
+    such as <command>socat</command> and <command>curl</command>.</para>
+
+    <para>In order to control the given Kea service via unix domain socket, use
+    <command>socat</command> as follows:
 <screen>
 <screen>
 $ socat UNIX:/path/to/the/kea/socket -
 $ socat UNIX:/path/to/the/kea/socket -
 </screen>
 </screen>
@@ -108,6 +214,16 @@ will be sent to Kea and the responses received from Kea printed to standard outp
     such a simplistic client written in C is available in the Kea Developer's
     such a simplistic client written in C is available in the Kea Developer's
     Guide, chapter Control Channel Overview, section Using Control Channel.</para>
     Guide, chapter Control Channel Overview, section Using Control Channel.</para>
 
 
+    <para>In order to use Kea's RESTful API with <command>curl</command> try the
+    following:
+<screen>
+$ curl -X POST -H "Content-Type: application/json" -d '{ "command": "config-get", "service": [ "dhcp4" ] }' http://ca.example.org:8000/
+</screen>
+
+    This assumes that the Control Agent is running on host
+    <filename>ca.example.org</filename> and runs RESTful service on port 8000.
+    </para>
+
     </section>
     </section>
 
 
     <section id="commands-common">
     <section id="commands-common">
@@ -404,4 +520,36 @@ will be sent to Kea and the responses received from Kea printed to standard outp
 
 
     </section> <!-- end of commands supported by both servers -->
     </section> <!-- end of commands supported by both servers -->
 
 
+    <section id="agent-commands">
+      <title>Commands Supported by Control Agent</title>
+      <para>The following commands listed in <xref linkend="commands-common"/>
+      are also supported by the Control Agent, i.e. when the
+      <command>service</command> parameter is blank the commands are handled
+      by the CA and they relate to the CA process itself:
+      <itemizedlist>
+        <listitem>
+          <simpara>build-report</simpara>
+        </listitem>
+        <listitem>
+          <simpara>config-get</simpara>
+        </listitem>
+        <listitem>
+          <simpara>config-test</simpara>
+        </listitem>
+        <listitem>
+          <simpara>config-write</simpara>
+        </listitem>
+        <listitem>
+          <simpara>list-commands</simpara>
+        </listitem>
+        <listitem>
+          <simpara>shutdown</simpara>
+        </listitem>
+        <listitem>
+          <simpara>version-get</simpara>
+        </listitem>
+      </itemizedlist>
+      </para>
+    </section>
+
   </chapter>
   </chapter>

+ 2 - 0
doc/guide/kea-guide.xml

@@ -64,6 +64,8 @@
 
 
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="keactrl.xml" />
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="keactrl.xml" />
 
 
+  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="agent.xml" />
+
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="dhcp4-srv.xml" />
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="dhcp4-srv.xml" />
 
 
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="dhcp6-srv.xml" />
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="dhcp6-srv.xml" />

+ 16 - 0
doc/guide/logging.xml

@@ -183,6 +183,22 @@
         <itemizedlist>
         <itemizedlist>
           <listitem>
           <listitem>
             <simpara>
             <simpara>
+              <command>kea-ctrl-agent</command> - the root logger for the
+              Control Agent exposing RESTful control API. All components used
+              by the Control Agent inherit the settings from this logger.
+            </simpara>
+          </listitem>
+
+          <listitem>
+            <simpara>
+              <command>kea-ctrl-agent.http</command> - a logger which outputs
+              log messages related to receiving, parsing and sending HTTP
+              messages.
+            </simpara>
+          </listitem>
+
+          <listitem>
+            <simpara>
               <command>kea-dhcp4</command> - the root logger for the DHCPv4
               <command>kea-dhcp4</command> - the root logger for the DHCPv4
               server. All components used by the DHCPv4 server inherit the
               server. All components used by the DHCPv4 server inherit the
               settings from this logger.
               settings from this logger.

+ 1 - 0
src/bin/agent/Makefile.am

@@ -14,6 +14,7 @@ CLEANFILES  = *.gcno *.gcda ca_messages.h ca_messages.cc s-messages
 man_MANS = kea-ctrl-agent.8
 man_MANS = kea-ctrl-agent.8
 DISTCLEANFILES = $(man_MANS)
 DISTCLEANFILES = $(man_MANS)
 EXTRA_DIST = $(man_MANS) kea-ctrl-agent.xml
 EXTRA_DIST = $(man_MANS) kea-ctrl-agent.xml
+EXTRA_DIST += agent.dox agent_hooks.dox
 
 
 if GENERATE_DOCS
 if GENERATE_DOCS
 kea-ctrl-agent.8: kea-ctrl-agent.xml
 kea-ctrl-agent.8: kea-ctrl-agent.xml

+ 128 - 0
src/bin/agent/agent.dox

@@ -0,0 +1,128 @@
+// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+//
+// 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
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+/**
+ @page controlAgent Control Agent Component
+
+Kea 1.2 release has introduced the Control Agent component (CA), which
+is started by the "kea-ctrl-agent" binary. The CA exposes a RESTful API
+which is used by the administrators to manage Kea servers' instances.
+
+In the most typical case, the CA forwards commands received over the
+RESTful API to the respective Kea servers, e.g. DHCPv4 server, DHCPv6
+server etc. The communication between the CA and other servers is
+established with the use of unix domain sockets. This is possible because
+the CA is running on the same system as other Kea services to which
+messages are forwarded.
+
+The CA can forward the same command to multiple Kea services and return
+an aggregated response (from all services) over the RESTful API. The
+"service" parameter included in the client's command can contain one
+or more services at which the command is targeted. The CA will
+iterate over this list and forward the command to each of them
+individually.
+
+In some cases, the commands containing the "service" value can be handled
+directly by the CA. This is usually the case when the CA is running
+with hooks libraries attached. The hooks libraries must implement
+callouts for the "control_command_receive" hook point, which will be
+invoked by the CA when the command is received. If the hooks libraries
+set the 'skip' status, it is an indication to the CA that the command
+has been processed by the CA and that it should return the response created
+by the hooks libraries to the client. An example of the hooks library attached
+to the CA and handling the commands for other services is a library which
+stores or retrieves some data from the SQL database.
+
+The "service" parameter is optional. If it is not included in the command
+(or it is an empty list), this indicates that the command relates to the
+CA and that the CA should handle it, e.g. return its own configuration in
+response to a "config-get" command.
+
+@section ctrlAgentHttp Receiving commands over HTTP
+
+Control Agent uses libkea-http library to establish HTTP connections,
+receive messages and send responses over HTTP. This library uses boost ASIO
+for creating TCP connections and asynchronously receive and send the data
+over the sockets.
+
+The @ref isc::http::HttpListener provides an entry point to this library.
+It is used by the CA to bind the acceptor to the specific address and
+port. When the client connects to this address and port, the acceptor's
+callback function is invoked which opens a new connection and starts
+receiving data over that socket. The @ref isc::http::HttpConnection
+implements the logic to read and parse received data. Each new TCP
+connection is associated with unique instance of the @ref isc::http::HttpConnection
+When a portion of data is received (asynchronously) over
+the socket it is provided to the instance of the
+@ref isc::http::HttpRequestParser object (unique per connection) and
+data parsing is continued until the parser runs out of data or until
+the entire HTTP request has been received. The
+@ref isc::http::HttpRequestParser signals these events using the
+@ref isc::http::HttpRequestParser::needData and
+@ref isc::http::HttpRequestParser::httpParseOk respectively.
+
+libkea-http is designed to handle processing messages carrying different
+content types. The Control Agent uses "application/json" content
+type which describes messages with JSON structures carried within the
+message body. The JSON structures represent commands sent to the Kea
+server(s) by controlling clients. libkea-http provides generic classes
+(derived from @ref isc::http::HttpRequest) which facilitate validation of
+messages holding various content types.
+CA uses @ref isc::http::PostHttpRequestJson, which encapsulate messages
+sent using HTTP POST and including JSON content, to represent received messages.
+
+@section ctrlAgentCreatingResponse Creating HTTP responses
+
+The @ref isc::http::HttpResponseCreatorFactory is an interface which should
+be implemented by components using libkea-http to generate instances of
+the HTTP responses of a desired type. The instance of the factory class is
+provided to the @ref isc::http::HttpListener via its constructor. The listener
+calls an implementation of the
+@ref isc::http::HttpResponseCreatorFactory::create when a new HTTP
+message has been received and parsed.
+
+The CA component includes the @ref isc::agent::CtrlAgentResponseCreatorFactory
+class. Its @c create() method implementation returns
+an instance of the @ref isc::agent::CtrlAgentResponseCreator, which is a
+derivation of the @ref isc::http::HttpResponseCreator. This creator creates
+instances of the @ref isc::http::HttpResponseJson, holding responses to
+the commands in the JSON format.
+
+@section ctrlAgentCommandMgr Handling commands with Command Manager
+
+The @ref isc::agent::CtrlAgentCommandMgr is a derivation of the
+@ref isc::config::HookedCommandMgr which adds the capability to forward
+commands received over HTTP to specific Kea servers. The
+@ref isc::agent::CtrlAgentCommandMgr forwards commands over a Unix domain
+socket, using @ref isc::asiolink::UnixDomainSocket class. All responses
+to a particular command (possibly received from multiple Kea servers) are
+aggregated within a JSON list and sent back to the controlling client over
+HTTP.
+
+In some cases the responses may be generated locally (without forwarding).
+Typically, the command will be generated by the CA when the command sent
+by the client lacks the "service" parameter, which indicates that the
+command is targeted at the CA itself. In some cases the commands can also
+be processed by the hooks libraries attached to the CA.
+
+@section CtrlAgentSecurity Security considerations
+
+The Control Agent doesn't provide any mechanisms to secure the communication
+over the RESTful API. In the design of the CA we have considered including built-in
+HTTPS solutions (HTTP + TLS), making use of crypto libraries supported by Kea.
+It was eventually decided to not implement the secure layer within Kea for the following reasons:
+- additional code complexity which requires maintenance, bug fixing and
+  monitoring for security vulnerabilities in the OpenSSL/Botan code,
+- OpenSSL/Botan code may be awkward to use and it is likely we wouldn't
+  implement it right,
+- need to support two crypto backends: OpenSSL and Botan which puts significant
+  burden on Kea maintenance.
+
+In the installations where securing command channel is critical (most of the
+installations?), a reverse HTTP proxy can be setup using one of the third
+party HTTP server implementations, e.g. Apache, nginx etc.
+
+*/

+ 58 - 0
src/bin/agent/agent_hooks.dox

@@ -0,0 +1,58 @@
+// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+//
+// 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
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+/**
+@page agentHooks The Hooks API for the Control Agent
+
+@section agentHooksIntroduction Introduction
+The Kea Control Agent features "Hooks" API that allows the user-written
+code to be integrated with the Control Agent and handle some
+of the control commands. The hooks library can be either used to provide
+support for the new commands (not supported natively by the Control Agent)
+or "override" implementation of the existing handlers. The hooks library
+signals to the Control Agent that it has processed the given command by
+setting "next step status" value to SKIP.
+
+The hooks library can also be used to perform some additional tasks
+related to reception of the control command instead of handling it, e.g.
+logging or notifying some external service about reception of the
+command.
+
+@section agentHooksHookPoints Hooks in the Control Agent
+
+ @subsection agentHooksControlCommandReceive control_command_receive
+
+ - @b Arguments:
+   - name: @b command, type: isc::data::ConstElementPtr, direction: <b>in/out</b>
+   - name: @b response, type: isc::data::ConstElementPtr, direction: <b>in/out</b>
+
+ - @b Description: this callout is executed when Control Agent receives a
+   control command over the RESTful interface (HTTP).
+   The "command" argument is a pointer to the parsed JSON structure
+   including command name and command arguments. If the callout implements
+   the specified command, it handles the command and creates appropriate
+   response. The response should be returned in the "response" argument.
+   In most cases, the callout which handles the command will set the next
+   step action to SKIP, to prevent the server from trying to handle the
+   command on its own and overriding the response created by the callouts.
+   A notable exception is the 'list-commands' command for which the callouts
+   should not set the next step action to SKIP. The server has a special
+   code path for this command which combines the list of commands returned
+   by the callouts with the list of commands supported by the server. If
+   the callout sets the next step action to SKIP in this case, the server
+   will only return the list of commands supported by the hook library.
+   The callout can modify the command arguments to influence the command
+   processing by the Command Manager. For example, it may freely modify
+   the configuration received in 'set-config' before it is processed by
+   the server. The SKIP action is not set in this case.
+
+ - <b>Next step status</b>: if any callout sets the next step action to SKIP,
+   the server will assume that the command has been handled by the callouts
+   and will expect that the response is provided in the "response" argument.
+   The Control Agent will not handle the command in this case but simply
+   return the response returned by the callout to the caller.
+
+*/

+ 1 - 0
src/bin/keactrl/.gitignore

@@ -1,4 +1,5 @@
 /keactrl
 /keactrl
 /kea.conf
 /kea.conf
+/kea-ca.conf
 /keactrl.conf
 /keactrl.conf
 /keactrl.8
 /keactrl.8

+ 10 - 6
src/bin/keactrl/Makefile.am

@@ -5,16 +5,16 @@ SUBDIRS = . tests
 # If the default location needs to be changed it may be achieved by
 # If the default location needs to be changed it may be achieved by
 # setting KEACTRL_CONF environment variable.
 # setting KEACTRL_CONF environment variable.
 sbin_SCRIPTS  = keactrl
 sbin_SCRIPTS  = keactrl
-CONFIGFILES = keactrl.conf kea.conf
+CONFIGFILES = keactrl.conf kea.conf kea-ca.conf
 
 
 man_MANS = keactrl.8
 man_MANS = keactrl.8
 DISTCLEANFILES = keactrl keactrl.conf $(man_MANS)
 DISTCLEANFILES = keactrl keactrl.conf $(man_MANS)
-CLEANFILES = kea.conf
-EXTRA_DIST = keactrl.in keactrl.conf.in kea.conf.pre $(man_MANS) keactrl.xml
+CLEANFILES = kea.conf kea-ca.conf
+EXTRA_DIST = keactrl.in keactrl.conf.in kea.conf.pre kea-ca.conf.pre $(man_MANS) keactrl.xml
 
 
-# kea.conf is not really a source used for building other targets, but we need
-# this file to be generated before make install is called.
-BUILT_SOURCES = kea.conf
+# kea.conf and kea-ca.conf are not really sources used for building other targets, but we need
+# these files to be generated before make install is called.
+BUILT_SOURCES = kea.conf kea-ca.conf
 
 
 if GENERATE_DOCS
 if GENERATE_DOCS
 
 
@@ -32,6 +32,10 @@ endif
 kea.conf: kea.conf.pre
 kea.conf: kea.conf.pre
 	$(top_builddir)/tools/path_replacer.sh $(top_srcdir)/src/bin/keactrl/kea.conf.pre $@
 	$(top_builddir)/tools/path_replacer.sh $(top_srcdir)/src/bin/keactrl/kea.conf.pre $@
 
 
+kea-ca.conf: kea-ca.conf.pre
+	$(top_builddir)/tools/path_replacer.sh $(top_srcdir)/src/bin/keactrl/kea-ca.conf.pre $@
+
+
 if INSTALL_CONFIGURATIONS
 if INSTALL_CONFIGURATIONS
 
 
 install-data-local:
 install-data-local:

+ 44 - 0
src/bin/keactrl/kea-ca.conf.pre

@@ -0,0 +1,44 @@
+// This is a basic configuraton for the Kea Control Agent.
+{
+    // RESTful interface to be available at http://127.0.0.1:8080/
+    "Control-agent": {
+        "http-host": "127.0.0.1",
+        "http-port": 8080,
+
+        // Specify location of the files to which the Control Agent
+        // should connect to forward commands to the DHCPv4 and DHCPv6
+        // server via unix domain socket.
+        "control-sockets": {
+            "dhcp4-server": {
+                "socket-type": "unix",
+                "socket-name": "/tmp/kea-ctrl-dhcp4.sock"
+            },
+            "dhcp6-server": {
+                "socket-type": "unix",
+                "socket-name": "/tmp/kea-ctrl-dhcp6.sock"
+            }
+        },
+
+       // Specify hooks libraries that are attached to the Control Agent.
+       // Such hooks libraries should support 'control_command_receive'
+       // hook point. This is currently commented out because it has to
+       // point to the existing hooks library. Otherwise the Control
+       // Agent will fail to start.
+        "hooks-libraries": [
+//      {
+//          "library": "/opt/local/control-agent-commands.so",
+//          "parameters": {
+//              "param1": "foo"
+//          }
+//      }
+        ]
+    },
+
+    // Basic logging configuration for the Control Agent.
+    "Logging": {
+        "loggers": [ {
+            "name": "kea-ctrl-agent",
+            "severity": "INFO"
+        } ]
+    }
+}