Kea 3.1.1
translator_host.cc
Go to the documentation of this file.
1// Copyright (C) 2018-2025 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 checkAndGetLeaf(result, data_node, "excluded-prefixes");
82 }
83
84 return (result->empty() ? ElementPtr() : result);
85}
86
87void
88TranslatorHost::setHost(string const& xpath, ConstElementPtr elem) {
89 try {
90 if ((model_ == KEA_DHCP4_SERVER) ||
91 (model_ == KEA_DHCP6_SERVER)) {
92 setHostKea(xpath, elem);
93 } else {
95 "setHost not implemented for the model: " << model_);
96 }
97 } catch (Error const& ex) {
99 "setting host reservation '" << elem->str()
100 << "' : " << ex.what());
101 }
102}
103
104void
105TranslatorHost::setHostKea(string const& xpath, ConstElementPtr elem) {
106 // Set the list element. This is important in case we have no other elements except the keys.
107 setItem(xpath, ElementPtr(), LeafBaseType::Unknown);
108
109 // Skip keys "identifier" and "identifier-type" since they were set with the
110 // list element in the call above with the LeafBaseType::Unknown parameter.
111
112 checkAndSetLeaf(elem, xpath, "hostname", LeafBaseType::String);
113
114 checkAndSetLeafList(elem, xpath, "client-classes", LeafBaseType::String);
115
116 ConstElementPtr options = elem->get("option-data");
117 if (options && !options->empty()) {
118 setOptionDataList(xpath, options);
119 }
120
121 if (model_ == KEA_DHCP4_SERVER) {
122 checkAndSetLeaf(elem, xpath, "boot-file-name", LeafBaseType::String);
123 checkAndSetLeaf(elem, xpath, "ip-address", LeafBaseType::String);
124 checkAndSetLeaf(elem, xpath, "next-server", LeafBaseType::String);
125 checkAndSetLeaf(elem, xpath, "server-hostname", LeafBaseType::String);
126 } else {
127 checkAndSetLeafList(elem, xpath, "ip-addresses", LeafBaseType::String);
128 checkAndSetLeafList(elem, xpath, "prefixes", LeafBaseType::String);
129 checkAndSetLeafList(elem, xpath, "excluded-prefixes", LeafBaseType::String);
130 }
131
132 // User context is supported in both kea-dhcp4-server and kea-dhcp6-server.
133 checkAndSetUserContext(elem, xpath);
134}
135
136TranslatorHosts::TranslatorHosts(Session session, const string& model)
137 : Translator(session, model),
138 TranslatorOptionData(session, model),
139 TranslatorOptionDataList(session, model),
140 TranslatorHost(session, model) {
141}
142
144TranslatorHosts::getHosts(DataNode const& data_node) {
145 return getList<TranslatorHost>(data_node, "host", *this,
147}
148
151 try {
152 return getHosts(findXPath(xpath));
153 } catch (NetconfError const&) {
154 return ElementPtr();
155 }
156}
157
158void
159TranslatorHosts::setHosts(string const& xpath, ConstElementPtr elem) {
160 try {
161 if ((model_ == KEA_DHCP4_SERVER) ||
162 (model_ == KEA_DHCP6_SERVER)) {
163 setHostsKea(xpath, elem);
164 } else {
166 "setHosts not implemented for the model: " << model_);
167 }
168 } catch (Error const& ex) {
170 "setting host reservations '" << elem->str()
171 << "' : " << ex.what());
172 }
173}
174
175void
177 for (size_t i = 0; i < elem->size(); ++i) {
178 string id_type = "unknown";
179 ElementPtr host = elem->getNonConst(i);
180 ConstElementPtr id = host->get("hw-address");
181 if (id) {
182 id_type = "hw-address";
183 goto found;
184 }
185 id = host->get("duid");
186 if (id) {
187 id_type = "duid";
188 goto found;
189 }
190 if (model_ == KEA_DHCP4_SERVER) {
191 id = host->get("circuit-id");
192 if (id) {
193 id_type = "circuit-id";
194 goto found;
195 }
196 id = host->get("client-id");
197 if (id) {
198 id_type = "client-id";
199 goto found;
200 }
201 }
202 id = host->get("flex-id");
203 if (id) {
204 id_type = "flex-id";
205 goto found;
206 }
207
208 found:
209 if (id_type == "unknown") {
210 isc_throw(BadValue, "getHosts: can't find the identifier type in "
211 << host->str());
212 }
213 ostringstream key;
214 key << xpath << "/host[identifier-type='" << id_type
215 << "'][identifier='" << id->stringValue() << "']";
216 setHost(key.str(), host);
217 }
218}
219
220} // namespace yang
221} // namespace isc
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:304
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.
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.
TranslatorOptionDataList(sysrepo::Session session, const std::string &model)
Constructor.
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
isc::data::ElementPtr getList(libyang::DataNode const &data_node, std::string const &xpath, T &t, isc::data::ElementPtr(T::*f)(libyang::DataNode const &)) const
Retrieve a list as ElementPtr from sysrepo from a certain xpath.
Definition translator.h:274
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.