Commit 96b0712f authored by Thomas Markwalder's avatar Thomas Markwalder
Browse files

[5589] Initial checkin

New stat_cmds hook library initial commit.
Both stat-lease4/6-get commands implemented and unit tested

modified:
    configure.ac
    src/hooks/dhcp/Makefile.am
new:
    src/hooks/dhcp/stat_cmds/.gitignore
    src/hooks/dhcp/stat_cmds/Makefile.am
    src/hooks/dhcp/stat_cmds/stat_cmds.cc
    src/hooks/dhcp/stat_cmds/stat_cmds.dox
    src/hooks/dhcp/stat_cmds/stat_cmds.h
    src/hooks/dhcp/stat_cmds/stat_cmds_callouts.cc
    src/hooks/dhcp/stat_cmds/stat_cmds_log.cc
    src/hooks/dhcp/stat_cmds/stat_cmds_log.h
    src/hooks/dhcp/stat_cmds/stat_cmds_messages.mes
    src/hooks/dhcp/stat_cmds/tests/.gitignore
    src/hooks/dhcp/stat_cmds/tests/Makefile.am
    src/hooks/dhcp/stat_cmds/tests/run_unittests.cc
    src/hooks/dhcp/stat_cmds/tests/stat_cmds_unittest.cc
    src/hooks/dhcp/stat_cmds/version.cc
parent 593ddeae
......@@ -1400,6 +1400,8 @@ AC_CONFIG_FILES([Makefile
src/hooks/dhcp/user_chk/Makefile
src/hooks/dhcp/user_chk/tests/Makefile
src/hooks/dhcp/user_chk/tests/test_data_files_config.h
src/hooks/dhcp/stat_cmds/Makefile
src/hooks/dhcp/stat_cmds/tests/Makefile
src/lib/Makefile
src/lib/asiodns/Makefile
src/lib/asiodns/tests/Makefile
......
SUBDIRS = user_chk lease_cmds
SUBDIRS = user_chk lease_cmds stat_cmds
/stat_cmds_messages.cc
/stat_cmds_messages.h
/s-messages
/html
SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(KEA_CXXFLAGS)
# Define rule to build logging source files from message file
stat_cmds_messages.h stat_cmds_messages.cc: s-messages
s-messages: stat_cmds_messages.mes
$(top_builddir)/src/lib/log/compiler/kea-msg-compiler $(top_srcdir)/src/hooks/dhcp/stat_cmds/stat_cmds_messages.mes
touch $@
# Tell automake that the message files are built as part of the build process
# (so that they are built before the main library is built).
BUILT_SOURCES = stat_cmds_messages.h stat_cmds_messages.cc
# Ensure that the message file and doxygen file is included in the distribution
EXTRA_DIST = stat_cmds_messages.mes
EXTRA_DIST += stat_cmds.dox
# Get rid of generated message files on a clean
CLEANFILES = *.gcno *.gcda stat_cmds_messages.h stat_cmds_messages.cc s-messages
# convenience archive
noinst_LTLIBRARIES = libstat_cmds.la
libstat_cmds_la_SOURCES = stat_cmds.cc stat_cmds.h
libstat_cmds_la_SOURCES += stat_cmds_callouts.cc
libstat_cmds_la_SOURCES += stat_cmds_log.cc stat_cmds_log.h
libstat_cmds_la_SOURCES += version.cc
nodist_libstat_cmds_la_SOURCES = stat_cmds_messages.cc stat_cmds_messages.h
libstat_cmds_la_CXXFLAGS = $(AM_CXXFLAGS)
libstat_cmds_la_CPPFLAGS = $(AM_CPPFLAGS)
# install the shared object into $(libdir)/hooks
lib_hooksdir = $(libdir)/hooks
lib_hooks_LTLIBRARIES = libdhcp_stat_cmds.la
libdhcp_stat_cmds_la_SOURCES =
libdhcp_stat_cmds_la_LDFLAGS = $(AM_LDFLAGS)
libdhcp_stat_cmds_la_LDFLAGS += -avoid-version -export-dynamic -module
libdhcp_stat_cmds_la_LIBADD = libstat_cmds.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/cc/libkea-cc.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/eval/libkea-eval.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/stats/libkea-stats.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/log/libkea-log.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/util/threads/libkea-threads.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/util/libkea-util.la
libdhcp_stat_cmds_la_LIBADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
libdhcp_stat_cmds_la_LIBADD += $(LOG4CPLUS_LIBS)
libdhcp_stat_cmds_la_LIBADD += $(CRYPTO_LIBS)
libdhcp_stat_cmds_la_LIBADD += $(BOOST_LIBS)
This diff is collapsed.
// Copyright (C) 2018 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 libdhcp_stat_cmds Kea Stat Commands Hooks Library
@section libdhcp_stat_cmdsIntro Introduction
Welcome to Kea Stat Commands Hooks Library. This documentation is addressed to
developers who are interested in the internal operation of the Stat Commands
library. This file provides information needed to understand and perhaps extend
this library.
This documentation is stand-alone: you should have read and understood <a
href="http://kea.isc.org/docs/devel/">Kea Developer's Guide</a> and in
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
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
corresponds to the file name of the library: isc::stat_cmds.
@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.
*/
// Copyright (C) 2017-2018 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/.
#ifndef STAT_CMDS_H
#define STAT_CMDS_H
#include <cc/data.h>
#include <hooks/hooks.h>
#include <boost/shared_ptr.hpp>
namespace isc {
namespace stat_cmds {
/// @brief Forward declaration of implementation class.
class StatCmdsImpl;
/// @brief Implements the logic for processing commands pertaining to
/// stat manipulation.
///
/// This class is used by the callouts implementing command handlers for
/// stat manipulations.
class StatCmds {
public:
/// @brief Constructor.
///
/// It creates an instance of the @c StatCmdsImpl.
StatCmds();
/// @brief stat-lease4-get command handler
///
/// This command attempts to fetch lease4 statistics for one or
/// more subnets based upon subnet selection criteria (or lack thereof).
/// It extracts the command name and arguments from the given Callouthandle,
/// attempts to process them, and then set's the handle's "response"
/// arguments accordingly.
/// {
/// "command": "stat-lease4-get",
/// "arguments": {
/// "from_storage: true/false, // optional - maybe?
/// "subnet-id": x, // optional
/// "subnet-id-range": { // optional
/// "first-subnet-id": x, // id >= x
/// "last-subnet-id": y // id <= x
/// }
/// }
/// }
///
/// It produces a response as described below:
///
/// {
/// "result": 0,
/// "text": "<message>",
/// "arguments": {
/// "result-set": {
/// "timestamp": "2018-03-22 09:43:30.815371",
/// "columns": ["subnet_id", "total-addresses",
/// "assigned-addresses", "declined-addresses"],
/// "rows": [
/// [1, 600, 450, 3],
/// :
/// ]
/// }
/// }
/// }
///
/// @param handle Callout context - which is expected to contain the
///
/// add command JSON text in the "command" argument
/// @return result of the operation
int
statLease4GetHandler(hooks::CalloutHandle& handle);
/// @brief stat-lease6-get command handler
///
/// This command attempts to fetch lease6 statistics for one or
/// more subnets based upon subnet selection criteria (or lack thereof).
/// It extracts the command name and arguments from the given Callouthandle,
/// attempts to process them, and then set's the handle's "response"
/// argument accordingly.
/// {
/// "command": "stat-lease6-get",
/// "arguments": {
/// "from_storage: true/false,
/// "subnet-id": x, // optional
/// "subnet-id-range": { // optional
/// "first-subnet-id": x, // id >= x
/// "last-subnet-id": y // id <= x
/// }
/// }
/// }
///
/// It produces a response as described below:
///
/// {
/// "result": 0,
/// "text": "<message>",
/// "arguments": {
/// "result-set": {
/// "timestamp": "2018-03-22 09:43:30.815371",
/// "columns": ["subnet_id", "total-nas",
/// "assigned-nas", "declined-nas",
/// "total-pds", "assigned-pds"],
/// "rows": [
/// [1, 600, 450, 3, 64, 10],
/// :
/// ]
/// }
/// }
/// }
///
///
/// @param handle Callout context - which is expected to contain the
/// add command JSON text in the "command" argument
/// @return result of the operation
int
statLease6GetHandler(hooks::CalloutHandle& handle);
#if 0
private:
/// Pointer to the actual implementation
boost::shared_ptr<StatCmdsImpl> impl_;
#endif
};
};
};
#endif
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the End User License
// Agreement. See COPYING file in the premium/ directory.
// Functions accessed by the hooks framework use C linkage to avoid the name
// mangling that accompanies use of the C++ compiler as well as to avoid
// issues related to namespaces.
#include <stat_cmds.h>
#include <stat_cmds_log.h>
#include <cc/command_interpreter.h>
#include <hooks/hooks.h>
using namespace isc::config;
using namespace isc::data;
using namespace isc::hooks;
using namespace isc::stat_cmds;
extern "C" {
/// @brief This is a command callout for 'stat-lease4-get' command.
///
/// @param handle Callout handle used to retrieve a command and
/// provide a response.
/// @return 0 if this callout has been invoked successfully,
/// 1 otherwise.
int stat_lease4_get(CalloutHandle& handle) {
StatCmds stat_cmds;
return(stat_cmds.statLease4GetHandler(handle));
}
/// @brief This is a command callout for 'stat-lease6-get' command.
///
/// @param handle Callout handle used to retrieve a command and
/// provide a response.
/// @return 0 if this callout has been invoked successfully,
/// 1 otherwise.
int stat_lease6_get(CalloutHandle& handle) {
StatCmds stat_cmds;
return(stat_cmds.statLease6GetHandler(handle));
}
/// @brief This function is called when the library is loaded.
///
/// @param handle library handle
/// @return 0 when initialization is successful, 1 otherwise
int load(LibraryHandle& handle) {
handle.registerCommandCallout("stat-lease4-get", stat_lease4_get);
handle.registerCommandCallout("stat-lease6-get", stat_lease6_get);
LOG_INFO(stat_cmds_logger, STAT_CMDS_INIT_OK);
return (0);
}
/// @brief This function is called when the library is unloaded.
///
/// @return 0 if deregistration was successful, 1 otherwise
int unload() {
LOG_INFO(stat_cmds_logger, STAT_CMDS_DEINIT_OK);
return (0);
}
} // end extern "C"
// Copyright (C) 2018 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/.
#include <stat_cmds_log.h>
namespace isc {
namespace stat_cmds {
isc::log::Logger stat_cmds_logger("stat_cmds_hooks");
}
}
// Copyright (C) 2018 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/.
#ifndef STAT_CMD_LOG_H
#define STAT_CMD_LOG_H
#include <log/logger_support.h>
#include <log/macros.h>
#include <stat_cmds_messages.h>
namespace isc {
namespace stat_cmds {
extern isc::log::Logger stat_cmds_logger;
} // end of isc::stat_cmds
} // end of isc namespace
#endif
# Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
% STAT_LEASE4_GET stat-lease4-get command successful (parameters: %1)
The stat-lease4-get command has been successful. Parameters of the command
are logged.
% STAT_LEASE4_GET_FAILED stat-lease4-get command failed (parameters: %1, reason: %2)
The stat-lease4-get command has failed. Both the reason as well as the
parameters passed are logged.
% STAT_LEASE6_GET stat-lease4-get command successful (parameters: %1)
The stat-lease4-get command has been successful. Parameters of the command
are logged.
% STAT_LEASE6_GET_FAILED stat-lease4-get command failed (parameters: %1, reason: %2)
The stat-lease4-get command has failed. Both the reason as well as the
parameters passed are logged.
% STAT_CMDS_DEINIT_FAILED unloading Stat Commands hooks library failed: %1
This error message indicates an error during unloading the Lease Commands
hooks library. The details of the error are provided as argument of
the log message.
% STAT_CMDS_DEINIT_OK unloading Stat Commands hooks library successful
This info message indicates that the Stat Commands hooks library has been
removed successfully.
% STAT_CMDS_INIT_FAILED loading Stat Commands hooks library failed: %1
This error message indicates an error during loading the Lease Commands
hooks library. The details of the error are provided as argument of
the log message.
% STAT_CMDS_INIT_OK loading Stat Commands hooks library successful
This info message indicates that the Stat Commands hooks library has been
loaded successfully. Enjoy!
stat_cmds_unittests
stat_cmds_unittests.log
stat_cmds_unittests.trs
test-suite.log
*~
SUBDIRS = .
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/hooks/dhcp/stat_cmds -I$(top_srcdir)/src/hooks/dhcp/stat_cmds
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CPPFLAGS += -DSTAT_CMDS_LIB_SO=\"$(abs_top_builddir)/src/hooks/dhcp/stat_cmds/.libs/libdhcp_stat_cmds.so\"
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
AM_CXXFLAGS = $(KEA_CXXFLAGS)
if USE_STATIC_LINK
AM_LDFLAGS = -static
endif
# Unit test data files need to get installed.
EXTRA_DIST =
CLEANFILES = *.gcno *.gcda
# TESTS_ENVIRONMENT = $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
LOG_COMPILER = $(LIBTOOL)
AM_LOG_FLAGS = --mode=execute
TESTS =
if HAVE_GTEST
TESTS += stat_cmds_unittests
stat_cmds_unittests_SOURCES = run_unittests.cc
stat_cmds_unittests_SOURCES += stat_cmds_unittest.cc
stat_cmds_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
stat_cmds_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS)
stat_cmds_unittests_CXXFLAGS = $(AM_CXXFLAGS)
stat_cmds_unittests_LDADD = $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
stat_cmds_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
stat_cmds_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
stat_cmds_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
stat_cmds_unittests_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la
stat_cmds_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
stat_cmds_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
stat_cmds_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
stat_cmds_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
stat_cmds_unittests_LDADD += $(LOG4CPLUS_LIBS)
stat_cmds_unittests_LDADD += $(CRYPTO_LIBS)
stat_cmds_unittests_LDADD += $(BOOST_LIBS)
stat_cmds_unittests_LDADD += $(GTEST_LDADD)
if HAVE_CQL
stat_cmds_unittests_LDFLAGS += $(CQL_LIBS)
endif
endif
noinst_PROGRAMS = $(TESTS)
// 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/.
#include <log/logger_support.h>
#include <gtest/gtest.h>
int
main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
isc::log::initLogger();
int result = RUN_ALL_TESTS();
return (result);
}
This diff is collapsed.
// Copyright (C) 2018 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/.
#include <config.h>
#include <hooks/hooks.h>
extern "C" {
/// @brief returns Kea hooks version.
int version() {
return (KEA_HOOKS_VERSION);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment