summaryrefslogtreecommitdiffstats
path: root/src/lib/process/d_cfg_mgr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/process/d_cfg_mgr.cc')
-rw-r--r--src/lib/process/d_cfg_mgr.cc164
1 files changed, 164 insertions, 0 deletions
diff --git a/src/lib/process/d_cfg_mgr.cc b/src/lib/process/d_cfg_mgr.cc
new file mode 100644
index 0000000..a08a903
--- /dev/null
+++ b/src/lib/process/d_cfg_mgr.cc
@@ -0,0 +1,164 @@
+// Copyright (C) 2013-2023 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+
+#include <cc/command_interpreter.h>
+#include <dhcp/libdhcp++.h>
+#include <process/d_log.h>
+#include <process/d_cfg_mgr.h>
+#include <process/daemon.h>
+#include <process/redact_config.h>
+#include <util/encode/hex.h>
+#include <util/strutil.h>
+
+#include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+
+#include <limits>
+#include <iostream>
+#include <vector>
+#include <map>
+
+using namespace std;
+using namespace isc;
+using namespace isc::config;
+using namespace isc::dhcp;
+using namespace isc::data;
+using namespace isc::asiolink;
+
+namespace isc {
+namespace process {
+
+// *********************** DCfgMgrBase *************************
+
+DCfgMgrBase::DCfgMgrBase(ConfigPtr context) {
+ setContext(context);
+}
+
+DCfgMgrBase::~DCfgMgrBase() {
+}
+
+void
+DCfgMgrBase::resetContext() {
+ ConfigPtr context = createNewContext();
+ setContext(context);
+}
+
+void
+DCfgMgrBase::setContext(ConfigPtr& context) {
+ if (!context) {
+ isc_throw(DCfgMgrBaseError, "DCfgMgrBase: context cannot be NULL");
+ }
+
+ context_ = context;
+}
+
+ConstElementPtr
+DCfgMgrBase::redactConfig(ConstElementPtr const& config) const {
+ ConstElementPtr result(config);
+ for (std::list<std::string>& json_path : jsonPathsToRedact()) {
+ result = isc::process::redactConfig(result, json_path);
+ }
+ return result;
+}
+
+list<list<string>> DCfgMgrBase::jsonPathsToRedact() const {
+ static list<list<string>> const list;
+ return list;
+}
+
+isc::data::ConstElementPtr
+DCfgMgrBase::simpleParseConfig(isc::data::ConstElementPtr config_set,
+ bool check_only,
+ const std::function<void()>& post_config_cb) {
+ if (!config_set) {
+ return (isc::config::createAnswer(CONTROL_RESULT_ERROR,
+ std::string("Can't parse NULL config")));
+ }
+ LOG_DEBUG(dctl_logger, isc::log::DBGLVL_COMMAND, DCTL_CONFIG_START)
+ .arg(redactConfig(config_set)->str());
+
+ // The parsers implement data inheritance by directly accessing
+ // configuration context. For this reason the data parsers must store
+ // the parsed data into context immediately. This may cause data
+ // inconsistency if the parsing operation fails after the context has been
+ // modified. We need to preserve the original context here
+ // so as we can rollback changes when an error occurs.
+ ConfigPtr original_context = context_;
+ resetContext();
+ bool rollback = false;
+
+ // Answer will hold the result returned to the caller.
+ ConstElementPtr answer;
+
+ try {
+ // Logging is common so factor it.
+ Daemon::configureLogger(config_set, context_);
+
+ // Let's call the actual implementation
+ answer = parse(config_set, check_only);
+
+ // and check the response returned.
+ int code = 0;
+ isc::config::parseAnswer(code, answer);
+
+ // Everything was fine. Configuration set processed successfully.
+ if (!check_only) {
+ if (code == 0) {
+ // Call the callback only when parsing was successful.
+ if (post_config_cb) {
+ post_config_cb();
+ }
+ LOG_INFO(dctl_logger, DCTL_CONFIG_COMPLETE).arg(getConfigSummary(0));
+ // Set the last commit timestamp.
+ auto now = boost::posix_time::second_clock::universal_time();
+ context_->setLastCommitTime(now);
+ } else {
+ rollback = true;
+ }
+
+ // Use the answer provided.
+ //answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS, "Configuration committed.");
+ } else {
+ LOG_INFO(dctl_logger, DCTL_CONFIG_CHECK_COMPLETE)
+ .arg(getConfigSummary(0))
+ .arg(config::answerToText(answer));
+ }
+
+ } catch (const std::exception& ex) {
+ LOG_ERROR(dctl_logger, DCTL_PARSER_FAIL).arg(ex.what());
+ answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, ex.what());
+ rollback = true;
+ }
+
+ if (check_only) {
+ // If this is a configuration check only, then don't actually apply
+ // the configuration and reverse to the previous one.
+ context_ = original_context;
+ }
+
+ if (rollback) {
+ // An error occurred, so make sure that we restore original context.
+ context_ = original_context;
+ }
+
+ return (answer);
+}
+
+
+void
+DCfgMgrBase::setCfgDefaults(isc::data::ElementPtr) {
+}
+
+isc::data::ConstElementPtr
+DCfgMgrBase::parse(isc::data::ConstElementPtr, bool) {
+ isc_throw(DCfgMgrBaseError, "This class does not implement simple parser paradigm yet");
+}
+
+} // end of isc::dhcp namespace
+} // end of isc namespace