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 
13 using namespace isc::util;
14 
15 namespace isc {
16 namespace ha {
17 
18 HAConfig::PeerConfig::PeerConfig()
19  : name_(), url_(""), role_(STANDBY), auto_failover_(false) {
20 }
21 
22 void
23 HAConfig::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 
33 void
34 HAConfig::PeerConfig::setRole(const std::string& role) {
35  role_ = stringToRole(role);
36 }
37 
38 std::string
40  std::ostringstream label;
41  label << getName() << " (" << getUrl().toText() << ")";
42  return (label.str());
43 }
44 
46 HAConfig::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 
65 std::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 
86 void
87 HAConfig::StateConfig::setPausing(const std::string& pausing) {
88  pausing_ = stringToPausing(pausing);
89 }
90 
92 HAConfig::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 
106 std::string
108  switch (pausing) {
109  case STATE_PAUSE_ALWAYS:
110  return ("always");
111 
112  case STATE_PAUSE_NEVER:
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),
143  heartbeat_delay_(10000), max_response_delay_(60000), max_ack_delay_(10000),
145 }
146 
148 HAConfig::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 
165 void
166 HAConfig::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 
173  this_server_name_ = s;
174 }
175 
176 
177 void
178 HAConfig::setHAMode(const std::string& ha_mode) {
179  ha_mode_ = stringToHAMode(ha_mode);
180 }
181 
183 HAConfig::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 
194 std::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 
208 HAConfig::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 
232  return (getPeerConfig(getThisServerName()));
233 }
234 
238  copy.erase(getThisServerName());
239  return (copy);
240 }
241 
242 void
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
isc::util::StatePausing
StatePausing
State machine pausing modes.
Definition: state_model.h:44
isc::data::copy
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
Definition: data.cc:1114
isc::ha::HAConfig::StateConfig::StateConfig
StateConfig(const int state)
Constructor.
Definition: ha_config.cc:82
isc::ha::HAConfig::LOAD_BALANCING
@ LOAD_BALANCING
Definition: ha_config.h:38
isc::ha::HAConfig::getThisServerConfig
PeerConfigPtr getThisServerConfig() const
Returns configuration of this server.
Definition: ha_config.cc:231
isc::ha::HAConfig::send_lease_updates_
bool send_lease_updates_
Send lease updates to partner?
Definition: ha_config.h:495
isc::ha::HAConfig::validate
void validate() const
Validates configuration.
Definition: ha_config.cc:243
isc::ha::HAConfig::setThisServerName
void setThisServerName(const std::string &this_server_name)
Sets name of this server.
Definition: ha_config.cc:166
ha_config.h
isc::util::str::trim
string trim(const string &instring)
Trim Leading and Trailing Spaces.
Definition: strutil.cc:53
isc::ha::HAConfig::getOtherServersConfig
PeerConfigMap getOtherServersConfig() const
Returns configuration of other servers.
Definition: ha_config.cc:236
isc::ha::HAConfig::HAModeToString
static std::string HAModeToString(const HAMode &ha_mode)
Returns HA mode name.
Definition: ha_config.cc:195
isc::ha::HAConfig::PeerConfig::setName
void setName(const std::string &name)
Sets server name.
Definition: ha_config.cc:23
isc::util::STATE_PAUSE_ALWAYS
@ STATE_PAUSE_ALWAYS
Definition: state_model.h:45
isc::ha::HAConfig::sync_page_limit_
uint32_t sync_page_limit_
Page size limit while synchronizing leases.
Definition: ha_config.h:498
isc::ha::HAConfig::heartbeat_delay_
uint32_t heartbeat_delay_
Heartbeat delay in milliseconds.
Definition: ha_config.h:500
isc::ha::HAConfig::max_unacked_clients_
uint32_t max_unacked_clients_
Maximum number of unacked clients.
Definition: ha_config.h:503
isc::ha::HAConfig::PeerConfig::getLogLabel
std::string getLogLabel() const
Returns a string identifying a server used in logging.
Definition: ha_config.cc:39
isc::ha::HAConfig::peers_
PeerConfigMap peers_
Map of peers' configurations.
Definition: ha_config.h:504
isc::util
Definition: edns.h:19
isc
Defines the logger used by the top-level component of kea-dhcp-ddns.
Definition: agent_parser.cc:144
strutil.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: exceptions/exceptions.h:192
isc::ha::HAConfig::PeerConfig::STANDBY
@ STANDBY
Definition: ha_config.h:67
isc::ha::HAConfig::this_server_name_
std::string this_server_name_
This server name.
Definition: ha_config.h:493
isc::InvalidOperation
A generic exception that is thrown if a function is called in a prohibited way.
Definition: exceptions/exceptions.h:143
isc::BadValue
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Definition: exceptions/exceptions.h:132
isc::ha::HAConfig::stringToHAMode
static HAMode stringToHAMode(const std::string &ha_mode)
Decodes HA mode provided as string.
Definition: ha_config.cc:183
isc::ha::HAConfig::StateConfigPtr
boost::shared_ptr< StateConfig > StateConfigPtr
Pointer to the state configuration.
Definition: ha_config.h:211
isc::ha::HAConfig::ha_mode_
HAMode ha_mode_
Mode of operation.
Definition: ha_config.h:494
isc::ha::HAConfig::sync_timeout_
uint32_t sync_timeout_
Timeout for syncing lease database (ms)
Definition: ha_config.h:497
isc::ha::HAConfig::getThisServerName
std::string getThisServerName() const
Returns name of this server.
Definition: ha_config.h:261
isc::ha::HAConfig::PeerConfig
HA peer configuration.
Definition: ha_config.h:47
isc::ha::HAConfig::PeerConfig::BACKUP
@ BACKUP
Definition: ha_config.h:68
isc::ha::HAConfigValidationError
Exception thrown when configuration validation fails.
Definition: ha_config.h:22
isc::ha::HAConfig::StateConfig::stringToPausing
static util::StatePausing stringToPausing(const std::string &pausing)
Converts pausing mode from the textual form.
Definition: ha_config.cc:92
isc::ha::HAConfig::state_machine_
StateMachineConfigPtr state_machine_
State machine configuration.
Definition: ha_config.h:505
isc::ha::HAConfig::sync_leases_
bool sync_leases_
Synchronize databases on startup?
Definition: ha_config.h:496
isc::ha::HAConfig::StateConfig::pausingToString
static std::string pausingToString(const util::StatePausing &pausing)
Returns pausing mode in the textual form.
Definition: ha_config.cc:107
isc::ha::HAConfig::PeerConfigMap
std::map< std::string, PeerConfigPtr > PeerConfigMap
Map of the servers' configurations.
Definition: ha_config.h:162
isc::ha::HAConfig::PeerConfig::SECONDARY
@ SECONDARY
Definition: ha_config.h:66
isc::ha::HAConfig::PeerConfig::setRole
void setRole(const std::string &role)
Sets servers role.
Definition: ha_config.cc:34
isc::ha::HAConfig::max_ack_delay_
uint32_t max_ack_delay_
Maximum DHCP message ack delay.
Definition: ha_config.h:502
isc::ha::HAConfig::getPeerConfig
PeerConfigPtr getPeerConfig(const std::string &name) const
Returns configuration of the specified server.
Definition: ha_config.cc:208
isc::ha::HAConfig::PeerConfigPtr
boost::shared_ptr< PeerConfig > PeerConfigPtr
Pointer to the server's configuration.
Definition: ha_config.h:159
isc::ha::HAConfig::StateMachineConfig::getStateConfig
StateConfigPtr getStateConfig(const int state)
Returns pointer to the state specific configuration.
Definition: ha_config.cc:126
exceptions.h
name_
const Name & name_
Definition: dns/message.cc:693
isc::ha::HAConfig::StateMachineConfig
State machine configuration information.
Definition: ha_config.h:218
isc::ha::HAConfig::PeerConfig::PRIMARY
@ PRIMARY
Definition: ha_config.h:65
isc::util::STATE_PAUSE_NEVER
@ STATE_PAUSE_NEVER
Definition: state_model.h:46
isc::ha::HAConfig::StateConfig
Configuration specific to a single HA state.
Definition: ha_config.h:166
isc::ha::HAConfig::StateConfig::setPausing
void setPausing(const std::string &pausing)
Sets pausing mode for the gievn state.
Definition: ha_config.cc:87
isc::ha::HAConfig::setHAMode
void setHAMode(const std::string &ha_mode)
Sets new mode of operation.
Definition: ha_config.cc:178
isc::util::STATE_PAUSE_ONCE
@ STATE_PAUSE_ONCE
Definition: state_model.h:47
isc::ha::HAConfig::HOT_STANDBY
@ HOT_STANDBY
Definition: ha_config.h:39
isc::ha::HAConfig::getFailoverPeerConfig
PeerConfigPtr getFailoverPeerConfig() const
Returns configuration of the partner which takes part in failover.
Definition: ha_config.cc:218
isc::ha::HAConfig::selectNextPeerConfig
PeerConfigPtr selectNextPeerConfig(const std::string &name)
Creates and returns pointer to the new peer's configuration.
Definition: ha_config.cc:148
isc::ha::HAConfig::max_response_delay_
uint32_t max_response_delay_
Max delay in response to heartbeats.
Definition: ha_config.h:501
ha_service_states.h
isc::ha::HAConfig::PeerConfig::Role
Role
Server's role in the High Availability setup.
Definition: ha_config.h:64
isc::ha::HAConfig::HAMode
HAMode
Mode of operation.
Definition: ha_config.h:37
isc::ha::HAConfig::PeerConfig::roleToString
static std::string roleToString(const HAConfig::PeerConfig::Role &role)
Returns role name.
Definition: ha_config.cc:66
isc::ha::HAConfig::PeerConfig::stringToRole
static Role stringToRole(const std::string &role)
Decodes role provided as a string.
Definition: ha_config.cc:46
isc::ha::HAConfig::HAConfig
HAConfig()
Constructor.
Definition: ha_config.cc:140