Kea 2.5.8
command_creator.cc
Go to the documentation of this file.
1// Copyright (C) 2018-2024 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
7#include <config.h>
8
9#include <command_creator.h>
12#include <boost/pointer_cast.hpp>
13
14using namespace isc::data;
15using namespace isc::dhcp;
16using namespace std;
17
18namespace isc {
19namespace ha {
20
21unordered_set<string> CommandCreator::ha_commands4_ = {
22 "list-commands", "status-get",
23 "dhcp-disable", "dhcp-enable",
24 "ha-reset", "ha-heartbeat",
25 "lease4-update", "lease4-del",
26 "lease4-get-all", "lease4-get-page",
27 "ha-maintenance-notify", "ha-sync-complete-notify"
28};
29
30unordered_set<string> CommandCreator::ha_commands6_ = {
31 "list-commands", "status-get",
32 "dhcp-disable", "dhcp-enable",
33 "ha-reset", "ha-heartbeat",
34 "lease6-bulk-apply",
35 "lease6-update", "lease6-del",
36 "lease6-get-all", "lease6-get-page",
37 "ha-maintenance-notify", "ha-sync-complete-notify"
38};
39
41CommandCreator::createDHCPDisable(const unsigned int origin_id,
42 const unsigned int max_period,
43 const HAServerType& server_type) {
44 ElementPtr args;
45 args = Element::createMap();
46 args->set("origin-id", Element::create(origin_id));
47 // Add for backward compatibility with Kea 2.4.0 and earlier.
48 args->set("origin", Element::create("ha-partner"));
49 // max-period is optional. A value of 0 means that it is not specified.
50 if (max_period > 0) {
51 args->set("max-period", Element::create(static_cast<long int>(max_period)));
52 }
53 ConstElementPtr command = config::createCommand("dhcp-disable", args);
54 insertService(command, server_type);
55 return (command);
56}
57
59CommandCreator::createDHCPEnable(const unsigned int origin_id,
60 const HAServerType& server_type) {
61 ElementPtr args;
62 args = Element::createMap();
63 args->set("origin-id", Element::create(origin_id));
64 // Add for backward compatibility with Kea 2.4.0 and earlier.
65 args->set("origin", Element::create("ha-partner"));
66 ConstElementPtr command = config::createCommand("dhcp-enable", args);
67 insertService(command, server_type);
68 return (command);
69}
70
72CommandCreator::createHAReset(const std::string& server_name,
73 const HAServerType& server_type) {
74 auto args = Element::createMap();
75 args->set("server-name", Element::create(server_name));
76 ConstElementPtr command = config::createCommand("ha-reset", args);
77 insertService(command, server_type);
78 return (command);
79}
80
82CommandCreator::createHeartbeat(const std::string& server_name,
83 const HAServerType& server_type) {
84 auto args = Element::createMap();
85 args->set("server-name", Element::create(server_name));
86 ConstElementPtr command = config::createCommand("ha-heartbeat", args);
87 insertService(command, server_type);
88 return (command);
89}
90
93 ElementPtr lease_as_json = lease4.toElement();
94 insertLeaseExpireTime(lease_as_json);
95 lease_as_json->set("force-create", Element::create(true));
96 lease_as_json->set("origin", Element::create("ha-partner"));
97 ConstElementPtr command = config::createCommand("lease4-update", lease_as_json);
98 insertService(command, HAServerType::DHCPv4);
99 return (command);
100}
101
104 ElementPtr lease_as_json = lease4.toElement();
105 insertLeaseExpireTime(lease_as_json);
106 lease_as_json->set("origin", Element::create("ha-partner"));
107 ConstElementPtr command = config::createCommand("lease4-del", lease_as_json);
108 insertService(command, HAServerType::DHCPv4);
109 return (command);
110}
111
114 ConstElementPtr command = config::createCommand("lease4-get-all");
115 insertService(command, HAServerType::DHCPv4);
116 return (command);
117}
118
121 const uint32_t limit) {
122 // Zero value is not allowed.
123 if (limit == 0) {
124 isc_throw(BadValue, "limit value for lease4-get-page command must not be 0");
125 }
126
127 // Get the last lease returned on the previous page. A null pointer means that
128 // we're fetching first page. In that case a keyword "start" is used to indicate
129 // that first page should be returned.
130 ElementPtr from_element = Element::create(last_lease4 ? last_lease4->addr_.toText() : "start");
131 // Set the maximum size of the page.
132 ElementPtr limit_element = Element::create(static_cast<long long int>(limit));
133 // Put both parameters into arguments map.
135 args->set("from", from_element);
136 args->set("limit", limit_element);
137
138 // Create the command.
139 ConstElementPtr command = config::createCommand("lease4-get-page", args);
140 insertService(command, HAServerType::DHCPv4);
141 return (command);
142}
143
146 const Lease6CollectionPtr& deleted_leases) {
147 ElementPtr deleted_leases_list = Element::createList();
148 for (auto const& lease : *deleted_leases) {
149 ElementPtr lease_as_json = lease->toElement();
150 insertLeaseExpireTime(lease_as_json);
151 deleted_leases_list->add(lease_as_json);
152 }
153
154 ElementPtr leases_list = Element::createList();
155 for (auto const& lease : *leases) {
156 ElementPtr lease_as_json = lease->toElement();
157 insertLeaseExpireTime(lease_as_json);
158 leases_list->add(lease_as_json);
159 }
160
162 args->set("deleted-leases", deleted_leases_list);
163 args->set("leases", leases_list);
164 args->set("origin", Element::create("ha-partner"));
165
166 ConstElementPtr command = config::createCommand("lease6-bulk-apply", args);
167 insertService(command, HAServerType::DHCPv6);
168 return (command);
169}
170
173 ElementPtr deleted_leases_list = Element::createList();
174 ElementPtr leases_list = Element::createList();
175
177 Lease6Ptr lease;
178 while ((lease = boost::dynamic_pointer_cast<Lease6>(leases.pop(op_type)))) {
179 ElementPtr lease_as_json = lease->toElement();
180 insertLeaseExpireTime(lease_as_json);
181 if (op_type == LeaseUpdateBacklog::DELETE) {
182 deleted_leases_list->add(lease_as_json);
183 } else {
184 leases_list->add(lease_as_json);
185 }
186 }
187
189 args->set("deleted-leases", deleted_leases_list);
190 args->set("leases", leases_list);
191 args->set("origin", Element::create("ha-partner"));
192
193 ConstElementPtr command = config::createCommand("lease6-bulk-apply", args);
194 insertService(command, HAServerType::DHCPv6);
195 return (command);
196}
197
200 ElementPtr lease_as_json = lease6.toElement();
201 insertLeaseExpireTime(lease_as_json);
202 lease_as_json->set("force-create", Element::create(true));
203 lease_as_json->set("origin", Element::create("ha-partner"));
204 ConstElementPtr command = config::createCommand("lease6-update", lease_as_json);
205 insertService(command, HAServerType::DHCPv6);
206 return (command);
207}
208
211 ElementPtr lease_as_json = lease6.toElement();
212 insertLeaseExpireTime(lease_as_json);
213 lease_as_json->set("origin", Element::create("ha-partner"));
214 ConstElementPtr command = config::createCommand("lease6-del", lease_as_json);
215 insertService(command, HAServerType::DHCPv6);
216 return (command);
217}
218
221 ConstElementPtr command = config::createCommand("lease6-get-all");
222 insertService(command, HAServerType::DHCPv6);
223 return (command);
224}
225
228 const uint32_t limit) {
229 // Zero value is not allowed.
230 if (limit == 0) {
231 isc_throw(BadValue, "limit value for lease6-get-page command must not be 0");
232 }
233
234 // Get the last lease returned on the previous page. A null pointer means that
235 // we're fetching first page. In that case a keyword "start" is used to indicate
236 // that first page should be returned.
237 ElementPtr from_element = Element::create(last_lease6 ? last_lease6->addr_.toText() : "start");
238 // Set the maximum size of the page.
239 ElementPtr limit_element = Element::create(static_cast<long long int>(limit));
240 // Put both parameters into arguments map.
242 args->set("from", from_element);
243 args->set("limit", limit_element);
244
245 // Create the command.
246 ConstElementPtr command = config::createCommand("lease6-get-page", args);
247 insertService(command, HAServerType::DHCPv6);
248 return (command);
249}
250
252CommandCreator::createMaintenanceNotify(const std::string& server_name,
253 const bool cancel,
254 const HAServerType& server_type) {
255 auto args = Element::createMap();
256 args->set("server-name", Element::create(server_name));
257 args->set("cancel", Element::create(cancel));
258 auto command = config::createCommand("ha-maintenance-notify", args);
259 insertService(command, server_type);
260 return (command);
261}
262
264CommandCreator::createSyncCompleteNotify(const unsigned int origin_id,
265 const std::string& server_name,
266 const HAServerType& server_type) {
267 auto args = Element::createMap();
268 args->set("server-name", Element::create(server_name));
269 args->set("origin-id", Element::create(origin_id));
270 // Add for backward compatibility with Kea 2.5.5 to Kea 2.5.7.
271 // The origin parameter was introduced for this command in Kea 2.5.5 but
272 // renamed to origin-id to be consistent with the origin-id used in
273 // dhcp-enable and dhcp-disable commands starting from Kea 2.5.8.
274 args->set("origin", Element::create(origin_id));
275 auto command = config::createCommand("ha-sync-complete-notify", args);
276 insertService(command, server_type);
277 return (command);
278}
279
280void
281CommandCreator::insertLeaseExpireTime(ElementPtr& lease) {
282 if ((lease->getType() != Element::map) ||
283 (!lease->contains("cltt") || (lease->get("cltt")->getType() != Element::integer) ||
284 (!lease->contains("valid-lft") ||
285 (lease->get("valid-lft")->getType() != Element::integer)))) {
286 isc_throw(Unexpected, "invalid lease format");
287 }
288
289 int64_t cltt = lease->get("cltt")->intValue();
290 int64_t valid_lifetime = lease->get("valid-lft")->intValue();
291 int64_t expire = cltt + valid_lifetime;
292 lease->set("expire", Element::create(expire));
293 lease->remove("cltt");
294}
295
296void
297CommandCreator::insertService(ConstElementPtr& command,
298 const HAServerType& server_type) {
300 const string service_name = (server_type == HAServerType::DHCPv4 ? "dhcp4" : "dhcp6");
301 service->add(Element::create(service_name));
302
303 // We have no better way of setting a new element here than
304 // doing const pointer cast. That's another reason why this
305 // functionality could be moved to the core code. We don't
306 // do it however, because we want to minimize concurrent
307 // code changes in the premium and core Kea repos.
308 (boost::const_pointer_cast<Element>(command))->set("service", service);
309}
310
311} // end of namespace ha
312} // 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 when an unexpected error condition occurs.
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:249
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:304
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition: data.cc:299
static data::ConstElementPtr createLease4Delete(const dhcp::Lease4 &lease4)
Creates lease4-del command.
static data::ConstElementPtr createHeartbeat(const std::string &server_name, const HAServerType &server_type)
Creates ha-heartbeat command for DHCP server.
static std::unordered_set< std::string > ha_commands4_
List of commands used by the High Availability in v4.
static data::ConstElementPtr createLease4Update(const dhcp::Lease4 &lease4)
Creates lease4-update command.
static data::ConstElementPtr createLease6Update(const dhcp::Lease6 &lease6)
Creates lease6-update command.
static data::ConstElementPtr createSyncCompleteNotify(const unsigned int origin_id, const std::string &server_name, const HAServerType &server_type)
Creates ha-sync-complete-notify command.
static data::ConstElementPtr createLease6Delete(const dhcp::Lease6 &lease6)
Creates lease6-del command.
static data::ConstElementPtr createLease6BulkApply(const dhcp::Lease6CollectionPtr &leases, const dhcp::Lease6CollectionPtr &deleted_leases)
Creates lease6-bulk-apply command.
static data::ConstElementPtr createLease4GetAll()
Creates lease4-get-all command.
static data::ConstElementPtr createLease6GetPage(const dhcp::Lease6Ptr &lease6, const uint32_t limit)
Creates lease6-get-page command.
static data::ConstElementPtr createDHCPDisable(const unsigned int origin_id, const unsigned int max_period, const HAServerType &server_type)
Creates dhcp-disable command for DHCP server.
static data::ConstElementPtr createDHCPEnable(const unsigned int origin_id, const HAServerType &server_type)
Creates dhcp-enable command for DHCP server.
static std::unordered_set< std::string > ha_commands6_
List of commands used by the High Availability in v6.
static data::ConstElementPtr createHAReset(const std::string &server_name, const HAServerType &server_type)
Creates ha-reset command.
static data::ConstElementPtr createLease6GetAll()
Creates lease6-get-all command.
static data::ConstElementPtr createMaintenanceNotify(const std::string &server_name, const bool cancel, const HAServerType &server_type)
Creates ha-maintenance-notify command.
static data::ConstElementPtr createLease4GetPage(const dhcp::Lease4Ptr &lease4, const uint32_t limit)
Creates lease4-get-page command.
Queue holding a backlog of unsent lease updates.
dhcp::LeasePtr pop(OpType &op_type)
Returns the next lease update and removes it from the queue.
OpType
Type of the lease update (operation type).
This file contains several functions and constants that are used for handling commands and responses ...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
ConstElementPtr createCommand(const std::string &command)
Creates a standard command message with no argument (of the form { "command": "my_command" })
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:29
boost::shared_ptr< Element > ElementPtr
Definition: data.h:28
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition: lease.h:505
boost::shared_ptr< Lease6Collection > Lease6CollectionPtr
A shared pointer to the collection of IPv6 leases.
Definition: lease.h:673
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition: lease.h:292
HAServerType
Lists possible server types for which HA service is created.
Defines the logger used by the top-level component of kea-lfc.
Structure that holds a lease for IPv4 address.
Definition: lease.h:300
virtual isc::data::ElementPtr toElement() const
Return the JSON representation of a lease.
Definition: lease.cc:386
Structure that holds a lease for IPv6 address and/or prefix.
Definition: lease.h:513
virtual isc::data::ElementPtr toElement() const
Return the JSON representation of a lease.
Definition: lease.cc:625