1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
|
<!--
- Copyright (C) 2015-2019 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/.
-->
<!-- Converted by db4-upgrade version 1.1 -->
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="ctrl-channel">
<title>Management API</title>
<para>A classic approach to daemon configuration assumes that
the server's configuration is stored in configuration files
and, when the configuration is changed, the daemon is restarted.
This approach has the significant disadvantage of introducing periods
of downtime when client traffic is not handled. Another risk
is that if the new configuration is invalid for any reason,
the server may refuse to start, which will further extend the
downtime period until the issue is resolved.</para>
<para>To avoid such problems, the DHCPv4, DHCPv6 and D2 servers in Kea
include support for a mechanism that allows
online reconfiguration without requiring server shutdown.
Both servers can be instructed to open control sockets, which
is a communications channel. The server is able to receive
commands on that channel, act on them, and report back status.</para>
<para>The DHCPv4, DHCPv6 and D2 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 to control
the servers directly using unix domain sockets it requires that
the controlling client be running on the same machine as
the server. SSH is usually used to
connect remotely to the controlled machine.</para>
<para>Network administrators usually prefer using some form
of a RESTful API to control the servers, rather than using UNIX
domain sockets directly. Therefore,
Kea includes a 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 the 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 targeted at the CA itself and will try to handle
it on its own.
</para>
<para>Control connections over both HTTP and UNIX domain sockets are
guarded with timeouts. The default timeout value is set to 10s
and is not configurable.
</para>
<section xml:id="ctrl-channel-syntax">
<title>Data Syntax</title>
<para>Communication over the control channel is conducted using JSON
structures. If configured, Kea will open a socket and listen
for incoming connections. A process connecting to this socket
is expected to send JSON commands structured as follows:
<screen>
{
"command": "foo",
"service": [ "dhcp4" ]
"arguments": {
"param1": "value1",
"param2": "value2",
...
}
}
</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 the command to execute and
is mandatory. <command>arguments</command> is a map of parameters
required to carry out the given command. The exact content and
format of the map is command-specific.</para>
<para>
<command>service</command> is a list of the servers at which the control
command is targeted. In the example above, the control command is
targeted at the DHCPv4 server. In most cases, the CA will simply forward this
command to the DHCPv4 server for processing via a 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 a command for the
given server. As an example, the hooks library loaded by the CA
may perform some operations on the database, such as 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, since the DHCPv4 server doesn't have to stop
processing DHCP messages to apply changes to the database. Nevertheless,
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 simply processes this message
on its own. For example, a <command>config-get</command> command which
includes no service parameter returns the Control Agent's own
configuration. The <command>config-get</command> with a service
value "dhcp4" is forwarded to the DHCPv4 server and returns the
DHCPv4 server's configuration.
</para>
<para>
The following list shows the 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>
{
"result": 0|1|2|3,
"text": "textual description",
"arguments": {
"argument1": "value1",
"argument2": "value2",
...
}
}
</screen>
<command>result</command> indicates the outcome of the command. A value of 0
means success, while any non-zero value designates an error or a
failure to complete the requested action. Currently 1 indicates a generic
error, 2 means that a command is not supported, and 3 means that the
requested operation was completed, but the requested object was not
found. For example, a well-formed
command that requests a subnet that exists in a server's configuration
returns the result 0. If the server encounters an error condition, it
returns 1. If the command asks for the IPv6 subnet, but was sent to a DHCPv4
server, it returns 2. If the query asks for a subnet-id and there
is no subnet with such an id, the result is 3.</para>
<para>
The <command>text</command> field typically appears when the result is non-zero
and contains a description of the error encountered, but it often also appears
for successful outcomes. The exact text is command-specific, but in general
uses plain English to describe the outcome of the command.
<command>arguments</command> is a map of additional data values
returned by the server which are specific to the command issued. The map
may be present, but that depends on the specific command.
</para>
<note>
<simpara>
When sending commands via Control Agent, it is possible to specify
multiple services at which the command is targeted. CA forwards this
command to each service individually. Thus, the CA response to the
controlling client contains an array of individual responses.
</simpara>
</note>
</section>
<section xml:id="ctrl-channel-client">
<title>Using the Control Channel</title>
<para>The easiest way to start interacting 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> in interactive mode as follows:
<screen>
$ socat UNIX:/path/to/the/kea/socket -
</screen>
or in batch mode, include the "ignoreeof" option as shown below to ensure
socat waits long enough for the server to respond:
<screen>
$ echo "{ some command...}" | socat UNIX:/path/to/the/kea/socket -,ignoreeof
</screen>
where <command>/path/to/the/kea/socket</command> is the path specified in the
<command>Dhcp4/control-socket/socket-name</command> parameter in the Kea
configuration file. Text passed to <command>socat</command>
is sent to Kea and the responses received from Kea are printed to standard
output. This approach communicates with the specific server directly and
bypasses the Control Agent.</para>
<para>It is also easy to open a UNIX socket programmatically. An example of
a simple client written in C is available in the Kea Developer's
Guide, in the Control Channel Overview chapter, in the Using Control Channel section.</para>
<para>To use Kea's RESTful API with <command>curl</command>, you may
use 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 is running the RESTful service on port 8000.
</para>
</section>
<section xml:id="commands-common">
<title>Commands Supported by Both the DHCPv4 and DHCPv6 Servers</title>
<section xml:id="command-build-report">
<title>build-report</title>
<para>
The <emphasis>build-report</emphasis> command returns
on the control channel what the command line
<command>-W</command> argument displays, i.e. the embedded
content of the <filename>config.report</filename> file.
This command does not take any parameters.
</para>
<screen>
{
"command": "build-report"
}
</screen>
</section> <!-- end of command-build-report -->
<section xml:id="command-config-get">
<title>config-get</title>
<para>The <emphasis>config-get</emphasis> command retrieves the current
configuration used by the server. This command does not take any
parameters. The configuration returned is roughly equal to the
configuration that was loaded using the -c command line option during server
start-up or later set using config-set command. However, there may be
certain differences, as comments are not retained. If the original
configuration used file inclusion, the returned configuration will
include all parameters from all the included files.</para>
<para> Note that the returned configuration is not redacted, i.e. it will
contain database passwords in plain text if those were specified in the
original configuration. Care should be taken not to expose the command
channel to unprivileged users.</para>
<para>
An example command invocation looks like this:
<screen>
{
"command": "config-get"
}
</screen>
</para>
</section> <!-- end of command-config-get -->
<section xml:id="command-config-reload">
<title>config-reload</title>
<para>The <emphasis>config-reload</emphasis> command instructs
Kea to load again the configuration file that was used
previously. This operation is useful if the configuration file
has been changed by some external source; for example, a
sysadmin can tweak the configuration file and use this command
to force Kea pick up the changes.</para>
<para>Caution should be taken when mixing this with config-set
commands. Kea remembers the location of the configuration file
it was started with, and this configuration can be significantly
changed using config-set command. When config-reload is issued
after config-set, Kea will attempt to reload its original
configuration from the file, possibly losing all changes
introduced using config-set or other commands.</para>
<para><emphasis>config-reload</emphasis> does not take any parameters.
An example command invocation looks like this:
<screen>
{
"command": "config-reload"
}
</screen>
</para>
</section> <!-- end of command-config-reload -->
<section xml:id="command-config-test">
<title>config-test</title>
<para>
The <emphasis>config-test</emphasis> command instructs the server to check
whether the new configuration supplied in the command's arguments can
be loaded. The supplied configuration is expected to be the full
configuration for the target server, along with an optional Logger
configuration. As for the <command>-t</command> command, some sanity checks
are not performed so it is possible a configuration which successfully
passes this command will still fail in the <command>config-set</command>
command or at launch time.
The structure of the command is as follows:
</para>
<screen>
{
"command": "config-test",
"arguments": {
"<server>": {
},
"Logging": {
}
}
}
</screen>
<para>
where <server> is the configuration element name for a given server
such as "Dhcp4" or "Dhcp6". For example:
</para>
<screen>
{
"command": "config-test",
"arguments": {
"Dhcp6": {
:
},
"Logging": {
:
}
}
}
</screen>
<para>
The server's response will contain a numeric code, "result" (0 for success,
non-zero on failure), and a string, "text", describing the outcome:
<screen>
{"result": 0, "text": "Configuration seems sane..." }
or
{"result": 1, "text": "unsupported parameter: BOGUS (<string>:16:26)" }
</screen>
</para>
</section> <!-- end of command-config-test -->
<section xml:id="command-config-write">
<title>config-write</title>
<para>The <emphasis>config-write</emphasis> command instructs the Kea server
to write its current configuration to a file on disk. It takes one
optional argument called <emphasis>filename</emphasis> that specifies
the name of the file to write the configuration to. If not specified, the
name used when starting Kea (passed as a -c argument) will be
used. If a relative path is specified, Kea will write its files
only in the directory it is running.</para>
<para>
An example command invocation looks like this:
<screen>
{
"command": "config-write",
"arguments": {
"filename": "config-modified-2017-03-15.json"
}
}
</screen>
</para>
</section> <!-- end of command-config-write -->
<section xml:id="command-leases-reclaim">
<title>leases-reclaim</title>
<para>
The <emphasis>leases-reclaim</emphasis> command instructs the server to
reclaim all expired leases immediately. The command has the following
JSON syntax:
<screen>
{
"command": "leases-reclaim",
"arguments": {
"remove": true
}
}
</screen>
</para>
<para>The <emphasis>remove</emphasis> boolean parameter is mandatory
and indicates whether the reclaimed leases should be removed from
the lease database (if true), or left in the
<emphasis>expired-reclaimed</emphasis> state (if false). The latter
facilitates lease affinity, i.e. the ability to re-assign an expired lease to
the same client which used this lease before. See
<xref linkend="lease-affinity"/> for the details. Also, see
<xref linkend="lease-reclamation"/> for general information
about the processing of expired leases (leases reclamation).</para>
</section>
<section xml:id="command-libreload">
<title>libreload</title>
<para>
The <emphasis>libreload</emphasis> command first unloads and then
loads all currently loaded hook libraries. This is primarily intended
to allow one or more hook libraries to be replaced with newer versions
without requiring Kea servers to be reconfigured or restarted. Note that
the hook libraries are passed the same parameter values (if any)
that were passed when they originally loaded.
<screen>
{
"command": "libreload",
"arguments": { }
}
</screen>
</para>
<para>
The server will respond with a result of either 0, indicating success, or 1,
indicating failure.
</para>
</section> <!-- end of command-libreload -->
<section xml:id="command-list-commands">
<title>list-commands</title>
<para>
The <emphasis>list-commands</emphasis> command retrieves a list of all
commands supported by the server. It does not take any arguments.
An example command may look like this:
<screen>
{
"command": "list-commands",
"arguments": { }
}
</screen>
</para>
<para>
The server responds with a list of all supported commands. The
arguments element is a list of strings, each of which conveys
one supported command.
</para>
</section> <!-- end of command-list-commands -->
<section xml:id="command-config-set">
<title>config-set</title>
<para>
The <emphasis>config-set</emphasis> command instructs the server to replace
its current configuration with the new configuration supplied in the
command's arguments. The supplied configuration is expected to be the full
configuration for the target server, along with an optional Logger
configuration. While optional, the Logger configuration is highly
recommended, as without it the server will revert to its default logging
configuration. The structure of the command is as follows:
</para>
<screen>
{
"command": "config-set",
"arguments": {
"<server>": {
},
"Logging": {
}
}
}
</screen>
<para>
where <server> is the configuration element name for a given server
such as "Dhcp4" or "Dhcp6". For example:
</para>
<screen>
{
"command": "config-set",
"arguments": {
"Dhcp6": {
:
},
"Logging": {
:
}
}
}
</screen>
<para>
If the new configuration proves to be invalid, the server retains
its current configuration. Please note that the new configuration is
retained in memory only; if the server is restarted or a configuration
reload is triggered via a signal, the server uses the configuration
stored in its configuration file.
The server's response contains a numeric code, "result" (0 for success,
non-zero on failure), and a string, "text", describing the outcome:
<screen>
{"result": 0, "text": "Configuration successful." }
or
{"result": 1, "text": "unsupported parameter: BOGUS (<string>:16:26)" }
</screen>
</para>
</section> <!-- end of command-config-set -->
<section xml:id="command-shutdown">
<title>shutdown</title>
<para>
The <emphasis>shutdown</emphasis> command instructs the server to initiate
its shutdown procedure. It is the equivalent of sending a SIGTERM signal
to the process. This command does not take any arguments. An example
command may look like this:
<screen>
{
"command": "shutdown"
}
</screen>
</para>
<para>
The server responds with a confirmation that the shutdown procedure
has been initiated.
</para>
</section> <!-- end of command-shutdown -->
<section id="command-dhcp-disable">
<title>dhcp-disable</title>
<para>
The <emphasis>dhcp-disable</emphasis> command globally disables the DHCP
service. The server continues to operate, but it drops all received DHCP
messages. This command is useful when the server's maintenance requires that
the server temporarily stop allocating new leases and renew existing leases.
It is also useful in failover-like configurations during a synchronization of
the lease databases at startup, or recovery after a failure. The optional parameter
<emphasis>max-period</emphasis> specifies the time in seconds after which the
DHCP service should be automatically re-enabled, if the
<emphasis>dhcp-enable</emphasis> command is not sent before this time elapses.
</para>
<screen>
{
"command": "dhcp-disable",
"arguments": {
"max-period": 20
}
}
</screen>
</section> <!-- end of command-dhcp-disable -->
<section id="command-dhcp-enable">
<title>dhcp-enable</title>
<para>
The <emphasis>dhcp-enable</emphasis> command globally enables the DHCP
service.
</para>
<screen>
{
"command": "dhcp-enable"
}
</screen>
</section> <!-- end of command-dhcp-disable -->
<section xml:id="command-version-get">
<title>version-get</title>
<para>
The <emphasis>version-get</emphasis> command returns
extended information about the Kea version. It is the same
information available via the <command>-V</command> command-line
argument. This command does not take any parameters.
</para>
<screen>
{
"command": "version-get"
}
</screen>
</section> <!-- end of command-version-get -->
</section> <!-- end of commands supported by both servers -->
<section>
<title>Commands Supported by D2 Server</title>
<para>The D2 server supports only a subset of DHCPv4 / DHCPv6 server
commands:
<itemizedlist>
<listitem>
<simpara>build-report</simpara>
</listitem>
<listitem>
<simpara>config-get</simpara>
</listitem>
<listitem>
<simpara>config-reload</simpara>
</listitem>
<listitem>
<simpara>config-set</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>
<section xml: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-reload</simpara>
</listitem>
<listitem>
<simpara>config-set</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>
|