Line data Source code
1 : /*
2 : * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3 : */
4 : #include "base/os.h"
5 : #include <iostream>
6 : #include <fstream>
7 : #include <pugixml/pugixml.hpp>
8 : #include <boost/filesystem.hpp>
9 : #include <boost/uuid/uuid.hpp>
10 :
11 : #include <test/test_cmn_util.h>
12 : #include <pkt/test/test_pkt_util.h>
13 : #include <pkt/flow_mgmt.h>
14 : #include <oper/global_vrouter.h>
15 : #include "test_xml.h"
16 : #include "test_xml_validate.h"
17 : #include "test_xml_packet.h"
18 :
19 : using namespace std;
20 : using namespace pugi;
21 : using namespace boost::uuids;
22 : using namespace AgentUtXmlUtils;
23 :
24 : namespace AgentUtXmlUtils {
25 5586 : bool GetStringAttribute(const xml_node &node, const string &name,
26 : string *value) {
27 5586 : xml_attribute attr = node.attribute(name.c_str());
28 5586 : if (!attr) {
29 3163 : return false;;
30 : }
31 :
32 2423 : *value = attr.as_string();
33 :
34 2423 : return true;
35 : }
36 :
37 1476 : bool GetUintAttribute(const xml_node &node, const string &name,
38 : uint16_t *value) {
39 1476 : xml_attribute attr = node.attribute(name.c_str());
40 1476 : if (!attr) {
41 704 : return false;;
42 : }
43 :
44 772 : *value = attr.as_uint();
45 :
46 772 : return true;
47 : }
48 :
49 15 : bool GetIntAttribute(const xml_node &node, const string &name, int *value) {
50 15 : xml_attribute attr = node.attribute(name.c_str());
51 15 : if (!attr) {
52 10 : return false;;
53 : }
54 :
55 5 : *value = attr.as_int();
56 :
57 5 : return true;
58 : }
59 :
60 0 : bool GetBoolAttribute(const xml_node &node, const string &name,
61 : bool *value) {
62 0 : xml_attribute attr = node.attribute(name.c_str());
63 0 : if (!attr) {
64 0 : return false;;
65 : }
66 :
67 0 : string str = attr.as_string();
68 0 : if (str == "true" || str == "yes")
69 0 : *value = true;
70 : else
71 0 : *value = false;
72 0 : return true;
73 0 : }
74 :
75 44 : void NovaIntfAdd(bool op_delete, const uuid &id, const Ip4Address &ip,
76 : const uuid &vm_uuid, const uuid vn_uuid, const string &name,
77 : const string &mac, const string vm_name) {
78 44 : if (op_delete) {
79 23 : PortUnSubscribe(id);
80 23 : cout << "Nova Del Interface Message " << endl;
81 23 : return;
82 : }
83 :
84 21 : PortSubscribe(name, id, vm_uuid, vm_name, vn_uuid, MakeUuid(1), ip,
85 21 : Ip6Address::v4_compatible(ip), mac);
86 21 : cout << "Nova Add Interface Message " << endl;
87 21 : return;
88 : }
89 :
90 432 : void LinkXmlNode(xml_node *parent, const string <ype, const string lname,
91 : const string &rtype, const string rname) {
92 432 : xml_node n = parent->append_child("link");
93 :
94 432 : xml_node n1 = n.append_child("node");
95 432 : n1.append_attribute("type") = ltype.c_str();
96 :
97 432 : xml_node n2 = n1.append_child("name");
98 432 : n2.append_child(pugi::node_pcdata).set_value(lname.c_str());
99 :
100 432 : n1 = n.append_child("node");
101 432 : n1.append_attribute("type") = rtype.c_str();
102 :
103 432 : n2 = n1.append_child("name");
104 432 : n2.append_child(pugi::node_pcdata).set_value(rname.c_str());
105 :
106 432 : string mdata = GetMetadata(ltype.c_str(), rtype.c_str());
107 432 : xml_node n3 = n.append_child("metadata");
108 432 : n3.append_attribute("type") = mdata.c_str();
109 864 : return;
110 432 : }
111 :
112 365 : xml_node AddXmlNodeWithAttr(xml_node *parent, const char *attr) {
113 365 : xml_node n = parent->append_child("node");
114 365 : n.append_attribute("type") = attr;
115 365 : return n;
116 : }
117 :
118 2340 : xml_node AddXmlNodeWithValue(xml_node *parent, const char *name,
119 : const string &value) {
120 2340 : xml_node n = parent->append_child(name);
121 2340 : n.append_child(pugi::node_pcdata).set_value(value.c_str());
122 2340 : return n;
123 : }
124 :
125 35 : xml_node AddXmlNodeWithIntValue(xml_node *parent, const char *name,
126 : int val) {
127 35 : stringstream s;
128 35 : s << val;
129 35 : xml_node n = parent->append_child(name);
130 35 : n.append_child(pugi::node_pcdata).set_value(s.str().c_str());
131 35 : return n;
132 35 : }
133 : }
134 :
135 : /////////////////////////////////////////////////////////////////////////////
136 : // AgentUtXmlTest routines
137 : /////////////////////////////////////////////////////////////////////////////
138 22 : AgentUtXmlTest::AgentUtXmlTest(const std::string &name) : file_name_(name) {
139 22 : }
140 :
141 22 : AgentUtXmlTest::~AgentUtXmlTest() {
142 :
143 22 : for (AgentUtXmlTestList::iterator i = test_list_.begin();
144 55 : i != test_list_.end(); i++) {
145 33 : delete *i;
146 : }
147 22 : }
148 :
149 555 : void AgentUtXmlTest::AddConfigEntry(const std::string &name,
150 : AgentUtXmlTestConfigCreateFn fn) {
151 555 : config_factory_[name] = fn;
152 555 : }
153 :
154 510 : void AgentUtXmlTest::AddValidateEntry(const std::string &name,
155 : AgentUtXmlTestValidateCreateFn fn) {
156 510 : validate_factory_[name] = fn;
157 510 : }
158 :
159 : AgentUtXmlTest::AgentUtXmlTestConfigCreateFn
160 657 : AgentUtXmlTest::GetConfigCreateFn(const std::string &name) {
161 657 : AgentUtXmlTestConfigFactory::iterator iter = config_factory_.find(name);
162 657 : if (iter == config_factory_.end()) {
163 274 : return AgentUtXmlTest::AgentUtXmlTestConfigCreateFn();
164 : }
165 :
166 383 : return iter->second;
167 : }
168 :
169 : AgentUtXmlTest::AgentUtXmlTestValidateCreateFn
170 259 : AgentUtXmlTest::GetValidateCreateFn(const std::string &name) {
171 259 : AgentUtXmlTestValidateFactory::iterator iter = validate_factory_.find(name);
172 259 : if (iter == validate_factory_.end()) {
173 0 : assert(0);
174 : }
175 518 : return iter->second;
176 : }
177 :
178 20 : bool AgentUtXmlTest::ReadXml() {
179 20 : xml_node list = doc_.child("test_suite");
180 20 : GetStringAttribute(list, "name", &name_);
181 :
182 53 : for (xml_node node = list.first_child(); node; node = node.next_sibling()) {
183 33 : if (strcmp(node.name(), "test") == 0) {
184 33 : xml_attribute attr = node.attribute("name");
185 33 : if (!attr) {
186 0 : cout << "Missing attribute \"name\". Skipping" << endl;
187 0 : continue;
188 : }
189 : AgentUtXmlTestCase *test = new AgentUtXmlTestCase(attr.value(),
190 33 : node, this);
191 33 : attr = node.attribute("verbose");
192 33 : bool verbose = false;
193 33 : if (!attr) {
194 18 : verbose = false;
195 : } else {
196 15 : if (atoi(attr.value()))
197 0 : verbose = true;
198 : }
199 33 : test->set_verbose(verbose);
200 33 : test_list_.push_back(test);
201 33 : test->ReadXml();
202 : }
203 : }
204 :
205 20 : return true;
206 : }
207 :
208 22 : bool AgentUtXmlTest::Load() {
209 22 : boost::system::error_code ec;
210 22 : boost::filesystem::path file_path(file_name_);
211 22 : uintmax_t file_size = boost::filesystem::file_size(file_path, ec);
212 22 : if (ec) {
213 1 : cout << "Error <" << ec << "> opening file" << file_name_ << endl;
214 1 : return false;
215 : }
216 :
217 21 : std::fstream file(file_name_.c_str(), std::ios::binary | std::ios_base::in);
218 21 : if (!file) {
219 0 : cout << "Error <fstream error> opening file" << file_name_ << endl;
220 0 : return false;
221 : }
222 :
223 21 : std::vector<char> data(file_size + 1, 0);
224 21 : file.read(data.data(), file_size);
225 21 : if (!file || file.gcount() < static_cast<std::streamsize>(file_size)) {
226 0 : cout << "Error <fstream::read> reading file" << file_name_ << endl;
227 0 : return false;
228 : }
229 :
230 21 : xml_parse_result result = doc_.load_string(data.data());
231 21 : if (result) {
232 20 : cout << "Loaded data file successfully" << endl;
233 : } else {
234 1 : cout << "Error in XML string at offset <: " << result.offset
235 1 : << "> (error at [..." << (data.data() + result.offset) << "])" << endl;
236 1 : return false;
237 : }
238 :
239 20 : return true;
240 22 : }
241 :
242 20 : void AgentUtXmlTest::ToString(string *str) {
243 20 : stringstream s;
244 :
245 20 : s << "Test Suite : " << name_ << endl;
246 20 : *str += s.str();
247 20 : for (AgentUtXmlTestList::iterator it = test_list_.begin();
248 53 : it != test_list_.end(); it++) {
249 33 : (*it)->ToString(str);
250 : }
251 40 : return;
252 20 : }
253 :
254 20 : bool AgentUtXmlTest::Run() {
255 20 : for (AgentUtXmlTestList::iterator it = test_list_.begin();
256 53 : it != test_list_.end(); it++) {
257 33 : (*it)->Run();
258 : }
259 :
260 20 : return true;
261 : }
262 :
263 0 : bool AgentUtXmlTest::Run(std::string test_case) {
264 0 : for (AgentUtXmlTestList::iterator it = test_list_.begin();
265 0 : it != test_list_.end(); it++) {
266 0 : if ((*it)->name().compare(test_case) == 0) {
267 0 : (*it)->Run();
268 0 : return true;
269 : }
270 : }
271 :
272 0 : return false;
273 : }
274 :
275 : /////////////////////////////////////////////////////////////////////////////
276 : // AgentUtXmlTestCase routines
277 : /////////////////////////////////////////////////////////////////////////////
278 657 : static bool CheckConfigNode(const string &node_name, const xml_node &node,
279 : uuid *id, string *name) {
280 657 : if (strcmp(node.name(), node_name.c_str()) != 0) {
281 0 : return false;
282 : }
283 :
284 657 : xml_attribute attr = node.attribute("name");
285 657 : if (!attr) {
286 : cout << "Attribute \"name\" not found for " << node_name
287 62 : << ". Skipping..." << endl;
288 62 : return false;
289 : }
290 :
291 595 : *name = attr.as_string();
292 595 : if (*name == "") {
293 0 : cout << "Invalid \"name\" for " << node_name << " Skipping" << endl;
294 0 : return false;
295 : }
296 :
297 595 : if (node_name == "validate")
298 145 : return false;
299 :
300 450 : attr = node.attribute("uuid");
301 450 : if (!attr) {
302 : cout << "Attribute \"uuid\" not found for " << node_name
303 0 : << ". Skipping..." << endl;
304 0 : return false;;
305 : }
306 :
307 450 : int x = attr.as_uint();
308 450 : if (x == 0) {
309 1 : cout << "Invalid \"uuid\" (0) for " << node_name << " Skipping" << endl;
310 1 : return false;
311 : }
312 :
313 449 : *id = MakeUuid(x);
314 :
315 449 : return true;
316 : }
317 :
318 33 : AgentUtXmlTestCase::AgentUtXmlTestCase(const std::string &name,
319 : const xml_node &node,
320 33 : AgentUtXmlTest *test)
321 33 : : name_(name), xml_node_(node), test_(test), verbose_(false) {
322 33 : cout << "Creating test-case <" << name_ << ">" << endl;
323 33 : }
324 :
325 66 : AgentUtXmlTestCase::~AgentUtXmlTestCase() {
326 33 : for (AgentUtXmlNodeList::iterator i = node_list_.begin();
327 689 : i != node_list_.end(); i++) {
328 656 : delete *i;
329 : }
330 66 : }
331 :
332 33 : bool AgentUtXmlTestCase::ReadXml() {
333 690 : for (xml_node node = xml_node_.first_child(); node;
334 657 : node = node.next_sibling()) {
335 :
336 657 : string str;
337 657 : bool op_delete = false;
338 1868 : if (GetStringAttribute(node, "delete", &str) == true ||
339 1211 : GetStringAttribute(node, "del", &str) == true) {
340 237 : if (str != "false" && str != "0")
341 237 : op_delete = true;
342 : }
343 :
344 : uuid id;
345 657 : string name;
346 657 : AgentUtXmlNode *cfg = NULL;
347 :
348 : AgentUtXmlTest::AgentUtXmlTestConfigCreateFn fn =
349 1314 : test_->GetConfigCreateFn(node.name());
350 657 : if (CheckConfigNode(node.name(), node, &id, &name) == true) {
351 449 : if (fn.empty() == false)
352 382 : cfg = fn(node.name(), name, id, node, this);
353 : }
354 :
355 657 : if (strcmp(node.name(), "link") == 0) {
356 107 : cfg = new AgentUtXmlLink(node, this);
357 : }
358 :
359 657 : if (strcmp(node.name(), "packet") == 0) {
360 22 : if (GetStringAttribute(node, "name", &name) == false) {
361 0 : cout << "Attribute \"name\" not specified for Packet. Skipping"
362 0 : << endl;
363 0 : continue;
364 : }
365 22 : cfg = new AgentUtXmlPacket(name, node, this);
366 : }
367 :
368 657 : if (strcmp(node.name(), "task") == 0) {
369 0 : cfg = new AgentUtXmlTask(node, this);
370 : }
371 :
372 657 : if (strcmp(node.name(), "validate") == 0) {
373 145 : if (GetStringAttribute(node, "name", &name) == false) {
374 : cout << "Attribute \"name\" not specified for validate."
375 0 : " Skipping" << endl;
376 0 : continue;
377 : }
378 145 : cfg = new AgentUtXmlValidate(name, node, this);
379 : }
380 :
381 657 : if (cfg) {
382 656 : cfg->set_op_delete(op_delete);
383 : } else {
384 1 : cout << "Unknown node name <" << node.name() << ">. Ignoring"
385 1 : << endl;
386 : }
387 657 : if (cfg) {
388 656 : bool ret = cfg->ReadXml();
389 656 : if (op_delete == false && ret == false) {
390 0 : delete cfg;
391 0 : cfg = NULL;
392 : }
393 : }
394 :
395 657 : if (cfg) {
396 656 : node_list_.push_back(cfg);
397 : }
398 657 : }
399 :
400 33 : return true;
401 : }
402 :
403 33 : bool AgentUtXmlTestCase::Run() {
404 33 : for (AgentUtXmlNodeList::iterator it = node_list_.begin();
405 689 : it != node_list_.end(); it++) {
406 656 : if ((*it)->gen_xml() == false) {
407 184 : (*it)->Run();
408 184 : TestClient::WaitForIdle();
409 184 : continue;
410 : }
411 :
412 472 : xml_document doc;
413 :
414 472 : xml_node decl = doc.prepend_child(pugi::node_declaration);
415 472 : decl.append_attribute("version") = "1.0";
416 :
417 472 : xml_node n = doc.append_child("config");
418 472 : xml_node n1;
419 472 : if ((*it)->op_delete()) {
420 229 : n1 = n.append_child("delete");
421 : } else {
422 243 : n1 = n.append_child("update");
423 : }
424 472 : (*it)->ToXml(&n1);
425 472 : if (verbose_) {
426 0 : doc.print(std::cout);
427 : }
428 472 : Agent *agent = Agent::GetInstance();
429 472 : agent->ifmap_parser()->ConfigParse(n, 0);
430 472 : TestClient::WaitForIdle();
431 472 : }
432 :
433 33 : return true;
434 : }
435 :
436 33 : void AgentUtXmlTestCase::ToString(string *str) {
437 33 : stringstream s;
438 :
439 33 : s << "Test Case : " << name_ << endl;
440 33 : *str += s.str();
441 33 : for (AgentUtXmlNodeList::iterator it = node_list_.begin();
442 689 : it != node_list_.end(); it++) {
443 656 : (*it)->ToString(str);
444 : }
445 66 : return;
446 33 : }
447 :
448 : /////////////////////////////////////////////////////////////////////////////
449 : // AgentUtXmlNode routines
450 : /////////////////////////////////////////////////////////////////////////////
451 472 : AgentUtXmlNode::AgentUtXmlNode(const string &name, const xml_node &node,
452 472 : AgentUtXmlTestCase *test_case) :
453 472 : node_(node), name_(name), op_delete_(false), gen_xml_(true),
454 472 : test_case_(test_case) {
455 472 : }
456 :
457 184 : AgentUtXmlNode::AgentUtXmlNode(const string &name, const xml_node &node,
458 184 : bool gen_xml, AgentUtXmlTestCase *test_case) :
459 184 : node_(node), name_(name), op_delete_(false), gen_xml_(gen_xml),
460 184 : test_case_(test_case) {
461 184 : }
462 :
463 656 : AgentUtXmlNode::~AgentUtXmlNode() {
464 656 : }
465 :
466 532 : bool AgentUtXmlNode::ReadXml() {
467 532 : string str;
468 532 : op_delete_ = false;
469 1509 : if (GetStringAttribute(node_, "delete", &str) == true ||
470 977 : GetStringAttribute(node_, "del", &str) == true) {
471 167 : if (str != "false" && str != "0")
472 167 : op_delete_ = true;
473 : }
474 :
475 532 : return true;
476 532 : }
477 :
478 617 : void AgentUtXmlNode::ToString(string *str) {
479 617 : stringstream s;
480 :
481 617 : if (op_delete_)
482 229 : s << "Delete ";
483 : else
484 388 : s << "Add ";
485 :
486 617 : s << NodeType() << " : " << name_ << " ";
487 :
488 617 : *str += s.str();
489 1234 : return;
490 617 : }
491 :
492 : /////////////////////////////////////////////////////////////////////////////
493 : // AgentUtXmlTask routines
494 : /////////////////////////////////////////////////////////////////////////////
495 0 : AgentUtXmlTask::AgentUtXmlTask(const xml_node &node,
496 0 : AgentUtXmlTestCase *test_case) :
497 0 : AgentUtXmlNode("task", node, false, test_case) {
498 0 : }
499 :
500 0 : AgentUtXmlTask::~AgentUtXmlTask() {
501 0 : }
502 :
503 0 : bool AgentUtXmlTask::ReadXml() {
504 0 : GetStringAttribute(node(), "stop", &stop_);
505 0 : return true;
506 : }
507 :
508 0 : bool AgentUtXmlTask::ToXml(xml_node *parent) {
509 0 : return true;
510 : }
511 :
512 0 : void AgentUtXmlTask::ToString(string *str) {
513 0 : AgentUtXmlNode::ToString(str);
514 0 : stringstream s;
515 :
516 0 : s << "Stop : " << stop_ << endl;
517 0 : *str += s.str();
518 0 : return;
519 0 : }
520 :
521 0 : string AgentUtXmlTask::NodeType() {
522 0 : return "Task";
523 : }
524 :
525 0 : bool AgentUtXmlTask::Run() {
526 0 : if (boost::iequals(stop_, "1") || boost::iequals(stop_, "yes")) {
527 0 : TestClient::WaitForIdle();
528 0 : TaskScheduler::GetInstance()->Stop();
529 : } else {
530 0 : TaskScheduler::GetInstance()->Start();
531 0 : TestClient::WaitForIdle();
532 : }
533 0 : return true;
534 : }
535 :
536 : /////////////////////////////////////////////////////////////////////////////
537 : // AgentUtXmlLink routines
538 : /////////////////////////////////////////////////////////////////////////////
539 107 : AgentUtXmlLink::AgentUtXmlLink(const xml_node &node,
540 107 : AgentUtXmlTestCase *test_case) :
541 107 : AgentUtXmlNode("link", node, test_case) {
542 107 : }
543 :
544 214 : AgentUtXmlLink::~AgentUtXmlLink() {
545 214 : }
546 :
547 107 : bool AgentUtXmlLink::ReadXml() {
548 107 : if (GetStringAttribute(node(), "left", &l_node_) == false) {
549 0 : cout << "Left node-type not specified for link. Skipping" << endl;
550 0 : return false;
551 : }
552 :
553 107 : if (GetStringAttribute(node(), "left-name", &l_name_) == false) {
554 0 : cout << "Right node-name not specified for link. Skipping" << endl;
555 0 : return false;
556 : }
557 :
558 107 : if (GetStringAttribute(node(), "right", &r_node_) == false) {
559 0 : cout << "Right node-type not specified for link. Skipping" << endl;
560 0 : return false;
561 : }
562 :
563 107 : if (GetStringAttribute(node(), "right-name", &r_name_) == false) {
564 0 : cout << "Right node-name not specified for link. Skipping" << endl;
565 0 : return false;
566 : }
567 :
568 107 : return true;
569 : }
570 :
571 107 : bool AgentUtXmlLink::ToXml(xml_node *parent) {
572 107 : LinkXmlNode(parent, l_node_, l_name_, r_node_, r_name_);
573 107 : return true;
574 : }
575 :
576 107 : void AgentUtXmlLink::ToString(string *str) {
577 107 : AgentUtXmlNode::ToString(str);
578 107 : stringstream s;
579 :
580 214 : s << "<" << l_node_ << " : " << l_name_ << "> <" << " right-node "
581 107 : << r_node_ << " : " << r_name_ << ">" << endl;
582 :
583 107 : *str += s.str();
584 214 : return;
585 107 : }
586 :
587 107 : string AgentUtXmlLink::NodeType() {
588 107 : return "Link";
589 : }
590 :
591 : /////////////////////////////////////////////////////////////////////////////
592 : // AgentUtXmlConfig routines
593 : /////////////////////////////////////////////////////////////////////////////
594 365 : AgentUtXmlConfig::AgentUtXmlConfig(const string &name, const uuid &id,
595 : const xml_node &node,
596 365 : AgentUtXmlTestCase *test_case) :
597 365 : AgentUtXmlNode(name, node, test_case), id_(id) {
598 365 : }
599 :
600 0 : AgentUtXmlConfig::AgentUtXmlConfig(const string &name, const uuid &id,
601 : const xml_node &node, bool gen_xml,
602 0 : AgentUtXmlTestCase *test_case) :
603 0 : AgentUtXmlNode(name, node, gen_xml, test_case), id_(id) {
604 0 : }
605 :
606 365 : AgentUtXmlConfig::~AgentUtXmlConfig() {
607 365 : }
608 :
609 365 : bool AgentUtXmlConfig::ReadXml() {
610 365 : return AgentUtXmlNode::ReadXml();
611 : }
612 :
613 365 : void AgentUtXmlConfig::ToString(std::string *str) {
614 365 : AgentUtXmlNode::ToString(str);
615 365 : stringstream s;
616 365 : s << " UUID : " << id_;
617 365 : *str += s.str();
618 365 : }
619 :
620 198 : static void AddPermissions(xml_node *parent) {
621 198 : xml_node n = parent->append_child("permissions");
622 :
623 198 : AddXmlNodeWithValue(&n, "owner", "cloud-admin");
624 198 : AddXmlNodeWithValue(&n, "owner-access", "7");
625 198 : AddXmlNodeWithValue(&n, "group", "cloud-admin-group");
626 198 : AddXmlNodeWithValue(&n, "group-access", "7");
627 198 : AddXmlNodeWithValue(&n, "other-access", "7");
628 198 : }
629 :
630 198 : static void AddUuid(xml_node *parent, const uuid &id) {
631 198 : xml_node n = parent->append_child("uuid");
632 :
633 198 : std::vector<uint8_t> v1(id.size());
634 198 : std::vector<uint64_t> v(id.size());
635 198 : std::copy(id.begin(), id.end(), v.begin());
636 :
637 198 : uint64_t ms_val = v[7] + (v[6] << 8) + (v[5] << 16) + (v[4] << 24) +
638 198 : (v[3] << 32) + (v[2] << 40) + (v[1] << 48) + (v[0] << 56);
639 198 : uint64_t ls_val = v[15] + (v[14] << 8) + (v[13] << 16) + (v[12] << 24) +
640 198 : (v[11] << 32) + (v[10] << 40) + (v[9] << 48) + (v[8] << 56);
641 198 : stringstream s;
642 198 : s << ms_val;
643 198 : AddXmlNodeWithValue(&n, "uuid-mslong", s.str());
644 :
645 198 : stringstream s1;
646 198 : s1 << ls_val;
647 198 : AddXmlNodeWithValue(&n, "uuid-lslong", s1.str());
648 198 : }
649 :
650 330 : void AgentUtXmlConfig::AddIdPerms(xml_node *parent) {
651 :
652 330 : if (op_delete())
653 132 : return;
654 :
655 198 : xml_node n = parent->append_child("id-perms");
656 198 : AddPermissions(&n);
657 198 : AddUuid(&n, id());
658 198 : AddXmlNodeWithValue(&n, "enable", "true");
659 : }
|