24 {
"delayed-updates-limit", Element::integer,
"100" },
29 {
"delayed-updates-limit", Element::integer,
"0" },
30 {
"heartbeat-delay", Element::integer,
"10000" },
31 {
"max-ack-delay", Element::integer,
"10000" },
32 {
"max-response-delay", Element::integer,
"60000" },
33 {
"max-unacked-clients", Element::integer,
"10" },
34 {
"require-client-certs", Element::boolean,
"true" },
35 {
"restrict-commands", Element::boolean,
"false" },
36 {
"send-lease-updates", Element::boolean,
"true" },
37 {
"sync-leases", Element::boolean,
"true" },
38 {
"sync-timeout", Element::integer,
"60000" },
39 {
"sync-page-limit", Element::integer,
"10000" },
40 {
"wait-backup-ack", Element::boolean,
"false" }
45 {
"enable-multi-threading", Element::boolean,
"false" },
46 {
"http-client-threads", Element::integer,
"0" },
47 {
"http-dedicated-listener", Element::boolean,
"false" },
48 {
"http-listener-threads", Element::integer,
"0" }
53 {
"auto-failover", Element::boolean,
"true" }
58 {
"pause", Element::string,
"never" }
72 parseInternal(config_storage, config);
73 logConfigStatus(config_storage);
78 }
catch (
const std::exception& ex) {
84HAConfigParser::parseInternal(
const HAConfigPtr& config_storage,
93 if (config->getType() != Element::list) {
97 const auto& config_vec = config->listValue();
98 if (config_vec.size() != 1) {
99 isc_throw(ConfigError,
"invalid number of configurations in the HA configuration"
100 " list. Expected exactly one configuration");
108 config_storage->setHAMode(
getString(c,
"mode"));
118 if (c->getType() != Element::map) {
119 isc_throw(ConfigError,
"expected list of maps in the HA configuration");
123 if (!c->contains(
"peers")) {
124 isc_throw(ConfigError,
"'peers' parameter missing in HA configuration");
129 if (peers->getType() != Element::list) {
130 isc_throw(ConfigError,
"'peers' parameter must be a list");
137 if (state_machine->getType() != Element::map) {
138 isc_throw(ConfigError,
"'state-machine' parameter must be a map");
141 states_list = state_machine->get(
"states");
142 if (states_list && (states_list->getType() != Element::list)) {
143 isc_throw(ConfigError,
"'states' parameter must be a list");
150 config_storage->setThisServerName(
getString(c,
"this-server-name"));
153 config_storage->setSendLeaseUpdates(
getBoolean(c,
"send-lease-updates"));
156 config_storage->setSyncLeases(
getBoolean(c,
"sync-leases"));
159 uint32_t sync_timeout = getAndValidateInteger<uint32_t>(c,
"sync-timeout");
160 config_storage->setSyncTimeout(sync_timeout);
163 uint32_t sync_page_limit = getAndValidateInteger<uint32_t>(c,
"sync-page-limit");
164 config_storage->setSyncPageLimit(sync_page_limit);
167 uint32_t delayed_updates_limit = getAndValidateInteger<uint32_t>(c,
"delayed-updates-limit");
168 config_storage->setDelayedUpdatesLimit(delayed_updates_limit);
171 uint16_t heartbeat_delay = getAndValidateInteger<uint16_t>(c,
"heartbeat-delay");
172 config_storage->setHeartbeatDelay(heartbeat_delay);
175 uint16_t max_response_delay = getAndValidateInteger<uint16_t>(c,
"max-response-delay");
176 config_storage->setMaxResponseDelay(max_response_delay);
179 uint16_t max_ack_delay = getAndValidateInteger<uint16_t>(c,
"max-ack-delay");
180 config_storage->setMaxAckDelay(max_ack_delay);
183 uint32_t max_unacked_clients = getAndValidateInteger<uint32_t>(c,
"max-unacked-clients");
184 config_storage->setMaxUnackedClients(max_unacked_clients);
187 config_storage->setWaitBackupAck(
getBoolean(c,
"wait-backup-ack"));
190 ElementPtr mt_config = boost::const_pointer_cast<Element>(c->get(
"multi-threading"));
193 mt_config = Element::createMap();
194 c->set(
"multi-threading", mt_config);
195 }
else if (mt_config->getType() != Element::map) {
196 isc_throw(ConfigError,
"multi-threading configuration must be a map");
203 config_storage->setEnableMultiThreading(
getBoolean(mt_config,
"enable-multi-threading"));
206 config_storage->setHttpDedicatedListener(
getBoolean(mt_config,
"http-dedicated-listener"));
209 uint32_t threads = getAndValidateInteger<uint32_t>(mt_config,
"http-listener-threads");
210 config_storage->setHttpListenerThreads(threads);
213 threads = getAndValidateInteger<uint32_t>(mt_config,
"http-client-threads");
214 config_storage->setHttpClientThreads(threads);
219 config_storage->setTrustAnchor(
getString(c,
"trust-anchor"));
225 config_storage->setCertFile(
getString(c,
"cert-file"));
231 config_storage->setKeyFile(
getString(c,
"key-file"));
235 config_storage->setRequireClientCerts(
getBoolean(c,
"require-client-certs"));
238 config_storage->setRestrictCommands(
getBoolean(c,
"restrict-commands"));
241 const auto& peers_vec = peers->listValue();
244 for (
auto p = peers_vec.begin(); p != peers_vec.end(); ++p) {
247 if ((*p)->getType() != Element::map) {
248 isc_throw(ConfigError,
"peer configuration must be a map");
254 auto cfg = config_storage->selectNextPeerConfig(
getString(*p,
"name"));
260 if ((*p)->contains(
"trust-anchor")) {
261 cfg->setTrustAnchor(
getString(*p, (
"trust-anchor")));
265 if ((*p)->contains(
"cert-file")) {
266 cfg->setCertFile(
getString(*p, (
"cert-file")));
270 if ((*p)->contains(
"key-file")) {
271 cfg->setKeyFile(
getString(*p, (
"key-file")));
278 cfg->setAutoFailover(
getBoolean(*p,
"auto-failover"));
281 std::string password;
282 if ((*p)->contains(
"basic-auth-password")) {
283 if ((*p)->contains(
"basic-auth-password-file")) {
284 isc_throw(dhcp::DhcpConfigError,
"only one of "
285 <<
"basic-auth-password and "
286 <<
"basic-auth-password-file parameter can be "
287 <<
"configured in peer '"
288 << cfg->getName() <<
"'");
290 password =
getString((*p),
"basic-auth-password");
292 if ((*p)->contains(
"basic-auth-password-file")) {
293 std::string password_file =
294 getString((*p),
"basic-auth-password-file");
297 }
catch (
const std::exception& ex) {
298 isc_throw(dhcp::DhcpConfigError,
"bad password file in peer '"
299 << cfg->getName() <<
"': " << ex.what());
304 if ((*p)->contains(
"basic-auth-user")) {
305 std::string user =
getString((*p),
"basic-auth-user");
312 }
catch (
const std::exception& ex) {
313 isc_throw(dhcp::DhcpConfigError, ex.what() <<
" in peer '"
314 << cfg->getName() <<
"'");
321 const auto& states_vec = states_list->listValue();
323 std::set<int> configured_states;
326 for (
auto s = states_vec.begin(); s != states_vec.end(); ++s) {
329 if ((*s)->getType() != Element::map) {
330 isc_throw(ConfigError,
"state configuration must be a map");
336 std::string state_name =
getString(*s,
"state");
340 if (configured_states.count(state) > 0) {
341 isc_throw(ConfigError,
"duplicated configuration for the '"
342 << state_name <<
"' state");
344 configured_states.insert(state);
346 config_storage->getStateMachineConfig()->
347 getStateConfig(state)->setPausing(
getString(*s,
"pause"));
354 config_storage->validate();
359 const std::string& parameter_name)
const {
360 int64_t value =
getInteger(config, parameter_name);
362 isc_throw(ConfigError,
"'" << parameter_name <<
"' must not be negative");
364 }
else if (value > std::numeric_limits<T>::max()) {
365 isc_throw(ConfigError,
"'" << parameter_name <<
"' must not be greater than "
366 << +std::numeric_limits<T>::max());
369 return (
static_cast<T
>(value));
373HAConfigParser::logConfigStatus(
const HAConfigPtr& config_storage)
const {
379 if (!config_storage->amSendingLeaseUpdates()) {
384 if (!config_storage->amSyncingLeases()) {
389 if (config_storage->amSendingLeaseUpdates() !=
390 config_storage->amSyncingLeases()) {
392 .arg(config_storage->amSendingLeaseUpdates() ?
"true" :
"false")
393 .arg(config_storage->amSyncingLeases() ?
"true" :
"false");
403 if (!config_storage->getThisServerConfig()->isAutoFailover()) {
405 .arg(config_storage->getThisServerName());
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.
void parse(const HAConfigPtr &config_storage, const data::ConstElementPtr &config)
Parses HA configuration.
Represents a basic HTTP authentication.
#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
isc::log::Logger ha_logger("ha-hooks")
const isc::log::MessageID HA_CONFIGURATION_SUCCESSFUL
const isc::log::MessageID HA_CONFIG_AUTO_FAILOVER_DISABLED
boost::shared_ptr< HAConfig > HAConfigPtr
Pointer to the High Availability configuration structure.
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(const string &file_name)
Get the content of a regular file.
Defines the logger used by the top-level component of kea-lfc.