Kea  2.3.7
d_cfg_mgr.cc
Go to the documentation of this file.
1 // Copyright (C) 2013-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 
10 #include <dhcp/libdhcp++.h>
11 #include <process/d_log.h>
12 #include <process/d_cfg_mgr.h>
13 #include <process/daemon.h>
14 #include <process/redact_config.h>
15 #include <util/encode/hex.h>
16 #include <util/strutil.h>
17 
18 #include <boost/foreach.hpp>
19 #include <boost/lexical_cast.hpp>
20 #include <boost/algorithm/string.hpp>
21 
22 #include <limits>
23 #include <iostream>
24 #include <vector>
25 #include <map>
26 
27 using namespace std;
28 using namespace isc;
29 using namespace isc::config;
30 using namespace isc::dhcp;
31 using namespace isc::data;
32 using namespace isc::asiolink;
33 
34 namespace isc {
35 namespace process {
36 
37 // *********************** DCfgMgrBase *************************
38 
39 DCfgMgrBase::DCfgMgrBase(ConfigPtr context) {
40  setContext(context);
41 }
42 
43 DCfgMgrBase::~DCfgMgrBase() {
44 }
45 
46 void
47 DCfgMgrBase::resetContext() {
48  ConfigPtr context = createNewContext();
49  setContext(context);
50 }
51 
52 void
53 DCfgMgrBase::setContext(ConfigPtr& context) {
54  if (!context) {
55  isc_throw(DCfgMgrBaseError, "DCfgMgrBase: context cannot be NULL");
56  }
57 
58  context_ = context;
59 }
60 
63  ConstElementPtr result(config);
64  for (std::list<std::string>& json_path : jsonPathsToRedact()) {
65  result = isc::process::redactConfig(result, json_path);
66  }
67  return result;
68 }
69 
70 list<list<string>> DCfgMgrBase::jsonPathsToRedact() const {
71  static list<list<string>> const list;
72  return list;
73 }
74 
76 DCfgMgrBase::simpleParseConfig(isc::data::ConstElementPtr config_set,
77  bool check_only,
78  const std::function<void()>& post_config_cb) {
79  if (!config_set) {
81  std::string("Can't parse NULL config")));
82  }
84  .arg(redactConfig(config_set)->str());
85 
86  // The parsers implement data inheritance by directly accessing
87  // configuration context. For this reason the data parsers must store
88  // the parsed data into context immediately. This may cause data
89  // inconsistency if the parsing operation fails after the context has been
90  // modified. We need to preserve the original context here
91  // so as we can rollback changes when an error occurs.
92  ConfigPtr original_context = context_;
93  resetContext();
94  bool rollback = false;
95 
96  // Answer will hold the result returned to the caller.
97  ConstElementPtr answer;
98 
99  try {
100  // Logging is common so factor it.
101  Daemon::configureLogger(config_set, context_);
102 
103  // Let's call the actual implementation
104  answer = parse(config_set, check_only);
105 
106  // and check the response returned.
107  int code = 0;
108  isc::config::parseAnswer(code, answer);
109 
110  // Everything was fine. Configuration set processed successfully.
111  if (!check_only) {
112  if (code == 0) {
113  // Call the callback only when parsing was successful.
114  if (post_config_cb) {
115  post_config_cb();
116  }
117  LOG_INFO(dctl_logger, DCTL_CONFIG_COMPLETE).arg(getConfigSummary(0));
118  // Set the last commit timestamp.
119  auto now = boost::posix_time::second_clock::universal_time();
120  context_->setLastCommitTime(now);
121  } else {
122  rollback = true;
123  }
124 
125  // Use the answer provided.
126  //answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS, "Configuration committed.");
127  } else {
129  .arg(getConfigSummary(0))
130  .arg(config::answerToText(answer));
131  }
132 
133  } catch (const std::exception& ex) {
134  LOG_ERROR(dctl_logger, DCTL_PARSER_FAIL).arg(ex.what());
135  answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, ex.what());
136  rollback = true;
137  }
138 
139  if (check_only) {
140  // If this is a configuration check only, then don't actually apply
141  // the configuration and reverse to the previous one.
142  context_ = original_context;
143  }
144 
145  if (rollback) {
146  // An error occurred, so make sure that we restore original context.
147  context_ = original_context;
148  }
149 
150  return (answer);
151 }
152 
153 
154 void
155 DCfgMgrBase::setCfgDefaults(isc::data::ElementPtr) {
156 }
157 
159 DCfgMgrBase::parse(isc::data::ConstElementPtr, bool) {
160  isc_throw(DCfgMgrBaseError, "This class does not implement simple parser paradigm yet");
161 }
162 
163 } // end of isc::dhcp namespace
164 } // end of isc namespace
Exception thrown if the configuration manager encounters an error.
Definition: d_cfg_mgr.h:29
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_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
ConstElementPtr createAnswer(const int status_code, const std::string &text, const ConstElementPtr &arg)
ConstElementPtr parseAnswer(int &rcode, const ConstElementPtr &msg)
std::string answerToText(const ConstElementPtr &msg)
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
const int DBGLVL_COMMAND
This debug level is reserved for logging the exchange of messages/commands between processes,...
Definition: log_dbglevels.h:54
isc::log::Logger dctl_logger("dctl")
Defines the logger used within libkea-process library.
Definition: d_log.h:18
const isc::log::MessageID DCTL_CONFIG_START
const isc::log::MessageID DCTL_CONFIG_CHECK_COMPLETE
boost::shared_ptr< ConfigBase > ConfigPtr
Non-const pointer to the ConfigBase.
Definition: config_base.h:176
const isc::log::MessageID DCTL_PARSER_FAIL
const isc::log::MessageID DCTL_CONFIG_COMPLETE
ConstElementPtr redactConfig(ConstElementPtr const &element, list< string > const &json_path)
Redact a configuration.
Defines the logger used by the top-level component of kea-lfc.