VMware {code} Community
DVyas
Contributor
Contributor
Jump to solution

VMware vSphere Web Services API - Get Host/Cluster list

Hi,

How could I get all host(ESX/ESXi)/cluseter details from VMware vCenter Server?

I am newbie in developing such kind of VMware client application.

Suggest me way for developing such kind of application.

Thanks

D V

Tags (2)
1 Solution

Accepted Solutions
stumpr
Virtuoso
Virtuoso
Jump to solution

So you'll actually need a traversal spec for ComputeResource. This will also pick up your clustered hosts as well.

You'll need to add the following:

ns1__TraversalSpec ComputeResourceTraversalSpec;

ComputeResourceTraversalSelectionSpec.name = new string("ComputeResourceTraversalSpec");

ComputeResourceTraversalSpec.name = new string("ComputeResourceTraversalSpec");
ComputeResourceTraversalSpec.type = "ComputeResource";
ComputeResourceTraversalSpec.path = "host";
ComputeResourceTraversalSpec.skip = &xsd_true;

FolderTraversalSpec.selectSet.push_back(&ComputeResourceTraversalSelectionSpec);

ObjectSpec.selectSet.push_back(&ComputeResourceTraversalSpec);

That will let you traverse from folder to datacenter to folder to compute resource to hostsystem.

I tested it on my end to be sure and it works.

Reuben Stump | http://www.virtuin.com | @ReubenStump

View solution in original post

Reply
0 Kudos
9 Replies
admin
Immortal
Immortal
Jump to solution

You have to call RetrieveProperties API and use TraversalSpec to traverse through your inventory. Please refer attached C# sample for your reference on how to create a PropertyFilterSpec. This sample list Virtual Machines in a Datacenter under different Clusters. You may also refer PropertyCollector sample shipped along VI SDK.

DVyas
Contributor
Contributor
Jump to solution

Hi,

Thanks for your reply.

It was helpful.

Is it possible to use Visual C++ ( with vSphere web service API) for developing such application or I must use C#.

Reply
0 Kudos
admin
Immortal
Immortal
Jump to solution

VMware has exposed certain set of APIs in form of webServices to mange their Virtual infrastructure, known as VI APIs . These can be consumed by any programming language which is soap-compliant.

C# is one such language. VMware Infrastructure (VI) SDK is used to develop client applications that can manage, monitor, and control the life-cycle of virtual infrastructure using the VMware Infrastructure management components. It includes samples in both Java and C#.

So, you may consume the APIs using C++.

Reply
0 Kudos
DVyas
Contributor
Contributor
Jump to solution

Hi,

Finally I came up with working C++ code to get VM names from vCenter server.

Now I want to get hostSystem details, so I changed following code

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.all = &xsd_true;

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 )

{

cout << "Number of Objects " << RetrievePropertiesRes.returnval.size() << endl;

for (i=0; i < RetrievePropertiesRes.returnval.size(); i++)

{

cout << " Object Type: " << *RetrievePropertiesRes.returnval[0]->obj->type;

cout << " (" << RetrievePropertiesRes.returnval[i]->propSet.size() << " properties), ";

for (j=0; j < RetrievePropertiesRes.returnval[i]->propSet.size(); j++)

{

DynamicProperty = *RetrievePropertiesRes.returnval[i]->propSet[j];

if ( DynamicProperty.name == "name" )

{

name = (xsd__string *) DynamicProperty.val;

//cout << "Name = " << ((xsd__string *) DynamicProperty.val)->__item;

cout << "Name: " << name->__item;

}

}

cout << endl;

}

else

{

soap_print_fault(vim.soap, stderr);

}

To

FolderTraversalSelectionSpec.name = new string("FolderTraversalSpec");

DataCenterHostTraversalSelectionSpec.name = new string("DataCenterHostTraversalSpec");

DataCenterHostTraversalSpec.name = new string("DataCenterHostTraversalSpec");

DataCenterHostTraversalSpec.type = "Datacenter";

DataCenterHostTraversalSpec.path = "hostFolder";

DataCenterHostTraversalSpec.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 = "HostSystem";

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 )

{

cout << "Number of Objects " << RetrievePropertiesRes.returnval.size() << endl;

for (i=0; i < RetrievePropertiesRes.returnval.size(); i++)

{

cout << " Object Type: " << *RetrievePropertiesRes.returnval[0]->obj->type;

cout << " (" << RetrievePropertiesRes.returnval[i]->propSet.size() << " properties), ";

for (j=0; j < RetrievePropertiesRes.returnval[i]->propSet.size(); j++)

{

DynamicProperty = *RetrievePropertiesRes.returnval[i]->propSet[j];

if ( DynamicProperty.name == "name" )

{

name = (xsd__string *) DynamicProperty.val;

//cout << "Name = " << ((xsd__string *) DynamicProperty.val)->__item;

cout << "Name: " << name->__item;

}

}

cout << endl;

}

else

{

soap_print_fault(vim.soap, stderr);

}

But output gives Number of Objects 0.

Actually result should be Number of Objects 2, as there are 2 ESX managed by vCenter Server.

Thanks,

D V

Reply
0 Kudos
stumpr
Virtuoso
Virtuoso
Jump to solution

Without looking at it in too much detail, I think you also need a traversal spec for ComputeResource(s). Are your two hosts in an HA cluster?

Under your hostFolder you can have hosts, folders and computeResource entities. So without a traversal spec for computeResource(s) you probably won't see any hosts that are in a cluster.

Reuben Stump | http://www.virtuin.com | @ReubenStump
DVyas
Contributor
Contributor
Jump to solution

Hi,

I just have one datacenter. No cluster created.

Hierarachy is as follows.

-


datacenter1

---Host1

--VM1

--VMn

---Host2

--VM1

-- VMn

-


Thanks,

D V

Reply
0 Kudos
stumpr
Virtuoso
Virtuoso
Jump to solution

So you'll actually need a traversal spec for ComputeResource. This will also pick up your clustered hosts as well.

You'll need to add the following:

ns1__TraversalSpec ComputeResourceTraversalSpec;

ComputeResourceTraversalSelectionSpec.name = new string("ComputeResourceTraversalSpec");

ComputeResourceTraversalSpec.name = new string("ComputeResourceTraversalSpec");
ComputeResourceTraversalSpec.type = "ComputeResource";
ComputeResourceTraversalSpec.path = "host";
ComputeResourceTraversalSpec.skip = &xsd_true;

FolderTraversalSpec.selectSet.push_back(&ComputeResourceTraversalSelectionSpec);

ObjectSpec.selectSet.push_back(&ComputeResourceTraversalSpec);

That will let you traverse from folder to datacenter to folder to compute resource to hostsystem.

I tested it on my end to be sure and it works.

Reuben Stump | http://www.virtuin.com | @ReubenStump
Reply
0 Kudos
DVyas
Contributor
Contributor
Jump to solution

Hi,

Finally I got my program working to get both Host and VM List.

Thanks

Reply
0 Kudos
pk2006
Enthusiast
Enthusiast
Jump to solution

I am trying with following code - it still gives me 0 objects. i do have two ESX registered with vCenter server.

I am new to VMware API, Please let me know wht am i missing in this to host from the vCenter server?

ns2__TraversalSpec DataCenterHostTraversalSpec, FolderTraversalSpec, ComputeResourceTraversalSpec;

ns2__SelectionSpec DataCenterHostTraversalSelectionSpec, FolderTraversalSelectionSpec, ComputeResourceTraversalSelectionSpec;

ns2__PropertySpec PropertySpec;

ns2__ObjectSpec ObjectSpec;

ns2__PropertyFilterSpec PropertyFilterSpec;

ns2__DynamicProperty DynamicProperty;

ns2__RetrievePropertiesRequestType RetrievePropertiesReq;

ns2_RetrievePropertiesResponse RetrievePropertiesRes;

ns2__ManagedObjectReference* vm_mor = NULL;

bool xsd_true = 1;

bool xsd_false = 0;

FolderTraversalSelectionSpec.name = new string("FolderTraversalSpec");

DataCenterHostTraversalSelectionSpec.name = new string("DataCenterHostTraversalSpec");

DataCenterHostTraversalSpec.name = new string("DataCenterHostTraversalSpec");

DataCenterHostTraversalSpec.type = "Datacenter";

DataCenterHostTraversalSpec.path = "hostFolder";

DataCenterHostTraversalSpec.skip = &xsd_true;

FolderTraversalSpec.name = new string("FolderTraversalSpec");

FolderTraversalSpec.type = "Folder";

FolderTraversalSpec.path = "childEntity";

FolderTraversalSpec.skip = &xsd_true;

ComputeResourceTraversalSelectionSpec.name = new string("ComputeResourceTraversalSpec");

ComputeResourceTraversalSpec.name = new string("ComputeResourceTraversalSpec");

ComputeResourceTraversalSpec.type = "ComputeResource";

ComputeResourceTraversalSpec.path = "host";

ComputeResourceTraversalSpec.skip = &xsd_true;

DataCenterHostTraversalSpec.selectSet.push_back(&FolderTraversalSelectionSpec);

FolderTraversalSpec.selectSet.push_back(&DataCenterHostTraversalSelectionSpec);

FolderTraversalSpec.selectSet.push_back(&FolderTraversalSelectionSpec);

FolderTraversalSpec.selectSet.push_back(&ComputeResourceTraversalSelectionSpec);

PropertySpec.type = "HostSystem";

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(&DataCenterHostTraversalSpec);

ObjectSpec.selectSet.push_back(&ComputeResourceTraversalSpec);

PropertyFilterSpec.propSet.push_back(&PropertySpec);

PropertyFilterSpec.objectSet.push_back(&ObjectSpec);

RetrievePropertiesReq._USCOREthis = ServiceContent->propertyCollector;

RetrievePropertiesReq.specSet.push_back(&PropertyFilterSpec);

if (vim.__ns2__RetrieveProperties(&RetrievePropertiesReq, &RetrievePropertiesRes) == SOAP_OK)

{

cout << "Number of Objects " << RetrievePropertiesRes.returnval.size() << endl;

ns2__ObjectContent* oc = NULL;

ns2__DynamicProperty dynamicProperty;

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), ";

dynamicProperty = *RetrievePropertiesRes.returnval[i]->propSet[i];

xsd__string* name = (xsd__string*) dynamicProperty.val;

cout << name << endl;

}

}