Commit ceb361c7 authored by Marcin Siodelski's avatar Marcin Siodelski

[5075] Created Control Agent application stub.

parent 16be7fe3
......@@ -1512,6 +1512,9 @@ AC_CONFIG_FILES([compatcheck/Makefile
Makefile
src/Makefile
src/bin/Makefile
src/bin/agent/Makefile
src/bin/agent/tests/Makefile
src/bin/agent/tests/ctrl_agent_process_tests.sh
src/bin/d2/Makefile
src/bin/d2/tests/Makefile
src/bin/d2/tests/d2_process_tests.sh
......
# The following build order must be maintained.
SUBDIRS = dhcp4 dhcp6 d2 perfdhcp admin lfc keactrl
SUBDIRS = dhcp4 dhcp6 d2 agent perfdhcp admin lfc keactrl
check-recursive: all-recursive
/kea-ctrl-agent
/ctrl_agent_messages.cc
/ctrl_agent_messages.h
/s-messages
SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(KEA_CXXFLAGS)
if USE_STATIC_LINK
AM_LDFLAGS = -static
endif
CLEANFILES = *.gcno *.gcda ctrl_agent_messages.h ctrl_agent__messages.cc s-messages
#man_MANS = kea-ctrl-agent.8
#DISTCLEANFILES = $(man_MANS)
#EXTRA_DIST = $(man_MANS) kea-ctrl-agent.xml agent.dox
#if GENERATE_DOCS
#kea-ctrl-agent.8: kea-ctrl-agent.xml
# @XSLTPROC@ --novalid --xinclude --nonet -o $@ \
# http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl \
# $(srcdir)/kea-ctrl-agent.xml
#else
#$(man_MANS):
# @echo Man generation disabled. Creating dummy $@. Configure with --enable-generate-docs to enable it.
# @echo Man generation disabled. Remove this file, configure with --enable-generate-docs, and rebuild Kea > $@
#endif
ctrl_agent_messages.h ctrl_agent_messages.cc: s-messages
s-messages: ctrl_agent_messages.mes
$(top_builddir)/src/lib/log/compiler/kea-msg-compiler $(top_srcdir)/src/bin/agent/ctrl_agent_messages.mes
touch $@
BUILT_SOURCES = ctrl_agent_messages.h ctrl_agent_messages.cc
# convenience archive
noinst_LTLIBRARIES = libagent.la
libagent_la_SOURCES = ctrl_agent_cfg_mgr.cc ctrl_agent_cfg_mgr.h
libagent_la_SOURCES += ctrl_agent_controller.cc ctrl_agent_controller.h
libagent_la_SOURCES += ctrl_agent_log.cc ctrl_agent_log.h
libagent_la_SOURCES += ctrl_agent_process.cc ctrl_agent_process.h
nodist_libagent_la_SOURCES = ctrl_agent_messages.h ctrl_agent_messages.cc
EXTRA_DIST = ctrl_agent_messages.mes
sbin_PROGRAMS = kea-ctrl-agent
kea_ctrl_agent_SOURCES = main.cc
kea_ctrl_agent_LDADD = libagent.la
kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/cfgrpt/libcfgrpt.la
kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/process/libkea-process.la
kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la
kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
kea_ctrl_agent_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
kea_ctrl_agent_LDADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS) $(BOOST_LIBS)
kea_ctrl_agent_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS)
// Copyright (C) 2016 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 <agent/ctrl_agent_cfg_mgr.h>
using namespace isc::dhcp;
using namespace isc::process;
namespace isc {
namespace agent {
CtrlAgentCfgMgr::CtrlAgentCfgMgr()
: DCfgMgrBase(DCfgContextBasePtr(new CtrlAgentCfgContext())) {
}
CtrlAgentCfgMgr::~CtrlAgentCfgMgr() {
}
std::string
CtrlAgentCfgMgr::getConfigSummary(const uint32_t selection) {
return ("Control Agent is currently not configurable.");
}
isc::dhcp::ParserPtr
CtrlAgentCfgMgr::createConfigParser(const std::string& element_id,
const isc::data::Element::Position& pos) {
// Create dummy parser, so as we don't return null pointer.
isc::dhcp::ParserPtr parser;
parser.reset(new Uint32Parser(element_id, getContext()->getUint32Storage()));
return (parser);
}
DCfgContextBasePtr
CtrlAgentCfgMgr::createNewContext() {
return (DCfgContextBasePtr(new CtrlAgentCfgContext()));
}
} // namespace isc::agent
} // namespace isc
// Copyright (C) 2016 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 CTRL_AGENT_CFG_MGR_H
#define CTRL_AGENT_CFG_MGR_H
#include <process/d_cfg_mgr.h>
namespace isc {
namespace agent {
class CtrlAgentCfgContext;
/// @brief Pointer to a configuration context.
typedef boost::shared_ptr<CtrlAgentCfgContext> CtrlAgentCfgContextPtr;
/// @brief Control Agent Configuration Context.
///
/// Implement the storage container for configuration context.
/// It provides a single enclosure for the storage of configuration parameters
/// and any other Control Agent specific information that needs to be accessible
/// during configuration parsing as well as to the application as a whole.
/// It is derived from the context base class, DCfgContextBase.
class CtrlAgentCfgContext : public process::DCfgContextBase {
public:
/// @brief Creates a clone of this context object.
///
/// @return A pointer to the new clone.
virtual process::DCfgContextBasePtr clone() {
return (process::DCfgContextBasePtr(new CtrlAgentCfgContext(*this)));
}
private:
/// @brief Private assignment operator to avoid potential for slicing.
CtrlAgentCfgContext& operator=(const CtrlAgentCfgContext& rhs);
};
/// @brief Ctrl Agent Configuration Manager.
///
/// Provides the mechanisms for managing the Control Agent application's
/// configuration.
class CtrlAgentCfgMgr : public process::DCfgMgrBase {
public:
/// @brief Constructor.
CtrlAgentCfgMgr();
/// @brief Destructor
virtual ~CtrlAgentCfgMgr();
/// @brief Convenience method that returns the Control Agent configuration
/// context.
///
/// @return returns a pointer to the configuration context.
CtrlAgentCfgContextPtr getCtrlAgentCfgContext() {
return (boost::dynamic_pointer_cast<CtrlAgentCfgContext>(getContext()));
}
/// @brief Returns configuration summary in the textual format.
///
/// @param selection Bitfield which describes the parts of the configuration
/// to be returned. This parameter is ignored for the Control Agent.
///
/// @return Summary of the configuration in the textual format.
virtual std::string getConfigSummary(const uint32_t selection);
protected:
/// @brief Create a parser instance based on an element id.
///
/// Given an element_id returns an instance of the appropriate parser.
///
/// @param element_id is the string name of the element as it will appear
/// in the configuration set.
/// @param pos position within the configuration text (or file) of element
/// to be parsed. This is passed for error messaging.
///
/// @return returns a ParserPtr to the parser instance.
virtual isc::dhcp::ParserPtr
createConfigParser(const std::string& element_id,
const isc::data::Element::Position& pos
= isc::data::Element::Position());
/// @brief Creates a new, blank CtrlAgentCfgContext context.
///
///
/// This method is used at the beginning of configuration process to
/// create a fresh, empty copy of a CtrlAgentCfgContext. This new context
/// will be populated during the configuration process and will replace the
/// existing context provided the configuration process completes without
/// error.
///
/// @return Returns a DCfgContextBasePtr to the new context instance.
virtual process::DCfgContextBasePtr createNewContext();
};
/// @brief Defines a shared pointer to CtrlAgentCfgMgr.
typedef boost::shared_ptr<CtrlAgentCfgMgr> CtrlAgentCfgMgrPtr;
} // namespace isc::agent
} // namespace isc
#endif // CTRL_AGENT_CFG_MGR_H
// Copyright (C) 2016 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 <agent/ctrl_agent_controller.h>
#include <agent/ctrl_agent_process.h>
using namespace isc::process;
namespace isc {
namespace agent {
/// @brief Defines the application name, this is passed into base class
/// it may be used to locate configuration data and appears in log statement.
const char* CtrlAgentController::agent_app_name_ = "CtrlAgent";
/// @brief Defines the executable name. This is passed into the base class
const char* CtrlAgentController::agent_bin_name_ = "kea-ctrl-agent";
DControllerBasePtr&
CtrlAgentController::instance() {
// If the instance hasn't been created yet, create it. Note this method
// must use the base class singleton instance methods.
if (!getController()) {
DControllerBasePtr controller_ptr(new CtrlAgentController());
setController(controller_ptr);
}
return (getController());
}
DProcessBase*
CtrlAgentController::createProcess() {
// Instantiate and return an instance of the D2 application process. Note
// that the process is passed the controller's io_service.
return (new CtrlAgentProcess(getAppName().c_str(), getIOService()));
}
CtrlAgentController::CtrlAgentController()
: DControllerBase(agent_app_name_, agent_bin_name_) {
}
CtrlAgentController::~CtrlAgentController() {
}
} // namespace isc::agent
} // namespace isc
// Copyright (C) 2016 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 CTRL_AGENT_CONTROLLER_H
#define CTRL_AGENT_CONTROLLER_H
#include <process/d_controller.h>
namespace isc {
namespace agent {
/// @brief Process Controller for Control Agent Process.
///
/// This class is the Control Agent specific derivation of the DControllerBase.
/// It creates and manages an instance of the Control Agent application process,
/// CtrlAgentProcess.
class CtrlAgentController : public process::DControllerBase {
public:
/// @brief Static singleton instance method.
///
/// This method returns the base class singleton instance member.
/// It instantiates the singleton and sets the base class instance
/// member upon first invocation.
///
/// @return returns the pointer reference to the singleton instance.
static process::DControllerBasePtr& instance();
/// @brief Destructor
virtual ~CtrlAgentController();
/// @brief Defines the application name, this is passed into base class
/// and appears in log statements.
static const char* agent_app_name_;
/// @brief Defines the executable name. This is passed into the base class
/// by convention this should match the executable name.
static const char* agent_bin_name_;
private:
/// @brief Creates an instance of the Control Agent application
/// process.
///
/// This method is invoked during the process initialization step of
/// the controller launch.
///
/// @return returns a DProcessBase* to the application process created.
/// Note the caller is responsible for destructing the process. This
/// is handled by the base class, which wraps this pointer with a smart
/// pointer.
virtual process::DProcessBase* createProcess();
/// @brief Constructor is declared private to maintain the integrity of
/// the singleton instance.
CtrlAgentController();
};
} // namespace isc::agent
} // namespace isc
#endif // CTRL_AGENT_CONTROLLER_H
// Copyright (C) 2016 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 <agent/ctrl_agent_log.h>
namespace isc {
namespace agent {
isc::log::Logger agent_logger("ctrl-agent");
} // namespace isc::agent
} // namespace isc
// Copyright (C) 2016 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 CTRL_AGENT_LOG_H
#define CTRL_AGENT_LOG_H
#include <log/logger_support.h>
#include <log/macros.h>
#include <agent/ctrl_agent_messages.h>
namespace isc {
namespace agent {
/// @brief Control Agent logger.
extern isc::log::Logger agent_logger;
} // namespace isc::agent
} // namespace isc
#endif
# Copyright (C) 2016 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/.
$NAMESPACE isc::agent
% CTRL_AGENT_FAILED application experienced a fatal error: %1
This is a debug message issued when the Control Agent application
encounters an unrecoverable error from within the event loop.
% CTRL_AGENT_RUN_EXIT application is exiting the event loop
This is a debug message issued when the Control Angent exits its
event loop.
% CTRL_AGENT_STARTED Kea Control Agent version %1 started
This informational message indicates that the DHCP-DDNS server has
processed all configuration information and is ready to begin processing.
The version is also printed.
// Copyright (C) 2016 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 <agent/ctrl_agent_process.h>
#include <agent/ctrl_agent_log.h>
#include <cc/command_interpreter.h>
using namespace isc::process;
namespace isc {
namespace agent {
CtrlAgentProcess::CtrlAgentProcess(const char* name,
const asiolink::IOServicePtr& io_service)
: DProcessBase(name, io_service, DCfgMgrBasePtr(new CtrlAgentCfgMgr())) {
}
CtrlAgentProcess::~CtrlAgentProcess() {
}
void
CtrlAgentProcess::init() {
}
void
CtrlAgentProcess::run() {
LOG_INFO(agent_logger, CTRL_AGENT_STARTED).arg(VERSION);
while (!shouldShutdown()) {
try {
getIoService()->run_one();
} catch (const std::exception& ex) {
LOG_FATAL(agent_logger, CTRL_AGENT_FAILED).arg(ex.what());
isc_throw(DProcessBaseError,
"Process run method failed: " << ex.what());
}
}
LOG_DEBUG(agent_logger, DBGLVL_START_SHUT, CTRL_AGENT_RUN_EXIT);
}
isc::data::ConstElementPtr
CtrlAgentProcess::shutdown(isc::data::ConstElementPtr args) {
setShutdownFlag(true);
return (isc::config::createAnswer(0, "Control Agent is shutting down"));
}
isc::data::ConstElementPtr
CtrlAgentProcess::configure(isc::data::ConstElementPtr config_set) {
int rcode = 0;
isc::data::ConstElementPtr answer = getCfgMgr()->parseConfig(config_set);
config::parseAnswer(rcode, answer);
return (answer);
}
isc::data::ConstElementPtr
CtrlAgentProcess::command(const std::string& command,
isc::data::ConstElementPtr args) {
return (isc::config::createAnswer(COMMAND_INVALID, "Unrecognized command: "
+ command));
}
CtrlAgentCfgMgrPtr
CtrlAgentProcess::getCtrlAgentCfgMgr() {
return(boost::dynamic_pointer_cast<CtrlAgentCfgMgr>(getCfgMgr()));
}
} // namespace isc::agent
} // namespace isc
// Copyright (C) 2016 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 CTRL_AGENT_PROCESS_H
#define CTRL_AGENT_PROCESS_H
#include <agent/ctrl_agent_cfg_mgr.h>
#include <process/d_process.h>
namespace isc {
namespace agent {
/// @brief Kea Control Agent Application Process
///
/// CtrlAgentProcess provides top level application logic for the Control
/// Agent, a process managing Kea servers.
///
/// The Control Agent receives JSON control commands over HTTP and forwards
/// the JSON commands to the respective Kea servers. The JSON command
/// includes a name of the server to which the command pertains. After
/// receiving a response from the Kea server it is sent back over HTTP
/// to the control API client.
///
/// Some commands are handled by the Control Agent process itself, rather than
/// forwarded to the Kea servers. An example of such command is the one that
/// instructs the agent to start a specific service.
class CtrlAgentProcess : public process::DProcessBase {
public:
/// @brief Constructor
///
/// @param name name is a text label for the process. Generally used
/// in log statements, but otherwise arbitrary.
/// @param io_service is the io_service used by the caller for
/// asynchronous event handling.
CtrlAgentProcess(const char* name, const asiolink::IOServicePtr& io_service);
/// @brief Destructor
virtual ~CtrlAgentProcess();
/// @brief Initialize the Control Agent process.
///
/// This is invoked by the controller after command line arguments but
/// prior to configuration reception. The base class provides this method
/// as a place to perform any derivation-specific initialization steps
/// that are inappropriate for the constructor but necessary prior to
/// launch.
virtual void init();
/// @brief Implements the process's event loop.
///
/// @throw DProcessBaseError if an operational error is encountered.
virtual void run();
/// @brief Initiates the process's shutdown process.
///
/// This is last step in the shutdown event callback chain, that is
/// intended to notify the process it is to begin its shutdown process.
///
/// @param args an Element set of shutdown arguments (if any) that are
/// supported by the process derivation.
///
/// @return an Element that contains the results of argument processing,
/// consisting of an integer status value (0 means successful,
/// non-zero means failure), and a string explanation of the outcome.
///
/// @throw DProcessBaseError if an operational error is encountered.
virtual isc::data::ConstElementPtr
shutdown(isc::data::ConstElementPtr args);
/// @brief Processes the given configuration.
///
/// This method may be called multiple times during the process lifetime.
/// Certainly once during process startup, and possibly later if the user
/// alters configuration. This method must not throw, it should catch any
/// processing errors and return a success or failure answer as described
/// below.
///
/// @param config_set a new configuration (JSON) for the process
/// @return an Element that contains the results of configuration composed
/// of an integer status value (0 means successful, non-zero means failure),
/// and a string explanation of the outcome.
virtual isc::data::ConstElementPtr
configure(isc::data::ConstElementPtr config_set);
/// @brief Processes the given command.
///
/// This method is called to execute any custom commands supported by the
/// process. This method must not throw, it should catch any processing
/// errors and return a success or failure answer as described below.
///
/// @param command is a string label representing the command to execute.
/// @param args is a set of arguments (if any) required for the given
/// command.
/// @return an Element that contains the results of command composed
/// of an integer status value:
///
/// - COMMAND_SUCCESS indicates a command was successful.
/// - COMMAND_ERROR indicates a valid command failed execute.
/// - COMMAND_INVALID indicates a command is not valid.
///
/// and a string explanation of the outcome.
virtual isc::data::ConstElementPtr
command(const std::string& command, isc::data::ConstElementPtr args);
/// @brief Returns a pointer to the configuration manager.
CtrlAgentCfgMgrPtr getCtrlAgentCfgMgr();
};
/// @brief Defines a shared pointer to CtrlAgentProcess.
typedef boost::shared_ptr<CtrlAgentProcess> CtrlAgentProcessPtr;
}; // namespace isc::agent
}; // namespace isc
#endif // CTRL_AGENT_PROCESS_H
// Copyright (C) 2016 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 <agent/ctrl_agent_controller.h>
#include <exceptions/exceptions.h>
#include <cstdlib>
#include <iostream>
using namespace isc::agent;
using namespace isc::process;
int main(int argc, char* argv[]) {
int ret = EXIT_SUCCESS;
// Launch the controller passing in command line arguments.
// Exit program with the controller's return code.
try {
// Instantiate/fetch the application controller singleton.
DControllerBasePtr& controller = CtrlAgentController::instance();
// 'false' value disables test mode.
controller->launch(argc, argv, false);
} catch (const VersionMessage& ex) {
std::cout << ex.what() << std::endl;
} catch (const isc::Exception& ex) {
std::cerr << "Service failed:" << ex.what() << std::endl;
ret = EXIT_FAILURE;
}
return (ret);
}
/ctrl_agent_unittests
/ctrl_agent_process_tests.sh
SHTESTS =
# The test of dynamic reconfiguration based on signals will work only
# if we are using file based configuration approach.
SHTESTS += ctrl_agent_process_tests.sh
noinst_SCRIPTS = ctrl_agent_process_tests.sh
EXTRA_DIST = ctrl_agent_process_tests.sh.in
# test using command-line arguments, so use check-local target instead of TESTS
check-local:
for shtest in $(SHTESTS) ; do \
echo Running test: $$shtest ; \
export KEA_LOCKFILE_DIR=$(abs_top_builddir); \
export KEA_PIDFILE_DIR=$(abs_top_builddir); \
${SHELL} $(abs_builddir)/$$shtest || exit ; \
done
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/bin # for generated spec_config.h header
AM_CPPFLAGS += -I$(top_srcdir)/src/bin
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/bin/agent/tests\"
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
CLEANFILES = $(builddir)/interfaces.txt $(builddir)/logger_lockfile
DISTCLEANFILES = ctrl_agent_process_tests.sh
AM_CXXFLAGS =