Kea 2.2.0
translator_host.cc
Go to the documentation of this file.
1// Copyright (C) 2018-2021 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
10#include <yang/adaptor.h>
11#include <yang/yang_models.h>
12#include <sstream>
13
14using namespace std;
15using namespace isc::data;
16using namespace sysrepo;
17
18namespace isc {
19namespace yang {
20
21TranslatorHost::TranslatorHost(S_Session session, const string& model)
22 : TranslatorBasic(session, model),
23 TranslatorOptionData(session, model),
24 TranslatorOptionDataList(session, model) {
25}
26
28}
29
31 TranslatorHost::getHost(const string& xpath) {
32 try {
33 if ((model_ == KEA_DHCP4_SERVER) ||
34 (model_ == KEA_DHCP6_SERVER)) {
35 return (getHostKea(xpath));
36 }
37 } catch (const sysrepo_exception& ex) {
39 "sysrepo error getting host reservation at '" << xpath
40 << "': " << ex.what());
41 }
43 "getHost not implemented for the model: " << model_);
44}
45
47TranslatorHost::getHostKea(const string& xpath) {
48 ConstElementPtr id_type = getItem(xpath + "/identifier-type");
49 ConstElementPtr id = getItem(xpath + "/identifier");
50 if (!id_type || !id) {
51 isc_throw(Unexpected, "getHostKea requires both identifier and "
52 "identifier-type");
53 }
54 ElementPtr result = Element::createMap();
55 result->set(id_type->stringValue(), id);
56 ConstElementPtr hostname = getItem(xpath + "/hostname");
57 if (hostname) {
58 result->set("hostname", hostname);
59 }
60 if (model_ == KEA_DHCP4_SERVER) {
61 ConstElementPtr address = getItem(xpath + "/ip-address");
62 if (address) {
63 result->set("ip-address", address);
64 }
65 } else {
66 ConstElementPtr addresses = getItems(xpath + "/ip-addresses");
67 if (addresses && (addresses->size() > 0)) {
68 result->set("ip-addresses", addresses);
69 }
70 ConstElementPtr prefixes = getItems(xpath + "/prefixes");
71 if (prefixes && (prefixes->size() > 0)) {
72 result->set("prefixes", prefixes);
73 }
74 }
75 ConstElementPtr options = getOptionDataList(xpath);
76 if (options && (options->size() > 0)) {
77 result->set("option-data", options);
78 }
79 ConstElementPtr classes = getItems(xpath + "/client-classes");
80 if (classes) {
81 result->set("client-classes", classes);
82 }
83 if (model_ == KEA_DHCP4_SERVER) {
84 ConstElementPtr next = getItem(xpath + "/next-server");
85 if (next) {
86 result->set("next-server", next);
87 }
88 ConstElementPtr hostname = getItem(xpath + "/server-hostname");
89 if (hostname) {
90 result->set("server-hostname", hostname);
91 }
92 ConstElementPtr boot = getItem(xpath + "/boot-file-name");
93 if (boot) {
94 result->set("boot-file-name", boot);
95 }
96 }
97 ConstElementPtr context = getItem(xpath + "/user-context");
98 if (context) {
99 result->set("user-context", Element::fromJSON(context->stringValue()));
100 }
101 return (result);
102}
103
104void
105TranslatorHost::setHost(const string& xpath, ConstElementPtr elem) {
106 try {
107 if ((model_ == KEA_DHCP4_SERVER) ||
108 (model_ == KEA_DHCP6_SERVER)) {
109 setHostKea(xpath, elem);
110 } else {
112 "setHost not implemented for the model: " << model_);
113 }
114 } catch (const sysrepo_exception& ex) {
116 "sysrepo error setting host reservation '" << elem->str()
117 << "' at '" << xpath << "': " << ex.what());
118 }
119}
120
121void
122TranslatorHost::setHostKea(const string& xpath, ConstElementPtr elem) {
123 ConstElementPtr hostname = elem->get("hostname");
124 // Skip identifier and identifier type as they are keys.
125 if (hostname) {
126 setItem(xpath + "/hostname", hostname, SR_STRING_T);
127 }
128 if (model_ == KEA_DHCP4_SERVER) {
129 ConstElementPtr address = elem->get("ip-address");
130 if (address) {
131 setItem(xpath + "/ip-address", address, SR_STRING_T);
132 }
133 } else {
134 ConstElementPtr addresses = elem->get("ip-addresses");
135 if (addresses && (addresses->size() > 0)) {
136 for (ConstElementPtr address : addresses->listValue()) {
137 setItem(xpath + "/ip-addresses", address, SR_STRING_T);
138 }
139 }
140 ConstElementPtr prefixes = elem->get("prefixes");
141 if (prefixes && (prefixes->size() > 0)) {
142 for (ConstElementPtr prefix : prefixes->listValue()) {
143 setItem(xpath + "/prefixes", prefix, SR_STRING_T);
144 }
145 }
146 }
147 ConstElementPtr options = elem->get("option-data");
148 if (options && (options->size() > 0)) {
149 setOptionDataList(xpath, options);
150 }
151 ConstElementPtr classes = elem->get("client-classes");
152 if (classes && (classes->size() > 0)) {
153 for (ConstElementPtr cclass : classes->listValue()) {
154 setItem(xpath + "/client-classes", cclass, SR_STRING_T);
155 }
156 }
157
158 // These are DHCPv4-specific parameters.
159 if (model_ == KEA_DHCP4_SERVER) {
160 ConstElementPtr next = elem->get("next-server");
161 if (next) {
162 setItem(xpath + "/next-server", next, SR_STRING_T);
163 }
164 ConstElementPtr hostname = elem->get("server-hostname");
165 if (hostname) {
166 setItem(xpath + "/server-hostname", hostname, SR_STRING_T);
167 }
168 ConstElementPtr boot = elem->get("boot-file-name");
169 if (boot) {
170 setItem(xpath + "/boot-file-name", boot, SR_STRING_T);
171 }
172 }
173
174 // User context is supported in both kea-dhcp4-server and kea-dhcp6-server.
175 ConstElementPtr context = Adaptor::getContext(elem);
176 if (context) {
177 setItem(xpath + "/user-context", Element::create(context->str()),
178 SR_STRING_T);
179 }
180}
181
182TranslatorHosts::TranslatorHosts(S_Session session, const string& model)
183 : TranslatorBasic(session, model),
184 TranslatorOptionData(session, model),
185 TranslatorOptionDataList(session, model),
186 TranslatorHost(session, model) {
187}
188
190}
191
193TranslatorHosts::getHosts(const string& xpath) {
194 return getList<TranslatorHost>(xpath + "/host", *this,
196}
197
198void
199TranslatorHosts::setHosts(const string& xpath, ConstElementPtr elem) {
200 try {
201 if ((model_ == KEA_DHCP4_SERVER) ||
202 (model_ == KEA_DHCP6_SERVER)) {
203 setHostsKea(xpath, elem);
204 } else {
206 "setHosts not implemented for the model: " << model_);
207 }
208 } catch (const sysrepo_exception& ex) {
210 "sysrepo error setting host reservations '" << elem->str()
211 << "' at '" << xpath << "': " << ex.what());
212 }
213}
214
215void
217 for (size_t i = 0; i < elem->size(); ++i) {
218 string id_type = "unknown";
219 ConstElementPtr host = elem->get(i);
220 ConstElementPtr id = host->get("hw-address");
221 if (id) {
222 id_type = "hw-address";
223 goto found;
224 }
225 id = host->get("duid");
226 if (id) {
227 id_type = "duid";
228 goto found;
229 }
230 if (model_ == KEA_DHCP4_SERVER) {
231 id = host->get("circuit-id");
232 if (id) {
233 id_type = "circuit-id";
234 goto found;
235 }
236 id = host->get("client-id");
237 if (id) {
238 id_type = "client-id";
239 goto found;
240 }
241 }
242 id = host->get("flex-id");
243 if (id) {
244 id_type = "flex-id";
245 goto found;
246 }
247
248 found:
249 if (id_type == "unknown") {
250 isc_throw(BadValue, "getHosts: can't find the identifier type in "
251 << host->str());
252 }
253 ostringstream key;
254 key << xpath << "/host[identifier-type='" << id_type
255 << "'][identifier='" << id->stringValue() << "']";
256 setHost(key.str(), host);
257 }
258}
259
260} // namespace yang
261} // namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown when a function is not implemented.
A generic exception that is thrown when an unexpected error condition occurs.
static isc::data::ConstElementPtr getContext(isc::data::ConstElementPtr parent)
Get user context.
Definition: adaptor.cc:27
Between YANG and JSON translator class for basic values.
Definition: translator.h:19
isc::data::ElementPtr getItem(const std::string &xpath)
Get and translate basic value from YANG to JSON.
Definition: translator.cc:105
std::string model_
The model.
Definition: translator.h:171
void setItem(const std::string &xpath, isc::data::ConstElementPtr elem, sr_type_t type)
Translate and set basic value from JSON to YANG.
Definition: translator.cc:260
isc::data::ElementPtr getItems(const std::string &xpath)
Get and translate a list of basic values from YANG to JSON.
Definition: translator.cc:124
Translation between YANG and JSON for a single host reservation.
virtual ~TranslatorHost()
Destructor.
isc::data::ElementPtr getHost(const std::string &xpath)
Get and translate a host reservation from YANG to JSON.
void setHost(const std::string &xpath, isc::data::ConstElementPtr elem)
Translate and set host reservation from JSON to YANG.
TranslatorHost(sysrepo::S_Session session, const std::string &model)
Constructor.
isc::data::ElementPtr getHostKea(const std::string &xpath)
getHost for kea-dhcp[46]-server models.
void setHostKea(const std::string &xpath, isc::data::ConstElementPtr elem)
setHost for kea-dhcp[46]-server models.
isc::data::ElementPtr getHosts(const std::string &xpath)
Get and translate host reservations from YANG to JSON.
TranslatorHosts(sysrepo::S_Session session, const std::string &model)
Constructor.
void setHosts(const std::string &xpath, isc::data::ConstElementPtr elem)
Translate and set (address) host reservations from JSON to YANG.
virtual ~TranslatorHosts()
Destructor.
void setHostsKea(const std::string &xpath, isc::data::ConstElementPtr elem)
setHosts for kea-dhcp[46].
A translator class for converting an option data list between YANG and JSON.
isc::data::ConstElementPtr getOptionDataList(const std::string &xpath)
Get and translate option data list from YANG to JSON.
void setOptionDataList(const std::string &xpath, isc::data::ConstElementPtr elem)
Translate and set option data list from JSON to YANG.
Option data translation between YANG and JSON.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
Defines the logger used by the top-level component of kea-lfc.