Kea 1.5.0
translator_host.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
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;
16#ifndef HAVE_PRE_0_7_6_SYSREPO
17using namespace sysrepo;
18#endif
19
20namespace isc {
21namespace yang {
22
23TranslatorHost::TranslatorHost(S_Session session, const string& model)
24 : TranslatorBasic(session, model),
25 TranslatorOptionData(session, model),
26 TranslatorOptionDataList(session, model) {
27}
28
30}
31
33 TranslatorHost::getHost(const string& xpath) {
34 try {
35 if ((model_ == KEA_DHCP4_SERVER) ||
36 (model_ == KEA_DHCP6_SERVER)) {
37 return (getHostKea(xpath));
38 }
39 } catch (const sysrepo_exception& ex) {
41 "sysrepo error getting host reservation at '" << xpath
42 << "': " << ex.what());
43 }
45 "getHost not implemented for the model: " << model_);
46}
47
49TranslatorHost::getHostKea(const string& xpath) {
50 ConstElementPtr id_type = getItem(xpath + "/identifier-type");
51 ConstElementPtr id = getItem(xpath + "/identifier");
52 if (!id_type || !id) {
53 isc_throw(Unexpected, "getHostKea requires both identifier and "
54 "identifier-type");
55 }
57 result->set(id_type->stringValue(), id);
58 ConstElementPtr hostname = getItem(xpath + "/hostname");
59 if (hostname) {
60 result->set("hostname", hostname);
61 }
62 if (model_ == KEA_DHCP4_SERVER) {
63 ConstElementPtr address = getItem(xpath + "/ip-address");
64 if (address) {
65 result->set("ip-address", address);
66 }
67 } else {
68 ConstElementPtr addresses = getItems(xpath + "/ip-addresses");
69 if (addresses && (addresses->size() > 0)) {
70 result->set("ip-addresses", addresses);
71 }
72 ConstElementPtr prefixes = getItems(xpath + "/prefixes");
73 if (prefixes && (prefixes->size() > 0)) {
74 result->set("prefixes", prefixes);
75 }
76 }
77 ConstElementPtr options = getOptionDataList(xpath);
78 if (options && (options->size() > 0)) {
79 result->set("option-data", options);
80 }
81 ConstElementPtr classes = getItems(xpath + "/client-classes");
82 if (classes) {
83 result->set("client-classes", classes);
84 }
85 if (model_ == KEA_DHCP4_SERVER) {
86 ConstElementPtr next = getItem(xpath + "/next-server");
87 if (next) {
88 result->set("next-server", next);
89 }
90 ConstElementPtr hostname = getItem(xpath + "/server-hostname");
91 if (hostname) {
92 result->set("server-hostname", hostname);
93 }
94 ConstElementPtr boot = getItem(xpath + "/boot-file-name");
95 if (boot) {
96 result->set("boot-file-name", boot);
97 }
98 }
99 ConstElementPtr context = getItem(xpath + "/user-context");
100 if (context) {
101 result->set("user-context", Element::fromJSON(context->stringValue()));
102 }
103 return (result);
104}
105
106void
107TranslatorHost::setHost(const string& xpath, ConstElementPtr elem) {
108 try {
109 if ((model_ == KEA_DHCP4_SERVER) ||
110 (model_ == KEA_DHCP6_SERVER)) {
111 setHostKea(xpath, elem);
112 } else {
114 "setHost not implemented for the model: " << model_);
115 }
116 } catch (const sysrepo_exception& ex) {
118 "sysrepo error setting host reservation '" << elem->str()
119 << "' at '" << xpath << "': " << ex.what());
120 }
121}
122
123void
124TranslatorHost::setHostKea(const string& xpath, ConstElementPtr elem) {
125 ConstElementPtr hostname = elem->get("hostname");
126 // Skip identifier and identifier type as they are keys.
127 if (hostname) {
128 setItem(xpath + "/hostname", hostname, SR_STRING_T);
129 }
130 if (model_ == KEA_DHCP4_SERVER) {
131 ConstElementPtr address = elem->get("ip-address");
132 if (address) {
133 setItem(xpath + "/ip-address", address, SR_STRING_T);
134 }
135 } else {
136 ConstElementPtr addresses = elem->get("ip-addresses");
137 if (addresses && (addresses->size() > 0)) {
138 for (ConstElementPtr address : addresses->listValue()) {
139 setItem(xpath + "/ip-addresses", address, SR_STRING_T);
140 }
141 }
142 ConstElementPtr prefixes = elem->get("prefixes");
143 if (prefixes && (prefixes->size() > 0)) {
144 for (ConstElementPtr prefix : prefixes->listValue()) {
145 setItem(xpath + "/prefixes", prefix, SR_STRING_T);
146 }
147 }
148 }
149 ConstElementPtr options = elem->get("option-data");
150 if (options && (options->size() > 0)) {
151 setOptionDataList(xpath, options);
152 }
153 ConstElementPtr classes = elem->get("client-classes");
154 if (classes && (classes->size() > 0)) {
155 for (ConstElementPtr cclass : classes->listValue()) {
156 setItem(xpath + "/client-classes", cclass, SR_STRING_T);
157 }
158 }
159
160 // These are DHCPv4-specific parameters.
161 if (model_ == KEA_DHCP4_SERVER) {
162 ConstElementPtr next = elem->get("next-server");
163 if (next) {
164 setItem(xpath + "/next-server", next, SR_STRING_T);
165 }
166 ConstElementPtr hostname = elem->get("server-hostname");
167 if (hostname) {
168 setItem(xpath + "/server-hostname", hostname, SR_STRING_T);
169 }
170 ConstElementPtr boot = elem->get("boot-file-name");
171 if (boot) {
172 setItem(xpath + "/boot-file-name", boot, SR_STRING_T);
173 }
174 }
175
176 // User context is supported in both kea-dhcp4-server and kea-dhcp6-server.
177 ConstElementPtr context = Adaptor::getContext(elem);
178 if (context) {
179 setItem(xpath + "/user-context", Element::create(context->str()),
180 SR_STRING_T);
181 }
182}
183
184TranslatorHosts::TranslatorHosts(S_Session session, const string& model)
185 : TranslatorBasic(session, model),
186 TranslatorOptionData(session, model),
187 TranslatorOptionDataList(session, model),
188 TranslatorHost(session, model) {
189}
190
192}
193
195TranslatorHosts::getHosts(const string& xpath) {
196 try {
198 S_Iter_Value iter = getIter(xpath + "/host");
199 if (!iter) {
200 // Can't happen.
201 isc_throw(Unexpected, "getHosts can't get iterator: " << xpath);
202 }
203 for (;;) {
204 const string& host = getNext(iter);
205 if (host.empty()) {
206 break;
207 }
208 result->add(getHost(host));
209 }
210 return (result);
211 } catch (const sysrepo_exception& ex) {
213 "sysrepo error getting host reservations at '" << xpath
214 << "': " << ex.what());
215 }
216}
217
218void
219TranslatorHosts::setHosts(const string& xpath, ConstElementPtr elem) {
220 try {
221 if ((model_ == KEA_DHCP4_SERVER) ||
222 (model_ == KEA_DHCP6_SERVER)) {
223 setHostsKea(xpath, elem);
224 } else {
226 "setHosts not implemented for the model: " << model_);
227 }
228 } catch (const sysrepo_exception& ex) {
230 "sysrepo error setting host reservations '" << elem->str()
231 << "' at '" << xpath << "': " << ex.what());
232 }
233}
234
235void
237 for (size_t i = 0; i < elem->size(); ++i) {
238 string id_type = "unknown";
239 ConstElementPtr host = elem->get(i);
240 ConstElementPtr id = host->get("hw-address");
241 if (id) {
242 id_type = "hw-address";
243 goto found;
244 }
245 id = host->get("duid");
246 if (id) {
247 id_type = "duid";
248 goto found;
249 }
250 if (model_ == KEA_DHCP4_SERVER) {
251 id = host->get("circuit-id");
252 if (id) {
253 id_type = "circuit-id";
254 goto found;
255 }
256 id = host->get("client-id");
257 if (id) {
258 id_type = "client-id";
259 goto found;
260 }
261 }
262 id = host->get("flex-id");
263 if (id) {
264 id_type = "flex-id";
265 goto found;
266 }
267
268 found:
269 if (id_type == "unknown") {
270 isc_throw(BadValue, "getHosts: can't find the identifier type in "
271 << host->str());
272 }
273 ostringstream key;
274 key << xpath << "/host[identifier-type='" << id_type
275 << "'][identifier='" << id->stringValue() << "']";
276 setHost(key.str(), host);
277 }
278}
279
280}; // end of namespace isc::yang
281}; // end of 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 ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:223
static ElementPtr fromJSON(const std::string &in, bool preproc=false)
These functions will parse the given string (JSON) representation of a compound element.
Definition: data.cc:750
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:268
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition: data.cc:263
static isc::data::ConstElementPtr getContext(isc::data::ConstElementPtr parent)
Get user context.
Definition: adaptor.cc:25
Between YANG and JSON translator class for basic values.
Definition: translator.h:27
std::string getNext(sysrepo::S_Iter_Value iter)
Get xpath of the next YANG list item.
Definition: translator.cc:283
isc::data::ElementPtr getItem(const std::string &xpath)
Get and translate basic value from YANG to JSON.
Definition: translator.cc:104
sysrepo::S_Iter_Value getIter(const std::string &xpath)
List iterator methods keeping the session private.
Definition: translator.cc:278
std::string model_
The model.
Definition: translator.h:132
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:250
isc::data::ElementPtr getItems(const std::string &xpath)
Get and translate a list of basic values from YANG to JSON.
Definition: translator.cc:119
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:23
boost::shared_ptr< Element > ElementPtr
Definition: data.h:22
Defines the logger used by the top-level component of kea-dhcp-ddns.