Commit a5b5c2b7 authored by Francis Dupont's avatar Francis Dupont

[3732] removed bundy from code and most docs

parent 95750a3a
......@@ -1279,34 +1279,6 @@ AC_SUBST(PERL)
AC_PATH_PROGS(AWK, gawk awk)
AC_SUBST(AWK)
# Kea configuration backend section
# Currently there are 2 backends available: BUNDY and JSON
# It is possible that we may extend this to accept additional backends.
AC_ARG_WITH(kea-config,
AC_HELP_STRING([--with-kea-config],
[Selects configuration backend; currently available options are: BUNDY
(Kea reads configuration and commands from Bundy framework) or JSON (default,
Kea reads configuration from a JSON file from disk)]),
[CONFIG_BACKEND="$withval"],
[CONFIG_BACKEND=JSON])
AM_CONDITIONAL(CONFIG_BACKEND_BUNDY, test "x$CONFIG_BACKEND" = "xBUNDY")
AM_CONDITIONAL(CONFIG_BACKEND_JSON, test "x$CONFIG_BACKEND" = "xJSON")
if test "x$CONFIG_BACKEND" = "xBUNDY"; then
AC_DEFINE(CONFIG_BACKEND_BUNDY, 1, [Define to 1 if Kea config was set to BUNDY])
fi
if test "x$CONFIG_BACKEND" = "xJSON"; then
AC_DEFINE(CONFIG_BACKEND_JSON, 1, [Define to 1 if Kea config was set to JSON])
fi
# Let's sanity check if the specified backend value is allowed
if test "x$CONFIG_BACKEND" != "xBUNDY" && test "x$CONFIG_BACKEND" != "xJSON"; then
AC_MSG_ERROR("Invalid configuration backend specified: $CONFIG_BACKEND. The only supported are: BUNDY JSON")
fi
AC_ARG_ENABLE(generate_docs, [AC_HELP_STRING([--enable-generate-docs],
[regenerate documentation using Docbook [default=no]])],
enable_generate_docs=$enableval, enable_generate_docs=no)
......
// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
......@@ -43,7 +43,7 @@ decided to keep it. However, even though the Kea team is focused on a
backend that reads a JSON configuration file from disk, it decided to
make it easy for others to use different backends.
While ISC currently (May 2014) plans to maintain only one configuration backend
While ISC currently (May 2015) maintains only one configuration backend
(a JSON file read from disk), there may be other organizations (e.g.
the Bundy project community) that will maintain other backends. It is quite
possible that additional backends (e.g. using LDAP or XML) will be
......@@ -87,13 +87,12 @@ The following are some details of the JSON backend framework.
-# A switch called --with-kea-config has been implemented in the
configure script. It allows the selection at compilation time of how the
servers will be configured. Currently (June 2014),
there are two values: JSON (the default, read configuration from a JSON file)
and BUNDY (use the BUNDY/BIND10 framework). Although the Bundy/BIND10
framework has been removed from Kea, the configuration choice
is available for other projects (e.g. Bundy) that want to include an
implementation of Kea using that backend. Such projects are advised to
import the Kea modules and compile them with the Bundy backend
enabled.<br/><br/>
there is one value: JSON (read configuration from a JSON file)
Although the Bundy/BIND10 framework has been removed from Kea, the
configuration choice is available for other projects (e.g. Bundy)
that want to include an implementation of Kea using that backend.
Such projects are advised to import the Kea modules and compile
them with the Bundy backend enabled.<br/><br/>
This switchable backend concept is quite simple. There are different
implementations of ControlledXSrv class, each backend keeping its code
in a separate file. It is a matter of compiling/linking
......
......@@ -6,20 +6,8 @@
<chapter id="kea-config">
<title>Kea configuration</title>
<para>Depending on the configuration backend chosen (see <xref
linkend="dhcp-config-backend"/>), the configuration mechanisms are different. The
following sections describe details of the different configuration backends. Note
that only one configuration backend can be used and its selection is
made when the configure script is run.</para>
<section id="bundy-backend">
<title>BUNDY configuration backend</title>
<para>This legacy configuration backend allows Kea to use the former BIND 10
framework. That framework and this Kea configuration backend is no longer
supported by ISC. It is currently developed as part of the Bundy project (see
<ulink url="http://bundy-dns.de">Bundy homepage</ulink>). See the Bundy project
documentation regarding configuration.</para>
</section>
<para>The following section describe details of the only configuration
backend which can be configured and used.</para>
<section id="json-backend">
<title>JSON configuration backend</title>
......
......@@ -389,29 +389,12 @@ Debian and Ubuntu:
<section id="dhcp-config-backend">
<title>Selecting the Configuration Backend</title>
<para>Kea 0.9 has introduced configuration backends that are
switchable during the compilation phase. The backend is chosen using
the --with-kea-config switch when running the configure script. It
currently supports two values: BUNDY and JSON. JSON is the default.
switchable during the compilation phase. Only one backend, JSON,
is currently supported.
</para>
<variablelist>
<varlistentry>
<term>BUNDY</term>
<listitem>
<simpara>BUNDY means
that Kea is linked with the Bundy configuration backend that
connects to the Bundy framework and in general works exactly the
same as Kea 0.8 and earlier BIND10 versions. The benefits
of that backend are uniform integration with the Bundy
framework, easy on-line reconfiguration using bindctl,
available RESTful API. On the other hand, it requires
the whole heavy Bundy framework that requires Python3
to be present. That backend is likely to go away with
the release of Kea 1.0.</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term>JSON</term>
<listitem>
......
# The following build order must be maintained.
SUBDIRS = dhcp4 dhcp6 d2 perfdhcp admin lfc
if CONFIG_BACKEND_JSON
SUBDIRS += keactrl
endif
SUBDIRS = dhcp4 dhcp6 d2 perfdhcp admin lfc keactrl
check-recursive: all-recursive
......@@ -69,13 +69,7 @@ libd2_la_SOURCES += nc_remove.cc nc_remove.h
libd2_la_SOURCES += nc_trans.cc nc_trans.h
libd2_la_SOURCES += state_model.cc state_model.h
if CONFIG_BACKEND_BUNDY
libd2_la_SOURCES += bundy_d2_controller.cc bundy_d2_controller.h
else
if CONFIG_BACKEND_JSON
libd2_la_SOURCES += d2_controller.cc d2_controller.h
endif
endif
nodist_libd2_la_SOURCES = d2_messages.h d2_messages.cc
EXTRA_DIST += d2_messages.mes
......
// Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <config.h>
#include <d2/bundy_d2_controller.h>
#include <d2/d2_process.h>
#include <d2/spec_config.h>
#include <sstream>
namespace isc {
namespace d2 {
/// @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* D2Controller::d2_app_name_ = "DHCP-DDNS";
/// @brief Defines the executable name. This is passed into the base class
const char* D2Controller::d2_bin_name_ = "kea-dhcp-ddns";
DControllerBasePtr&
D2Controller::instance() {
// If the instance hasn't been created yet, create it. Note this method
// must use the base class singleton instance methods. The base class
// must have access to the singleton in order to use it within BUNDY
// static function callbacks.
if (!getController()) {
DControllerBasePtr controller_ptr(new D2Controller());
setController(controller_ptr);
}
return (getController());
}
DProcessBase* D2Controller::createProcess() {
// Instantiate and return an instance of the D2 application process. Note
// that the process is passed the controller's io_service.
return (new D2Process(getAppName().c_str(), getIOService()));
}
D2Controller::D2Controller()
: DControllerBase(d2_app_name_, d2_bin_name_) {
// set the spec file either from the environment or
// use the production value.
if (getenv("KEA_FROM_BUILD")) {
setSpecFileName(std::string(getenv("KEA_FROM_BUILD")) +
"/src/bin/d2/dhcp-ddns.spec");
} else {
setSpecFileName(D2_SPECFILE_LOCATION);
}
}
D2Controller::~D2Controller() {
}
void
D2Controller::launch(int argc, char* argv[], const bool test_mode) {
// Step 1 is to parse the command line arguments.
try {
parseArgs(argc, argv);
} catch (const InvalidUsage& ex) {
usage(ex.what());
throw; // rethrow it
}
// Do not initialize logger here if we are running unit tests. It would
// replace an instance of unit test specific logger.
if (!test_mode) {
// Now that we know what the mode flags are, we can init logging.
// If standalone is enabled, do not buffer initial log messages
isc::log::initLogger(getBinName(),
(isVerbose() ? isc::log::DEBUG : isc::log::INFO),
isc::log::MAX_DEBUG_LEVEL, NULL, true);
}
LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_STARTING)
.arg(getAppName()).arg(getpid());
try {
// Step 2 is to create and initialize the application process object.
initProcess();
} catch (const std::exception& ex) {
LOG_FATAL(dctl_logger, DCTL_INIT_PROCESS_FAIL)
.arg(getAppName()).arg(ex.what());
isc_throw (ProcessInitError,
"Application Process initialization failed: " << ex.what());
}
// Next we connect to Bundy.
try {
establishSession();
} catch (const std::exception& ex) {
LOG_FATAL(dctl_logger, DCTL_SESSION_FAIL).arg(ex.what());
isc_throw (SessionStartError,
"Session start up failed: " << ex.what());
}
// Everything is clear for launch, so start the application's
// event loop.
try {
runProcess();
} catch (const std::exception& ex) {
LOG_FATAL(dctl_logger, DCTL_PROCESS_FAILED)
.arg(getAppName()).arg(ex.what());
isc_throw (ProcessRunError,
"Application process event loop failed: " << ex.what());
}
// Disconnect from Bundy.
try {
disconnectSession();
} catch (const std::exception& ex) {
LOG_ERROR(dctl_logger, DCTL_DISCONNECT_FAIL)
.arg(getAppName()).arg(ex.what());
isc_throw (SessionEndError, "Session end failed: " << ex.what());
}
// All done, so bail out.
LOG_INFO(dctl_logger, DCTL_STOPPING).arg(getAppName());
}
void
D2Controller::parseArgs(int argc, char* argv[])
{
// Iterate over the given command line options. If its a stock option
// ("s" or "v") handle it here. If its a valid custom option, then
// invoke customOption.
int ch;
opterr = 0;
optind = 1;
std::string opts(":v" + getCustomOpts());
while ((ch = getopt(argc, argv, opts.c_str())) != -1) {
switch (ch) {
case 'v':
// Enables verbose logging.
setVerbose(true);
break;
case '?': {
// We hit an invalid option.
isc_throw(InvalidUsage, "unsupported option: ["
<< static_cast<char>(optopt) << "] "
<< (!optarg ? "" : optarg));
break;
}
default:
// We hit a valid custom option
if (!customOption(ch, optarg)) {
// This would be a programmatic error.
isc_throw(InvalidUsage, " Option listed but implemented?: ["
<< static_cast<char>(ch) << "] "
<< (!optarg ? "" : optarg));
}
break;
}
}
// There was too much information on the command line.
if (argc > optind) {
isc_throw(InvalidUsage, "extraneous command line information");
}
}
void
D2Controller::establishSession() {
LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_CCSESSION_STARTING)
.arg(getAppName()).arg(getSpecFileName());
// Create the Bundy command control session with the our IOService.
cc_session_ = SessionPtr(new isc::cc::Session(
getIOService()->get_io_service()));
// Create the Bundy config session with the stub configuration handler.
// This handler is internally invoked by the constructor and on success
// the constructor updates the current session with the configuration that
// had been committed in the previous session. If we do not install
// the dummy handler, the previous configuration would be lost.
config_session_ = ModuleCCSessionPtr(new isc::config::ModuleCCSession(
getSpecFileName(), *cc_session_,
dummyConfigHandler,
commandHandler,
false));
// Enable configuration even processing.
config_session_->start();
// We initially create ModuleCCSession() with a dummy configHandler, as
// the session module is too eager to send partial configuration.
// Replace the dummy config handler with the real handler.
config_session_->setConfigHandler(configHandler);
// Call the real configHandler with the full configuration retrieved
// from the config session.
isc::data::ConstElementPtr answer = configHandler(
config_session_->getFullConfig());
// Parse the answer returned from the configHandler. Log the error but
// keep running. This provides an opportunity for the user to correct
// the configuration dynamically.
int ret = 0;
isc::data::ConstElementPtr comment = isc::config::parseAnswer(ret, answer);
if (ret) {
LOG_ERROR(dctl_logger, DCTL_CONFIG_LOAD_FAIL)
.arg(getAppName()).arg(comment->str());
}
}
void D2Controller::disconnectSession() {
LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_CCSESSION_ENDING)
.arg(getAppName());
// Destroy the Bundy config session.
if (config_session_) {
config_session_.reset();
}
// Destroy the Bundy command and control session.
if (cc_session_) {
cc_session_->disconnect();
cc_session_.reset();
}
}
isc::data::ConstElementPtr
D2Controller::dummyConfigHandler(isc::data::ConstElementPtr) {
LOG_DEBUG(dctl_logger, DBGLVL_START_SHUT, DCTL_CONFIG_STUB)
.arg(getController()->getAppName());
return (isc::config::createAnswer(0, "Configuration accepted."));
}
isc::data::ConstElementPtr
D2Controller::configHandler(isc::data::ConstElementPtr new_config) {
LOG_DEBUG(dctl_logger, DBGLVL_COMMAND, DCTL_CONFIG_UPDATE)
.arg(getController()->getAppName()).arg(new_config->str());
// Invoke the instance method on the controller singleton.
return (getController()->updateConfig(new_config));
}
// Static callback which invokes non-static handler on singleton
isc::data::ConstElementPtr
D2Controller::commandHandler(const std::string& command,
isc::data::ConstElementPtr args) {
LOG_DEBUG(dctl_logger, DBGLVL_COMMAND, DCTL_COMMAND_RECEIVED)
.arg(getController()->getAppName()).arg(command)
.arg(args ? args->str() : "(no args)");
// Invoke the instance method on the controller singleton.
return (getController()->executeCommand(command, args));
}
isc::data::ConstElementPtr
D2Controller::updateConfig(isc::data::ConstElementPtr new_config) {
if (!config_session_) {
// That should never happen as we install config_handler
// after we instantiate the server.
isc::data::ConstElementPtr answer =
isc::config::createAnswer(1, "Configuration rejected,"
" Session has not started.");
return (answer);
}
// Let's get the existing configuration.
isc::data::ConstElementPtr full_config = config_session_->getFullConfig();
// The configuration passed to this handler function is partial.
// In other words, it just includes the values being modified.
// In the same time, there may be dependencies between various
// configuration parsers. For example: the option value can
// be set if the definition of this option is set. If someone removes
// an existing option definition then the partial configuration that
// removes that definition is triggered while a relevant option value
// may remain configured. This eventually results in the
// configuration being in the inconsistent state.
// In order to work around this problem we need to merge the new
// configuration with the existing (full) configuration.
// Let's create a new object that will hold the merged configuration.
boost::shared_ptr<isc::data::MapElement>
merged_config(new isc::data::MapElement());
// Merge an existing and new configuration.
merged_config->setValue(full_config->mapValue());
isc::data::merge(merged_config, new_config);
// Send the merged configuration to the application.
return (getProcess()->configure(merged_config));
}
void
D2Controller::usage(const std::string & text)
{
if (text != "") {
std::cerr << "Usage error: " << text << std::endl;
}
std::cerr << "Usage: " << getBinName() << std::endl;
std::cerr << " -v: verbose output" << std::endl;
std::cerr << getUsageText() << std::endl;
}
}; // namespace isc::d2
}; // namespace isc
// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef BUNDY_D2_CONTROLLER_H
#define BUNDY_D2_CONTROLLER_H
#include <asiolink/io_service.h>
#include <cc/data.h>
#include <cc/session.h>
#include <config/ccsession.h>
#include <d2/d2_log.h>
#include <d2/d_controller.h>
#include <d2/d_process.h>
#include <exceptions/exceptions.h>
#include <log/logger_support.h>
#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>
namespace isc {
namespace d2 {
/// @brief Exception thrown when the session start up fails.
class SessionStartError: public isc::Exception {
public:
SessionStartError (const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) { };
};
/// @brief Exception thrown when the session end fails.
class SessionEndError: public isc::Exception {
public:
SessionEndError (const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) { };
};
/// @brief Defines a shared pointer to a Session.
typedef boost::shared_ptr<isc::cc::Session> SessionPtr;
/// @brief Defines a shared pointer to a ModuleCCSession.
typedef boost::shared_ptr<isc::config::ModuleCCSession> ModuleCCSessionPtr;
/// @brief Bundy-integrated Process Controller for D2 Process
/// This class is the DHCP-DDNS specific derivation of DControllerBase which
/// is managed by BUNDY. It creates and manages an instance of the DHCP-DDNS
/// application process, D2Process.
///
/// D2 will be constructed with this class if the project is configured with
/// --with-kea-config=BUNDY
class D2Controller : public 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 DControllerBasePtr& instance();
/// @brief Destructor.
virtual ~D2Controller();
/// @brief Defines the application name, this is passed into base class
/// and appears in log statements.
static const char* d2_app_name_;
/// @brief Defines the executable name. This is passed into the base class
/// by convention this should match the BUNDY module name.
static const char* d2_bin_name_;
/// @brief Acts as the primary entry point into the controller execution
/// and provides the outermost application control logic:
///
/// 1. parse command line arguments
/// 2. instantiate and initialize the application process
/// 3. establish BUNDY session(s) if in integrated mode
/// 4. start and wait on the application process event loop
/// 5. upon event loop completion, disconnect from BUNDY (if needed)
/// 6. exit to the caller
///
/// It is intended to be called from main() and be given the command line
/// arguments. Note this method is deliberately not virtual to ensure the
/// proper sequence of events occur.
///
/// This function can be run in the test mode. It prevents initialization
/// of D2 module logger. This is used in unit tests which initialize logger
/// in their main function. Such logger uses environmental variables to
/// control severity, verbosity etc. Reinitialization of logger by this
/// function would replace unit tests specific logger configuration with
/// this suitable for D2 running as a Bundy module.
///
/// @param argc is the number of command line arguments supplied
/// @param argv is the array of string (char *) command line arguments
/// @param test_mode is a bool value which indicates if
/// @c DControllerBase::launch should be run in the test mode (if true).
/// This parameter doesn't have default value to force test implementers to
/// enable test mode explicitly.
///
/// @throw throws one of the following exceptions:
/// InvalidUsage - Indicates invalid command line.
/// ProcessInitError - Failed to create and initialize application
/// process object.
/// SessionStartError - Could not connect to BUNDY (integrated mode only).
/// ProcessRunError - A fatal error occurred while in the application
/// process event loop.
/// SessionEndError - Could not disconnect from BUNDY (integrated mode
/// only).
virtual void launch(int argc, char* argv[], const bool test_mode);
/// @brief A dummy configuration handler that always returns success.
///
/// This configuration handler does not perform configuration
/// parsing and always returns success. A dummy handler should
/// be installed using \ref isc::config::ModuleCCSession ctor
/// to get the initial configuration. This initial configuration
/// comprises values for only those elements that were modified
/// the previous session. The D2 configuration parsing can't be
/// used to parse the initial configuration because it may need the
/// full configuration to satisfy dependencies between the
/// various configuration values. Installing the dummy handler
/// that guarantees to return success causes initial configuration
/// to be stored for the session being created and that it can
/// be later accessed with \ref isc::config::ConfigData::getFullConfig.
///
/// @param new_config new configuration.
///
/// @return success configuration status.
static isc::data::ConstElementPtr
dummyConfigHandler(isc::data::ConstElementPtr new_config);
/// @brief A callback for handling all incoming configuration updates.
///