OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
dns_config_parser.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include "dns_config_parser.h"
6 
7 #include <sstream>
8 #include <boost/algorithm/string/trim.hpp>
9 #include <boost/asio/ip/address.hpp>
10 #include <boost/uuid/name_generator.hpp>
11 #include <boost/uuid/nil_generator.hpp>
12 #include <boost/uuid/uuid.hpp>
13 #include <boost/uuid/uuid_io.hpp>
14 #include <pugixml/pugixml.hpp>
15 #include "base/logging.h"
16 #include "bind/bind_util.h"
17 #include "cfg/dns_config.h"
19 
20 using namespace std;
21 using namespace pugi;
22 
23 namespace {
24 
25 static void MapObjectLink(const string &ltype, const string &lname,
26  const string &rtype, const string &rname,
27  const string &linkname,
30  DBRequest *request = new DBRequest;
31  request->oper = oper;
33  request->key.reset(key);
34  key->id_type = ltype;
35  key->id_name = lname;
37  request->data.reset(data);
38  data->metadata = linkname;
39  data->id_type = rtype;
40  data->id_name = rname;
42  requests->push_back(request);
43 }
44 
45 static void MapObjectLinkAttr(const string &ltype, const string &lname,
46  const string &rtype, const string &rname,
47  const string &linkname, AutogenProperty *attr,
50  DBRequest *request = new DBRequest;
51  request->oper = oper;
53  request->key.reset(key);
54  key->id_type = ltype;
55  key->id_name = lname;
57  request->data.reset(data);
58  data->metadata = linkname;
59  data->id_type = rtype;
60  data->id_name = rname;
61  data->content.reset(attr);
63  requests->push_back(request);
64 }
65 
66 static void SetData(const string &identifier, const string &id_type,
67  const string &metadata, AutogenProperty *params,
68  DnsConfigParser::RequestList *requests) {
69  DBRequest *request = new DBRequest;
72  request->key.reset(key);
73  key->id_type = id_type;
74  key->id_name = identifier;
76  request->data.reset(data);
77  data->metadata = metadata;
78  data->content.reset(params);
80  requests->push_back(request);
81 }
82 
83 static void ClearData(const string &identifier, const string &id_type,
84  const string &metadata,
85  DnsConfigParser::RequestList *requests) {
86  DBRequest *request = new DBRequest;
89  request->key.reset(key);
90  key->id_type = id_type;
91  key->id_name = identifier;
93  request->data.reset(data);
94  data->metadata = metadata;
96  requests->push_back(request);
97 }
98 
99 static bool ParseVnNetworkIpam(const xml_node &node, bool add_change,
100  DnsConfigParser::RequestList *requests) {
101  xml_attribute name_attr = node.attribute("name");
102  xml_attribute ipam_attr = node.attribute("ipam");
103  xml_attribute vn_attr = node.attribute("vn");
104  string name;
105  string ipam;
106  string vn;
107 
108  if (name_attr)
109  name = name_attr.value();
110  if (ipam_attr)
111  ipam = ipam_attr.value();
112  if (vn_attr)
113  vn = vn_attr.value();
114 
115  unique_ptr<autogen::VnSubnetsType> params(new autogen::VnSubnetsType());
116  if (!params->XmlParse(node)) {
117  assert(0);
118  }
119 
120  if (add_change) {
121  MapObjectLinkAttr("virtual-network", vn, "network-ipam", ipam,
122  "virtual-network-network-ipam", params.release(), requests,
124  } else {
125  MapObjectLinkAttr("virtual-network", vn, "network-ipam", ipam,
126  "virtual-network-network-ipam", params.release(), requests,
128  }
129 
130  return true;
131 }
132 
133 static bool ParseNetworkIpam(const xml_node &node, bool add_change,
134  DnsConfigParser::RequestList *requests) {
135  xml_attribute name = node.attribute("name");
136  string identifier;
137  if (name)
138  identifier = name.value();
139 
140  unique_ptr<autogen::IpamType> params(new autogen::IpamType());
141  if (!params->XmlParse(node)) {
142  assert(0);
143  }
144 
145  if (add_change) {
146  SetData(identifier, "network-ipam", "network-ipam-mgmt",
147  params.release(), requests);
148  } else {
149  ClearData(identifier, "network-ipam", "network-ipam-mgmt", requests);
150  }
151 
152  return true;
153 }
154 
155 static bool ParseVirtualDNS(const xml_node &node, bool add_change,
156  DnsConfigParser::RequestList *requests) {
157  xml_attribute name = node.attribute("name");
158  xml_attribute domain = node.attribute("domain");
159  string identifier;
160  string view;
161 
162  if (name)
163  identifier = name.value();
164  if (domain)
165  view = domain.value();
166 
167  unique_ptr<autogen::VirtualDnsType> params(new autogen::VirtualDnsType());
168  if (!params->XmlParse(node)) {
169  assert(0);
170  }
171 
172  if (add_change) {
173  SetData(identifier, "virtual-DNS", "virtual-DNS-data",
174  params.release(), requests);
175  MapObjectLink("domain", view, "virtual-DNS", identifier,
176  "domain-virtual-DNS", requests,
178  } else {
179  ClearData(identifier, "virtual-DNS", "virtual-DNS-data", requests);
180  MapObjectLink("domain", view, "virtual-DNS", identifier,
181  "domain-virtual-DNS", requests,
183  }
184 
185  return true;
186 }
187 
188 static bool ParseVirtualDNSRecord(const xml_node &node, bool add_change,
189  DnsConfigParser::RequestList *requests) {
190  xml_attribute name = node.attribute("name");
191  xml_attribute dns = node.attribute("dns");
192  string identifier;
193  string virtual_dns;
194 
195  if (name)
196  identifier = name.value();
197  if (dns)
198  virtual_dns = dns.value();
199 
200  unique_ptr<autogen::VirtualDnsRecordType> params(new autogen::VirtualDnsRecordType());
201  if (!params->XmlParse(node)) {
202  assert(0);
203  }
204 
205  if (add_change) {
206  SetData(identifier, "virtual-DNS-record", "virtual-DNS-record-data",
207  params.release(), requests);
208  MapObjectLink("virtual-DNS", virtual_dns,
209  "virtual-DNS-record", identifier,
210  "virtual-DNS-virtual-DNS-record", requests,
212  } else {
213  ClearData(identifier, "virtual-DNS-record",
214  "virtual-DNS-record-data", requests);
215  MapObjectLink("virtual-DNS", virtual_dns,
216  "virtual-DNS-record", identifier,
217  "virtual-DNS-virtual-DNS-record", requests,
219  }
220 
221  return true;
222 }
223 
224 static bool ParseGlobalQosConfig(const xml_node &node, bool add_change,
225  DnsConfigParser::RequestList *requests) {
226  xml_attribute name = node.attribute("name");
227  string identifier;
228  if (name)
229  identifier = name.value();
230 
231  for (xml_node child = node.first_child(); child;
232  child = child.next_sibling()) {
233  if (strcmp(child.name(), "control-traffic-dscp") == 0) {
234  unique_ptr<autogen::ControlTrafficDscpType> cfg(
235  new autogen::ControlTrafficDscpType());
236  assert(cfg->XmlParse(child));
237 
238  if (add_change) {
239  SetData(identifier, "global-qos-config",
240  "control-traffic-dscp", cfg.release(), requests);
241  } else {
242  ClearData(identifier, "global-qos-config",
243  "control-traffic-dscp", requests);
244  }
245  }
246  }
247  return true;
248 }
249 
250 } // namespace
251 
253 }
254 
255 bool DnsConfigParser::ParseConfig(const xml_node &root, bool add_change,
256  RequestList *requests) const {
257 
258  for (xml_node node = root.first_child(); node; node = node.next_sibling()) {
259  if (strcmp(node.name(), "network-ipam") == 0) {
260  ParseNetworkIpam(node, add_change, requests);
261  }
262  else if (strcmp(node.name(), "virtual-network-network-ipam") == 0) {
263  ParseVnNetworkIpam(node, add_change, requests);
264  }
265  else if (strcmp(node.name(), "virtual-DNS") == 0) {
266  ParseVirtualDNS(node, add_change, requests);
267  }
268  else if (strcmp(node.name(), "virtual-DNS-record") == 0) {
269  ParseVirtualDNSRecord(node, add_change, requests);
270  }
271  else if (strcmp(node.name(), "global-qos-config") == 0) {
272  ParseGlobalQosConfig(node, add_change, requests);
273  }
274  }
275 
276  return true;
277 }
278 
279 bool DnsConfigParser::Parse(const std::string &content) {
280  istringstream sstream(content);
281  xml_document xdoc;
282  xml_parse_result result = xdoc.load(sstream);
283  if (!result) {
284  std::stringstream str;
285  str << "Unable to load XML document. (status="
286  << result.status << ", offset=" << result.offset << ")";
287  DNS_TRACE(DnsError, str.str());
288  return false;
289  }
290 
291  RequestList requests;
292  for (xml_node node = xdoc.first_child(); node; node = node.next_sibling()) {
293  bool add_change;
294  if (strcmp(node.name(), "config") == 0) {
295  add_change = true;
296  } else if (strcmp(node.name(), "delete") == 0) {
297  add_change = false;
298  } else {
299  continue;
300  }
301  if (!ParseConfig(node, add_change, &requests)) {
302  STLDeleteValues(&requests);
303  return false;
304  }
305  }
306 
307  while (!requests.empty()) {
308  unique_ptr<DBRequest> req(requests.front());
309  requests.pop_front();
310 
312  static_cast<IFMapTable::RequestKey *>(req->key.get());
313 
315  if (table == NULL) {
316  continue;
317  }
318  table->Enqueue(req.get());
319  }
320 
321  return true;
322 }
void STLDeleteValues(Container *container)
Definition: util.h:101
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
bool Enqueue(DBRequest *req)
Definition: db_table.cc:194
std::unique_ptr< AutogenProperty > content
Definition: db.h:24
std::list< DBRequest * > RequestList
void set_origin(Origin in_origin)
Definition: ifmap_origin.h:21
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
DBOperation oper
Definition: db_table.h:42
#define DNS_TRACE(Obj,...)
Definition: dns_config.h:34
static IFMapTable * FindTable(DB *db, const std::string &element_type)
Definition: ifmap_table.cc:39
bool ParseConfig(const pugi::xml_node &root, bool add_change, RequestList *requests) const
bool Parse(const std::string &content)