Efficient way to traverse vcenter inventory and retrieve properties

2k Views Asked by At

I'm using yavijava and am required to traverse a vCenter and build a list of all hosts and VMs on it. For each host and VM, I need to retrieve a few properties such as the name, amount of RAM/CPU etc. My current code looks like this:

ManagedEntity[] hosts = new InventoryNavigator.searchManagedEntities("VirtualMachine");
for(int i=0;i<hosts.length;i++) {
  String name = hosts[i].getName();
  String xxx = hosts[i].XXXXX;
.....

And so on for the VMs too.

My question is, is there a more efficient way to do this considering the fact that there are a significant number of objects and each call (such as getName) sends a new request to vSphere?

1

There are 1 best solutions below

4
On BEST ANSWER

You will want to build a property collector manually and depending on the inventory you will want to create an inventory system to relate the objects. I have a sample on github for clusters: https://github.com/yavijava/yavijava_cluster_prop_example

    RetrieveOptions options = new RetrieveOptions();
    options.setMaxObjects(100);
    String[] vmProps = new String[2];
    vmProps[0] = "name";
    vmProps[1] = "runtime.host";
    PropertySpec vmSpec = new PropertySpec();
    vmSpec.setAll(false);
    vmSpec.setType("VirtualMachine");
    vmSpec.setPathSet(vmProps);

    String[] hostProps = new String[4];
    hostProps[0] = "name";
    hostProps[1] = "summary.hardware.numCpuCores";
    hostProps[2] = "summary.hardware.cpuModel";
    hostProps[3] = "summary.hardware.memorySize";
    PropertySpec hostSpec = new PropertySpec();
    hostSpec.setAll(false);
    hostSpec.setType("HostSystem");
    hostSpec.setPathSet(hostProps);

    String[] clusterProps = new String[2];
    clusterProps[0] = "name";
    clusterProps[1] = "parent";
    PropertySpec clusterSpec = new PropertySpec();
    clusterSpec.setAll(false);
    clusterSpec.setType("ClusterComputeResource");
    clusterSpec.setPathSet(clusterProps);

    ObjectSpec oSpec = new ObjectSpec();
    oSpec.setObj(clusterMe.getMOR());
    oSpec.setSelectSet(com.vmware.vim25.mo.util.PropertyCollectorUtil.buildFullTraversalV4());
    PropertyFilterSpec[] pfSpec = new PropertyFilterSpec[1];
    pfSpec[0] = new PropertyFilterSpec();

    ObjectSpec[] oo = new ObjectSpec[1];
    oo[0] = oSpec;

    pfSpec[0].setObjectSet(oo);
    PropertySpec[] pp = new PropertySpec[3];
    pp[0] = vmSpec;
    pp[1] = hostSpec;
    pp[2] = clusterSpec;

    pfSpec[0].setPropSet(pp);
    RetrieveResult ret = serviceInstance.getPropertyCollector().retrievePropertiesEx(pfSpec, options);

    for (ObjectContent aRet : ret.getObjects()) {
        if(aRet.getObj().type.equalsIgnoreCase("ClusterComputeResource")) {
            printInfo(aRet);
        }
        if(aRet.getObj().type.equalsIgnoreCase("HostSystem")) {
            System.out.println("Host Info: ");
            printInfo(aRet);
            System.out.println("#######################");
        }
        if(aRet.getObj().type.equalsIgnoreCase("VirtualMachine")) {
            System.out.println("VirtualMachine: ");
            printInfo(aRet);
            System.out.println("#######################################");
        }
    }
}

private static void printInfo(ObjectContent objectContent) {
    // This is super generic here... To actually relate the objects so you
    // know which HostSystem a VirtualMachine lives on you need to implement
    // some kind of inventory system and use the MOR from the HostSystem
    // and the MOR from the vm.runtime.host
    for(DynamicProperty props: objectContent.getPropSet()) {
        System.out.println(props.val);
    }
}