14#include <boost/make_shared.hpp> 
   71        auto config_storage = boost::make_shared<HAConfigMapper>();
 
   75        parseAll(config_storage, 
config);
 
   76        validateRelationships(config_storage);
 
   77        logConfigStatus(config_storage);
 
   78        return (config_storage);
 
   83    } 
catch (
const std::exception& ex) {
 
 
  103    auto const& config_vec = 
config->listValue();
 
  104    if (config_vec.empty()) {
 
  107    for (
auto const& cfg : config_vec) {
 
  108        parseOne(config_storage, cfg);
 
  117        isc_throw(ConfigError, 
"HA configuration must not be null");
 
  122        isc_throw(ConfigError, 
"HA configuration for a relationship must be a map");
 
  129    rel_config->setHAMode(
getString(config, 
"mode"));
 
  139    if (!config->contains(
"peers")) {
 
  140        isc_throw(ConfigError, 
"'peers' parameter missing in HA configuration");
 
  146        isc_throw(ConfigError, 
"'peers' parameter must be a list");
 
  154            isc_throw(ConfigError, 
"'state-machine' parameter must be a map");
 
  157        states_list = state_machine->get(
"states");
 
  158        if (states_list && (states_list->getType() != 
Element::list)) {
 
  159            isc_throw(ConfigError, 
"'states' parameter must be a list");
 
  166    rel_config->setThisServerName(
getString(config, 
"this-server-name"));
 
  169    rel_config->setSendLeaseUpdates(
getBoolean(config, 
"send-lease-updates"));
 
  172    rel_config->setSyncLeases(
getBoolean(config, 
"sync-leases"));
 
  175    uint32_t sync_timeout = getAndValidateInteger<uint32_t>(config, 
"sync-timeout");
 
  176    rel_config->setSyncTimeout(sync_timeout);
 
  179    uint32_t sync_page_limit = getAndValidateInteger<uint32_t>(config, 
"sync-page-limit");
 
  180    rel_config->setSyncPageLimit(sync_page_limit);
 
  183    uint32_t delayed_updates_limit = getAndValidateInteger<uint32_t>(config, 
"delayed-updates-limit");
 
  184    rel_config->setDelayedUpdatesLimit(delayed_updates_limit);
 
  187    uint16_t heartbeat_delay = getAndValidateInteger<uint16_t>(config, 
"heartbeat-delay");
 
  188    rel_config->setHeartbeatDelay(heartbeat_delay);
 
  191    uint16_t max_response_delay = getAndValidateInteger<uint16_t>(config, 
"max-response-delay");
 
  192    rel_config->setMaxResponseDelay(max_response_delay);
 
  195    uint16_t max_ack_delay = getAndValidateInteger<uint16_t>(config, 
"max-ack-delay");
 
  196    rel_config->setMaxAckDelay(max_ack_delay);
 
  199    uint32_t max_unacked_clients = getAndValidateInteger<uint32_t>(config, 
"max-unacked-clients");
 
  200    rel_config->setMaxUnackedClients(max_unacked_clients);
 
  203    uint32_t max_rejected_lease_updates = getAndValidateInteger<uint32_t>(config, 
"max-rejected-lease-updates");
 
  204    rel_config->setMaxRejectedLeaseUpdates(max_rejected_lease_updates);
 
  207    rel_config->setWaitBackupAck(
getBoolean(config, 
"wait-backup-ack"));
 
  210    ElementPtr mt_config = boost::const_pointer_cast<Element>(config->get(
"multi-threading"));
 
  214        config->set(
"multi-threading", mt_config);
 
  216        isc_throw(ConfigError, 
"multi-threading configuration must be a map");
 
  223    rel_config->setEnableMultiThreading(
getBoolean(mt_config, 
"enable-multi-threading"));
 
  226    rel_config->setHttpDedicatedListener(
getBoolean(mt_config, 
"http-dedicated-listener"));
 
  229    uint32_t threads = getAndValidateInteger<uint32_t>(mt_config, 
"http-listener-threads");
 
  230    rel_config->setHttpListenerThreads(threads);
 
  233    threads = getAndValidateInteger<uint32_t>(mt_config, 
"http-client-threads");
 
  234    rel_config->setHttpClientThreads(threads);
 
  239        rel_config->setTrustAnchor(
getString(config, 
"trust-anchor"));
 
  245        rel_config->setCertFile(
getString(config, 
"cert-file"));
 
  251        rel_config->setKeyFile(
getString(config, 
"key-file"));
 
  255    rel_config->setRequireClientCerts(
getBoolean(config, 
"require-client-certs"));
 
  258    rel_config->setRestrictCommands(
getBoolean(config, 
"restrict-commands"));
 
  261    auto const& peers_vec = peers->listValue();
 
  264    for (
auto const& p : peers_vec) {
 
  268            isc_throw(ConfigError, 
"peer configuration must be a map");
 
  274        auto cfg = rel_config->selectNextPeerConfig(
getString(p, 
"name"));
 
  280        if (p->contains(
"trust-anchor")) {
 
  281            cfg->setTrustAnchor(
getString(p, (
"trust-anchor")));
 
  285        if (p->contains(
"cert-file")) {
 
  286            cfg->setCertFile(
getString(p, (
"cert-file")));
 
  290        if (p->contains(
"key-file")) {
 
  291            cfg->setKeyFile(
getString(p, (
"key-file")));
 
  298        cfg->setAutoFailover(
getBoolean(p, 
"auto-failover"));
 
  301        std::string password;
 
  302        if (p->contains(
"basic-auth-password")) {
 
  303            if (p->contains(
"basic-auth-password-file")) {
 
  304                isc_throw(dhcp::DhcpConfigError, 
"only one of " 
  305                          << 
"basic-auth-password and " 
  306                          << 
"basic-auth-password-file parameter can be " 
  307                          << 
"configured in peer '" 
  308                          << cfg->getName() << 
"'");
 
  310            password = 
getString(p, 
"basic-auth-password");
 
  312        if (p->contains(
"basic-auth-password-file")) {
 
  313            std::string password_file =
 
  314                getString(p, 
"basic-auth-password-file");
 
  317            } 
catch (
const std::exception& ex) {
 
  318                isc_throw(dhcp::DhcpConfigError, 
"bad password file in peer '" 
  319                          << cfg->getName() << 
"': " << ex.what());
 
  324        if (p->contains(
"basic-auth-user")) {
 
  325            std::string user = 
getString(p, 
"basic-auth-user");
 
  330                    auth.reset(
new BasicHttpAuth(user, password));
 
  332            } 
catch (
const std::exception& ex) {
 
  333                isc_throw(dhcp::DhcpConfigError, ex.what() << 
" in peer '" 
  334                          << cfg->getName() << 
"'");
 
  341        auto const& states_vec = states_list->listValue();
 
  343        std::set<int> configured_states;
 
  346        for (
auto const& s : states_vec) {
 
  350                isc_throw(ConfigError, 
"state configuration must be a map");
 
  356            std::string state_name = 
getString(s, 
"state");
 
  360            if (configured_states.count(state) > 0) {
 
  361                isc_throw(ConfigError, 
"duplicated configuration for the '" 
  362                          << state_name << 
"' state");
 
  364            configured_states.insert(state);
 
  366            rel_config->getStateMachineConfig()->
 
  367                getStateConfig(state)->setPausing(
getString(s, 
"pause"));
 
  374    rel_config->validate();
 
  376    auto peer_configs = rel_config->getAllServersConfig();
 
  377    for (
auto const& peer_config : peer_configs) {
 
  379            config_storage->map(peer_config.first, rel_config);
 
  381        } 
catch (
const std::exception& ex) {
 
  382            isc_throw(HAConfigValidationError, 
"server names must be unique for different relationships: " 
  390                                        const std::string& parameter_name) {
 
  391    int64_t value = 
getInteger(config, parameter_name);
 
  393        isc_throw(ConfigError, 
"'" << parameter_name << 
"' must not be negative");
 
  395    } 
else if (value > std::numeric_limits<T>::max()) {
 
  396        isc_throw(ConfigError, 
"'" << parameter_name << 
"' must not be greater than " 
  397                                   << +std::numeric_limits<T>::max());
 
  400    return (
static_cast<T
>(value));
 
  407    for (
auto const& config : config_storage->getAll()) {
 
  411        if (!config->amSendingLeaseUpdates()) {
 
  413                .arg(config->getThisServerName());
 
  417        if (!config->amSyncingLeases()) {
 
  419                .arg(config->getThisServerName());
 
  423        if (config->amSendingLeaseUpdates() !=
 
  424            config->amSyncingLeases()) {
 
  426                .arg(config->getThisServerName())
 
  427                .arg(config->amSendingLeaseUpdates() ? 
"true" : 
"false")
 
  428                .arg(config->amSyncingLeases() ? 
"true" : 
"false");
 
  438        if (!config->getThisServerConfig()->isAutoFailover()) {
 
  440                .arg(config->getThisServerName());
 
  447    auto configs = config_storage->getAll();
 
  448    if (configs.size() <= 1) {
 
  451    std::unordered_set<std::string> server_names;
 
  452    for (
auto const& config : configs) {
 
  455            isc_throw(HAConfigValidationError, 
"multiple HA relationships are only supported for 'hot-standby' mode");
 
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
An exception that is thrown if an error occurs while configuring any server.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
static std::string getString(isc::data::ConstElementPtr scope, const std::string &name)
Returns a string parameter from a scope.
static bool getBoolean(isc::data::ConstElementPtr scope, const std::string &name)
Returns a boolean parameter from a scope.
static int64_t getInteger(isc::data::ConstElementPtr scope, const std::string &name)
Returns an integer parameter from a scope.
static size_t setDefaults(isc::data::ElementPtr scope, const SimpleDefaults &default_values)
Sets the default values.
static HAConfigMapperPtr parse(const data::ConstElementPtr &config)
Parses HA configuration.
static HAConfigPtr create()
Instantiates a HAConfig.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
boost::shared_ptr< const Element > ConstElementPtr
std::vector< SimpleDefault > SimpleDefaults
This specifies all default values in a given scope (e.g. a subnet).
boost::shared_ptr< Element > ElementPtr
boost::shared_ptr< HAConfigMapper > HAConfigMapperPtr
Pointer to an object mapping HAConfig to relationships.
isc::log::Logger ha_logger("ha-hooks")
const isc::log::MessageID HA_CONFIGURATION_SUCCESSFUL
const isc::log::MessageID HA_CONFIG_AUTO_FAILOVER_DISABLED
const isc::log::MessageID HA_CONFIG_LEASE_UPDATES_AND_SYNCING_DIFFER
const isc::log::MessageID HA_CONFIG_LEASE_UPDATES_DISABLED
const isc::log::MessageID HA_CONFIG_LEASE_SYNCING_DISABLED
int stringToState(const std::string &state_name)
Returns state for a given name.
boost::shared_ptr< BasicHttpAuth > BasicHttpAuthPtr
Type of pointers to basic HTTP authentication objects.
string getContent(string const &file_name)
Get the content of a regular file.
Defines the logger used by the top-level component of kea-lfc.