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_config.h>
10 #include <yang/adaptor_config.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 
TranslatorConfig(S_Session session,const string & model)21 TranslatorConfig::TranslatorConfig(S_Session session, const string& model)
22     : TranslatorBasic(session, model),
23       TranslatorControlSocket(session, model),
24       TranslatorDatabase(session, model),
25       TranslatorDatabases(session, model),
26       TranslatorOptionData(session, model),
27       TranslatorOptionDataList(session, model),
28       TranslatorOptionDef(session, model),
29       TranslatorOptionDefList(session, model),
30       TranslatorClass(session, model),
31       TranslatorClasses(session, model),
32       TranslatorPool(session, model),
33       TranslatorPools(session, model),
34       TranslatorPdPool(session, model),
35       TranslatorPdPools(session, model),
36       TranslatorHost(session, model),
37       TranslatorHosts(session, model),
38       TranslatorSubnet(session, model),
39       TranslatorSubnets(session, model),
40       TranslatorSharedNetwork(session, model),
41       TranslatorSharedNetworks(session, model),
42       TranslatorLogger(session, model),
43       TranslatorLoggers(session, model) {
44 }
45 
~TranslatorConfig()46 TranslatorConfig::~TranslatorConfig() {
47 }
48 
49 ElementPtr
getConfig()50 TranslatorConfig::getConfig() {
51     try {
52         if (model_ == IETF_DHCPV6_SERVER) {
53             return (getConfigIetf6());
54         } else if (model_ == KEA_DHCP4_SERVER) {
55             return (getConfigKea4());
56         } else if (model_ == KEA_DHCP6_SERVER) {
57             return (getConfigKea6());
58         }
59     } catch (const sysrepo_exception& ex) {
60         isc_throw(SysrepoError, "sysrepo error getting config: " << ex.what());
61     }
62     isc_throw(NotImplemented,
63               "getConfig not implemented for the model: " << model_);
64 }
65 
66 ElementPtr
getConfigIetf6()67 TranslatorConfig::getConfigIetf6() {
68     ElementPtr result = Element::createMap();
69     ElementPtr dhcp6 = Element::createMap();
70     result->set("Dhcp6", dhcp6);
71     string xpath = "/" + model_ + ":server/server-config";
72     ConstElementPtr ranges =
73         getSubnets(xpath + "/network-ranges");
74     if (ranges && !ranges->empty()) {
75         dhcp6->set("subnet6", ranges);
76     }
77     // Skip everything else.
78     return (result);
79 }
80 
81 ElementPtr
getConfigKea4()82 TranslatorConfig::getConfigKea4() {
83     ElementPtr result = Element::createMap();
84     ElementPtr dhcp = getServerKeaDhcp4();
85     result->set("Dhcp4", dhcp);
86     return (result);
87 }
88 
89 ElementPtr
getConfigKea6()90 TranslatorConfig::getConfigKea6() {
91     ElementPtr result = Element::createMap();
92     ElementPtr dhcp = getServerKeaDhcp6();
93     result->set("Dhcp6", dhcp);
94     return (result);
95 }
96 
97 void
getParam(ElementPtr & storage,const std::string & xpath,const std::string & name)98 TranslatorConfig::getParam(ElementPtr& storage, const std::string& xpath,
99                            const std::string& name) {
100     ConstElementPtr x = getItem(xpath + "/" + name);
101     if (x) {
102         storage->set(name, x);
103     }
104 }
105 
getHook(string const & xpath)106 ElementPtr TranslatorConfig::getHook(string const& xpath) {
107     ElementPtr const& hook_library(Element::createMap());
108     ElementPtr const& name(getItem(xpath + "/library"));
109     if (name) {
110         hook_library->set("library", name);
111         ElementPtr const& parameters(getItem(xpath + "/parameters"));
112         if (parameters) {
113             hook_library->set("parameters",
114                               Element::fromJSON(parameters->stringValue()));
115         }
116     }
117     return hook_library;
118 }
119 
120 ElementPtr
getHooksKea(const std::string & xpath)121 TranslatorConfig::getHooksKea(const std::string& xpath) {
122     return getList(xpath + "/hook-library", *this, &TranslatorConfig::getHook);
123 }
124 
125 isc::data::ElementPtr
getExpiredKea(const std::string & xpath)126 TranslatorConfig::getExpiredKea(const std::string& xpath) {
127     ElementPtr expired = Element::createMap();
128 
129     getParam(expired, xpath, "reclaim-timer-wait-time");
130     getParam(expired, xpath, "flush-reclaimed-timer-wait-time");
131     getParam(expired, xpath, "hold-reclaimed-time");
132     getParam(expired, xpath, "max-reclaim-leases");
133     getParam(expired, xpath, "max-reclaim-time");
134     getParam(expired, xpath, "unwarned-reclaim-cycles");
135 
136     if (!expired->empty()) {
137         return (expired);
138     }
139 
140     return (ElementPtr());
141 }
142 
143 isc::data::ElementPtr
getDdnsKea(const std::string & xpath)144 TranslatorConfig::getDdnsKea(const std::string& xpath) {
145     ElementPtr ddns = Element::createMap();
146     getParam(ddns, xpath, "enable-updates");
147     getParam(ddns, xpath, "qualifying-suffix");
148     getParam(ddns, xpath, "server-ip");
149     getParam(ddns, xpath, "server-port");
150     getParam(ddns, xpath, "sender-ip");
151     getParam(ddns, xpath, "sender-port");
152     getParam(ddns, xpath, "max-queue-size");
153     getParam(ddns, xpath, "ncr-protocol");
154     getParam(ddns, xpath, "ncr-format");
155     getParam(ddns, xpath, "override-no-update");
156     getParam(ddns, xpath, "override-client-update");
157     getParam(ddns, xpath, "replace-client-name");
158     getParam(ddns, xpath, "generated-prefix");
159     getParam(ddns, xpath, "hostname-char-set");
160     getParam(ddns, xpath, "hostname-char-replacement");
161 
162     ConstElementPtr context = getItem(xpath + "/user-context");
163     if (context) {
164         ddns->set("user-context", Element::fromJSON(context->stringValue()));
165     }
166 
167     if (!ddns->empty()) {
168         // If there's something to return, use it.
169         return (ddns);
170     }
171 
172     // If not, return null.
173     return (ElementPtr());
174 }
175 
176 ElementPtr
getConfigControlKea(const string & xpath)177 TranslatorConfig::getConfigControlKea(const string& xpath) {
178     ElementPtr config_ctrl = Element::createMap();
179     getParam(config_ctrl, xpath, "config-fetch-wait-time");
180     ConstElementPtr databases = getDatabases(xpath + "/config-database");
181     if (databases && !databases->empty()) {
182         config_ctrl->set("config-databases", databases);
183     }
184     if (!config_ctrl->empty()) {
185         // If there's something to return, use it.
186         return (config_ctrl);
187     }
188 
189     // If not, return null.
190     return (ElementPtr());
191 }
192 
193 ElementPtr
getServerKeaDhcpCommon(const string & xpath)194 TranslatorConfig::getServerKeaDhcpCommon(const string& xpath) {
195     ElementPtr result = Element::createMap();
196 
197     getParam(result, xpath, "valid-lifetime");
198     getParam(result, xpath, "min-valid-lifetime");
199     getParam(result, xpath, "max-valid-lifetime");
200     getParam(result, xpath, "renew-timer");
201     getParam(result, xpath, "rebind-timer");
202     getParam(result, xpath, "calculate-tee-times");
203     getParam(result, xpath, "t1-percent");
204     getParam(result, xpath, "t2-percent");
205     getParam(result, xpath, "decline-probation-period");
206     getParam(result, xpath, "hostname-char-set");
207     getParam(result, xpath, "hostname-char-replacement");
208 
209     ConstElementPtr networks = getSharedNetworks(xpath);
210     if (networks && !networks->empty()) {
211         result->set("shared-networks", networks);
212     }
213     ConstElementPtr classes = getClasses(xpath);
214     if (classes && !classes->empty()) {
215         result->set("client-classes", classes);
216     }
217     ConstElementPtr database = getDatabase(xpath + "/lease-database");
218     if (database) {
219         result->set("lease-database", database);
220     }
221     ConstElementPtr databases = getDatabases(xpath + "/hosts-database");
222     if (databases && !databases->empty()) {
223         result->set("hosts-databases", databases);
224     }
225     ConstElementPtr host_ids =
226         getItems(xpath + "/host-reservation-identifiers");
227     if (host_ids) {
228         result->set("host-reservation-identifiers", host_ids);
229     }
230     ConstElementPtr defs = getOptionDefList(xpath);
231     if (defs && !defs->empty()) {
232         result->set("option-def", defs);
233     }
234     ConstElementPtr options = getOptionDataList(xpath);
235     if (options && !options->empty()) {
236         result->set("option-data", options);
237     }
238     ConstElementPtr hooks = getHooksKea(xpath);
239     if (hooks && !hooks->empty()) {
240         result->set("hooks-libraries", hooks);
241     }
242     ConstElementPtr expired =
243         getExpiredKea(xpath + "/expired-leases-processing");
244     if (expired) {
245         result->set("expired-leases-processing", expired);
246     }
247     getParam(result, xpath, "dhcp4o6-port");
248     ConstElementPtr socket = getControlSocket(xpath + "/control-socket");
249     if (socket) {
250         result->set("control-socket", socket);
251     }
252     ConstElementPtr ddns = getDdnsKea(xpath + "/dhcp-ddns");
253     if (ddns) {
254         result->set("dhcp-ddns", ddns);
255     }
256     ConstElementPtr context = getItem(xpath + "/user-context");
257     if (context) {
258         result->set("user-context", Element::fromJSON(context->stringValue()));
259     }
260     ConstElementPtr checks = getItem(xpath + "/sanity-checks/lease-checks");
261     if (checks) {
262         ElementPtr sanity = Element::createMap();
263         sanity->set("lease-checks", checks);
264         result->set("sanity-checks", sanity);
265     }
266     getParam(result, xpath, "reservation-mode");
267     ConstElementPtr hosts = getHosts(xpath);
268     if (hosts && !hosts->empty()) {
269         result->set("reservations", hosts);
270     }
271     ConstElementPtr config_ctrl =
272         getConfigControlKea(xpath + "/config-control");
273     if (config_ctrl) {
274         result->set("config-control", config_ctrl);
275     }
276     getParam(result, xpath, "server-tag");
277     ConstElementPtr queue_ctrl = getItem(xpath + "/dhcp-queue-control");
278     if (queue_ctrl) {
279         result->set("dhcp-queue-control",
280                     Element::fromJSON(queue_ctrl->stringValue()));
281     }
282     ConstElementPtr loggers = getLoggers(xpath);
283     if (loggers && !loggers->empty()) {
284         result->set("loggers", loggers);
285     }
286     return (result);
287 }
288 
289 ElementPtr
getServerKeaDhcp4()290 TranslatorConfig::getServerKeaDhcp4() {
291     string xpath = "/kea-dhcp4-server:config";
292     ElementPtr result = getServerKeaDhcpCommon(xpath);
293     // Handle subnets.
294     ConstElementPtr subnets = getSubnets(xpath);
295     if (subnets && !subnets->empty()) {
296         result->set("subnet4", subnets);
297     }
298     // Handle interfaces.
299     ElementPtr if_config = Element::createMap();
300     ConstElementPtr ifs = getItems(xpath + "/interfaces-config/interfaces");
301     if (ifs && !ifs->empty()) {
302         if_config->set("interfaces", ifs);
303     }
304     getParam(if_config, xpath + "/interfaces-config", "dhcp-socket-type");
305     getParam(if_config, xpath + "/interfaces-config", "outbound-interface");
306     getParam(if_config, xpath + "/interfaces-config", "re-detect");
307     ConstElementPtr context =
308         getItem(xpath + "/interfaces-config/user-context");
309     if (context) {
310         if_config->set("user-context",
311                        Element::fromJSON(context->stringValue()));
312     }
313     if (!if_config->empty()) {
314         result->set("interfaces-config", if_config);
315     }
316     // Handle DHCPv4 specific global parameters.
317     getParam(result, xpath, "echo-client-id");
318     getParam(result, xpath, "match-client-id");
319     getParam(result, xpath, "next-server");
320     getParam(result, xpath, "server-hostname");
321     getParam(result, xpath, "boot-file-name");
322     getParam(result, xpath, "authoritative");
323     return (result);
324 }
325 
326 ElementPtr
getServerKeaDhcp6()327 TranslatorConfig::getServerKeaDhcp6() {
328     string xpath = "/kea-dhcp6-server:config";
329     ElementPtr result = getServerKeaDhcpCommon(xpath);
330     // Handle DHCPv6 specific global parameters.
331     getParam(result, xpath, "data-directory");
332     getParam(result, xpath, "preferred-lifetime");
333     getParam(result, xpath, "min-preferred-lifetime");
334     getParam(result, xpath, "max-preferred-lifetime");
335     // Handle subnets.
336     ConstElementPtr subnets = getSubnets(xpath);
337     if (subnets && !subnets->empty()) {
338         result->set("subnet6", subnets);
339     }
340     // Handle interfaces.
341     ElementPtr if_config = Element::createMap();
342     ConstElementPtr ifs = getItems(xpath + "/interfaces-config/interfaces");
343     if (ifs && !ifs->empty()) {
344         if_config->set("interfaces", ifs);
345     }
346     getParam(if_config, xpath + "/interfaces-config", "re-detect");
347     ConstElementPtr context =
348         getItem(xpath + "/interfaces-config/user-context");
349     if (context) {
350         if_config->set("user-context",
351                        Element::fromJSON(context->stringValue()));
352     }
353     if (!if_config->empty()) {
354         result->set("interfaces-config", if_config);
355     }
356     // Handle DHCPv6 specific global entries.
357     ConstElementPtr relay = getItems(xpath + "/relay-supplied-options");
358     if (relay) {
359         result->set("relay-supplied-options", relay);
360     }
361     ConstElementPtr macs = getItems(xpath + "/mac-sources");
362     if (macs) {
363         result->set("mac-sources", macs);
364     }
365     // Handle server-id.
366     // @todo: move to a DUID translator.
367     ElementPtr server_id = Element::createMap();
368     getParam(server_id, xpath + "/server-id", "type");
369     getParam(server_id, xpath + "/server-id", "identifier");
370     getParam(server_id, xpath + "/server-id", "time");
371     getParam(server_id, xpath + "/server-id", "htype");
372     getParam(server_id, xpath + "/server-id", "enterprise-id");
373     getParam(server_id, xpath + "/server-id", "persist");
374     context = getItem(xpath + "/server-id/user-context");
375     if (context) {
376         server_id->set("user-context",
377                        Element::fromJSON(context->stringValue()));
378     }
379     if (!server_id->empty()) {
380         result->set("server-id", server_id);
381     }
382     return (result);
383 }
384 
385 void
setConfig(ConstElementPtr elem)386 TranslatorConfig::setConfig(ConstElementPtr elem) {
387     try {
388         if (model_ == IETF_DHCPV6_SERVER) {
389             if (elem) {
390                 AdaptorConfig::preProcess6(elem);
391                 setConfigIetf6(elem);
392             } else {
393                 delConfigIetf6();
394             }
395         } else if (model_ == KEA_DHCP4_SERVER) {
396             if (elem) {
397                 AdaptorConfig::preProcess4(elem);
398                 setConfigKea4(elem);
399             } else {
400                 delConfigKea();
401             }
402         } else if (model_ == KEA_DHCP6_SERVER) {
403             if (elem) {
404                 AdaptorConfig::preProcess6(elem);
405                 setConfigKea6(elem);
406             } else {
407                 delConfigKea();
408             }
409         } else {
410             isc_throw(NotImplemented,
411                       "setConfig not implemented for the model: " << model_);
412         }
413     } catch (const sysrepo_exception& ex) {
414         isc_throw(SysrepoError,
415                   "sysrepo error setting config '" << elem->str()
416                   << "': " << ex.what());
417     }
418 }
419 
420 void
delConfigIetf6()421 TranslatorConfig::delConfigIetf6() {
422     delItem("/" + model_ + ":server");
423 }
424 
425 void
setConfigIetf6(ConstElementPtr elem)426 TranslatorConfig::setConfigIetf6(ConstElementPtr elem) {
427     string xpath = "/" + model_ + ":server/server-config";
428     ConstElementPtr dhcp6 = elem->get("Dhcp6");
429     if (!dhcp6) {
430         isc_throw(BadValue, "no Dhcp6 entry in " << elem->str());
431     }
432     ConstElementPtr ranges = dhcp6->get("subnet6");
433     if (ranges && !ranges->empty()) {
434         setSubnets(xpath + "/network-ranges", ranges);
435     }
436     // Skip everything else.
437 }
438 
439 void
delConfigKea()440 TranslatorConfig::delConfigKea() {
441     delItem("/" + model_ + ":config");
442 }
443 
444 void
setConfigKea4(ConstElementPtr elem)445 TranslatorConfig::setConfigKea4(ConstElementPtr elem) {
446     ConstElementPtr dhcp = elem->get("Dhcp4");
447     if (dhcp) {
448         setServerKeaDhcp4(dhcp);
449     }
450 }
451 
452 void
setConfigKea6(ConstElementPtr elem)453 TranslatorConfig::setConfigKea6(ConstElementPtr elem) {
454     ConstElementPtr dhcp = elem->get("Dhcp6");
455     if (dhcp) {
456         setServerKeaDhcp6(dhcp);
457     }
458 }
459 
460 void
setServerKeaDhcpCommon(const string & xpath,ConstElementPtr elem)461 TranslatorConfig::setServerKeaDhcpCommon(const string& xpath,
462                                          ConstElementPtr elem) {
463     ConstElementPtr valid = elem->get("valid-lifetime");
464     if (valid) {
465         setItem(xpath + "/valid-lifetime", valid, SR_UINT32_T);
466     }
467     ConstElementPtr min_valid = elem->get("min-valid-lifetime");
468     if (min_valid) {
469         setItem(xpath + "/min-valid-lifetime", min_valid, SR_UINT32_T);
470     }
471     ConstElementPtr max_valid = elem->get("max-valid-lifetime");
472     if (max_valid) {
473         setItem(xpath + "/max-valid-lifetime", max_valid, SR_UINT32_T);
474     }
475     ConstElementPtr renew = elem->get("renew-timer");
476     if (renew) {
477         setItem(xpath + "/renew-timer", renew, SR_UINT32_T);
478     }
479     ConstElementPtr rebind = elem->get("rebind-timer");
480     if (rebind) {
481         setItem(xpath + "/rebind-timer", rebind, SR_UINT32_T);
482     }
483     ConstElementPtr calculate = elem->get("calculate-tee-times");
484     if (calculate) {
485         setItem(xpath + "/calculate-tee-times", calculate, SR_BOOL_T);
486     }
487     ConstElementPtr t1_percent =  elem->get("t1-percent");
488     if (t1_percent) {
489         setItem(xpath + "/t1-percent", t1_percent, SR_DECIMAL64_T);
490     }
491     ConstElementPtr t2_percent =  elem->get("t2-percent");
492     if (t2_percent) {
493         setItem(xpath + "/t2-percent", t2_percent, SR_DECIMAL64_T);
494     }
495     ConstElementPtr period = elem->get("decline-probation-period");
496     if (period) {
497         setItem(xpath + "/decline-probation-period", period, SR_UINT32_T);
498     }
499     ConstElementPtr networks = elem->get("shared-networks");
500     if (networks) {
501         setSharedNetworks(xpath, networks);
502     }
503     ConstElementPtr classes = elem->get("client-classes");
504     if (classes && !classes->empty()) {
505         setClasses(xpath, classes);
506     }
507     ConstElementPtr database = elem->get("lease-database");
508     if (database) {
509         setDatabase(xpath + "/lease-database", database);
510     }
511     ConstElementPtr databases = elem->get("hosts-databases");
512     if (databases && !databases->empty()) {
513         setDatabases(xpath + "/hosts-database", databases);
514     } else {
515         // Reuse of database from lease-database.
516         database = elem->get("hosts-database");
517         if (database) {
518             ElementPtr list = Element::createList();
519             list->add(copy(database));
520             setDatabases(xpath + "/hosts-database", list);
521         }
522     }
523     ConstElementPtr host_ids = elem->get("host-reservation-identifiers");
524     if (host_ids) {
525         for (ConstElementPtr id : host_ids->listValue()) {
526             setItem(xpath + "/host-reservation-identifiers", id, SR_ENUM_T);
527         }
528     }
529     ConstElementPtr defs = elem->get("option-def");
530     if (defs && !defs->empty()) {
531         setOptionDefList(xpath, defs);
532     }
533     ConstElementPtr options = elem->get("option-data");
534     if (options && !options->empty()) {
535         setOptionDataList(xpath, options);
536     }
537     ConstElementPtr hook_libs = elem->get("hooks-libraries");
538     if (hook_libs) {
539         for (ConstElementPtr lib : hook_libs->listValue()) {
540             ConstElementPtr name = lib->get("library");
541             if (!name) {
542                 continue;
543             }
544             ostringstream hook_lib;
545             hook_lib << xpath << "/hook-library[library='"
546                      << name->stringValue() << "']";
547             ConstElementPtr params = lib->get("parameters");
548             if (params) {
549                 hook_lib << "/parameters";
550                 setItem(hook_lib.str(), Element::create(params->str()),
551                         SR_STRING_T);
552             } else {
553                 ConstElementPtr list = Element::createList();
554                 setItem(hook_lib.str(), list, SR_LIST_T);
555             }
556         }
557     }
558     ConstElementPtr expired = elem->get("expired-leases-processing");
559     if (expired) {
560         ConstElementPtr reclaim = expired->get("reclaim-timer-wait-time");
561         if (reclaim) {
562             setItem(xpath + "/expired-leases-processing/reclaim-timer-wait-time",
563                     reclaim, SR_UINT32_T);
564         }
565         ConstElementPtr flush =
566             expired->get("flush-reclaimed-timer-wait-time");
567         if (flush) {
568             setItem(xpath + "/expired-leases-processing/flush-reclaimed-timer-wait-time",
569                     flush, SR_UINT32_T);
570         }
571         ConstElementPtr hold = expired->get("hold-reclaimed-time");
572         if (hold) {
573             setItem(xpath + "/expired-leases-processing/hold-reclaimed-time",
574                     hold, SR_UINT32_T);
575         }
576         ConstElementPtr max_leases = expired->get("max-reclaim-leases");
577         if (max_leases) {
578             setItem(xpath + "/expired-leases-processing/max-reclaim-leases",
579                     max_leases, SR_UINT32_T);
580         }
581         ConstElementPtr max_time = expired->get("max-reclaim-time");
582         if (max_time) {
583             setItem(xpath + "/expired-leases-processing/max-reclaim-time",
584                     max_time, SR_UINT32_T);
585         }
586         ConstElementPtr unwarned = expired->get("unwarned-reclaim-cycles");
587         if (unwarned) {
588             setItem(xpath + "/expired-leases-processing/unwarned-reclaim-cycles",
589                     unwarned, SR_UINT32_T);
590         }
591     }
592     ConstElementPtr port = elem->get("dhcp4o6-port");
593     if (port) {
594         setItem(xpath + "/dhcp4o6-port", port, SR_UINT16_T);
595     }
596     ConstElementPtr socket = elem->get("control-socket");
597     if (socket) {
598         setControlSocket(xpath + "/control-socket", socket);
599     }
600     ConstElementPtr char_set = elem->get("hostname-char-set");
601     if (char_set) {
602         setItem(xpath + "/hostname-char-set", char_set, SR_STRING_T);
603     }
604     ConstElementPtr char_repl = elem->get("hostname-char-replacement");
605     if (char_repl) {
606         setItem(xpath + "/hostname-char-replacement", char_repl, SR_STRING_T);
607     }
608     ConstElementPtr ddns = elem->get("dhcp-ddns");
609     if (ddns) {
610         ConstElementPtr enable = ddns->get("enable-updates");
611         if (enable) {
612             setItem(xpath + "/dhcp-ddns/enable-updates", enable, SR_BOOL_T);
613         }
614         ConstElementPtr suffix = ddns->get("qualifying-suffix");
615         if (suffix) {
616             setItem(xpath + "/dhcp-ddns/qualifying-suffix", suffix,
617                     SR_STRING_T);
618         }
619         ConstElementPtr server_ip = ddns->get("server-ip");
620         if (server_ip) {
621             setItem(xpath + "/dhcp-ddns/server-ip", server_ip, SR_STRING_T);
622         }
623         ConstElementPtr server_port = ddns->get("server-port");
624         if (server_port) {
625             setItem(xpath + "/dhcp-ddns/server-port", server_port,
626                     SR_UINT16_T);
627         }
628         ConstElementPtr sender_ip = ddns->get("sender-ip");
629         if (sender_ip) {
630             setItem(xpath + "/dhcp-ddns/sender-ip", sender_ip, SR_STRING_T);
631         }
632         ConstElementPtr sender_port = ddns->get("sender-port");
633         if (sender_port) {
634             setItem(xpath + "/dhcp-ddns/sender-port", sender_port,
635                     SR_UINT16_T);
636         }
637         ConstElementPtr queue = ddns->get("max-queue-size");
638         if (queue) {
639             setItem(xpath + "/dhcp-ddns/max-queue-size", queue, SR_UINT32_T);
640         }
641         ConstElementPtr protocol = ddns->get("ncr-protocol");
642         if (protocol) {
643             setItem(xpath + "/dhcp-ddns/ncr-protocol", protocol, SR_ENUM_T);
644         }
645         ConstElementPtr format = ddns->get("ncr-format");
646         if (format) {
647             setItem(xpath + "/dhcp-ddns/ncr-format", format, SR_ENUM_T);
648         }
649         ConstElementPtr no_up = ddns->get("override-no-update");
650         if (no_up) {
651             setItem(xpath + "/dhcp-ddns/override-no-update", no_up, SR_BOOL_T);
652         }
653         ConstElementPtr client = ddns->get("override-client-update");
654         if (client) {
655             setItem(xpath + "/dhcp-ddns/override-client-update", client,
656                     SR_BOOL_T);
657         }
658         ConstElementPtr replace = ddns->get("replace-client-name");
659         if (replace) {
660             setItem(xpath + "/dhcp-ddns/replace-client-name", replace,
661                     SR_ENUM_T);
662         }
663         ConstElementPtr generated = ddns->get("generated-prefix");
664         if (generated) {
665             setItem(xpath + "/dhcp-ddns/generated-prefix", generated,
666                     SR_STRING_T);
667         }
668         ConstElementPtr char_set = ddns->get("hostname-char-set");
669         if (char_set) {
670             setItem(xpath + "/dhcp-ddns/hostname-char-set", char_set,
671                     SR_STRING_T);
672         }
673         ConstElementPtr char_repl = ddns->get("hostname-char-replacement");
674         if (char_repl) {
675             setItem(xpath + "/dhcp-ddns/hostname-char-replacement", char_repl,
676                     SR_STRING_T);
677         }
678         ConstElementPtr context = Adaptor::getContext(ddns);
679         if (context) {
680             ConstElementPtr repr = Element::create(context->str());
681             setItem(xpath + "/dhcp-ddns/user-context", repr, SR_STRING_T);
682         }
683     }
684     ConstElementPtr context = Adaptor::getContext(elem);
685     if (context) {
686         ConstElementPtr repr = Element::create(context->str());
687         setItem(xpath + "/user-context", repr, SR_STRING_T);
688     }
689     ConstElementPtr sanity = elem->get("sanity-checks");
690     if (sanity) {
691         ConstElementPtr checks = sanity->get("lease-checks");
692         if (checks) {
693             setItem(xpath + "/sanity-checks/lease-checks", checks, SR_ENUM_T);
694         }
695     }
696     ConstElementPtr hr_mode = elem->get("reservation-mode");
697     if (hr_mode) {
698         setItem(xpath + "/reservation-mode", hr_mode, SR_ENUM_T);
699     }
700     ConstElementPtr hosts = elem->get("reservations");
701     if (hosts && !hosts->empty()) {
702         setHosts(xpath, hosts);
703     }
704     ConstElementPtr config_ctrl = elem->get("config-control");
705     if (config_ctrl && !config_ctrl->empty()) {
706         ConstElementPtr cfwt = config_ctrl->get("config-fetch-wait-time");
707         if (cfwt) {
708             setItem(xpath + "/config-control/config-fetch-wait-time", cfwt,
709                     SR_UINT32_T);
710         }
711         databases = config_ctrl->get("config-databases");
712         if (databases && !databases->empty()) {
713             setDatabases(xpath + "/config-control/config-database", databases);
714         }
715     }
716     ConstElementPtr server_tag = elem->get("server-tag");
717     if (server_tag) {
718         setItem(xpath + "/server-tag", server_tag, SR_STRING_T);
719     }
720     ConstElementPtr queue_ctrl = elem->get("dhcp-queue-control");
721     if (queue_ctrl) {
722         ConstElementPtr repr = Element::create(queue_ctrl->str());
723         setItem(xpath + "/dhcp-queue-control", repr, SR_STRING_T);
724     }
725     ConstElementPtr loggers = elem->get("loggers");
726     if (loggers) {
727         setLoggers(xpath, loggers);
728     }
729 }
730 
731 void
setServerKeaDhcp4(ConstElementPtr elem)732 TranslatorConfig::setServerKeaDhcp4(ConstElementPtr elem) {
733     string xpath = "/kea-dhcp4-server:config";
734     setServerKeaDhcpCommon(xpath, elem);
735     ConstElementPtr subnets = elem->get("subnet4");
736     if (subnets) {
737         setSubnets(xpath, subnets);
738     }
739     ConstElementPtr if_config = elem->get("interfaces-config");
740     if (if_config) {
741         ConstElementPtr ifs = if_config->get("interfaces");
742         if (ifs && !ifs->empty()) {
743             for (ConstElementPtr intf : ifs->listValue()) {
744                 setItem(xpath + "/interfaces-config/interfaces",
745                         intf, SR_STRING_T);
746             }
747         }
748         ConstElementPtr ds_type = if_config->get("dhcp-socket-type");
749         if (ds_type) {
750             setItem(xpath + "/interfaces-config/dhcp-socket-type",
751                     ds_type, SR_ENUM_T);
752         }
753         ConstElementPtr out_if = if_config->get("outbound-interface");
754         if (out_if) {
755             setItem(xpath + "/interfaces-config/outbound-interface",
756                     out_if, SR_ENUM_T);
757         }
758         ConstElementPtr redetect = if_config->get("re-detect");
759         if (redetect) {
760             setItem(xpath + "/interfaces-config/re-detect",
761                     redetect, SR_BOOL_T);
762         }
763         ConstElementPtr context = Adaptor::getContext(if_config);
764         if (context) {
765             setItem(xpath + "/interfaces-config/user-context",
766                     Element::create(context->str()), SR_STRING_T);
767         }
768     }
769     ConstElementPtr echo = elem->get("echo-client-id");
770     if (echo) {
771         setItem(xpath + "/echo-client-id", echo, SR_BOOL_T);
772     }
773     ConstElementPtr match = elem->get("match-client-id");
774     if (match) {
775         setItem(xpath + "/match-client-id", match, SR_BOOL_T);
776     }
777     ConstElementPtr next = elem->get("next-server");
778     if (next) {
779         setItem(xpath + "/next-server", next, SR_STRING_T);
780     }
781     ConstElementPtr hostname = elem->get("server-hostname");
782     if (hostname) {
783         setItem(xpath + "/server-hostname", hostname, SR_STRING_T);
784     }
785     ConstElementPtr boot = elem->get("boot-file-name");
786     if (boot) {
787         setItem(xpath + "/boot-file-name", boot, SR_STRING_T);
788     }
789     ConstElementPtr auth = elem->get("authoritative");
790     if (auth) {
791         setItem(xpath + "/authoritative", auth, SR_BOOL_T);
792     }
793     checkAndSetLeaf(elem, xpath, "store-extended-info", SR_BOOL_T);
794 }
795 
796 void
setServerKeaDhcp6(ConstElementPtr elem)797 TranslatorConfig::setServerKeaDhcp6(ConstElementPtr elem) {
798     string xpath = "/kea-dhcp6-server:config";
799     setServerKeaDhcpCommon(xpath, elem);
800     ConstElementPtr data_dir = elem->get("data-directory");
801     if (data_dir) {
802         setItem(xpath + "/data-directory", data_dir, SR_STRING_T);
803     }
804     ConstElementPtr preferred = elem->get("preferred-lifetime");
805     if (preferred) {
806         setItem(xpath + "/preferred-lifetime", preferred, SR_UINT32_T);
807     }
808     ConstElementPtr min_pref = elem->get("min-preferred-lifetime");
809     if (min_pref) {
810         setItem(xpath + "/min-preferred-lifetime", min_pref, SR_UINT32_T);
811     }
812     ConstElementPtr max_pref = elem->get("max-preferred-lifetime");
813     if (max_pref) {
814         setItem(xpath + "/max-preferred-lifetime", max_pref, SR_UINT32_T);
815     }
816     ConstElementPtr subnets = elem->get("subnet6");
817     if (subnets) {
818         setSubnets(xpath, subnets);
819     }
820     ConstElementPtr if_config = elem->get("interfaces-config");
821     if (if_config) {
822         ConstElementPtr ifs = if_config->get("interfaces");
823         if (ifs && !ifs->empty()) {
824             for (ConstElementPtr intf : ifs->listValue()) {
825                 setItem(xpath + "/interfaces-config/interfaces",
826                         intf, SR_STRING_T);
827             }
828         }
829         ConstElementPtr redetect = if_config->get("re-detect");
830         if (redetect) {
831             setItem(xpath + "/interfaces-config/re-detect",
832                     redetect, SR_BOOL_T);
833         }
834         ConstElementPtr context = Adaptor::getContext(if_config);
835         if (context) {
836             setItem(xpath + "/interfaces-config/user-context",
837                     Element::create(context->str()), SR_STRING_T);
838         }
839     }
840     ConstElementPtr relay = elem->get("relay-supplied-options");
841     if (relay) {
842         for (ConstElementPtr addr : relay->listValue()) {
843             setItem(xpath + "/relay-supplied-options", addr, SR_STRING_T);
844         }
845     }
846     ConstElementPtr macs = elem->get("mac-sources");
847     if (macs) {
848         for (ConstElementPtr source : macs->listValue()) {
849             setItem(xpath + "/mac-sources", source, SR_STRING_T);
850         }
851     }
852     ConstElementPtr server_id = elem->get("server-id");
853     if (server_id) {
854         ConstElementPtr id_type = server_id->get("type");
855         if (id_type) {
856             setItem(xpath + "/server-id/type", id_type, SR_ENUM_T);
857         }
858         ConstElementPtr id_id = server_id->get("identifier");
859         if (id_id) {
860             setItem(xpath + "/server-id/identifier", id_id, SR_STRING_T);
861         }
862         ConstElementPtr id_time = server_id->get("time");
863         if (id_time) {
864             setItem(xpath + "/server-id/time", id_time, SR_UINT32_T);
865         }
866         ConstElementPtr id_htype = server_id->get("htype");
867         if (id_htype) {
868             setItem(xpath + "/server-id/htype", id_htype, SR_UINT16_T);
869         }
870         ConstElementPtr id_ent_id = server_id->get("enterprise-id");
871         if (id_ent_id) {
872             setItem(xpath + "/server-id/enterprise-id", id_ent_id,
873                     SR_UINT32_T);
874         }
875         ConstElementPtr id_persist = server_id->get("persist");
876         if (id_persist) {
877             setItem(xpath + "/server-id/persist", id_persist, SR_BOOL_T);
878         }
879         ConstElementPtr context = Adaptor::getContext(server_id);
880         if (context) {
881             ConstElementPtr repr = Element::create(context->str());
882             setItem(xpath + "/server-id/user-context", repr, SR_STRING_T);
883         }
884     }
885     checkAndSetLeaf(elem, xpath, "store-extended-info", SR_BOOL_T);
886 }
887 
888 }  // namespace yang
889 }  // namespace isc
890