Kea  2.1.7-git
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 
9 #include <yang/translator_host.h>
10 #include <yang/adaptor.h>
11 #include <yang/yang_models.h>
12 #include <sstream>
13 
14 using namespace std;
15 using namespace isc::data;
16 using namespace sysrepo;
17 
18 namespace isc {
19 namespace yang {
20 
21 TranslatorHost::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 
47 TranslatorHost::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 
104 void
105 TranslatorHost::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 
121 void
122 TranslatorHost::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 
182 TranslatorHosts::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 
193 TranslatorHosts::getHosts(const string& xpath) {
194  return getList<TranslatorHost>(xpath + "/host", *this,
196 }
197 
198 void
199 TranslatorHosts::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 
215 void
216 TranslatorHosts::setHostsKea(const string& xpath, ConstElementPtr elem) {
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
isc::data::ElementPtr getItems(const std::string &xpath)
Get and translate a list of basic values from YANG to JSON.
Definition: translator.cc:124
isc::data::ElementPtr getHostKea(const std::string &xpath)
getHost for kea-dhcp[46]-server models.
isc::data::ElementPtr getHosts(const std::string &xpath)
Get and translate host reservations from YANG to JSON.
void setHostsKea(const std::string &xpath, isc::data::ConstElementPtr elem)
setHosts for kea-dhcp[46].
A generic exception that is thrown when a function is not implemented.
Between YANG and JSON translator class for basic values.
Definition: translator.h:19
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
STL namespace.
virtual ~TranslatorHost()
Destructor.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
isc::data::ElementPtr getHost(const std::string &xpath)
Get and translate a host reservation from YANG to JSON.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
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
Translation between YANG and JSON for a single host reservation.
A translator class for converting an option data list between YANG and JSON.
A generic exception that is thrown when an unexpected error condition occurs.
std::string model_
The model.
Definition: translator.h:171
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
static isc::data::ConstElementPtr getContext(isc::data::ConstElementPtr parent)
Get user context.
Definition: adaptor.cc:27
void setHostKea(const std::string &xpath, isc::data::ConstElementPtr elem)
setHost for kea-dhcp[46]-server models.
TranslatorHosts(sysrepo::S_Session session, const std::string &model)
Constructor.
Defines the logger used by the top-level component of kea-lfc.
isc::data::ConstElementPtr getOptionDataList(const std::string &xpath)
Get and translate option data list from YANG to JSON.
isc::data::ElementPtr getItem(const std::string &xpath)
Get and translate basic value from YANG to JSON.
Definition: translator.cc:105
virtual ~TranslatorHosts()
Destructor.
Option data translation between YANG and JSON.
void setOptionDataList(const std::string &xpath, isc::data::ConstElementPtr elem)
Translate and set option data list from JSON to YANG.
void setHost(const std::string &xpath, isc::data::ConstElementPtr elem)
Translate and set host reservation from JSON to YANG.
void setHosts(const std::string &xpath, isc::data::ConstElementPtr elem)
Translate and set (address) host reservations from JSON to YANG.