Kea 2.7.1
translator_host.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
10#include <yang/yang_models.h>
11
12#include <sstream>
13
14using namespace std;
15using namespace isc::data;
16using namespace libyang;
17using namespace sysrepo;
18
19namespace isc {
20namespace yang {
21
22TranslatorHost::TranslatorHost(Session session, const string& model)
23 : Translator(session, model),
24 TranslatorOptionData(session, model),
25 TranslatorOptionDataList(session, model) {
26}
27
29TranslatorHost::getHost(DataNode const& data_node) {
30 try {
31 if ((model_ == KEA_DHCP4_SERVER) ||
32 (model_ == KEA_DHCP6_SERVER)) {
33 return (getHostKea(data_node));
34 }
35 } catch (Error const& ex) {
37 "getting host reservation:"
38 << ex.what());
39 }
41 "getHost not implemented for the model: " << model_);
42}
43
46 try {
47 return getHost(findXPath(xpath));
48 } catch (NetconfError const&) {
49 return ElementPtr();
50 }
51}
52
54TranslatorHost::getHostKea(DataNode const& data_node) {
55 ConstElementPtr id_type = getItem(data_node, "identifier-type");
56 ConstElementPtr id = getItem(data_node, "identifier");
57 if (!id_type || !id) {
58 isc_throw(MissingNode, "getHostKea requires both identifier and identifier-type");
59 }
61 result->set(id_type->stringValue(), id);
62
63 checkAndGetLeaf(result, data_node, "client-classes");
64 checkAndGetLeaf(result, data_node, "hostname");
65
66 checkAndGetAndJsonifyLeaf(result, data_node, "user-context");
67
68 ConstElementPtr options = getOptionDataList(data_node);
69 if (options) {
70 result->set("option-data", options);
71 }
72
73 if (model_ == KEA_DHCP4_SERVER) {
74 checkAndGetLeaf(result, data_node, "boot-file-name");
75 checkAndGetLeaf(result, data_node, "ip-address");
76 checkAndGetLeaf(result, data_node, "next-server");
77 checkAndGetLeaf(result, data_node, "server-hostname");
78 } else {
79 checkAndGetLeaf(result, data_node, "ip-addresses");
80 checkAndGetLeaf(result, data_node, "prefixes");
81 }
82
83 return (result->empty() ? ElementPtr() : result);
84}
85
86void
87TranslatorHost::setHost(string const& xpath, ConstElementPtr elem) {
88 try {
89 if ((model_ == KEA_DHCP4_SERVER) ||
90 (model_ == KEA_DHCP6_SERVER)) {
91 setHostKea(xpath, elem);
92 } else {
94 "setHost not implemented for the model: " << model_);
95 }
96 } catch (Error const& ex) {
98 "setting host reservation '" << elem->str()
99 << "' : " << ex.what());
100 }
101}
102
103void
104TranslatorHost::setHostKea(string const& xpath, ConstElementPtr elem) {
105 // Set the list element. This is important in case we have no other elements except the keys.
106 setItem(xpath, ElementPtr(), LeafBaseType::Unknown);
107
108 // Skip keys "identifier" and "identifier-type" since they were set with the
109 // list element in the call above with the LeafBaseType::Unknown parameter.
110
111 checkAndSetLeaf(elem, xpath, "hostname", LeafBaseType::String);
112
113 checkAndSetLeafList(elem, xpath, "client-classes", LeafBaseType::String);
114
115 ConstElementPtr options = elem->get("option-data");
116 if (options && !options->empty()) {
117 setOptionDataList(xpath, options);
118 }
119
120 if (model_ == KEA_DHCP4_SERVER) {
121 checkAndSetLeaf(elem, xpath, "boot-file-name", LeafBaseType::String);
122 checkAndSetLeaf(elem, xpath, "ip-address", LeafBaseType::String);
123 checkAndSetLeaf(elem, xpath, "next-server", LeafBaseType::String);
124 checkAndSetLeaf(elem, xpath, "server-hostname", LeafBaseType::String);
125 } else {
126 checkAndSetLeafList(elem, xpath, "ip-addresses", LeafBaseType::String);
127 checkAndSetLeafList(elem, xpath, "prefixes", LeafBaseType::String);
128 }
129
130 // User context is supported in both kea-dhcp4-server and kea-dhcp6-server.
131 checkAndSetUserContext(elem, xpath);
132}
133
134TranslatorHosts::TranslatorHosts(Session session, const string& model)
135 : Translator(session, model),
136 TranslatorOptionData(session, model),
137 TranslatorOptionDataList(session, model),
138 TranslatorHost(session, model) {
139}
140
142TranslatorHosts::getHosts(DataNode const& data_node) {
143 return getList<TranslatorHost>(data_node, "host", *this,
145}
146
149 try {
150 return getHosts(findXPath(xpath));
151 } catch (NetconfError const&) {
152 return ElementPtr();
153 }
154}
155
156void
157TranslatorHosts::setHosts(string const& xpath, ConstElementPtr elem) {
158 try {
159 if ((model_ == KEA_DHCP4_SERVER) ||
160 (model_ == KEA_DHCP6_SERVER)) {
161 setHostsKea(xpath, elem);
162 } else {
164 "setHosts not implemented for the model: " << model_);
165 }
166 } catch (Error const& ex) {
168 "setting host reservations '" << elem->str()
169 << "' : " << ex.what());
170 }
171}
172
173void
175 for (size_t i = 0; i < elem->size(); ++i) {
176 string id_type = "unknown";
177 ElementPtr host = elem->getNonConst(i);
178 ConstElementPtr id = host->get("hw-address");
179 if (id) {
180 id_type = "hw-address";
181 goto found;
182 }
183 id = host->get("duid");
184 if (id) {
185 id_type = "duid";
186 goto found;
187 }
188 if (model_ == KEA_DHCP4_SERVER) {
189 id = host->get("circuit-id");
190 if (id) {
191 id_type = "circuit-id";
192 goto found;
193 }
194 id = host->get("client-id");
195 if (id) {
196 id_type = "client-id";
197 goto found;
198 }
199 }
200 id = host->get("flex-id");
201 if (id) {
202 id_type = "flex-id";
203 goto found;
204 }
205
206 found:
207 if (id_type == "unknown") {
208 isc_throw(BadValue, "getHosts: can't find the identifier type in "
209 << host->str());
210 }
211 ostringstream key;
212 key << xpath << "/host[identifier-type='" << id_type
213 << "'][identifier='" << id->stringValue() << "']";
214 setHost(key.str(), host);
215 }
216}
217
218} // namespace yang
219} // 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.
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:304
Translation between YANG and JSON for a single host reservation.
isc::data::ElementPtr getHostFromAbsoluteXpath(std::string const &xpath)
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.
isc::data::ElementPtr getHostKea(libyang::DataNode const &data_node)
getHost for kea-dhcp[46]-server models.
isc::data::ElementPtr getHost(libyang::DataNode const &data_node)
Translate a host reservation from YANG to JSON.
void setHostKea(const std::string &xpath, isc::data::ConstElementPtr elem)
setHost for kea-dhcp[46]-server models.
TranslatorHost(sysrepo::Session session, const std::string &model)
Constructor.
isc::data::ElementPtr getHosts(libyang::DataNode const &data_node)
Translate host reservations from YANG to JSON.
TranslatorHosts(sysrepo::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.
void setHostsKea(const std::string &xpath, isc::data::ConstElementPtr elem)
setHosts for kea-dhcp[46].
isc::data::ElementPtr getHostsFromAbsoluteXpath(std::string const &xpath)
Translate host reservations from YANG to JSON.
A translator class for converting an option data list between YANG and JSON.
void setOptionDataList(const std::string &xpath, isc::data::ConstElementPtr elem)
Translate and set option data list from JSON to YANG.
isc::data::ConstElementPtr getOptionDataList(libyang::DataNode const &data_node)
Translate option data list from YANG to JSON.
Option data translation between YANG and JSON.
Between YANG and JSON translator class for basic values.
Definition translator.h:23
void checkAndSetLeaf(isc::data::ConstElementPtr const &from, std::string const &xpath, std::string const &name, libyang::LeafBaseType const type)
Get an element from given ElementPtr node and set it in sysrepo at given xpath.
Definition translator.cc:63
isc::data::ElementPtr getItem(libyang::DataNode const &data_node, std::string const &xpath) const
Translate a basic value from YANG to JSON for a given xpath that is relative to the given source node...
libyang::DataNode findXPath(std::string const &xpath) const
Retrieves a YANG data node by xpath.
void checkAndGetLeaf(isc::data::ElementPtr &storage, libyang::DataNode const &data_node, std::string const &name) const
Retrieves a child YANG data node identified by name from the given parent YANG container node and sto...
Definition translator.cc:32
void checkAndSetUserContext(isc::data::ConstElementPtr const &from, std::string const &xpath)
Get an element from given ElementPtr node and set it in sysrepo at given xpath.
Definition translator.cc:99
void setItem(const std::string &xpath, isc::data::ConstElementPtr const elem, libyang::LeafBaseType const type)
Translate and set basic value from JSON to YANG.
std::string model_
The model.
Definition translator.h:427
void checkAndGetAndJsonifyLeaf(isc::data::ElementPtr &storage, libyang::DataNode const &data_node, const std::string &name) const
Retrieves a child YANG data node identified by name from the given parent YANG container node,...
Definition translator.cc:53
void checkAndSetLeafList(isc::data::ConstElementPtr const &from, std::string const &xpath, std::string const &name, libyang::LeafBaseType const type)
Get an element from given ElementPtr node and set it in sysrepo at given xpath as a leaf-list.
Definition translator.cc:86
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
boost::shared_ptr< Element > ElementPtr
Definition data.h:28
Defines the logger used by the top-level component of kea-lfc.
Missing node error.
Generic NETCONF error.