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