Kea  1.9.9-git
netconf_config.cc
Go to the documentation of this file.
1 // Copyright (C) 2018 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 
9 #include <netconf/netconf_log.h>
11 #include <exceptions/exceptions.h>
12 #include <asiolink/io_error.h>
13 
14 #include <boost/foreach.hpp>
15 #include <boost/scoped_ptr.hpp>
16 #include <boost/algorithm/string/predicate.hpp>
17 
18 #include <sstream>
19 #include <string>
20 
21 using namespace std;
22 using namespace isc::process;
23 using namespace isc::data;
24 using namespace isc::http;
25 
26 namespace isc {
27 namespace netconf {
28 
29 // *********************** CfgControlSocket *************************
30 
31 CfgControlSocket::CfgControlSocket(Type type, const string& name,
32  const Url& url)
33  : type_(type), name_(name), url_(url) {
34 }
35 
37 }
38 
40 CfgControlSocket::stringToType(const string& type) {
41  if (type == "unix") {
42  return (CfgControlSocket::Type::UNIX);
43  } else if (type == "http") {
44  return (CfgControlSocket::Type::HTTP);
45  } else if (type == "stdout") {
46  return (CfgControlSocket::Type::STDOUT);
47  }
48 
49  isc_throw(BadValue, "Unknown control socket type: " << type);
50 }
51 
52 const string
54  switch (type) {
55  case CfgControlSocket::Type::UNIX:
56  return ("unix");
57  case CfgControlSocket::Type::HTTP:
58  return ("http");
59  case CfgControlSocket::Type::STDOUT:
60  return ("stdout");
61  default:
62  isc_throw(BadValue, "Unknown control socket type: " << type);
63  }
64 }
65 
68  ElementPtr result = Element::createMap();
69  // Set user-context
70  contextToElement(result);
71  // Set type
72  result->set("socket-type", Element::create(typeToString(type_)));
73  // Set name
74  result->set("socket-name", Element::create(name_));
75  // Set url
76  result->set("socket-url", Element::create(url_.toText()));
77  return (result);
78 }
79 
80 // *********************** CfgServer *************************
81 CfgServer::CfgServer(const string& model, CfgControlSocketPtr ctrl_sock)
82  : model_(model), boot_update_(true), subscribe_changes_(true),
83  validate_changes_(true), control_socket_(ctrl_sock) {
84 }
85 
87 }
88 
89 string
91  ostringstream s;
92  s << "model: " << model_ << ", control socker: ";
93  if (!control_socket_) {
94  s << "none";
95  } else {
96  switch (control_socket_->getType()) {
97  case CfgControlSocket::Type::UNIX:
98  s << "UNIX:'" << control_socket_->getName() << "'";
99  break;
100  case CfgControlSocket::Type::HTTP:
101  s << "HTTP:'" << control_socket_->getUrl().toText() << "'";
102  break;
103  case CfgControlSocket::Type::STDOUT:
104  s << "STDOUT";
105  break;
106  }
107  }
108  return (s.str());
109 }
110 
113  ElementPtr result = Element::createMap();
114  // Set user-context
115  contextToElement(result);
116  // Set model
117  result->set("model", Element::create(model_));
118  // Set boot-update
119  result->set("boot-update", Element::create(boot_update_));
120  // Set subscribe-changes
121  result->set("subscribe-changes", Element::create(subscribe_changes_));
122  // Set validate-changes
123  result->set("validate-changes", Element::create(validate_changes_));
124  // Set control-socket
125  if (control_socket_) {
126  result->set("control-socket", control_socket_->toElement());
127  }
128  return (result);
129 }
130 
131 ostream&
132 operator<<(ostream& os, const CfgServer& server) {
133  os << server.toText();
134  return (os);
135 }
136 
137 // *************************** PARSERS ***********************************
138 
139 // *********************** ControlSocketConfigParser *************************
140 
143  CfgControlSocketPtr result;
144  string type_str = getString(ctrl_sock_config, "socket-type");
145  string name = getString(ctrl_sock_config, "socket-name");
146  string url_str = getString(ctrl_sock_config, "socket-url");
147  ConstElementPtr user_context = ctrl_sock_config->get("user-context");
148 
149  // Type must be valid.
151  try {
152  type = CfgControlSocket::stringToType(type_str);
153  } catch (const std::exception& ex) {
154  isc_throw(ConfigError, ex.what() << " '" << type_str << "' ("
155  << getPosition("socket-type", ctrl_sock_config) << ")");
156  }
157 
158  // Url must be valid.
159  Url url(url_str);
160  if (!url.isValid()) {
161  isc_throw(ConfigError, "invalid control socket url: "
162  << url.getErrorMessage() << " '" << url_str << "' ("
163  << getPosition("socket-url", ctrl_sock_config) << ")");
164  }
165 
166  // Create the control socket.
167  try {
168  result.reset(new CfgControlSocket(type, name, url));
169  } catch (const std::exception& ex) {
170  isc_throw(ConfigError, ex.what() << " ("
171  << ctrl_sock_config->getPosition() << ")");
172  }
173 
174  // Add user-context.
175  if (user_context) {
176  result->setContext(user_context);
177  }
178 
179  return (result);
180 }
181 
182 // *********************** ServerConfigParser *************************
183 
186  CfgServerPtr result;
187  string model = getString(server_config, "model");
188  ConstElementPtr user_context = server_config->get("user-context");
189  ConstElementPtr ctrl_sock_config = server_config->get("control-socket");
190  CfgControlSocketPtr ctrl_sock;
191  if (ctrl_sock_config) {
193  ctrl_sock = parser.parse(ctrl_sock_config);
194  }
195  try {
196  result.reset(new CfgServer(model, ctrl_sock));
197  } catch (const std::exception& ex) {
198  isc_throw(ConfigError, ex.what() << " ("
199  << server_config->getPosition() << ")");
200  }
201 
202  // Add flags.
203  result->setBootUpdate(getBoolean(server_config, "boot-update"));
204  result->setSubscribeChanges(getBoolean(server_config, "subscribe-changes"));
205  result->setValidateChanges(getBoolean(server_config, "validate-changes"));
206 
207  // Add user-context.
208  if (user_context) {
209  result->setContext(user_context);
210  }
211 
212  return (result);
213 }
214 
215 }; // end of isc::netconf namespace
216 }; // end of isc namespace
static bool getBoolean(isc::data::ConstElementPtr scope, const std::string &name)
Returns a boolean parameter from a scope.
CfgServer(const std::string &model, CfgControlSocketPtr ctrl_sock)
Constructor.
static const std::string typeToString(CfgControlSocket::Type type)
Converts CfgControlSocket::Type to string.
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
Parser for CfgControlSocket.
std::string toText() const
Returns a text representation for the server.
boost::shared_ptr< Element > ElementPtr
Definition: data.h:20
STL namespace.
boost::shared_ptr< CfgServer > CfgServerPtr
Defines a pointer for CfgServer instances.
static Type stringToType(const std::string &type)
Converts socket type name to CfgControlSocket::Type.
std::string toText() const
Returns textual representation of the URL.
Definition: url.cc:65
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
Definition: user_context.cc:15
bool isValid() const
Checks if the URL is valid.
Definition: url.h:47
CfgControlSocketPtr parse(data::ConstElementPtr ctrl_sock_config)
Performs the actual parsing of the given "control-socket" element.
An exception that is thrown if an error occurs while configuring any server.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Represents an URL.
Definition: url.h:20
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:23
std::string getErrorMessage() const
Returns parsing error message.
Definition: url.h:52
Type
Defines the list of possible constrol socket types.
static std::string getString(isc::data::ConstElementPtr scope, const std::string &name)
Returns a string parameter from a scope.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
static const data::Element::Position & getPosition(const std::string &name, const data::ConstElementPtr parent)
Utility method that returns position of an element.
Defines the logger used by the top-level component of kea-dhcp-ddns.
virtual ~CfgServer()
Destructor (doing nothing).
const Name & name_
Definition: dns/message.cc:693
Represents a Control Socket.
virtual ~CfgControlSocket()
Destructor (doing nothing).
Contains declarations for loggers used by the Kea netconf agent.
Represents a Managed CfgServer.
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
ostream & operator<<(ostream &os, const CfgServer &server)
Dumps the contents of a CfgServer as text to a output stream.
boost::shared_ptr< CfgControlSocket > CfgControlSocketPtr
Defines a pointer for CfgControlSocket instances.
CfgServerPtr parse(data::ConstElementPtr server_config)
Performs the actual parsing of the given value from the "managed-servers" map.