Kea 1.5.0
ha_config.cc
Go to the documentation of this file.
1// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
8#include <util/strutil.h>
9#include <ha_config.h>
10#include <ha_service_states.h>
11#include <sstream>
12
13using namespace isc::util;
14
15namespace isc {
16namespace ha {
17
19 : name_(), url_(""), role_(STANDBY), auto_failover_(false) {
20}
21
22void
23HAConfig::PeerConfig::setName(const std::string& name) {
24 // We want to make sure that someone didn't provide a name that consists of
25 // a single space, tab etc.
26 const std::string& s = util::str::trim(name);
27 if (s.empty()) {
28 isc_throw(BadValue, "peer name must not be empty");
29 }
30 name_ = s;
31}
32
33void
34HAConfig::PeerConfig::setRole(const std::string& role) {
35 role_ = stringToRole(role);
36}
37
38std::string
40 std::ostringstream label;
41 label << getName() << " (" << getUrl().toText() << ")";
42 return (label.str());
43}
44
46HAConfig::PeerConfig::stringToRole(const std::string& role) {
47 if (role == "primary") {
49
50 } else if (role == "secondary") {
52
53 } else if (role == "standby") {
55
56 } else if (role == "backup") {
58
59 }
60
61 // Invalid value specified.
62 isc_throw(BadValue, "unsupported value '" << role << "' for role parameter");
63}
64
65std::string
67 switch (role) {
69 return ("primary");
71 return ("secondary");
73 return ("standby");
75 return ("backup");
76 default:
77 ;
78 }
79 return ("");
80}
81
83 : state_(state), pausing_(STATE_PAUSE_NEVER) {
84}
85
86void
87HAConfig::StateConfig::setPausing(const std::string& pausing) {
88 pausing_ = stringToPausing(pausing);
89}
90
92HAConfig::StateConfig::stringToPausing(const std::string& pausing) {
93 if (pausing == "always") {
94 return (STATE_PAUSE_ALWAYS);
95
96 } else if (pausing == "never") {
97 return (STATE_PAUSE_NEVER);
98
99 } else if (pausing == "once") {
100 return (STATE_PAUSE_ONCE);
101 }
102
103 isc_throw(BadValue, "unsupported value " << pausing << " of 'pause' parameter");
104}
105
106std::string
108 switch (pausing) {
110 return ("always");
111
113 return ("never");
114
115 case STATE_PAUSE_ONCE:
116 return ("once");
117
118 default:
119 ;
120 }
121
122 isc_throw(BadValue, "unsupported pause enumeration " << static_cast<int>(pausing));
123}
124
127 // Return config for the state if it exists already.
128 auto state_config = states_.find(state);
129 if (state_config != states_.end()) {
130 return (state_config->second);
131 }
132
133 // Create config for the state and store its pointer.
134 StateConfigPtr new_state_config(new StateConfig(state));
135 states_[state] = new_state_config;
136
137 return (new_state_config);
138}
139
142 sync_leases_(true), sync_timeout_(60000), sync_page_limit_(10000),
145}
146
148HAConfig::selectNextPeerConfig(const std::string& name) {
149 // Check if there is a configuration for this server name alrady. We can't
150 // have two servers with the same name.
151 if (peers_.count(name) > 0) {
152 isc_throw(BadValue, "peer with name '" << name << "' already specified");
153 }
154
155 // Name appears to be unique, so let's add it.
156 PeerConfigPtr cfg(new PeerConfig());
157 cfg->setName(name);
158 peers_[name] = cfg;
159
160 // Return this to the caller so as the caller can set parsed configuration
161 // for this peer.
162 return (cfg);
163}
164
165void
166HAConfig::setThisServerName(const std::string& this_server_name) {
167 // Avoid names consisting of spaces, tabs etc.
168 std::string s = util::str::trim(this_server_name);
169 if (s.empty()) {
170 isc_throw(BadValue, "'this-server-name' value must not be empty");
171 }
172
174}
175
176
177void
178HAConfig::setHAMode(const std::string& ha_mode) {
179 ha_mode_ = stringToHAMode(ha_mode);
180}
181
183HAConfig::stringToHAMode(const std::string& ha_mode) {
184 if (ha_mode == "load-balancing") {
185 return (LOAD_BALANCING);
186
187 } else if (ha_mode == "hot-standby") {
188 return (HOT_STANDBY);
189 }
190
191 isc_throw(BadValue, "unsupported value '" << ha_mode << "' for mode parameter");
192}
193
194std::string
196 switch (ha_mode) {
197 case LOAD_BALANCING:
198 return ("load-balancing");
199 case HOT_STANDBY:
200 return ("hot-standby");
201 default:
202 ;
203 }
204 return ("");
205}
206
208HAConfig::getPeerConfig(const std::string& name) const {
209 auto peer = peers_.find(name);
210 if (peer == peers_.end()) {
211 isc_throw(InvalidOperation, "no configuration specified for server " << name);
212 }
213
214 return (peer->second);
215}
216
220 for (auto peer = servers.begin(); peer != servers.end(); ++peer) {
221 if (peer->second->getRole() != HAConfig::PeerConfig::BACKUP) {
222 return (peer->second);
223 }
224 }
225
226 isc_throw(InvalidOperation, "no failover partner server found for this"
227 " server " << getThisServerName());
228}
229
233}
234
237 PeerConfigMap copy = peers_;
238 copy.erase(getThisServerName());
239 return (copy);
240}
241
242void
244 // Peers configurations must be provided.
245 if (peers_.count(getThisServerName()) == 0) {
246 isc_throw(HAConfigValidationError, "no peer configuration specified for the '"
247 << getThisServerName() << "'");
248 }
249
250 // Gather all the roles and see how many occurrences of each role we get.
251 std::map<PeerConfig::Role, unsigned> peers_cnt;
252 for (auto p = peers_.begin(); p != peers_.end(); ++p) {
253 if (!p->second->getUrl().isValid()) {
254 isc_throw(HAConfigValidationError, "invalid URL: "
255 << p->second->getUrl().getErrorMessage()
256 << " for server " << p->second->getName());
257 }
258
259 ++peers_cnt[p->second->getRole()];
260 }
261
262 // Only one primary server allowed.
263 if (peers_cnt.count(PeerConfig::PRIMARY) && (peers_cnt[PeerConfig::PRIMARY] > 1)) {
264 isc_throw(HAConfigValidationError, "multiple primary servers specified");
265 }
266
267 // Only one secondary server allowed.
268 if (peers_cnt.count(PeerConfig::SECONDARY) && (peers_cnt[PeerConfig::SECONDARY] > 1)) {
269 isc_throw(HAConfigValidationError, "multiple secondary servers specified");
270 }
271
272 // Only one standby server allowed.
273 if (peers_cnt.count(PeerConfig::STANDBY) && (peers_cnt[PeerConfig::STANDBY] > 1)) {
274 isc_throw(HAConfigValidationError, "multiple standby servers specified");
275 }
276
277 if (ha_mode_ == LOAD_BALANCING) {
278 // Standby servers not allowed in load balancing configuration.
279 if (peers_cnt.count(PeerConfig::STANDBY) > 0) {
280 isc_throw(HAConfigValidationError, "standby servers not allowed in the load "
281 "balancing configuration");
282 }
283
284 // Require one secondary server in the load balancing configuration.
285 if (peers_cnt.count(PeerConfig::SECONDARY) == 0) {
286 isc_throw(HAConfigValidationError, "secondary server required in the load"
287 " balancing configuration");
288 }
289
290 // Require one primary server in the load balancing configuration.
291 if (peers_cnt.count(PeerConfig::PRIMARY) == 0) {
292 isc_throw(HAConfigValidationError, "primary server required in the load"
293 " balancing configuration");
294 }
295
296 }
297
298 if (ha_mode_ == HOT_STANDBY) {
299 // Secondary servers not allowed in the hot standby configuration.
300 if (peers_cnt.count(PeerConfig::SECONDARY) > 0) {
301 isc_throw(HAConfigValidationError, "secondary servers not allowed in the hot"
302 " standby configuration");
303 }
304
305 // Require one standby server in the hot standby configuration.
306 if (peers_cnt.count(PeerConfig::STANDBY) == 0) {
307 isc_throw(HAConfigValidationError, "standby server required in the hot"
308 " standby configuration");
309 }
310
311 // Require one primary server in the hot standby configuration.
312 if (peers_cnt.count(PeerConfig::PRIMARY) == 0) {
313 isc_throw(HAConfigValidationError, "primary server required in the hot"
314 " standby configuration");
315 }
316 }
317}
318
319} // end of namespace isc::ha
320} // end of namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a function is called in a prohibited way.
Exception thrown when configuration validation fails.
Definition: ha_config.h:22
HA peer configuration.
Definition: ha_config.h:47
std::string getLogLabel() const
Returns a string identifying a server used in logging.
Definition: ha_config.cc:39
Role
Server's role in the High Availability setup.
Definition: ha_config.h:64
void setRole(const std::string &role)
Sets servers role.
Definition: ha_config.cc:34
static std::string roleToString(const HAConfig::PeerConfig::Role &role)
Returns role name.
Definition: ha_config.cc:66
static Role stringToRole(const std::string &role)
Decodes role provided as a string.
Definition: ha_config.cc:46
void setName(const std::string &name)
Sets server name.
Definition: ha_config.cc:23
Configuration specific to a single HA state.
Definition: ha_config.h:166
static util::StatePausing stringToPausing(const std::string &pausing)
Converts pausing mode from the textual form.
Definition: ha_config.cc:92
void setPausing(const std::string &pausing)
Sets pausing mode for the gievn state.
Definition: ha_config.cc:87
StateConfig(const int state)
Constructor.
Definition: ha_config.cc:82
static std::string pausingToString(const util::StatePausing &pausing)
Returns pausing mode in the textual form.
Definition: ha_config.cc:107
State machine configuration information.
Definition: ha_config.h:218
StateConfigPtr getStateConfig(const int state)
Returns pointer to the state specific configuration.
Definition: ha_config.cc:126
uint32_t max_response_delay_
Max delay in response to heartbeats.
Definition: ha_config.h:501
uint32_t sync_page_limit_
Page size limit while synchronizing leases.
Definition: ha_config.h:498
std::string getThisServerName() const
Returns name of this server.
Definition: ha_config.h:261
HAMode
Mode of operation.
Definition: ha_config.h:37
PeerConfigPtr getThisServerConfig() const
Returns configuration of this server.
Definition: ha_config.cc:231
std::map< std::string, PeerConfigPtr > PeerConfigMap
Map of the servers' configurations.
Definition: ha_config.h:162
void setHAMode(const std::string &ha_mode)
Sets new mode of operation.
Definition: ha_config.cc:178
HAMode ha_mode_
Mode of operation.
Definition: ha_config.h:494
bool send_lease_updates_
Send lease updates to partner?
Definition: ha_config.h:495
uint32_t max_unacked_clients_
Maximum number of unacked clients.
Definition: ha_config.h:503
PeerConfigMap peers_
Map of peers' configurations.
Definition: ha_config.h:504
uint32_t max_ack_delay_
Maximum DHCP message ack delay.
Definition: ha_config.h:502
void setThisServerName(const std::string &this_server_name)
Sets name of this server.
Definition: ha_config.cc:166
PeerConfigMap getOtherServersConfig() const
Returns configuration of other servers.
Definition: ha_config.cc:236
PeerConfigPtr getFailoverPeerConfig() const
Returns configuration of the partner which takes part in failover.
Definition: ha_config.cc:218
PeerConfigPtr getPeerConfig(const std::string &name) const
Returns configuration of the specified server.
Definition: ha_config.cc:208
PeerConfigPtr selectNextPeerConfig(const std::string &name)
Creates and returns pointer to the new peer's configuration.
Definition: ha_config.cc:148
bool sync_leases_
Synchronize databases on startup?
Definition: ha_config.h:496
StateMachineConfigPtr state_machine_
State machine configuration.
Definition: ha_config.h:505
HAConfig()
Constructor.
Definition: ha_config.cc:140
static HAMode stringToHAMode(const std::string &ha_mode)
Decodes HA mode provided as string.
Definition: ha_config.cc:183
uint32_t sync_timeout_
Timeout for syncing lease database (ms)
Definition: ha_config.h:497
boost::shared_ptr< StateConfig > StateConfigPtr
Pointer to the state configuration.
Definition: ha_config.h:211
void validate() const
Validates configuration.
Definition: ha_config.cc:243
uint32_t heartbeat_delay_
Heartbeat delay in milliseconds.
Definition: ha_config.h:500
static std::string HAModeToString(const HAMode &ha_mode)
Returns HA mode name.
Definition: ha_config.cc:195
std::string this_server_name_
This server name.
Definition: ha_config.h:493
boost::shared_ptr< PeerConfig > PeerConfigPtr
Pointer to the server's configuration.
Definition: ha_config.h:159
const Name & name_
Definition: dns/message.cc:693
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
string trim(const string &instring)
Trim Leading and Trailing Spaces.
Definition: strutil.cc:53
Definition: edns.h:19
StatePausing
State machine pausing modes.
Definition: state_model.h:44
@ STATE_PAUSE_ALWAYS
Definition: state_model.h:45
@ STATE_PAUSE_ONCE
Definition: state_model.h:47
@ STATE_PAUSE_NEVER
Definition: state_model.h:46
Defines the logger used by the top-level component of kea-dhcp-ddns.