Using VMware Webservice with C++ and gSOAP
For me one of the most annoying thing from VMware is the VMware Infrastructure Client, because it doesn’t support Linux. Every-time when I want to manage some machines, or I want to see the IP/Status/etc of some machines, I need to log on on some Windows Server and run the VMware Infrastructure Client from there. Because I’m running exclusively on Linux (Debian 5.0.1 Lenny) on my workstation, this can be very annoying. Anyway, VMware VirtualCenter is exposing to us a set of web services who can control your VMware ESX Cluster. Also VMware provide a VMware vSphere Web Services SDK 4.0 which is a set of samples and libraries what is helping you to write necessarily code, in Java or C#, to operate this web services.
Writing C++ Code for this web services is not an easy job if you don’t use a an XML data binding toolkit. gSOAP is such a toolkit and I will use it in my “experimental” VMware client application for Linux.
For this example you don’t need the VMware vSphere Web Services SDK 4.0, because we can extract the WSDL directly from VMware Server. You can do that using wget.
[rb@randombugs]$ wget https://IP_ADDRESS_OF_YOUR_VMware_VirtualCenter/sdk/vim.wsdl
Now we need to create an C++ interface for our web service.
[rb@randombugs]$ wsdl2h -o vim25.h vim.wsdl
[...snip...]Saving vim25.h
Cannot open file ‘typemap.dat’
Problem reading type map file typemap.dat.
Using internal type definitions for C++ instead.Reading file ‘vim.wsdl’
To complete the process, compile with:
soapcpp2 vim25.h
[rb@randombugs]$ soapcpp2 -x -C vim25.h -I /usr/include/gsoap/
Saving soapStub.h
Saving soapH.h
Saving soapC.cpp
Saving soapClient.cpp
Saving soapClientLib.cpp
Using ns1 service name: VimBinding
Using ns1 service style: document
Using ns1 service encoding: literal
Using ns1 service location: http://localhost:80
Using ns1 schema namespace: urn:vim25
Saving soapVimBindingProxy.h client proxy
Saving VimBinding.nsmap namespace mapping tableCompilation successful
Now we have the C++ interface to this WSDL. We just need to compile this C++ interface in a library for later use.
[rb@randombugs]$ g++ -fPIC -DWITH_OPENSSL -DWITH_COOKIES -c soapC.cpp
Compiling soapC.cpp it will take some time. This file should have aprox 30MB.
[rb@randombugs]$ g++ -fPIC -DWITH_OPENSSL -DWITH_COOKIES -c soapClient.cpp
[rb@randombugs]$ g++ -DWITH_OPENSSL -DWITH_COOKIES -o libvmsoap.o -shared soapC.o soapClient.o
You should move the library in /usr/local/lib. Also take a look in your /etc/ld.so.conf.d/*.conf to see if /usr/local/lib is defined. If si not just create a file /etc/ld.so.conf.d/local.conf with /usr/local/lib as content and run ldconfig to configure dynamic linker run-time bindings.
Now we are ready to compile our program:
[rb@randombugs]$ g++ -DWITH_OPENSSL -DWITH_COOKIES controlVMs.cpp /usr/include/gsoap/stdsoap2.cpp -o cvm -lvmsoap.o -lgsoapssl++ -lssl -lcrypto
I’m attaching the example program what is “inspired” by ashoksud, Steve Jin and stumpr from VMware communities forum
controlVM’s.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 | #include <iostream> #include "soapVimBindingProxy.h" #include "VimBinding.nsmap" #include "soapStub.h" #include "soapH.h" #include <time.h> #include <iostream> using namespace std; void sigpipe_handle(int x) { cout << "sigpipe " << x << endl; } static ns1__ManagedObjectReference* getVMManagedObjectRef(VimBinding* vim, ns1__ServiceContent* serviceContent,string vm_name) { ns1__TraversalSpec dataCenterVMTraversalSpec, folderTraversalSpec; ns1__SelectionSpec dataCenterVMTraversalSelectionSpec, folderTraversalSelectionSpec; ns1__PropertySpec propertySpec; ns1__ObjectSpec objectSpec; ns1__PropertyFilterSpec propertyFilterSpec; ns1__DynamicProperty dynamicProperty; ns1__RetrievePropertiesRequestType retrievePropertiesReq; _ns1__RetrievePropertiesResponse retrievePropertiesRes; ns1__ManagedObjectReference* vm_mor = NULL; bool xsd_true = 1; bool xsd_false = 0; folderTraversalSelectionSpec.name = new string("FolderTraversalSpec"); dataCenterVMTraversalSelectionSpec.name = new string("DataCenterVMTraversalSpec"); dataCenterVMTraversalSpec.name = new string("DataCenterVMTraversalSpec"); dataCenterVMTraversalSpec.type = "Datacenter"; dataCenterVMTraversalSpec.path = "vmFolder"; dataCenterVMTraversalSpec.skip = &xsd_true; folderTraversalSpec.name = new string("FolderTraversalSpec"); folderTraversalSpec.type = "Folder"; folderTraversalSpec.path = "childEntity"; folderTraversalSpec.skip = &xsd_true; dataCenterVMTraversalSpec.selectSet.push_back(&folderTraversalSelectionSpec); folderTraversalSpec.selectSet.push_back(&dataCenterVMTraversalSelectionSpec); folderTraversalSpec.selectSet.push_back(&folderTraversalSelectionSpec); propertySpec.type = "VirtualMachine"; propertySpec.all = &xsd_false; propertySpec.pathSet.push_back("name"); objectSpec.obj = serviceContent->rootFolder; objectSpec.skip = &xsd_true; objectSpec.selectSet.push_back(&folderTraversalSpec); objectSpec.selectSet.push_back(&dataCenterVMTraversalSpec); propertyFilterSpec.propSet.push_back(&propertySpec); propertyFilterSpec.objectSet.push_back(&objectSpec); retrievePropertiesReq._USCOREthis = serviceContent->propertyCollector; retrievePropertiesReq.specSet.push_back(&propertyFilterSpec); if (vim->__ns1__RetrieveProperties(&retrievePropertiesReq, &retrievePropertiesRes) == SOAP_OK) { for (int i = 0; i < retrievePropertiesRes.returnval.size(); i++) { dynamicProperty = *retrievePropertiesRes.returnval[i]->propSet[0]; // assert(dynamicProperty.name == "name"); xsd__string* name = (xsd__string*) dynamicProperty.val; if (vm_name == name->__item) { vm_mor = retrievePropertiesRes.returnval[i]->obj; break; } } } else { soap_print_fault(vim->soap, stderr); } delete folderTraversalSelectionSpec.name; delete folderTraversalSpec.name; delete dataCenterVMTraversalSelectionSpec.name; delete dataCenterVMTraversalSpec.name; return vm_mor; } static void powerVM(VimBinding* vim, ns1__ServiceContent* serviceContent, string vm_name, bool powerOn) { ns1__ManagedObjectReference* vm_mor = getVMManagedObjectRef(vim, serviceContent, vm_name); if (powerOn) { // Power-on the Virtual Machine. ns1__PowerOnVMRequestType powerOnReq; _ns1__PowerOnVM_USCORETaskResponse powerOnRes; // This line is changed powerOnReq._USCOREthis = vm_mor; if (vim->__ns1__PowerOnVM_USCORETask(&powerOnReq, &powerOnRes) == SOAP_OK) { // This line is changed cout << "PowerOn of VM " << vm_name << " successful" << endl << endl; } else { cout << "PowerOn of VM " << vm_name << " unsuccessful" << endl << endl; soap_print_fault(vim->soap,stderr); soap_done(vim->soap); soap_end(vim->soap); exit(1); } } else { // Power-off the Virtual Machine. ns1__PowerOffVMRequestType powerOffReq; _ns1__PowerOffVM_USCORETaskResponse powerOffRes; // This line is changed powerOffReq._USCOREthis = vm_mor; if (vim->__ns1__PowerOffVM_USCORETask(&powerOffReq, &powerOffRes) == SOAP_OK) { // This line is changed cout << "PowerOff of VM " << vm_name << " successful" << endl << endl; } else { cout << "PowerOff of VM " << vm_name << " unsuccessful" << endl << endl; soap_print_fault(vim->soap,stderr); soap_done(vim->soap); soap_end(vim->soap); exit(1); } } } int dumpVMs(VimBinding* vim, ns1__ServiceContent* serviceContent) { int returnCode = 0; bool xsd_true = 1; bool xsd_false = 0; ns1__SelectionSpec folderTraversalSelectionSpec; folderTraversalSelectionSpec.name = new string("FolderTraversalSpec"); ns1__SelectionSpec dataCenterVMTraversalSelectionSpec; dataCenterVMTraversalSelectionSpec.name = new string("DataCenterVMTraversalSpec"); ns1__TraversalSpec folderTraversalSpec; folderTraversalSpec.name = new string("FolderTraversalSpec"); folderTraversalSpec.type = "Folder"; folderTraversalSpec.path = "childEntity"; folderTraversalSpec.skip = &xsd_true; ns1__TraversalSpec dataCenterVMTraversalSpec; dataCenterVMTraversalSpec.name = new string("DataCenterVMTraversalSpec"); dataCenterVMTraversalSpec.type = "Datacenter"; dataCenterVMTraversalSpec.path = "vmFolder"; dataCenterVMTraversalSpec.skip = &xsd_true; dataCenterVMTraversalSpec.selectSet.push_back(&folderTraversalSelectionSpec); folderTraversalSpec.selectSet.push_back(&dataCenterVMTraversalSelectionSpec); folderTraversalSpec.selectSet.push_back(&folderTraversalSelectionSpec); ns1__PropertySpec propertySpec; propertySpec.type = "VirtualMachine"; propertySpec.pathSet.push_back("name"); propertySpec.pathSet.push_back("guest.ipAddress"); propertySpec.all = &xsd_false; ns1__PropertySpec propertySpec2; propertySpec2.type = "VirtualMachine"; propertySpec2.pathSet.push_back("name"); propertySpec2.pathSet.push_back("guest.guestState"); propertySpec2.all = &xsd_false; ns1__ObjectSpec objectSpec; objectSpec.obj = serviceContent->rootFolder; objectSpec.skip = &xsd_true; objectSpec.selectSet.push_back(&folderTraversalSpec); objectSpec.selectSet.push_back(&dataCenterVMTraversalSpec); ns1__PropertyFilterSpec propertyFilterSpec; propertyFilterSpec.propSet.push_back(&propertySpec); propertyFilterSpec.propSet.push_back(&propertySpec2); propertyFilterSpec.objectSet.push_back(&objectSpec); ns1__DynamicProperty* dynamicProperty; ns1__RetrievePropertiesRequestType retrievePropertiesReq; _ns1__RetrievePropertiesResponse retrievePropertiesRes; retrievePropertiesReq._USCOREthis = serviceContent->propertyCollector; retrievePropertiesReq.specSet.push_back(&propertyFilterSpec); if (vim->__ns1__RetrieveProperties(&retrievePropertiesReq, &retrievePropertiesRes) == SOAP_OK) { cout << "Number of Objects " << retrievePropertiesRes.returnval.size() << endl; ns1__ObjectContent* oc = NULL; for (int i=0; i < retrievePropertiesRes.returnval.size(); i++) { oc = retrievePropertiesRes.returnval[i]; cout << " Object Type: " << oc->obj->type->c_str(); cout << " (" << oc->propSet.size() << " properties), "; for (int j=0; j < oc->propSet.size(); j++) { dynamicProperty = oc->propSet[j]; if ( dynamicProperty->name == "name" ) { xsd__string* name = (xsd__string *) dynamicProperty->val; cout << " Name: " << name->__item; } if ( dynamicProperty->name == "guest.ipAddress" ) { xsd__string* name = (xsd__string *) dynamicProperty->val; cout << " IP Address: " << name->__item; } if ( dynamicProperty->name == "guest.guestState" ) { xsd__string* name = (xsd__string *) dynamicProperty->val; cout << " Guest State: " << name->__item; } } cout << endl; returnCode = 0; } } else { returnCode = 1; soap_print_fault(vim->soap, stderr); } delete folderTraversalSelectionSpec.name; delete folderTraversalSpec.name; delete dataCenterVMTraversalSelectionSpec.name; delete dataCenterVMTraversalSpec.name; return returnCode; } static void serverLogout(VimBinding* vim, ns1__ServiceContent* serviceContent) { ns1__LogoutRequestType logoutReq; _ns1__LogoutResponse logoutRes; logoutReq._USCOREthis = serviceContent->sessionManager; if (vim->__ns1__Logout(&logoutReq, &logoutRes) == SOAP_OK) { cout << "Logout - OK" << endl << endl; } else { cout << "Logout - NOT OK" << endl << endl; soap_print_fault(vim->soap,stderr); soap_done(vim->soap); soap_end(vim->soap); exit(1); } } static void serverLogin(VimBinding* vim, ns1__ServiceContent* serviceContent) { ns1__LoginRequestType loginReq; _ns1__LoginResponse loginRes; loginReq._USCOREthis = serviceContent->sessionManager; loginReq.userName = "xxxxxxxxxx"; loginReq.password = "xxxxxxxxxx"; if (vim->__ns1__Login(&loginReq, &loginRes) == SOAP_OK) { ns1__UserSession* userSession = loginRes.returnval; cout << "Login Successful: " << userSession->userName << endl; } else { cout << "Login - NOT OK" << endl << endl; soap_print_fault(vim->soap,stderr); soap_done(vim->soap); soap_end(vim->soap); exit(1); } } int main(int argc, char*argv[]) { VimBinding vim; ns1__ManagedObjectReference ManagedObjectRef; ns1__RetrieveServiceContentRequestType RetrieveServiceContentReq; _ns1__RetrieveServiceContentResponse RetrieveServiceContentRes; ns1__ServiceContent *ServiceContent; ns1__AboutInfo *AboutInfo; ns1__LoginRequestType LoginReq; _ns1__LoginResponse LoginRes; ns1__UserSession *UserSession; string vm_name; if (argc<2){ cout << "No parameters Provided !" <<endl; exit(1); } string vm_op(argv[1]); if (argc==3) vm_name=argv[2]; char* service_url = "https://xxxxxx/sdk"; vim.endpoint = service_url; soap_init(vim.soap); #ifdef DEBUG soap_set_recv_logfile(vim.soap, "service12.log"); // append all messages received in /logs/recv/service12.log soap_set_sent_logfile(vim.soap, "service13.log"); // append all messages sent in /logs/sent/service13.log soap_set_test_logfile(vim.soap, "test.log"); // append all DEBUG messages in /logs/sent/test.log #endif soap_ssl_init(); if (soap_ssl_client_context( vim.soap, SOAP_SSL_NO_AUTHENTICATION, NULL, NULL, NULL, NULL, NULL )) { cout << "SSL:"; soap_print_fault(vim.soap, stderr); exit(1); } ManagedObjectRef.__item = "ServiceInstance"; ManagedObjectRef.type = new string("ServiceInstance"); RetrieveServiceContentReq._USCOREthis = &ManagedObjectRef; if ( vim.__ns1__RetrieveServiceContent(&RetrieveServiceContentReq, &RetrieveServiceContentRes) == SOAP_OK ) { cout << "RetrieveServiceContent - OK" << endl; } else { soap_print_fault(vim.soap,stderr); exit(1); } ServiceContent = RetrieveServiceContentRes.returnval; if (ServiceContent && ServiceContent->about) { AboutInfo = ServiceContent->about; cout << "fullName: " << AboutInfo->fullName << endl; } if (ServiceContent && ServiceContent->sessionManager) { serverLogin(&vim, ServiceContent); if (vm_op=="list") if ( dumpVMs(&vim, ServiceContent) == 0) { cout << "dumpVMs Successful: " << endl; exit(0); } else { soap_print_fault(vim.soap, stderr); exit(1); } if (argc==3) { if (vm_op == "powerOn") { // Power-on the specified VM. powerVM(&vim, ServiceContent, vm_name, true); } else if (vm_op == "powerOff") { // Power-off the specified VM. powerVM(&vim, ServiceContent, vm_name, false); } } delete ManagedObjectRef.type; } serverLogout(&vim, ServiceContent); soap_done(vim.soap); soap_end(vim.soap); return 0; } |
If you want to debug the SOAP connection you should compile all libraries with -DDEBUG
g++ -DDEBUG -fPIC -DWITH_OPENSSL -DWITH_COOKIES -c soapC.cpp
g++ -DDEBUG -fPIC -DWITH_OPENSSL -DWITH_COOKIES -c soapClient.cpp
g++ -DDEBUG -DWITH_OPENSSL -DWITH_COOKIES -o libvmsoap.o -shared soapC.o soapClient.o
g++ -DDEBUG -DWITH_OPENSSL -DWITH_COOKIES controlVMs.cpp /usr/include/gsoap/stdsoap2.cpp -o cvm -lvmsoap.o -lgsoapssl++ -lssl -lcrypto
Running the program with DEBUG enabled will create 3 files: service12.log, service13.log and test.log. service12.log will contain the received XML messages, service13.log will contain the sent XML messages and test.log just soap debug messages.
controlVMs.cpp program is able to do 3 things:
1. List the VM’s what you have access
2. PowerOFF
3. PowerON
Examples of running:
./cvm list
RetrieveServiceContent – OK
fullName: VMware VirtualCenter 2.5.0 build-119598
Login Successful: user
Number of Objects 84
Object Type: VirtualMachine (3 properties), Guest State: running IP Address: 192.168.0.2 Name: test1
Object Type: VirtualMachine (3 properties), Guest State: running IP Address: 192.168.0.3 Name: test2
[ ... snip ... ]
To powerOn and powerOff a machine :
./cvm powerOn test1
./cvm powerOff test1
If you are interested in how is looking SOAP sent packets I attached a Login, List, Logout session bellow:
1 2 3 4 5 6 7 8 | <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <RetrieveServiceContent xmlns="urn:vim2"> <_this type="ServiceInstance">ServiceInstance</_this> </RetrieveServiceContent> </soapenv:Body> </soapenv:Envelope> |
1 2 3 4 5 6 7 8 9 10 | <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <Login xmlns="urn:vim2"> <_this type="SessionManager">SessionManager</_this> <userName>user</userName> <password>password</password> </Login> </soapenv:Body> </soapenv:Envelope> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <RetrieveProperties xmlns="urn:vim2"> <_this type="PropertyCollector">propertyCollector</_this> <specSet> <propSet> <type>ManagedEntity</type> <all>false</all> <pathSet>name</pathSet> </propSet> <objectSet> <obj type="Folder">group-d1</obj> <skip>false</skip> <selectSet xmlns:ns1="urn:vim2" xsi:type="ns1:TraversalSpec"> <ns1:name>visitFolders</ns1:name> <ns1:type>Folder</ns1:type> <ns1:path>childEntity</ns1:path> <ns1:skip>false</ns1:skip> <ns1:selectSet> <ns1:name>visitFolders</ns1:name> </ns1:selectSet> <ns1:selectSet> <ns1:name>dcToHf</ns1:name> </ns1:selectSet> <ns1:selectSet> <ns1:name>dcToVmf</ns1:name> </ns1:selectSet> <ns1:selectSet> <ns1:name>crToH</ns1:name> </ns1:selectSet> <ns1:selectSet> <ns1:name>crToRp</ns1:name> </ns1:selectSet> <ns1:selectSet> <ns1:name>HToVm</ns1:name> </ns1:selectSet> <ns1:selectSet> <ns1:name>rpToVm</ns1:name> </ns1:selectSet> </selectSet> <selectSet xmlns:ns2="urn:vim2" xsi:type="ns2:TraversalSpec"> <ns2:name>dcToVmf</ns2:name> <ns2:type>Datacenter</ns2:type> <ns2:path>vmFolder</ns2:path> <ns2:skip>false</ns2:skip> <ns2:selectSet> <ns2:name>visitFolders</ns2:name> </ns2:selectSet> </selectSet> <selectSet xmlns:ns3="urn:vim2" xsi:type="ns3:TraversalSpec"> <ns3:name>dcToHf</ns3:name> <ns3:type>Datacenter</ns3:type> <ns3:path>hostFolder</ns3:path> <ns3:skip>false</ns3:skip> <ns3:selectSet> <ns3:name>visitFolders</ns3:name> </ns3:selectSet> </selectSet> <selectSet xmlns:ns4="urn:vim2" xsi:type="ns4:TraversalSpec"> <ns4:name>crToH</ns4:name> <ns4:type>ComputeResource</ns4:type> <ns4:path>host</ns4:path> <ns4:skip>false</ns4:skip> </selectSet> <selectSet xmlns:ns5="urn:vim2" xsi:type="ns5:TraversalSpec"> <ns5:name>crToRp</ns5:name> <ns5:type>ComputeResource</ns5:type> <ns5:path>resourcePool</ns5:path> <ns5:skip>false</ns5:skip> <ns5:selectSet> <ns5:name>rpToRp</ns5:name> </ns5:selectSet> <ns5:selectSet> <ns5:name>rpToVm</ns5:name> </ns5:selectSet> </selectSet> <selectSet xmlns:ns6="urn:vim2" xsi:type="ns6:TraversalSpec"> <ns6:name>rpToRp</ns6:name> <ns6:type>ResourcePool</ns6:type> <ns6:path>resourcePool</ns6:path> <ns6:skip>false</ns6:skip> <ns6:selectSet> <ns6:name>rpToRp</ns6:name> </ns6:selectSet> <ns6:selectSet> <ns6:name>rpToVm</ns6:name> </ns6:selectSet> </selectSet> <selectSet xmlns:ns7="urn:vim2" xsi:type="ns7:TraversalSpec"> <ns7:name>HToVm</ns7:name> <ns7:type>HostSystem</ns7:type> <ns7:path>vm</ns7:path> <ns7:skip>false</ns7:skip> <ns7:selectSet> <ns7:name>visitFolders</ns7:name> </ns7:selectSet> </selectSet> <selectSet xmlns:ns8="urn:vim2" xsi:type="ns8:TraversalSpec"> <ns8:name>rpToVm</ns8:name> <ns8:type>ResourcePool</ns8:type> <ns8:path>vm</ns8:path> <ns8:skip>false</ns8:skip> </selectSet> </objectSet> </specSet> </RetrieveProperties> </soapenv:Body> </soapenv:Envelope> |
1 2 3 4 5 6 7 8 | <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <Logout xmlns="urn:vim2"> <_this type="SessionManager">SessionManager</_this> </Logout> </soapenv:Body> </soapenv:Envelope> |
Software used:
Debian 5.0.1 Lenny
gsoap 2.7.9l-0.2
g++ 4.1.3
Good Luck !























Leave your response!