diff options
Diffstat (limited to 'src/bin/netconf/netconf_config.cc')
-rw-r--r-- | src/bin/netconf/netconf_config.cc | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/src/bin/netconf/netconf_config.cc b/src/bin/netconf/netconf_config.cc new file mode 100644 index 0000000..f5a0531 --- /dev/null +++ b/src/bin/netconf/netconf_config.cc @@ -0,0 +1,211 @@ +// Copyright (C) 2018-2021 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 <netconf/netconf_log.h> +#include <netconf/netconf_cfg_mgr.h> +#include <exceptions/exceptions.h> +#include <asiolink/io_error.h> + +#include <boost/foreach.hpp> +#include <boost/scoped_ptr.hpp> +#include <boost/algorithm/string/predicate.hpp> + +#include <sstream> +#include <string> + +using namespace std; +using namespace isc::process; +using namespace isc::data; +using namespace isc::http; + +namespace isc { +namespace netconf { + +// *********************** CfgControlSocket ************************* + +CfgControlSocket::CfgControlSocket(Type type, const string& name, + const Url& url) + : type_(type), name_(name), url_(url) { +} + +CfgControlSocket::Type +CfgControlSocket::stringToType(const string& type) { + if (type == "unix") { + return (CfgControlSocket::Type::UNIX); + } else if (type == "http") { + return (CfgControlSocket::Type::HTTP); + } else if (type == "stdout") { + return (CfgControlSocket::Type::STDOUT); + } + + isc_throw(BadValue, "Unknown control socket type: " << type); +} + +const string +CfgControlSocket::typeToString(CfgControlSocket::Type type) { + switch (type) { + case CfgControlSocket::Type::UNIX: + return ("unix"); + case CfgControlSocket::Type::HTTP: + return ("http"); + case CfgControlSocket::Type::STDOUT: + return ("stdout"); + default: + isc_throw(BadValue, "Unknown control socket type: " << type); + } +} + +ElementPtr +CfgControlSocket::toElement() const { + ElementPtr result = Element::createMap(); + // Set user-context + contextToElement(result); + // Set type + result->set("socket-type", Element::create(typeToString(type_))); + // Set name + result->set("socket-name", Element::create(name_)); + // Set url + result->set("socket-url", Element::create(url_.toText())); + return (result); +} + +// *********************** CfgServer ************************* +CfgServer::CfgServer(const string& model, CfgControlSocketPtr ctrl_sock) + : model_(model), boot_update_(true), subscribe_changes_(true), + subscribe_notifications_(true), validate_changes_(true), + control_socket_(ctrl_sock) { +} + +string +CfgServer::toText() const { + ostringstream s; + s << "model: " << model_ << ", control socker: "; + if (!control_socket_) { + s << "none"; + } else { + switch (control_socket_->getType()) { + case CfgControlSocket::Type::UNIX: + s << "UNIX:'" << control_socket_->getName() << "'"; + break; + case CfgControlSocket::Type::HTTP: + s << "HTTP:'" << control_socket_->getUrl().toText() << "'"; + break; + case CfgControlSocket::Type::STDOUT: + s << "STDOUT"; + break; + } + } + return (s.str()); +} + +ElementPtr +CfgServer::toElement() const { + ElementPtr result = Element::createMap(); + // Set user-context + contextToElement(result); + // Set model + result->set("model", Element::create(model_)); + // Set boot-update + result->set("boot-update", Element::create(boot_update_)); + // Set subscribe-changes + result->set("subscribe-changes", Element::create(subscribe_changes_)); + // Set validate-changes + result->set("validate-changes", Element::create(validate_changes_)); + // Set control-socket + if (control_socket_) { + result->set("control-socket", control_socket_->toElement()); + } + return (result); +} + +ostream& +operator<<(ostream& os, const CfgServer& server) { + os << server.toText(); + return (os); +} + +// *************************** PARSERS *********************************** + +// *********************** ControlSocketConfigParser ************************* + +CfgControlSocketPtr +ControlSocketConfigParser::parse(ConstElementPtr ctrl_sock_config) { + CfgControlSocketPtr result; + string type_str = getString(ctrl_sock_config, "socket-type"); + string name = getString(ctrl_sock_config, "socket-name"); + string url_str = getString(ctrl_sock_config, "socket-url"); + ConstElementPtr user_context = ctrl_sock_config->get("user-context"); + + // Type must be valid. + CfgControlSocket::Type type; + try { + type = CfgControlSocket::stringToType(type_str); + } catch (const std::exception& ex) { + isc_throw(ConfigError, ex.what() << " '" << type_str << "' (" + << getPosition("socket-type", ctrl_sock_config) << ")"); + } + + // Url must be valid. + Url url(url_str); + if (!url.isValid()) { + isc_throw(ConfigError, "invalid control socket url: " + << url.getErrorMessage() << " '" << url_str << "' (" + << getPosition("socket-url", ctrl_sock_config) << ")"); + } + + // Create the control socket. + try { + result.reset(new CfgControlSocket(type, name, url)); + } catch (const std::exception& ex) { + isc_throw(ConfigError, ex.what() << " (" + << ctrl_sock_config->getPosition() << ")"); + } + + // Add user-context. + if (user_context) { + result->setContext(user_context); + } + + return (result); +} + +// *********************** ServerConfigParser ************************* + +CfgServerPtr +ServerConfigParser::parse(ConstElementPtr server_config) { + CfgServerPtr result; + string model = getString(server_config, "model"); + ConstElementPtr user_context = server_config->get("user-context"); + ConstElementPtr ctrl_sock_config = server_config->get("control-socket"); + CfgControlSocketPtr ctrl_sock; + if (ctrl_sock_config) { + ControlSocketConfigParser parser; + ctrl_sock = parser.parse(ctrl_sock_config); + } + try { + result.reset(new CfgServer(model, ctrl_sock)); + } catch (const std::exception& ex) { + isc_throw(ConfigError, ex.what() << " (" + << server_config->getPosition() << ")"); + } + + // Add flags. + result->setBootUpdate(getBoolean(server_config, "boot-update")); + result->setSubscribeChanges(getBoolean(server_config, "subscribe-changes")); + result->setValidateChanges(getBoolean(server_config, "validate-changes")); + + // Add user-context. + if (user_context) { + result->setContext(user_context); + } + + return (result); +} + +} // namespace netconf +} // namespace isc |