VMware {code} Community
p_arun
Contributor
Contributor

VI API with C/C++

Hi All,

I need to collect the Information about VMWare Objects like Virtual Host Server (ESX), Virtual Guests (VMs), Snapshots, Datastores, Extents, Storage Pool/Volumes etc.

I need to use VI SDK APIs. As mentioned C# and Java are more preferred languages for VI APIs. Is it possible to Invoke VI API through C/C++?

Thanks,

p.arun

0 Kudos
26 Replies
Niket
Enthusiast
Enthusiast

Hi Arun,

VI SDK API's supports SOAP enabled language. Currently, no toolkit is available for C/C+. Even though, if you want to use SDK API's with C/C+ you have to write your own stub generator for client side or can use AXISC++ for this process(you need to make certain modification for that).

Thanks

Niket

0 Kudos
dsubram
Enthusiast
Enthusiast

Hi,

I created a C/C++ applications using gSOAP tool and its working for my requirement.

Please let me know whats your requirement for which you would like to use C/C++ interface.

--Subram

0 Kudos
painulymukesh
Contributor
Contributor

Hi,

thanks for ur suggestions.

I am having the same problem. I tried with AXIS-CPP, for samples provided code generated successfully but failed for VIM wsdl files.

I also tried with gSOAP and code generation goes fine. Could you please suggest me to how to procedd with generated code?

My requirement is to get the the details about: VMWare Objects like Virtual Host Server (ESX), Virtual Guests (VMs), Snapshots, Datastores, Extents, Storage Pool/Volumes etc.

Thanks,

0 Kudos
dsubram
Enthusiast
Enthusiast

Hi Mukesh,

You can use the following command to compile a program by name vic.c, which is my sample program.

gcc -g -o vic `xml2-config --cflags --libs` -DWITH_OPENSSL -DWITH_COOKIES -I/root/gsoap-linux-2.7 -Wall vic.c soapC.c soapClient.c /root/gsoap-linux-2.7/stdsoap2.c -lssl -lcrypto

/root/gsoap-linux-2.7 is the directory location where I installed by gSOAP tool. In addition you also need to have OpenSSL installed on the system inorder to compile the program for HTTPS. You can go forward with a http communication too, but you need to enable HTTP port on ESX server to do so.

soapC.c and soapClient.c are the generated code.

Please let me know if you need more details.

--Subram ( dsubram@hp.com)

0 Kudos
painulymukesh
Contributor
Contributor

thanks a lot for your response!

I tried to write one test program (like vic.c) but not able to build that. Do you have the sample code for (vic.c) client test program?

thanks,

0 Kudos
dsubram
Enthusiast
Enthusiast

Hi ,

Following is the snippet of the code you can use to understand how to use gSOAP for communication with ESX Server. Request to go thru line by line as you need to modify various parameter inorder to start communciation such as IP Addr,. passwd for root, etc. Using the VI SDK User Guide you can modify ESX Server to accept http request. That will help you to start playing with the code immediately. Please let me know if you need more details.

#include <stdlib.h>

#include <stdio.h>

#include "soapH.h"

#include "VimBinding.nsmap"

struct ns2__ServiceContent *sc;

const char* EndPoint = "http://<IP>/sdk";

int main(int argc, char *argv)

{

struct soap *soap = soap_new();

struct ns2_RetrieveServiceContent rsc;

struct ns2__ManagedObjectReference mor;

struct ns2_RetrieveServiceContentResponse resp;

struct ns2_Login login;

struct ns2_LoginResponse loginresp;

struct ns2_FindByDnsName dnsname;

struct ns2_FindByDnsNameResponse dnsresponse;

struct ns2__ManagedObjectReference *hostref;

struct ns2_Logout logout;

struct ns2_LogoutResponse logoutresp;

struct ns2__ArrayOfPerfMetricId aMetIds;

struct ns2_QueryPerf queryperf;

struct ns2__PerfQuerySpec queryperfspec;

char prop,xmlstr;

int count;

struct metricList metMap;

struct ns2_QueryPerfProviderSummary qperfreq;

struct ns2_QueryPerfProviderSummaryResponse qperfresp;

struct ns2__PerfProviderSummary* perfsummary;

struct ns2_QueryAvailablePerfMetric perfmetric;

struct ns2_QueryAvailablePerfMetricResponse perfmetricresp;

struct ns2__PerfMetricId *metricIds;

memset(&rsc, 0, sizeof(rsc));

memset(&mor, 0, sizeof(mor));

memset(&resp, 0, sizeof(resp));

soap_init(soap);

soap->userid = "root";

soap->passwd = "iso*help";

soap_set_endpoint(soap, EndPoint);

if( soap_connect(soap,EndPoint,NULL) == SOAP_OK)

fprintf(stderr,"soap_connect Successful\n");

else

fprintf(stderr,"soap_connect is not Successful\n");

mor.__item = "ServiceInstance";

mor.type = "ServiceInstance";

rsc._USCOREthis = &mor;

if( soap_call___ns2__RetrieveServiceContent(soap, EndPoint, "", &rsc, &resp) == SOAP_OK ) {

fprintf(stderr, "retrieve success\n");

} else {

soap_print_fault(soap, stderr);

exit(1);

}

sc = resp.returnval;

if( sc && sc->sessionManager ) {

login._USCOREthis = sc->sessionManager;

login.userName = "root";

login.password = "iso*help";

login.locale = NULL;

if( soap_call___ns2__Login(soap, EndPoint, "", &login, &loginresp) == SOAP_OK ) {

fprintf(stderr, " LOGIN success\n");

} else {

soap_print_fault(soap, stderr);

}

}

logout. _USCOREthis = sc->sessionManager;

if( soap_call___ns2__Logout(soap,EndPoint,NULL,&logout,&logoutresp ) == SOAP_OK ) {

fprintf(stderr, "Logout success\n");

} else {

soap_print_fault(soap, stderr);

}

soap_end(soap);

}

0 Kudos
painulymukesh
Contributor
Contributor

thanks for your response.

I generated code by following commands:

./wsdl2h -c -x -s vimService.wsdl

./soapcpp2 -c -C -x vimService.h

It generated the following files:

soapC.c, soapClientLib.c, soapH.h, VimBinding.nsmap, soapClient.c, soapStub.h, vimService.h

But i didn't see the stdsoap.* files. Am i missing something while generating the code? I downloaded stdsoap.c/h files from sourceforge site.

Now, i copied your provided (vic.c) source code for client and tried to compile. But its not able to find the some of the structures which is inside vic.c file.

-


vic.c:13: storage size of `rsc' isn't known

struct ns2_RetrieveServiceContent rsc;

vic.c:16: storage size of `login' isn't known

struct ns2_Login login;

vic.c:18: storage size of `dnsname' isn't known

struct ns2_FindByDnsName dnsname;

vic.c:21: storage size of `logout' isn't known

struct ns2_Logout logout;

vic.c:26: storage size of `queryperf' isn't known

struct ns2_QueryPerf queryperf;

vic.c:31: storage size of `metMap' isn't known

struct metricList metMap;

vic.c:33: storage size of `qperfreq' isn't known

struct ns2_QueryPerfProviderSummary qperfreq;

vic.c:37: storage size of `perfmetric' isn't known

struct ns2_QueryAvailablePerfMetric perfmetric;

-


Even these structures are not present in soapStub.h.

thanks,

0 Kudos
dsubram
Enthusiast
Enthusiast

All the definitions are available in soapH.h file. You need to place the vic.c file in the same directory location where gSOAP generated files are existing.

stdsoap2.c file is avilable with gsoap-linux-2.7 . So you need to modify build script to point to the location where stdsoap2.c file is existing.

Seems to me that you are facing some common problems which is nothing to do with gSOAP and VIM SDK.

0 Kudos
painulymukesh
Contributor
Contributor

Hi dsubram,

Thanks for your cooperation. I had building problem because i generated client stub/code from VIM25 WSDL files and it seems changes has been made for some function prototypes as well as some structures in Vim25 wsdl files.

Now, i build with VIM WSDL (not vim25), its working fine with sample provided. I build without OpenSSL. While running the utility, soap_coonect() went fine but throwing error:

-


soap_connect Successful

Error 405 fault: SOAP-ENV:Server

"HTTP error"

Detail: HTTP/1.1 405 Method not allowed

-


It seems some configuration, i need to do on ESX/VirtualCenter machine. Could you please suggest for the same?

One more confusion like, how to deal with all new WSDL files? and what about the backward compatility?

Thanks,

MukeshPainuly

0 Kudos
dsubram
Enthusiast
Enthusiast

Did you enabled HTTP communication in ESX/Virtual Center?

Any program developed using VI SDK2.0 WSDL, can be used to contact ESX 3.5 which got 2.5 WSDL. This is tested and working in my environment.

Look into VISDK 2.0 ( ESX 3.0.x )or VISDK2.5 ( ESX 3.5.) to know how to configure ESX and Virtual Center for HTTP communication.

0 Kudos
bitherder
Contributor
Contributor

The modifications mentioned in order to use AXIS are to the wsdl file, is that correct? Are those modifications available anywhere? I've just run into what I believe is the same issue trying to generate stubs with AXIS2/C version 1.3.

Thanks for any information you can provide,

bitherder

0 Kudos
p_arun
Contributor
Contributor

Hi,

I am on leave and will be back on May 1st week. During leave I'll have

limited email access. Plz ping me @ +91-9866668247

Best Regards,

~ Arun Painuly

--

Best Regards,

~ Arun Painuly

0 Kudos
svustika
Contributor
Contributor

Hi,

Any body having the C or C++ code to find the list of VM running on the Particular ESX which is monitored by VC?

Thanks,

vkr

0 Kudos
dsubram
Enthusiast
Enthusiast

I have the sample program ready. But it lists VM IDs available on a particular ESX Server. If you would like to get details of each VM, its possible but we need to do more job on the program. If you would like I can provide you the sample binary.

0 Kudos
svustika
Contributor
Contributor

Hi,

If you provide code snipet that will be great help.

Thanks,

vkr

0 Kudos
dsubram
Enthusiast
Enthusiast

- You need to update the IP Addr, ESX Server DNS Name , User Login Name and password for the same.

Program is written for HTTP communication, so you should enable HTTP communication on the webserver thru which you are planning to retrieve the details.

In order to compile the code you need to have gSOAP tool kit and wsdl compiled using gSOAP toolkit.

Following is the sample code,

#include <stdlib.h>

#include <stdio.h>

#include "soapH.h"

#include "VimBinding.nsmap"

struct ns2__ServiceContent *sc;

const char* EndPoint = "[http://<ip] Addr>/sdk";

char* getProperty(struct soap*, struct ns2__ManagedObjectReference , char);

char* getProperty(struct soap *sp, struct ns2__ManagedObjectReference *mor, char *prop )

{

struct ns2__PropertySpec propspec;

struct ns2__ObjectSpec objspec;

struct ns2__PropertyFilterSpec filterspec;

struct ns2_RetrieveProperties retprop;

struct ns2_RetrievePropertiesResponse propres;

struct ns2__ObjectContent objcont;

struct ns2__DynamicProperty dynaprop;

int objcount,dynapropcount;

propspec.__sizedynamicProperty = 0;

propspec.dynamicProperty = NULL;

propspec.dynamicType = NULL;

propspec.type = mor->type;

propspec.__sizepathSet = 1;

propspec.pathSet = (char **)malloc( sizeof(char *));

propspec.pathSet[0] = prop;

propspec.all = xsd__boolean__false_;

objspec.__sizedynamicProperty = 0;

objspec.dynamicProperty = NULL;

objspec.dynamicType = NULL;

objspec.obj = mor;

objspec.__sizeselectSet = 0;

objspec.selectSet = NULL;

objspec.skip = xsd__boolean__false_;

filterspec.__sizedynamicProperty = 0;

filterspec.dynamicProperty = NULL;

filterspec.dynamicType = NULL;

filterspec.__sizepropSet = 1;

filterspec.propSet = &propspec;

filterspec.__sizeobjectSet =1;

filterspec.objectSet = &objspec;

retprop._USCOREthis = sc->propertyCollector;

retprop.__sizespecSet = 1;

retprop.specSet = &filterspec;

if( soap_call___ns2__RetrieveProperties(sp,EndPoint,NULL,&retprop,&propres ) == SOAP_OK

) {

fprintf(stderr, " soap_call___ns2__RetrieveProperties success\n");

} else {

soap_print_fault(sp, stderr);

}

fprintf(stderr,"No. of Objects : %d\n", propres.__sizereturnval);

for(objcount=0;objcount<propres.__sizereturnval;objcount++)

{

objcont = propres.returnval[objcount];

fprintf(stderr,"Size of dynamic property : %d\n",objcont.__sizepropSet);

for(dynapropcount=0;dynapropcount<objcont.__sizepropSet;dynapropcount++){

dynaprop = objcont.propSet[dynapropcount];

fprintf(stderr,"Name: %s\n",dynaprop.name);

}

}

return (dynaprop.val);

}

int main(int argc, char *argv)

{

struct soap *soap = soap_new();

struct ns2_RetrieveServiceContent rsc;

struct ns2__ManagedObjectReference mor;

struct ns2_RetrieveServiceContentResponse resp;

struct ns2_Login login;

struct ns2_LoginResponse loginresp;

struct ns2_FindByDnsName dnsname;

struct ns2_FindByDnsNameResponse dnsresponse;

struct ns2__ManagedObjectReference *hostref;

struct ns2_Logout logout;

struct ns2_LogoutResponse logoutresp;

struct ns2__ArrayOfPerfMetricId aMetIds;

struct ns2_QueryPerf queryperf;

struct ns2__PerfQuerySpec queryperfspec;

char prop,xmlstr;

void **vmlist;

int count;

struct ns2_QueryPerfProviderSummary qperfreq;

struct ns2_QueryPerfProviderSummaryResponse qperfresp;

struct ns2__PerfProviderSummary* perfsummary;

struct ns2_QueryAvailablePerfMetric perfmetric;

struct ns2_QueryAvailablePerfMetricResponse perfmetricresp;

struct ns2__PerfMetricId *metricIds;

memset(&rsc, 0, sizeof(rsc));

memset(&mor, 0, sizeof(mor));

memset(&resp, 0, sizeof(resp));

soap_init(soap);

soap->userid = "root";

soap->passwd = "iso*help";

soap_set_endpoint(soap, EndPoint);

if( soap_connect(soap,EndPoint,NULL) == SOAP_OK)

fprintf(stderr,"soap_connect Successful\n");

else

fprintf(stderr,"soap_connect is not Successful\n");

mor.__item = "ServiceInstance";

mor.type = "ServiceInstance";

rsc._USCOREthis = &mor;

if( soap_call___ns2__RetrieveServiceContent(soap, EndPoint, "", &rsc, &resp) == SOAP_

OK ) {

fprintf(stderr, "retrieve success\n");

} else {

soap_print_fault(soap, stderr);

exit(1);

}

sc = resp.returnval;

if( sc && sc->sessionManager ) {

login._USCOREthis = sc->sessionManager;

login.userName = "root";

login.password = "iso*help";

login.locale = NULL;

if( soap_call___ns2__Login(soap, EndPoint, "", &login, &loginresp) == SOAP_OK ) {

fprintf(stderr, " LOGIN success\n");

} else {

soap_print_fault(soap, stderr);

}

}

dnsname._USCOREthis = sc->searchIndex;

dnsname.datacenter = NULL;

dnsname.dnsName = "< DNS Name of the ESX Server>";

dnsname.vmSearch = xsd__boolean__false_;

if( soap_call___ns2__FindByDnsName(soap,EndPoint,NULL,&dnsname,&dnsresponse ) == SOAP_OK ) {

fprintf(stderr, "success\n");

} else {

fprintf(stderr, "Dns Name Failed\n");

soap_print_fault(soap, stderr);

}

hostref = dnsresponse.returnval;

fprintf(stderr," Item: %s\n",hostref->__item);

fprintf(stderr," Type: %s\n",hostref->type);

prop = getProperty(soap,hostref,"vm");

fprintf(stderr," VM List: %s\n",prop);

logout. _USCOREthis = sc->sessionManager;

if( soap_call___ns2__Logout(soap,EndPoint,NULL,&logout,&logoutresp ) == SOAP_OK ) {

fprintf(stderr, "Logout success\n");

} else {

soap_print_fault(soap, stderr);

}

soap_end(soap);

}

Sample Output of the program is:

soap_connect Successful

retrieve success

LOGIN success

success

Item: ha-host

Type: HostSystem

soap_call___ns2__RetrieveProperties success

No. of Objects : 1

Size of dynamic property : 1

Name: vm

VM List:

<ManagedObjectReference type="VirtualMachine">176</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">272</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">288</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">320</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">352</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">384</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">400</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">560</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">576</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">656</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">672</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">704</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">720</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">736</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">768</ManagedObjectReference>

<ManagedObjectReference type="VirtualMachine">784</ManagedObjectReference>

Logout success

You should have a XML parser to retrieve MOR of each VM to get details of each VM i.e. name, configurations, etc etc.

0 Kudos
svustika
Contributor
Contributor

Thank You very much for your help.

0 Kudos
svustika
Contributor
Contributor

Hi,

When i execute the above code i am getting the below out put

soap_connect Successful

retrieve success

LOGIN success

success

Item: (null)

Type: xwXwF

Error 400 fault: SOAP-ENV:Client

"HTTP Error: 400 Bad Request"

Detail:

No. of Objects : 0

VM List: (null)

Logout success

Can you please suggest me what might be the problem?

0 Kudos
dsubram
Enthusiast
Enthusiast

You should enable HTTP protocol on the ESX server. VI SDK user guide contains how to enable HTTP protocol on ESX Server. By defauly only HTTPS protocol get enabled on the webserver.

0 Kudos