Kea 2.5.5
d2_simple_parser.cc
Go to the documentation of this file.
1// Copyright (C) 2017-2023 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 <d2srv/d2_config.h>
11#include <cc/data.h>
12#include <hooks/hooks_manager.h>
13#include <hooks/hooks_parser.h>
14#include <boost/foreach.hpp>
15
16using namespace isc::data;
17using namespace isc::d2;
18using namespace isc;
19
20namespace {
21
23getProtocol(ConstElementPtr map, const std::string& name) {
24 ConstElementPtr value = map->get(name);
25 if (!value) {
26 isc_throw(D2CfgError, "Mandatory parameter " << name
27 << " not found (" << map->getPosition() << ")");
28 }
29 std::string str = value->stringValue();
30 try {
32 } catch (const std::exception& ex) {
34 "invalid NameChangeRequest protocol (" << str
35 << ") specified for parameter '" << name
36 << "' (" << value->getPosition() << ")");
37 }
38}
39
41getFormat(ConstElementPtr map, const std::string& name) {
42 ConstElementPtr value = map->get(name);
43 if (!value) {
44 isc_throw(D2CfgError, "Mandatory parameter " << name
45 << " not found (" << map->getPosition() << ")");
46 }
47 std::string str = value->stringValue();
48 try {
49 return (dhcp_ddns::stringToNcrFormat(str));
50 } catch (const std::exception& ex) {
52 "invalid NameChangeRequest format (" << str
53 << ") specified for parameter '" << name
54 << "' (" << value->getPosition() << ")");
55 }
56}
57
58} // anon
59
60namespace isc {
61namespace d2 {
76
83 { "ip-address", Element::string, "127.0.0.1" },
84 { "port", Element::integer, "53001" },
85 { "dns-server-timeout", Element::integer, "500" }, // in milliseconds
86 { "ncr-protocol", Element::string, "UDP" },
87 { "ncr-format", Element::string, "JSON" }
88};
89
92 { "digest-bits", Element::integer, "0" }
93};
94
102};
103
106 { "key-name", Element::string, "" }
107};
108
111 { "hostname", Element::string, "" },
112 { "port", Element::integer, "53" },
113 { "key-name", Element::string, "" }
114};
115
117
121
122size_t
124 size_t cnt = 0;
125 // Set global defaults first.
126 cnt = setDefaults(global, D2_GLOBAL_DEFAULTS);
127
128 // If the key list is present, set its members' defaults
129 if (global->find("tsig-keys")) {
130 ConstElementPtr keys = global->get("tsig-keys");
132 } else {
133 // Not present, so add an empty list.
134 ConstElementPtr list(new ListElement());
135 global->set("tsig-keys", list);
136 cnt++;
137 }
138
139 // Set the forward domain manager defaults.
140 cnt += setManagerDefaults(global, "forward-ddns", DDNS_DOMAIN_MGR_DEFAULTS);
141
142 // Set the reverse domain manager defaults.
143 cnt += setManagerDefaults(global, "reverse-ddns", DDNS_DOMAIN_MGR_DEFAULTS);
144 return (cnt);
145}
146
147size_t
149 const SimpleDefaults& domain_defaults) {
150 size_t cnt = 0;
151
152 // Set the domain's scalar defaults
153 cnt += setDefaults(domain, domain_defaults);
154 if (domain->find("dns-servers")) {
155 // Now add the defaults to its server list.
156 ConstElementPtr servers = domain->get("dns-servers");
157 cnt += setListDefaults(servers, DNS_SERVER_DEFAULTS);
158 }
159
160 return (cnt);
161}
162
163
164size_t
166 const std::string& mgr_name,
167 const SimpleDefaults& mgr_defaults) {
168 size_t cnt = 0;
169
170 if (!global->find(mgr_name)) {
171 // If it's not present, then default is an empty map
172 ConstElementPtr map(new MapElement());
173 global->set(mgr_name, map);
174 ++cnt;
175 } else {
176 // Get a writable copy of the manager element map
177 ElementPtr mgr =
178 boost::const_pointer_cast<Element>(global->get(mgr_name));
179
180 // Set the manager's scalar defaults first
181 cnt += setDefaults(mgr, mgr_defaults);
182
183 // Get the domain list and set defaults for them.
184 // The domain list may not be present ddns for this
185 // manager is disabled.
186 if (mgr->find("ddns-domains")) {
187 ConstElementPtr domains = mgr->get("ddns-domains");
188 BOOST_FOREACH(ElementPtr domain, domains->listValue()) {
189 // Set the domain's defaults. We can't use setListDefaults()
190 // as this does not handle sub-lists or maps, like server list.
192 }
193 }
194
195 }
196
197 return (cnt);
198}
199
201 const isc::data::ConstElementPtr& config,
202 bool check_only) {
203 // TSIG keys need to parse before the Domains, so we can catch Domains
204 // that specify undefined keys. Create the necessary parsing order now.
205 // addToParseOrder("tsig-keys");
206 // addToParseOrder("forward-ddns");
207 // addToParseOrder("reverse-ddns");
208
209 ConstElementPtr keys = config->get("tsig-keys");
210 if (keys) {
212 ctx->setKeys(parser.parse(keys));
213 }
214
215 ConstElementPtr fwd = config->get("forward-ddns");
216 if (fwd) {
218 DdnsDomainListMgrPtr mgr = parser.parse(fwd, "forward-ddns",
219 ctx->getKeys());
220 ctx->setForwardMgr(mgr);
221 }
222
223 ConstElementPtr rev = config->get("reverse-ddns");
224 if (rev) {
226 DdnsDomainListMgrPtr mgr = parser.parse(rev, "reverse-ddns",
227 ctx->getKeys());
228 ctx->setReverseMgr(mgr);
229 }
230
231 // Fetch the parameters in the config, performing any logical
232 // validation required.
233 asiolink::IOAddress ip_address(0);
234 uint32_t port = 0;
235 uint32_t dns_server_timeout = 0;
238
239 ip_address = SimpleParser::getAddress(config, "ip-address");
240 port = SimpleParser::getUint32(config, "port");
241 dns_server_timeout = SimpleParser::getUint32(config, "dns-server-timeout");
242
243 ncr_protocol = getProtocol(config, "ncr-protocol");
244 if (ncr_protocol != dhcp_ddns::NCR_UDP) {
245 isc_throw(D2CfgError, "ncr-protocol : "
246 << dhcp_ddns::ncrProtocolToString(ncr_protocol)
247 << " is not yet supported ("
248 << config->get("ncr-protocol")->getPosition() << ")");
249 }
250
251 ncr_format = getFormat(config, "ncr-format");
252 if (ncr_format != dhcp_ddns::FMT_JSON) {
253 isc_throw(D2CfgError, "NCR Format:"
254 << dhcp_ddns::ncrFormatToString(ncr_format)
255 << " is not yet supported"
256 << " (" << config->get("ncr-format")->getPosition() << ")");
257 }
258
259 ConstElementPtr user = config->get("user-context");
260 if (user) {
261 ctx->setContext(user);
262 }
263
264 ConstElementPtr socket = config->get("control-socket");
265 if (socket) {
266 if (socket->getType() != Element::map) {
267 isc_throw(D2CfgError, "Specified control-socket is expected to be a map"
268 ", i.e. a structure defined within { }");
269 }
270 ctx->setControlSocketInfo(socket);
271 }
272
273 // Finally, let's get the hook libs!
274 using namespace isc::hooks;
275 HooksConfig& libraries = ctx->getHooksConfig();
276 ConstElementPtr hooks = config->get("hooks-libraries");
277 if (hooks) {
278 HooksLibrariesParser hooks_parser;
279 hooks_parser.parse(libraries, hooks);
280 libraries.verifyLibraries(hooks->getPosition(), false);
281 }
282
283 // Attempt to create the new client config. This ought to fly as
284 // we already validated everything.
285 D2ParamsPtr params(new D2Params(ip_address, port, dns_server_timeout,
286 ncr_protocol, ncr_format));
287
288 ctx->getD2Params() = params;
289
290 if (!check_only) {
291 // This occurs last as if it succeeds, there is no easy way
292 // revert it. As a result, the failure to commit a subsequent
293 // change causes problems when trying to roll back.
294 HooksManager::prepareUnloadLibraries();
295 static_cast<void>(HooksManager::unloadLibraries());
296 libraries.loadLibraries(false);
297 }
298}
299
300}
301}
Exception thrown when the error during configuration handling occurs.
Definition: d2_config.h:136
Acts as a storage vault for D2 global scalar parameters.
Definition: d2_config.h:143
static const data::SimpleDefaults D2_GLOBAL_DEFAULTS
This table defines default global values for D2.
static size_t setManagerDefaults(data::ElementPtr global, const std::string &mgr_name, const data::SimpleDefaults &mgr_defaults)
Adds default values to a DDNS Domain List Manager.
static const data::SimpleDefaults TSIG_KEY_DEFAULTS
Supplies defaults for ddns-domains list elements (i.e. DdnsDomains)
static size_t setDdnsDomainDefaults(data::ElementPtr domain, const data::SimpleDefaults &domain_defaults)
Adds default values to a DDNS Domain element.
void parse(const D2CfgContextPtr &ctx, const isc::data::ConstElementPtr &config, bool check_only)
Parses the whole D2 configuration.
static size_t setAllDefaults(data::ElementPtr global)
Sets all defaults for D2 configuration.
static const data::SimpleDefaults DNS_SERVER_DEFAULTS
Supplies defaults for optional values DdnsDomain entries.
static const data::SimpleDefaults DDNS_DOMAIN_MGR_DEFAULTS
Supplies defaults for optional values in DDNS domain managers (e.g.
static const data::SimpleDefaults DDNS_DOMAIN_DEFAULTS
Supplies defaults for ddns-domains list elements (i.e. DdnsDomains)
Parser for DdnsDomainListMgr.
Definition: d2_config.h:905
DdnsDomainListMgrPtr parse(data::ConstElementPtr mgr_config, const std::string &mgr_name, const TSIGKeyInfoMapPtr keys)
Performs the actual parsing of the given manager element.
Definition: d2_config.cc:650
Parser for a list of TSIGKeyInfos.
Definition: d2_config.h:790
TSIGKeyInfoMapPtr parse(data::ConstElementPtr key_list_config)
Performs the parsing of the given list "tsig-key" elements.
Definition: d2_config.cc:458
static size_t setListDefaults(isc::data::ConstElementPtr list, const SimpleDefaults &default_values)
Sets the default values for all entries in a list.
static size_t setDefaults(isc::data::ElementPtr scope, const SimpleDefaults &default_values)
Sets the default values.
Wrapper class that holds hooks libraries configuration.
Definition: hooks_config.h:36
const isc::hooks::HookLibsCollection & get() const
Provides access to the configured hooks libraries.
Definition: hooks_config.h:54
void verifyLibraries(const isc::data::Element::Position &position, bool multi_threading_enabled) const
Verifies that libraries stored in libraries_ are valid.
Definition: hooks_config.cc:20
void loadLibraries(bool multi_threading_enabled) const
Commits hooks libraries configuration.
Definition: hooks_config.cc:57
Parser for hooks library list.
Definition: hooks_parser.h:21
void parse(HooksConfig &libraries, isc::data::ConstElementPtr value)
Parses parameters value.
Definition: hooks_parser.cc:28
A collection of classes for housing and parsing the application configuration necessary for the DHCP-...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< DdnsDomainListMgr > DdnsDomainListMgrPtr
Defines a pointer for DdnsDomain instances.
Definition: d2_cfg_mgr.h:153
boost::shared_ptr< D2CfgContext > D2CfgContextPtr
Pointer to a configuration context.
Definition: d2_cfg_mgr.h:25
boost::shared_ptr< D2Params > D2ParamsPtr
Defines a pointer for D2Params instances.
Definition: d2_config.h:257
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:29
std::vector< SimpleDefault > SimpleDefaults
This specifies all default values in a given scope (e.g. a subnet).
boost::shared_ptr< Element > ElementPtr
Definition: data.h:28
NameChangeProtocol stringToNcrProtocol(const std::string &protocol_str)
Function which converts text labels to NameChangeProtocol enums.
Definition: ncr_io.cc:23
NameChangeFormat
Defines the list of data wire formats supported.
Definition: ncr_msg.h:60
NameChangeProtocol
Defines the list of socket protocols supported.
Definition: ncr_io.h:68
std::string ncrProtocolToString(NameChangeProtocol protocol)
Function which converts NameChangeProtocol enums to text labels.
Definition: ncr_io.cc:36
NameChangeFormat stringToNcrFormat(const std::string &fmt_str)
Function which converts labels to NameChangeFormat enum values.
Definition: ncr_msg.cc:26
std::string ncrFormatToString(NameChangeFormat format)
Function which converts NameChangeFormat enums to text labels.
Definition: ncr_msg.cc:35
Defines the logger used by the top-level component of kea-lfc.