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.
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.
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#.
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++.
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
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.
Hi,
I just have one datacenter. No cluster created.
Hierarachy is as follows.
-
datacenter1
---Host1
--VM1
--VMn
---Host2
--VM1
-- VMn
-
Thanks,
D V
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.
Hi,
Finally I got my program working to get both Host and VM List.
Thanks
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;
}
}