From: Thomas Markwalder Date: Mon, 14 May 2018 11:32:06 +0000 (-0400) Subject: [5580] Added developor and admin doc X-Git-Tag: trac5549a_base~21^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7fc34c9475c3d34b6283146a34f4f5636872de7d;p=thirdparty%2Fkea.git [5580] Added developor and admin doc --- diff --git a/doc/Doxyfile b/doc/Doxyfile index 85156dbfcb..81b0a9677a 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -780,6 +780,7 @@ INPUT = ../src/bin/agent \ ../src/bin/lfc \ ../src/hooks/dhcp/user_chk \ ../src/hooks/dhcp/lease_cmds \ + ../src/hooks/dhcp/stat_cmds \ ../src/lib/asiodns \ ../src/lib/asiolink \ ../src/lib/cc \ diff --git a/doc/devel/mainpage.dox b/doc/devel/mainpage.dox index 281ba47a66..7f022fa338 100644 --- a/doc/devel/mainpage.dox +++ b/doc/devel/mainpage.dox @@ -54,6 +54,7 @@ * - @subpage hooksmgMaintenanceGuide * - @subpage libdhcp_user_chk * - @subpage libdhcp_lease_cmds + * - @subpage libdhcp_stat_cmds * * @section dhcpMaintenanceGuide DHCP Maintenance Guide * - @subpage dhcp4 diff --git a/doc/guide/Makefile.am b/doc/guide/Makefile.am index 7dca16a228..f87666ded8 100644 --- a/doc/guide/Makefile.am +++ b/doc/guide/Makefile.am @@ -8,7 +8,7 @@ dist_html_DATA = $(HTMLDOCS) kea-guide.css kea-logo-100x70.png DOCBOOK = kea-guide.xml intro.xml quickstart.xml install.xml admin.xml config.xml DOCBOOK += keactrl.xml dhcp4-srv.xml dhcp6-srv.xml lease-expiration.xml logging.xml DOCBOOK += ddns.xml hooks.xml libdhcp.xml lfc.xml stats.xml ctrl-channel.xml faq.xml -DOCBOOK += hooks-host-cache.xml hooks-radius.xml +DOCBOOK += hooks-host-cache.xml hooks-radius.xml hooks-stat-cmds.xml DOCBOOK += classify.xml shell.xml agent.xml EXTRA_DIST = $(DOCBOOK) diff --git a/doc/guide/hooks-stat-cmds.xml b/doc/guide/hooks-stat-cmds.xml new file mode 100644 index 0000000000..57890b7c5f --- /dev/null +++ b/doc/guide/hooks-stat-cmds.xml @@ -0,0 +1,283 @@ +
+ stat_cmds: Supplemental Statistics Commands + + This library provides additional statistics commands for + retrieving lease statistics from kea-dhcp servers. These commands + were added to address an issue with obtaining accurate lease + statistics in deployments running multiple Kea servers that use + shared lease back end. The in-memory statistics kept by individual + servers only track lease changes made by that server. Thus in a + deployment with multiple servers, these statistics are incomplete. + In Kea 1.4, the MySQL and PostgreSQL back ends were modified to track + lease allocation changes as they occur via database triggers. Additionally, + all four lease back ends were extended to support retrieving lease + statistics for all subnets, a single subnet, or a range of subnets. + Finally, this library was constructed to provide commands for retrieving + these statistics. Additional statistics commands may be added to this + library in future releases. + + + + The commands currently provided by this library are: + + + stat-lease4-get - fetches DHCPv4 lease statistics + + + stat-lease6-get - fetches DHCPv6 lease statistics + + + + + + The Stat commands library is part of the open source code and is + available to every Kea user. + + + + All commands use JSON syntax and can be issued either using directly to + the servers via the control channel (see ) + or via Control Agent (see ). + + + + This library may be loaded by both kea-dhcp4 and kea-dhcp6 servers. + It is loaded in the same way as other other libraries and currently has + no parameters: + + + +"Dhcp6": { + "hooks-libraries": [ + { + "library": "/path/libdhcp_stat_cmds.so" + } + ... + ] +} + + + + + In a deployment with multiple kea-dhcp servers sharing a common lease + storage, it may be loaded by any or all of the servers. However, one + thing to keep in mind is that a server's response to a stat-lease{4/6}-get + command will only contain data for subnets known to that server. In + other words, if subnet does not appear in a server's configuration, it + will not retrieve statistics for it. + + +
+ stat-lease4-get, stat-lease6-get commands + + The stat-lease4-get and stat-lease6-get + commands fetch lease statistics for a range of known subnets. The + range of subnets is determined through the use of optional command + input parameters: + + + subnet-id - ID of the subnet for which + lease statistics should be fetched. Use this to get statistics for + a single subnet. If the subnet does not exist the command result + code will be 2 (i.e. CONTROL_RESULT_EMPTY). + + + + subnet-range - A pair of subnet IDs which + describe an inclusive range of subnets for which statistics should + be retrieved. Note that fuzzy values are supported thus allowing + for a query for statistics using approximate ID values. If the + range does not include any known subnets, the command result code + will be 2 (i.e. CONTROL_RESULT_EMPTY). + + + first-subnet-id - ID of the first + subnet in the range. + + + last-subnet-id - ID of the first + subnet in the range. + + + + + + The use of subnet-id and subnet-range are mutually exclusive. + If no parameters are given, the result will contain data for all + known subnets. Note that in configurations with large numbers of + subnets, this can be result in a large response. + + The following command would fetch lease statistcis for all known subnets from kea-dhcp4 server: + +{ + "command": "stat-lease4-get", + "arguments": { + } +} + + + + The following command would fetch lease statistcis for subnet ID 10 from kea-dhcp6 server: + +{ + "command": "stat-lease6-get", + "arguments": { + "subnet-id" : 10 + } +} + + + + The following command would fetch lease statistcis for all subnets from subnet ID 10 through 50 from kea-dhcp4 server: + +{ + "command": "stat-lease4-get", + "arguments": { + "subnet-range" { + "first-subnet-id": 10, + "last-subnet-id": 50, + } + } +} + + + + + The response to the either command will contain three elements: + + + result - numeric value indicating the outcome of the + command where: + + 0 - command was successful + 1 - an error occurred, an explanation will + be the "text" element + 2 - indicates the fetch found no matching data + + + + + text - an explanation of the command outcome. When the command + succeeds it will contain the command name along with the number of rows returned. + + + arguments - a map containing the data returned by the + command as the element "result-set", which patterned after SQL statement responses: + + columns - a list of text column labels. + The columns returned for DHCPv4 are: + + subnet-id - ID of the subnet + total-addresses - total number of addresses + available for DHCPv4 management. In other words, this is the sum of all + addresses in all configured pools. This statistic changes only during + configuration changes. Note it does not take into account any addresses that + may be reserved due to host reservation. + + assigned-addresses - number of assigned + addresses in a given subnet. It increases every time a new lease is + allocated (as a result of receiving a DHCPREQUEST message) and is decreased + every time a lease is released (a DHCPRELEASE message is received) or expires. + + declined-addresses - number of IPv4 addresses + that are currently declined in a given subnet, so is a count of the number + of leases currently unavailable. Once a lease is recovered, this statistic + will be decreased. Ideally, this statistic should be zero. If this statistic + is non-zero (or worse increasing), a network administrator should investigate + if there is a misbehaving device in his network. + + + The columns returned for DHCPv6 are: + + subnet-id - ID of the subnet + total-nas - number of NA addresses available + for DHCPv6 management for a given subnet. In other words, this is the + sum of all addresses in all configured pools. This statistic changes + only during configuration changes. Note that it does not take into account + any addresses that may be reserved due to host reservation. + + assigned-nas - number of NA addresses in a + the subnet that are assigned. This statistic increases every time a new + lease is allocated (as a result of receiving a REQUEST message) and is + decreased every time a lease is released (a RELEASE message is received) + or expires. + + declined-nas - number of IPv6 addresses that + are currently declined and so counts the number of leases currently + unavailable. Once a lease is recovered, this statistic will be decreased. + Ideally, this statistic should be zero. If this statistic is non-zero + (or worse, increasing), the network administrator should investigate if + there is a misbehaving device in the network. + + total-pds - total number of PD prefixes available + of DHCPv6 management for a given subnet. In other words, this is the sum + of all prefixes in all configured pools. This statistic changes only during + configuration changes. Note it does not take into account any prefixes that + may be reserved due to host reservation. + + assigned-pds - number of PD prefixes in a given + subnet that are assigned. This statistic increases every time a new lease is + allocated (as a result of receiving a REQUEST message) and is decreased every + time a lease is released (a RELEASE message is received) or expires. + + + + rows - a list of rows, one per subnet ID. Each row + contains a data value for corresponding to and in the same order as each column + listed in "columns" for a given subnet. + + timestamp - textual date and time the data was fetched, + expressed as GMT + + + + + The response to a DHCPv4 command might look as follows: + + { + "result": 0, + "text": "stat-lease4-get: 2 rows found", + "arguments": { + "result-set": { + "columns": [ "subnet-id", "total-addresses", "assigned-addresses", "declined-addresses" ] + "rows": [ + [ 10, 256, 111, 0 ], [ 20, 4098, 2034, 4 ] + ], + "timestamp": "2018-05-04 15:03:37.000000" + } + } + } + + + + The response to a DHCPv6 command might look as follows: + + { + "result": 0, + "text": "stat-lease6-get: 2 rows found", + "arguments": { + "result-set": { + "columns": [ "subnet-id", "total-nas", "assigned-nas", "declined-nas", "total-pds", "assigned-pds" ] + "rows": [ + [ 10, 256, 111, 0 ], + [ 20, 4098, 2034, 4 ] + ], + "timestamp": "2018-05-04 15:03:37.000000" + } + } + } + + + + + + + + + + + + + +
+
diff --git a/doc/guide/hooks.xml b/doc/guide/hooks.xml index 4aaeddbeb8..14993fea91 100644 --- a/doc/guide/hooks.xml +++ b/doc/guide/hooks.xml @@ -2838,6 +2838,8 @@ both the command and the response. + + diff --git a/src/hooks/dhcp/stat_cmds/stat_cmds.cc b/src/hooks/dhcp/stat_cmds/stat_cmds.cc index e6c45fdf65..6611cfdd49 100644 --- a/src/hooks/dhcp/stat_cmds/stat_cmds.cc +++ b/src/hooks/dhcp/stat_cmds/stat_cmds.cc @@ -43,11 +43,11 @@ public: isc::Exception(file, line, what) { }; }; -///@brief Implements command handlinge for stat-lease-get commands +///@brief Implements command handlinge for stat-leaseX-get commands class LeaseStatCmdsImpl : private CmdsImpl { public: - /// @brief Wrapper class stat-lease-get command parameters. + /// @brief Wrapper class stat-leaseX-get command parameters. class Parameters { public: /// @brief Specifies the subnet-id for a single subnet, or @@ -92,7 +92,7 @@ public: int statLease6GetHandler(CalloutHandle& handle); - /// @Brief Parses command arguments into stat-lease-get parameters + /// @brief Parses command arguments into stat-leaseX-get parameters /// @param cmd_args Element form of command arguments to parse /// @throw BadValue if any of the following rules are broken: /// @@ -165,17 +165,17 @@ public: /// @brief Adds a row of Lease4 stat values to a list of value rows /// /// @param[out] value_rows list of rows to which to add - /// @param[out] subent_id id of the subnet of the new row. This value is + /// @param[out] subnet_id id of the subnet of the new row. This value is /// also used for fetching the total addresses in the subnet /// @param assigned number of assigned addresses in the subnet - /// @param assigned number of declined addresses in the subnet + /// @param declined number of declined addresses in the subnet void addValueRow4(ElementPtr value_rows, const SubnetID &subnet_id, int64_t assigned, int64_t declined); /// @brief Adds a row of Lease6 stat values to a list of value rows /// /// @param[out] value_rows list of rows to which to add - /// @param[out] subent_id id of the subnet of the new row. This value is + /// @param[out] subnet_id id of the subnet of the new row. This value is /// also used for fetching the total NAs and PDs in the subnet /// @param assigned number of assigned NAs in the subnet /// @param declined number of declined NAs in the subnet diff --git a/src/hooks/dhcp/stat_cmds/stat_cmds.dox b/src/hooks/dhcp/stat_cmds/stat_cmds.dox index aa1478f99d..53e850fb99 100644 --- a/src/hooks/dhcp/stat_cmds/stat_cmds.dox +++ b/src/hooks/dhcp/stat_cmds/stat_cmds.dox @@ -21,78 +21,179 @@ particular its section about hooks. @section stat_cmds Stat Commands Overview -Stat Commands (or stat_cmds) is a Hook library that can be loaded by Kea to -extend it with additional mechanisms. - -The primary purpose of this library is to provide commands that manage leases. -As such, the whole library is structured around command handlers. When the -library is loaded it registers a number of handlers for new commands. When a -command is issued (be it directly via control channel or indirectly via REST +Stat Commands (or stat_cmds) is a Hook library that can be loaded by +either kea-dhcp4 and kea-dhcp6 servers to extend them with additional +statistics mechanisms. + +The initial purpose of this library is provide supplemental commands for +obtaining accurate lease statistics in deployments that share lease storage +between multiple Kea DHCP servers. It is likely that additional statistics +related commands will be added to this library in future releases as use +cases for them arise. + +The library is structured around command handlers. When the library is +loaded it registers handlers for new commands. When a command +is issued (be it directly via control channel or indirectly via REST interface from control agent), the code receives a JSON command with -parameters. Those are parsed and then actual operation commences. This -operation always interacts with an instantiation of isc::dhcp::StatMgr -instance, which is Kea's way of storing leases. At the time of writing this text -(Aug. 2017), Kea supports four types of lease managers: memfile, MySQL, -PostgreSQL or Cassandra. The lease commands provided by this library -provide a unified interface for those backends. - -As with other hooks, this one also keeps its code in a separate namespace which +parameters. The command is routed the appropriate handler, its parameters +are parsed and command executed accordingly. Lastly, a response is +constructed and shipped back to the client. + +This lease statistics commands interact with both the isc::dhcp::StatsMgr +and the isc::dhcp::LeaseMgr instance. At the time of writing this text +(May, 2018), Kea supports four types of lease managers: memfile, MySQL, +PostgreSQL or Cassandra. The lease statistics commands provided by this +library provide a unified interface supported by all four of these backends. + +As with other hooks, this one keeps its code in a separate namespace which corresponds to the file name of the library: isc::stat_cmds. +For background on the design and design choices please refer to: Shared Lease Stats Design + @section stat_cmdsCode Stat Commands Code Overview -The library operation starts with Kea calling the load() function (file -load_unload.cc). It instantiates an isc::stat_cmds::StatCmds object. -The constructor of that object registers all of the lease commands. For a list, -see @ref isc::stat_cmds::StatCmds class documentation. This class uses Pimpl -design pattern, thus the real implementation is hidden in isc::stat_cmds::StatCmdsImpl. - -Almost every command has its own handler, except few that share the same handler -between v4 and v6 due to its similarity. For example -isc::stat_cmds::StatCmdsImpl::leaseAddHandler handles lease4-add and lease6-add -commands. Although the details differ between handlers, the general approach -is the same. First, it starts with parameters sanitization and then some -interaction with isc::dhcp::StatMgr is conducted. - -For commands that do something with a specific lease (lease4-get, lease6-get, -lease4-del, lease6-del), there is a @ref isc::stat_cmds::StatCmdsImpl::Parameters -class that contains parsed elements. - -For details see documentation and code of the following handlers: -- @ref isc::stat_cmds::StatCmdsImpl::leaseAddHandler (lease4-add, lease6-add) -- @ref isc::stat_cmds::StatCmdsImpl::leaseGetHandler (lease4-get, lease6-get) -- @ref isc::stat_cmds::StatCmdsImpl::lease4DelHandler (lease4-del) -- @ref isc::stat_cmds::StatCmdsImpl::lease6DelHandler (lease6-del) -- @ref isc::stat_cmds::StatCmdsImpl::lease4UpdateHandler (lease4-update) -- @ref isc::stat_cmds::StatCmdsImpl::lease6UpdateHandler (lease6-update) -- @ref isc::stat_cmds::StatCmdsImpl::lease4WipeHandler (lease4-wipe) -- @ref isc::stat_cmds::StatCmdsImpl::lease6WipeHandler (lease6-wipe) - -@section stat_cmdsDesigns Stat Commands Design choices - -The lease manipulation commands were implemented to provide a convenient interface -for sysadmins. The primary goal was to offer a way to interact with the live -lease database in unified way, regardless of the actual backend being used. - -For some backends (MySQL, PostgreSQL and Cassandra) it is possible to interact -directly with the backend while Kea is running and possibly change its content. This -ability is both powerful and dangerous. In particular, only rudimentary -checks are enforced by the DB schemas (e.g. not possible to have two leases -for the same address). However, it does not prevent sysadmins from making -more obscure errors, like inserting leases for subnets that do not exist -or configuring an address that is topologically outside of the subnet to which -it should belong. These kind of checks are only possible by DHCP-aware -code, which this library provides. - -Some of the queries may require a seemingly odd set of parameters. For example, -lease6-get query requires at least DUID, subnet-id and IAID to retrieve a lease -by DUID. The need for a sysadmin to know and specify an IAID is troublesome. -However, the guiding principle here was to use whatever queries were already -exposed by the lease manager and not introduce new indexes, unless absolutely -necessary. This ensures that there is no performance degradation when the -library is loaded. The only exception for that was lease4-wipe and lease6-wipe -commands that remove all leases from specific subnet. As there were no -queries that could retrieve or otherwise enumerate leases for a specific subnet, -a new query type and a new index had to be added. +Library operation starts with Kea calling the load() function (file +stat_cmds_callouts.cc). This function registers the command callout +functions for each of the libraries commands. For a list, +see @ref isc::stat_cmds::StatCmds class documentation. This class uses +the Pimpl design pattern, and thus the actual implementation is hidden +in @ref isc::stat_cmds::LeaseStatCmdsImpl. + +Unlike similar libraries, the Pimpl class is differentiated from the +the StatCmds class by the prefix "Lease" and it is instantiated in the outer +handler (e.g. @ref isc::stat_cmds::StatCmds::statLease4GetHandler) rather than +the StatCmds constructor. This was done in the event that commands, unrelated +to lease statistics, are added to this library and that would be better served +by Pimpl derviations specific to them. + +@subsection stat_cmdsLeaseStatCode Lease Stat Commands Code Overview + +There are two shared lease statistic commands, "stat-lease4-get" and "stat-lease6-get". +Both of these support the same input parameters and have their own command handlers: + +- @ref isc::stat_cmds::LeaseStatCmdsImpl::statLease4GetHandler (stat-lease4-get) +- @ref isc::stat_cmds::LeaseStatCmdsImpl::statLease6GetHandler (stat-lease6-get) + +Briefly, the commands are intended to fetch the lease statistics per subnet +for the range of subnets described by the input parameters. JSON text structure +of the commands is as follows: + +DHCPv4 command: + +@code +{ + "command": "stat-lease4-get", + "arguments": { + "subnet-id": x + "subnet-range": { + "first-subnet-id": x, + "last-subnet-id": y + } + } +} + + where subnet-id and subnet-range are optional and mutually exclusive +@endcode + +DHCPv6 command: + +@code +{ + "command": "stat-lease6-get", + "arguments": { + "subnet-id": x + "subnet-range": { + "first-subnet-id": x, + "last-subnet-id": y + } + } +} + + where subnet-id and subnet-range are optional and mutually exclusive +@endcode + + + +Command handling +for both commands is symetrical consists of the following steps: + +-# The input parameters (if any) are parsed. Invalid values or +combinations if detected result in generating a CONTROL_RESULT_ERROR +response to the client. (See @ref isc::stat_cmds::LeaseStatCmdsImpl::getParameters +and @ref isc::stat_cmds::LeaseStatCmdsImpl::Parameters) + +-# The parameters are used to identify the range of configured subnets +to include in the response. This is done by querying subnet configuration +housed by @ref isc::dhcp::CfgMgr. If the range contains no known subnets then a +CONTROL_RESULT_EMPTY response is sent back to the client. + +-# The initial result-set response is constructed. Essentially this is +an @ref isc::data::Element tree, which converted to JSON would appear as follows: + +@code + "result-set": { + "timestamp": "2018-03-22 09:43:30.815371", + "columns": [", , ... ], + "rows": [] + } +@endcode + +-# The acutal lease statistics are then retrieved from @ref isc::dhcp::LeaseMgr instance +by invoking of the three functions based on the input parameters: + +DHCPv4 functions: + +- @ref isc::dhcp::LeaseMgr::startLeaseStatsQuery4 +- @ref isc::dhcp::LeaseMgr::startSubnetLeaseStatsQuery4 +- @ref isc::dhcp::LeaseMgr::startSubnetRangeLeaseStatsQuery4 + +DHCPv6 functions: + +- @ref isc::dhcp::LeaseMgr::startLeaseStatsQuery6 +- @ref isc::dhcp::LeaseMgr::startSubnetLeaseStatsQuery6 +- @ref isc::dhcp::LeaseMgr::startSubnetRangeLeaseStatsQuery6 + +-# Iterate over the range of qualifying subnets adding a row of statistics for +each subnet to the result-set. Each row combines the subnet total(s) from isc::dhcp::StatsMgr +with the type and state counts from the lease query results. For subnets with no query +data (i.e. no leases), their rows have non-zero values for totals only. + +-# Finally, a CONTROL_RESULT_SUCCESS repsonse is generated containing the populated result-set. + +A DHCPv4 response might look like this: + +@code + { + "result-set\": { + "columns\": [ + "subnet-id", "total-addreses", + "assigned-addreses", "declined-addreses" + ], + "rows\": [ + [ 30, 256, 100, 2 ], + [ 40, 16, 0, 0 ], + [ 50, 256, 35, 0 ], + ], + timestamp\": \"2018-05-04 15:03:37.000000\" } + } +@endcode + +and DHCPv6 response might look like this: + +@code + { + "result-set": { + "columns": [ + "subnet-id", "total-nas", "assigned-nas", + "declined-nas", "total-pds", "assigned-pds" + ], + "rows": [ + [ 30, 16, 6, 0, 65536, 400 ], + [ 40, 16777216, 989837, 0, 0, 0 ] + ], + "timestamp": "2018-05-04 15:03:37.000000" } + } +@endcode */ diff --git a/src/hooks/dhcp/stat_cmds/stat_cmds.h b/src/hooks/dhcp/stat_cmds/stat_cmds.h index ce79d26f26..a67c4756fb 100644 --- a/src/hooks/dhcp/stat_cmds/stat_cmds.h +++ b/src/hooks/dhcp/stat_cmds/stat_cmds.h @@ -40,9 +40,8 @@ public: /// { /// "command": "stat-lease4-get", /// "arguments": { - /// "from_storage: true/false, // optional - maybe? - /// "subnet-id": x, // optional - /// "subnet-id-range": { // optional + /// "subnet-id": x // optional + /// "subnet-range": { // optional /// "first-subnet-id": x, // id >= x /// "last-subnet-id": y // id <= x /// } @@ -84,9 +83,8 @@ public: /// { /// "command": "stat-lease6-get", /// "arguments": { - /// "from_storage: true/false, - /// "subnet-id": x, // optional - /// "subnet-id-range": { // optional + /// "subnet-id": x // optional + /// "subnet-range": { // optional /// "first-subnet-id": x, // id >= x /// "last-subnet-id": y // id <= x /// } diff --git a/src/lib/dhcpsrv/lease_mgr.h b/src/lib/dhcpsrv/lease_mgr.h index 01190e67a9..a820304ae2 100644 --- a/src/lib/dhcpsrv/lease_mgr.h +++ b/src/lib/dhcpsrv/lease_mgr.h @@ -606,7 +606,7 @@ public: /// ordered ascending by subnet ID. /// /// @param first_subnet_id first subnet in the range of subnets - /// @param last last_subnet_id subnet in the range of subnets + /// @param last_subnet_id last subnet in the range of subnets /// @return A populated LeaseStatsQuery virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery6(const SubnetID& first_subnet_id, const SubnetID& last_subnet_id);