Kea 2.6.2
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
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 }
209 int rcode;
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);
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 }
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);
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 }
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.
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.
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
it forwards queries to a single upstream resolver and passes the answers back to the client It is constructed with the address of the forward server Queries are initiated with the question to ask the forward server
Definition asiodns.dox:60
it forwards queries to a single upstream resolver and passes the answers back to the client It is constructed with the address of the forward server Queries are initiated with the question to ask the forward a buffer into which to write the answer
Definition asiodns.dox:60
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.
bool getValidateChanges() const
Getter which returns the validate-changes flag.
bool getBootUpdate() const
Getter which returns the boot-update flag.
bool getSubscribeNotifications() const
Getter which returns the subscribe-changes flag.
bool getSubscribeChanges() const
Getter which returns the subscribe-changes flag.
const CfgControlSocketPtr & getCfgControlSocket() const
Getter which returns the control socket.
const std::string getModel() const
Getter which returns the model name.
virtual data::ConstElementPtr configTest(data::ElementPtr config, const std::string &service)=0
Test configuration.
virtual data::ConstElementPtr configSet(data::ElementPtr config, const std::string &service)=0
Set configuration.
virtual data::ConstElementPtr configGet(const std::string &service)=0
Get configuration.
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.
static std::optional< std::string > translateToYang(isc::data::ConstElementPtr const &elem, libyang::LeafBaseType const type)
Translate basic value from JSON to YANG.
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
std::string answerToText(const ConstElementPtr &msg)
Converts answer to printable text.
ConstElementPtr parseAnswer(int &rcode, const ConstElementPtr &msg)
Parses a standard config/command level answer and returns arguments or text status code.
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
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
std::pair< std::string, CfgServerPtr > CfgServersMapPair
Defines a iterator pairing of name and CfgServer.
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< ControlSocketBase > ControlSocketBasePtr
Type definition for the pointer to the ControlSocketBase.
const isc::log::MessageID NETCONF_CONFIG_CHANGED_DETAIL
const isc::log::MessageID NETCONF_SET_CONFIG_FAILED
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< CfgServer > CfgServerPtr
Defines a pointer for CfgServer instances.
boost::shared_ptr< NetconfCfgMgr > NetconfCfgMgrPtr
Defines a shared pointer to NetconfCfgMgr.
const isc::log::MessageID NETCONF_NOTIFICATION_RECEIVED
const isc::log::MessageID NETCONF_UPDATE_CONFIG_COMPLETED
std::shared_ptr< CfgControlSocket > CfgControlSocketPtr
Defines a pointer for CfgControlSocket instances.
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< CfgServersMap > CfgServersMapPtr
Defines a pointer to map of CfgServers.
const isc::log::MessageID NETCONF_MODULE_MISSING_WARN
const isc::log::MessageID NETCONF_NOT_SUBSCRIBED_TO_NOTIFICATIONS
boost::shared_ptr< DControllerBase > DControllerBasePtr
Defines the logger used by the top-level component of kea-lfc.
Contains declarations for loggers used by the Kea netconf agent.