Kea 2.5.8
netconf.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
9
10#include <config.h>
11
13#include <netconf/netconf.h>
15#include <netconf/netconf_log.h>
17#include <yang/yang_revisions.h>
18
19#include <sstream>
20#include <vector>
21
22using namespace std;
23using namespace isc::config;
24using namespace isc::data;
25using namespace isc::netconf;
26using namespace isc::yang;
27using namespace libyang;
28using namespace sysrepo;
29
30namespace {
31
33class NetconfAgentCallback {
34public:
38 NetconfAgentCallback(const CfgServersMapPair& service_pair)
39 : service_pair_(service_pair) {
40 }
41
43 CfgServersMapPair const service_pair_;
44
55 sysrepo::ErrorCode module_change(Session sess,
56 uint32_t /* subscription_id */,
57 string_view module_name,
58 optional<string_view> /* sub_xpath */,
59 Event event,
60 uint32_t /* request_id */) {
61 ostringstream event_type;
62 switch (event) {
63 case Event::Update:
64 // This could potentially be a hook point for mid-flight
65 // configuration changes.
66 event_type << "Event::Update";
67 break;
68 case Event::Change:
69 event_type << "Event::Change";
70 break;
71 case Event::Done:
72 event_type << "Event::Done";
73 break;
74 case Event::Abort:
75 event_type << "Event::Abort";
76 break;
77 case Event::Enabled:
78 event_type << "Event::Enabled";
79 break;
80 case Event::RPC:
81 event_type << "Event::RPC";
82 break;
83 default:
84 event_type << "UNKNOWN (" << event << ")";
85 break;
86 }
88 .arg(event_type.str());
89 NetconfAgent::logChanges(sess, module_name);
90 switch (event) {
91 case Event::Change:
92 return (NetconfAgent::change(sess, service_pair_));
93 case Event::Done:
94 return (NetconfAgent::done(sess, service_pair_));
95 default:
96 return (sysrepo::ErrorCode::Ok);
97 }
98 }
99
100 void event_notif(Session /* session */,
101 uint32_t /* subscription_id */,
102 NotificationType const notification_type,
103 optional<DataNode> const notification_tree,
104 NotificationTimeStamp const /* timestamp */) {
105 string n;
106 switch (notification_type) {
107 case NotificationType::Realtime:
108 n = "NotificationType::Realtime";
109 break;
110 case NotificationType::Replay:
111 n = "NotificationType::Replay";
112 break;
113 case NotificationType::ReplayComplete:
114 n = "NotificationType::ReplayComplete";
115 break;
116 case NotificationType::Terminated:
117 n = "NotificationType::Terminated";
118 break;
119 case NotificationType::Modified:
120 n = "NotificationType::Modified";
121 break;
122 case NotificationType::Suspended:
123 n = "NotificationType::Suspended";
124 break;
125 case NotificationType::Resumed:
126 n = "NotificationType::Resumed";
127 break;
128 }
129
130 optional<string> const str(
131 notification_tree->printStr(DataFormat::JSON, PrintFlags::WithDefaultsExplicit));
132 string const tree(str ? *str : string());
134 .arg(n)
135 .arg(service_pair_.first)
136 .arg(tree);
137 }
138}; // NetconfAgentCallback
139
140} //anonymous namespace
141
142namespace isc {
143namespace netconf {
144
146 clear();
147}
148
149void
151 // Check for a configuration manager.
152 if (!cfg_mgr) {
153 isc_throw(Unexpected, "missing configuration manager");
154 return;
155 }
156
157 // Retrieve configuration from existing running DHCP daemons.
158 const CfgServersMapPtr& servers =
159 cfg_mgr->getNetconfConfig()->getCfgServersMap();
160 for (auto const& pair : *servers) {
161 keaConfig(pair);
162 }
163
164 // Initialize sysrepo.
165 initSysrepo();
166
167 // Check modules / revisions.
168 checkModules(servers);
169
170 for (auto const& pair : *servers) {
171 yangConfig(pair);
174 }
175}
176
177void
179 subscriptions_.clear();
180 running_sess_.reset();
181 startup_sess_.reset();
182}
183
184void
186 string const& server(service_pair.first);
187 CfgServerPtr const& configuration(service_pair.second);
188
189 // If the boot-update flag is not set.
190 if (!configuration->getBootUpdate()) {
191 return;
192 }
193 CfgControlSocketPtr ctrl_sock = configuration->getCfgControlSocket();
194 if (!ctrl_sock) {
195 return;
196 }
198 try {
199 comm = controlSocketFactory(ctrl_sock);
200 } catch (exception const& ex) {
201 ostringstream msg;
202 msg << "createControlSocket failed with " << ex.what();
204 .arg(server)
205 .arg(msg.str());
206 return;
207 }
208 ConstElementPtr answer;
209 int rcode;
210 ConstElementPtr config;
212 .arg(server);
213 try {
214 answer = comm->configGet(server);
215 config = parseAnswer(rcode, answer);
216 } catch (exception const& ex) {
217 ostringstream msg;
218 msg << "config-get command failed with " << ex.what();
220 .arg(server)
221 .arg(msg.str());
222 return;
223 }
224 if (rcode != CONTROL_RESULT_SUCCESS) {
225 ostringstream msg;
226 msg << "config-get command returned " << answerToText(answer);
228 .arg(server)
229 .arg(msg.str());
230 return;
231 }
232 if (!config) {
234 .arg(server)
235 .arg("config-get command returned an empty configuration");
236 return;
237 }
240 .arg(server)
241 .arg(prettyPrint(config));
242}
243
244void
246 try {
247 running_sess_ = Connection{}.sessionStart();
248 running_sess_->switchDatastore(Datastore::Running);
249 startup_sess_ = Connection{}.sessionStart();
250 startup_sess_->switchDatastore(Datastore::Startup);
251 } catch (exception const& ex) {
252 isc_throw(Unexpected, "Can't establish a sysrepo session: "
253 << ex.what());
254 }
255
256 // Retrieve names and revisions of installed modules from sysrepo.
257 getModules();
258}
259
261 vector<Module> modules;
262 try {
263 Context context(running_sess_->getContext());
264 modules = context.modules();
265 } catch (Error const& ex) {
266 isc_throw(Unexpected, "can't retrieve available modules: " << ex.what());
267 }
268
269 for (Module const& module : modules) {
270 string const name(module.name());
271 if (!module.revision()) {
273 "could not retrieve module revision for module " << name);
274 }
275 string const revision(*module.revision());
276 modules_.emplace(name, revision);
277 }
278}
279
280bool
281NetconfAgent::checkModule(const string& module_name) const {
282 auto module = modules_.find(module_name);
283 if (module == modules_.end()) {
285 .arg(module_name);
286 return (false);
287 }
288 auto modrev = YANG_REVISIONS.find(module_name);
289 if (modrev == YANG_REVISIONS.end()) {
290 // Can't check revision?!
291 // It can happen only with a module which is not in
292 // YANG_REVISIONS but installed so likely on purpose.
293 return (true);
294 }
295 if (modrev->second != module->second) {
297 .arg(module_name)
298 .arg(modrev->second)
299 .arg(module->second);
300 return (false);
301 }
302 return (true);
303}
304
305void
306NetconfAgent::checkModules(CfgServersMapPtr const& servers /* = {} */) const {
307 bool faulty_model(false);
308 if (servers) {
309 for (auto const& pair : *servers) {
310 if (!checkModule(pair.second->getModel())) {
311 faulty_model = true;
312 }
313 }
314 }
315
316 if (faulty_model) {
317 isc_throw(Unexpected, "YANG module is missing or its revision is not "
318 "supported. Check logs for details.");
319 }
320
321 for (auto const& modrev : YANG_REVISIONS) {
322 auto module = modules_.find(modrev.first);
323 if (module == modules_.end()) {
325 .arg(modrev.first);
326 continue;
327 }
328 if (modrev.second != module->second) {
330 .arg(modrev.first)
331 .arg(modrev.second)
332 .arg(module->second);
333 }
334 }
335}
336
337void
339 string const& server(service_pair.first);
340 CfgServerPtr const& configuration(service_pair.second);
341
342 // If we're shutting down, or the boot-update flag is not set or the model
343 // associated with it is not specified.
344 if (!configuration->getBootUpdate() ||
345 configuration->getModel().empty()) {
346 return;
347 }
348
349 // First we need a way to reach the actual servers.
350 CfgControlSocketPtr ctrl_sock = configuration->getCfgControlSocket();
351 if (!ctrl_sock) {
352 return;
353 }
354
356 .arg(server);
357 ElementPtr config;
358 try {
359 // Retrieve configuration from Sysrepo.
360 TranslatorConfig tc(*startup_sess_, configuration->getModel());
361 config = tc.getConfig();
362 if (!config) {
363 ostringstream msg;
364 msg << "YANG configuration for "
365 << configuration->getModel()
366 << " is empty";
368 .arg(server)
369 .arg(msg.str());
370 return;
371 } else {
374 .arg(server)
375 .arg(prettyPrint(config));
376 }
377 } catch (exception const& ex) {
378 ostringstream msg;
379 msg << "get YANG configuration for " << server
380 << " failed with " << ex.what();
382 .arg(server)
383 .arg(msg.str());
384 return;
385 }
387 try {
388 comm = controlSocketFactory(ctrl_sock);
389 } catch (exception const& ex) {
390 ostringstream msg;
391 msg << "control socket creation failed with " << ex.what();
393 .arg(server)
394 .arg(msg.str());
395 return;
396 }
397 ConstElementPtr answer;
398 int rcode;
399 try {
400 answer = comm->configSet(config, server);
401 parseAnswer(rcode, answer);
402 } catch (exception const& ex) {
403 ostringstream msg;
404 msg << "config-set command failed with " << ex.what();
406 .arg(server)
407 .arg(msg.str());
408 return;
409 }
410 if (rcode != CONTROL_RESULT_SUCCESS) {
411 ostringstream msg;
412 msg << "config-set command returned " << answerToText(answer);
414 .arg(server)
415 .arg(msg.str());
416 return;
417 }
419 .arg(server);
420}
421
422void
424 string const& server(service_pair.first);
425 CfgServerPtr const& configuration(service_pair.second);
426 string const& model(configuration->getModel());
427
428 // If we're shutting down, or the subscribe-changes flag is not set or
429 // the model is not specified, give up on subscribing.
430 if (!configuration->getSubscribeChanges() || model.empty()) {
431 return;
432 }
434 .arg(server)
435 .arg(model);
436 auto callback = [=](Session session,
437 uint32_t subscription_id,
438 string_view module_name,
439 optional<string_view> sub_xpath,
440 Event event,
441 uint32_t request_id) {
442 NetconfAgentCallback agent(service_pair);
443 return agent.module_change(session, subscription_id, module_name, sub_xpath, event, request_id);
444 };
445 try {
446 SubscribeOptions options(SubscribeOptions::Default);
447 if (!configuration->getValidateChanges()) {
448 options = options | SubscribeOptions::DoneOnly;
449 }
450 Subscription subscription(
451 running_sess_->onModuleChange(model, callback, nullopt, 0, options));
452 subscriptions_.emplace(server, std::forward<Subscription>(subscription));
453 } catch (exception const& ex) {
454 ostringstream msg;
455 msg << "module change subscribe failed with " << ex.what();
456 msg << "change subscription for model " << model <<
457 " failed with: " << ex.what();
459 .arg(server)
460 .arg(configuration->getModel())
461 .arg(msg.str());
462 return;
463 }
464}
465
466void
468 string const& server(service_pair.first);
469 CfgServerPtr const& configuration(service_pair.second);
470 string const& model(configuration->getModel());
471
472 // If we're shutting down, or the subscribe-changes flag is not set or
473 // the model is not specified, give up on subscribing.
474 if (!configuration->getSubscribeNotifications() || model.empty()) {
475 return;
476 }
478 .arg(server)
479 .arg(model);
480
481 auto callback = [=](Session session,
482 uint32_t subscription_id,
483 NotificationType const notification_type,
484 optional<DataNode> const notification_tree,
485 NotificationTimeStamp const timestamp) {
486 NetconfAgentCallback agent(service_pair);
487 return agent.event_notif(session, subscription_id, notification_type, notification_tree, timestamp);
488 };
489 try {
490 Subscription subscription(running_sess_->onNotification(model, callback));
491 subscriptions_.emplace(server, std::forward<Subscription>(subscription));
492 } catch (exception const& ex) {
493 ostringstream msg;
494 msg << "event notification subscription for model " << model <<
495 " failed with: " << ex.what();
497 .arg(server)
498 .arg(configuration->getModel())
499 .arg(msg.str());
500 return;
501 }
502}
503
504sysrepo::ErrorCode
505NetconfAgent::change(Session sess, const CfgServersMapPair& service_pair) {
506 string const& server(service_pair.first);
507 CfgServerPtr const& configuration(service_pair.second);
508
509 // If we're shutting down, or the subscribe-changes or the
510 // validate-changes flag is not set or the model associated with
511 // it is not specified.
512 if (!configuration->getSubscribeChanges() ||
513 !configuration->getValidateChanges() ||
514 configuration->getModel().empty()) {
515 return (sysrepo::ErrorCode::Ok);
516 }
517 CfgControlSocketPtr ctrl_sock = configuration->getCfgControlSocket();
518 if (!ctrl_sock) {
519 return (sysrepo::ErrorCode::Ok);
520 }
522 .arg(server);
523 ElementPtr config;
524 try {
525 TranslatorConfig tc(sess, configuration->getModel());
526 config = tc.getConfig();
527 if (!config) {
528 ostringstream msg;
529 msg << "YANG configuration for "
530 << configuration->getModel()
531 << " is empty";
533 .arg(server)
534 .arg(msg.str());
535 return (sysrepo::ErrorCode::OperationFailed);
536 } else {
539 .arg(server)
540 .arg(prettyPrint(config));
541 }
542 } catch (exception const& ex) {
543 ostringstream msg;
544 msg << "get YANG configuration for " << server
545 << " failed with " << ex.what();
547 .arg(server)
548 .arg(msg.str());
549 return (sysrepo::ErrorCode::ValidationFailed);
550 }
552 try {
553 comm = controlSocketFactory(ctrl_sock);
554 } catch (exception const& ex) {
555 ostringstream msg;
556 msg << "createControlSocket failed with " << ex.what();
558 .arg(server)
559 .arg(msg.str());
560 return (sysrepo::ErrorCode::Ok);
561 }
562 ConstElementPtr answer;
563 int rcode;
564 try {
565 answer = comm->configTest(config, server);
566 parseAnswer(rcode, answer);
567 } catch (exception const& ex) {
568 stringstream msg;
569 msg << "configTest failed with " << ex.what();
571 .arg(server)
572 .arg(msg.str());
573 return (sysrepo::ErrorCode::ValidationFailed);
574 }
575 if (rcode != CONTROL_RESULT_SUCCESS) {
576 stringstream msg;
577 msg << "configTest returned " << answerToText(answer);
579 .arg(server)
580 .arg(msg.str());
581 return (sysrepo::ErrorCode::ValidationFailed);
582 }
584 .arg(server);
585 return (sysrepo::ErrorCode::Ok);
586}
587
588sysrepo::ErrorCode
589NetconfAgent::done(Session sess, const CfgServersMapPair& service_pair) {
590 string const& server(service_pair.first);
591 CfgServerPtr const& configuration(service_pair.second);
592
593 // Check if we should and can process this update.
594 if (!configuration->getSubscribeChanges() ||
595 configuration->getModel().empty()) {
596 return (sysrepo::ErrorCode::Ok);
597 }
598 CfgControlSocketPtr ctrl_sock = configuration->getCfgControlSocket();
599 if (!ctrl_sock) {
600 return (sysrepo::ErrorCode::Ok);
601 }
602
603 // All looks good, let's get started. Print an info that we're about
604 // to update the configuration.
606 .arg(server);
607
608 // Retrieve the configuration from SYSREPO first.
609 ElementPtr config;
610 try {
611 TranslatorConfig tc(sess, configuration->getModel());
612 config = tc.getConfig();
613 if (!config) {
614 ostringstream msg;
615 msg << "YANG configuration for "
616 << configuration->getModel()
617 << " is empty";
619 .arg(server)
620 .arg(msg.str());
621 return (sysrepo::ErrorCode::ValidationFailed);
622 } else {
625 .arg(server)
626 .arg(prettyPrint(config));
627 }
628 } catch (exception const& ex) {
629 ostringstream msg;
630 msg << "get YANG configuration for " << server
631 << " failed with " << ex.what();
633 .arg(server)
634 .arg(msg.str());
635 return (sysrepo::ErrorCode::ValidationFailed);
636 }
637
638 // Ok, now open the control socket. We need this to send the config to
639 // the server.
641 try {
642 comm = controlSocketFactory(ctrl_sock);
643 } catch (exception const& ex) {
644 ostringstream msg;
645 msg << "createControlSocket failed with " << ex.what();
647 .arg(server)
648 .arg(msg.str());
649 return (sysrepo::ErrorCode::Ok);
650 }
651
652 // Now apply the config using config-set command.
653 ConstElementPtr answer;
654 int rcode;
655 try {
656 answer = comm->configSet(config, server);
657 parseAnswer(rcode, answer);
658 } catch (exception const& ex) {
659 stringstream msg;
660 msg << "configSet failed with " << ex.what();
662 .arg(server)
663 .arg(msg.str());
664 return (sysrepo::ErrorCode::ValidationFailed);
665 }
666
667 // rcode == CONTROL_RESULT_SUCCESS, unless the docs say otherwise :).
668 if (rcode != CONTROL_RESULT_SUCCESS) {
669 stringstream msg;
670 msg << "configSet returned " << answerToText(answer);
672 .arg(server)
673 .arg(msg.str());
674 return (sysrepo::ErrorCode::ValidationFailed);
675 }
677 .arg(server);
678 return (sysrepo::ErrorCode::Ok);
679}
680
681void
682NetconfAgent::logChanges(Session sess, string_view const& model) {
683 ostringstream stream;
684 stream << "/" << model << ":*//.";
685 string const xpath(stream.str());
686 ChangeCollection const changes(sess.getChanges(xpath));
687 for (Change const& change : changes) {
688 ostringstream msg;
689 switch (change.operation) {
690 case sysrepo::ChangeOperation::Created:
691 msg << "created: ";
692 break;
693 case sysrepo::ChangeOperation::Deleted:
694 msg << "deleted: ";
695 break;
696 case sysrepo::ChangeOperation::Modified:
697 msg << "modified: ";
698 break;
699 case sysrepo::ChangeOperation::Moved:
700 msg << "moved: ";
701 break;
702 default:
703 msg << "unknown operation (" << change.operation << "): ";
704 }
705 string const path(change.node.path());
706 msg << path;
707 SchemaNode const& schema(change.node.schema());
708 NodeType const node_type(schema.nodeType());
709 if (node_type == NodeType::Container) {
710 msg << " (container)";
711 } else if (node_type == NodeType::List) {
712 msg << " (list)";
713 } else {
714 optional<string> const str(
716 LeafBaseType::Unknown));
717 if (str) {
718 msg << " = " << *str;
719 }
720 }
721
724 .arg(msg.str());
725 }
726}
727
728void
731 if (controller) {
732 boost::dynamic_pointer_cast<NetconfController>(controller)
733 ->getNetconfProcess()
734 ->setShutdownFlag(true);
735 }
736}
737
739 return boost::dynamic_pointer_cast<NetconfController>(NetconfController::instance())
740 ->getNetconfProcess()
741 ->shouldShutdown();
742}
743
744} // namespace netconf
745} // namespace isc
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown when an unexpected error condition occurs.
void subscribeToDataChanges(const CfgServersMapPair &service_pair)
Subscribe changes for a module in YANG datastore.
Definition: netconf.cc:423
std::optional< sysrepo::Session > running_sess_
Sysrepo running datastore session.
Definition: netconf.h:168
void getModules()
Retrieve names and revisions of installed modules through the sysrepo API.
Definition: netconf.cc:260
static void logChanges(sysrepo::Session sess, std::string_view const &model)
Log changes.
Definition: netconf.cc:682
void yangConfig(const CfgServersMapPair &service_pair)
Retrieve Kea server configuration from the YANG startup datastore and applies it to servers.
Definition: netconf.cc:338
virtual ~NetconfAgent()
Destructor (call clear).
Definition: netconf.cc:145
void initSysrepo()
Initialize sysrepo sessions.
Definition: netconf.cc:245
void keaConfig(const CfgServersMapPair &service_pair)
Get and display Kea server configuration.
Definition: netconf.cc:185
void announceShutdown() const
Set the shutdown flag of the process to true so that it can exit at the earliest convenient time.
Definition: netconf.cc:729
void checkModules(CfgServersMapPtr const &servers={}) const
Check module availability.
Definition: netconf.cc:306
std::map< const std::string, sysrepo::Subscription > subscriptions_
Subscription map.
Definition: netconf.h:174
bool shouldShutdown() const
Check the shutdown flag of the process.
Definition: netconf.cc:738
static sysrepo::ErrorCode change(sysrepo::Session sess, const CfgServersMapPair &service_pair)
Event::Change callback.
Definition: netconf.cc:505
std::optional< sysrepo::Session > startup_sess_
Sysrepo startup datastore session.
Definition: netconf.h:165
static sysrepo::ErrorCode done(sysrepo::Session sess, const CfgServersMapPair &service_pair)
Event::Done callback.
Definition: netconf.cc:589
void init(NetconfCfgMgrPtr cfg_mgr)
Initialization.
Definition: netconf.cc:150
void subscribeToNotifications(const CfgServersMapPair &service_pair)
Subscribe to notifications for a given YANG module.
Definition: netconf.cc:467
bool checkModule(const std::string &module_name) const
Check essential module availability.
Definition: netconf.cc:281
std::map< const std::string, const std::string > modules_
Available modules and revisions in Sysrepo.
Definition: netconf.h:171
static process::DControllerBasePtr & instance()
Static singleton instance method.
DHCP configuration translation between YANG and JSON.
isc::data::ElementPtr getConfig()
Translate the whole DHCP server configuration from YANG to JSON.
static isc::data::ElementPtr translateFromYang(std::optional< libyang::DataNode > data_node)
Translate basic value from the given YANG data node to JSON element.
Definition: translator.cc:270
static std::optional< std::string > translateToYang(isc::data::ConstElementPtr const &elem, libyang::LeafBaseType const type)
Translate basic value from JSON to YANG.
Definition: translator.cc:288
This file contains several functions and constants that are used for handling commands and responses ...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition: macros.h:32
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition: macros.h:20
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
ConstElementPtr parseAnswer(int &rcode, const ConstElementPtr &msg)
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
std::string answerToText(const ConstElementPtr &msg)
void prettyPrint(ConstElementPtr element, std::ostream &out, unsigned indent, unsigned step)
Pretty prints the data into stream.
Definition: data.cc:1547
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:29
boost::shared_ptr< Element > ElementPtr
Definition: data.h:28
const isc::log::MessageID NETCONF_VALIDATE_CONFIG_FAILED
const int NETCONF_DBG_TRACE_DETAIL_DATA
Additional information.
Definition: netconf_log.h:41
const isc::log::MessageID NETCONF_GET_CONFIG_STARTED
const isc::log::MessageID NETCONF_VALIDATE_CONFIG_REJECTED
const isc::log::MessageID NETCONF_VALIDATE_CONFIG_COMPLETED
const isc::log::MessageID NETCONF_CONFIG_CHANGE_EVENT
isc::log::Logger netconf_logger(NETCONF_LOGGER_NAME)
Base logger for the netconf agent.
Definition: netconf_log.h:49
const isc::log::MessageID NETCONF_VALIDATE_CONFIG
const isc::log::MessageID NETCONF_GET_CONFIG_FAILED
const isc::log::MessageID NETCONF_MODULE_REVISION_WARN
const isc::log::MessageID NETCONF_GET_CONFIG
std::shared_ptr< CfgServersMap > CfgServersMapPtr
Defines a pointer to map of CfgServers.
const isc::log::MessageID NETCONF_CONFIG_CHANGED_DETAIL
std::pair< std::string, CfgServerPtr > CfgServersMapPair
Defines a iterator pairing of name and CfgServer.
const isc::log::MessageID NETCONF_SET_CONFIG_FAILED
std::shared_ptr< CfgServer > CfgServerPtr
Defines a pointer for CfgServer instances.
const isc::log::MessageID NETCONF_VALIDATE_CONFIG_STARTED
const isc::log::MessageID NETCONF_SUBSCRIBE_CONFIG
const isc::log::MessageID NETCONF_MODULE_MISSING_ERR
std::shared_ptr< CfgControlSocket > CfgControlSocketPtr
Defines a pointer for CfgControlSocket instances.
const isc::log::MessageID NETCONF_NOTIFICATION_RECEIVED
const isc::log::MessageID NETCONF_UPDATE_CONFIG_COMPLETED
const isc::log::MessageID NETCONF_MODULE_REVISION_ERR
const isc::log::MessageID NETCONF_SUBSCRIBE_NOTIFICATIONS
const isc::log::MessageID NETCONF_SET_CONFIG_STARTED
const isc::log::MessageID NETCONF_SUBSCRIBE_CONFIG_FAILED
const isc::log::MessageID NETCONF_UPDATE_CONFIG_FAILED
const isc::log::MessageID NETCONF_BOOT_UPDATE_COMPLETED
const isc::log::MessageID NETCONF_SET_CONFIG
const isc::log::MessageID NETCONF_UPDATE_CONFIG
const isc::log::MessageID NETCONF_UPDATE_CONFIG_STARTED
ControlSocketBasePtr controlSocketFactory(CfgControlSocketPtr ctrl_sock)
Factory function for control sockets.
std::shared_ptr< ControlSocketBase > ControlSocketBasePtr
Type definition for the pointer to the ControlSocketBase.
const isc::log::MessageID NETCONF_MODULE_MISSING_WARN
const isc::log::MessageID NETCONF_NOT_SUBSCRIBED_TO_NOTIFICATIONS
boost::shared_ptr< NetconfCfgMgr > NetconfCfgMgrPtr
Defines a shared pointer to NetconfCfgMgr.
boost::shared_ptr< DControllerBase > DControllerBasePtr
Definition: d_controller.h:78
Defines the logger used by the top-level component of kea-lfc.
Contains declarations for loggers used by the Kea netconf agent.