VMware Aria Automation Orchestrator

 View Only

 Checking for vCenter tag on host using vRO action/workflow script?

Mike Wilson's profile image
Mike Wilson posted Jan 10, 2025 12:53 PM

I am attempting to create a function within a action/workflow that will test a host record for existence of a vCenter tag.

I have the code that will retrieve the relevant host record but unable to successfully test it for a tag. 

I've reviewed the various discussions here and other areas but the code examples provided does not work (either now or how im doing it).

In this thread they mention how to do what I am trying: https://community.broadcom.com/vmware-cloud-foundation/discussion/find-vms-with-a-tag-and-perform-an-actions-for-each-one

I've also looked at: https://community.broadcom.com/vmware-cloud-foundation/discussion/add-tags-to-multiple-vms

Unfortunately the variable definitions produce "not defined" errors specific to the com_vmware_*. Such as:

var objId = new com_vmware_vapi_std_dynamic__ID();
var tagging = new com_vmware_cis_tagging_tag__association(client);
var tagMgr = new com_vmware_cis_tagging_tag(client);
var catMgr = new com_vmware_cis_tagging_category(client);

Do these no longer work? Can someone point me in the right direction? 

If it's relevant we are using vRA Version VMware 8.16.2.34725 (23505094)


WhiteForEver's profile image
WhiteForEver

Hi,

I think I have somewhere a similar code you need. Will try to take a look during the weekend. 

WhiteForEver's profile image
WhiteForEver

If you want to check whether a VM has a specific tag, you can use this code. Create an action element with 3 inputs written in the JDocs and return type "boolean". If VM has the tag, the function will return true.

Give it a try. If you will need any further assistance, let me know.

/**
 * @param {String} tagNameToMatch_in - Name of tag to match with VM
 * @param {VAPI:VAPIEndpoint} vapiEndpoint_in - VAPI endpoint
 * @param {VC:VirtualMachine} vm_in - Virtual machine object
 *
 * @return {boolean} isVMhasTag
 */
;
System.log('vAPI Endpoint: ' + vapiEndpoint_in.endpointUrl);
try {
    var client = vapiEndpoint_in.client();
}
catch (e) {
    throw 'Failed to initiate vAPI client session with the endpoint. ' + e;
}
var isVMhasTag = false;
System.log('Retrieving tag list...');
var tagging = new com_vmware_cis_tagging_tag__association(client);
// get all tags
var tagMgr = new com_vmware_cis_tagging_tag(client);
//Create object to hold VM
var objId = new com_vmware_vapi_std_dynamic__ID();
// assign VM data to object
objId.id = vm_in.id;
// assign VM data to object
objId.type = vm_in.vimType;
// get tags assigned to VM
var tagList = tagging.list_attached_tags(objId);
if (typeof tagList === 'object' && tagList.length > 0) {
    tagList.forEach(function (tagId) {
        var tagObject = tagMgr.get(tagId);
        if (tagObject.name == tagNameToMatch_in) {
            System.log('VM : ' + vm_in.name + ' has the tag : ' + tagNameToMatch_in);
            isVMhasTag = true;
        }
    });
}
try {
    client.close();
}
catch (e) {
    System.warn('Failed to close vAPI client session. ' + e);
}
return isVMhasTag;
Mike Wilson's profile image
Mike Wilson

Okay, it appears your method is what I was trying but I still receive the errors originally mentioned. I will try it as an action but I would be surprised that those options are only available there.


Here is my code, I wrote it as a workflow and use a variable "endpoint" to a VAPI:VAPIEndpoint.

This code has extra logging to try and get some data out to see where my issue what but as I said, all of those new com_vmaware* calls are giving "not defined" errors. 


var getAllSystemNames = function() {
    systemNames = [];
    var allVcenters = VcPlugin.getAllVimHosts();

    for (var i = 0; i < allVcenters.length; i++) {
        var vc = allVcenters[i];
        System.log("Processing " + vc.name);
        var datacenters = vc.getAllDatacenters();
        for (var j = 0; j < datacenters.length; j++) {
            var clusters = datacenters[j].hostFolder.childEntity;
            for (var k = 0; k < clusters.length; k++) {
                if ('host' in clusters[k]) {
                    var hosts = clusters[k].host;
                    for (var l = 0; l < hosts.length; l++) {
                        var host = hosts[l];
                        System.log('Checking vHost '+host.name);
                                var systems = host.vm;
                                for (var m = 0; m < systems.length; m++) {
                                    System.log('Checking host '+systems[m].name + ' with ID :'+systems[m].id);
                                    try {
                                        if (checkHostForTag(systems[m], "monitor", "true")) {
                                            systemNames.push(systems[m].name);
                                            System.log('Adding ' + systems[m].name + ' from host ' + host.name);
                                        }
                                    } catch (e) {
                                        System.error("Error processing host " + systems[m].name + ": " + e.toString());
                                    }

                                }
                    }
                }
            }
        }
    }
    return systemNames;
};

function checkHostForTag(host, expectedTagName, expectedValue) {
    System.log('checkHostForTag:'+host.name)
    // var endpoints = VAPIManager.getAllEndpoints();
    // var endpointTest = endpoints[0];
    if (endpoint) {
        var client = endpoint.client();
        if (client) {
            var objId = new com_vmware_vapi_std_dynamic__ID();
            objId.id = host.id;
            objId.type = host.vimType;

            var tagging = new com_vmware_cis_tagging_tag__association(client);
            var tagMgr = new com_vmware_cis_tagging_tag(client);
            var catMgr = new com_vmware_cis_tagging_category(client);
            var tagList = tagging.list_attached_tags(objId);
            for (var i = 0; i < tagList.length; i++) {
                var theTag = tagMgr.get(tagList[i]);
                System.log("Tag details="+JSON.stringify(theTag));
                System.log("Checking tag on " + host.name + ": " + theTag.name);
                if (theTag.name.toLowerCase() === expectedTagName.toLowerCase() && theTag.description === expectedValue) {
                    return true;
                }
            }
        } else {
            System.warn('No client object for host.')
        }
    } else {
        System.warn('No endpoint defined.')
    }
    return false;
}

getAllSystemNames();
WhiteForEver's profile image
WhiteForEver

Ok. So... Method `getAllVimHosts` doesn't exists in API. Was exists, but doesn't supported for a long time. If you want to get all VMs, you can use `VcPlugin.getAllVirtualMachines()`, which accepts filters BTW.

Not related - looping through array of array of array is a most not optimal way to do that :). Take a look on XPATH, which accepts filters as well.

PS. Did you configure VAPI endpoint in vRO? If not, there is a workflow called `Add vAPI endpoint`. Please run it. Please make sure you can see VAPI endpoint in the inventory.

Mike Wilson's profile image
Mike Wilson

Well, for what its worth the getAllVimHosts() does pull down all the vHosts and I get all the hosts from those.

I can certainly look at the other method but the method I use does return the correct record "host" as best I can tell (VcVirtualMachine) that is used to test for tags.


Regarding the endpoint question, yes I have run the endpoint add workflow you mentioned. I also tested that record and also looked at the endpoint.name to confirm it was as I expected.

I will do some testing with getAllVirtualMachines() and see if that changes anything.

Mike Wilson's profile image
Mike Wilson

So I remembered why I was not using getAllVirtualMachines(). It doesn't cross vCenters. I have however used findAllForType() which does and also returns just the VMs.

Here is my latest code but still gives the original error.

const allSystemsList = Server.findAllForType("VC:VirtualMachine");
if (allSystemsList.length > 0) {
    var nonTagSystemsList = [];
    var taggedSystemsList = [];

    var endpoints = VAPIManager.getAllEndpoints();
    var endpoint = endpoints[0];
    var client = endpoint.client();
    var tagNameToMatch_in = 'monitor';

    System.log('Endpoint = ' + endpoint.name);
    allSystemsList.forEach(function (host) {
        System.log('Checking Host : '+ host.name);
        try {
            var tagging = new com_vmware_cis_tagging_tag__association(client);
            // get all tags
            var tagMgr = new com_vmware_cis_tagging_tag(client);
            //Create object to hold VM
            var objId = new com_vmware_vapi_std_dynamic__ID();
            // assign VM data to object
            objId.id = host.id;
            // assign VM data to object
            objId.type = host.vimType;
            // get tags assigned to VM
            var tagList = tagging.list_attached_tags(objId);
            if (typeof tagList === 'object' && tagList.length > 0) {
                tagList.forEach(function (tagId) {
                    var tagObject = tagMgr.get(tagId);
                    if (tagObject.name == tagNameToMatch_in) {
                        System.log('VM : ' + host.name + ' has the tag : ' + tagNameToMatch_in);
                        taggedSystemsList.push(host);
                    } else {
                        nonTagSystemsList.push(host);
                    }
                });
            }
        } catch(err) {
            System.warn('Error in catch '+err);
        }
    });
    client.close();
    nonTagSystemsList.forEach(function (host) {
        System.log('Systems NOT tagged = '+ host.name);
    });
} else {
    System.warn(' No host records found???')
}
WhiteForEver's profile image
WhiteForEver

Is that possible you can provide an exact full error log where the "undefined" is mentioned?

Mike Wilson's profile image
Mike Wilson

Absolutely.  This is generated using the "latest code" from above in an action.

2025-01-14 09:24:04.228 -06:00 warning([REDACTED]library.actions/getAllVMHosts_TEST) Error in catch ReferenceError: "com_vmware_cis_tagging_tag__association" is not defined.

This is repeated for every single VM found. I can re-order the com_vmware_cis* variable definitions but then whatever is on top will generate the same error.

WhiteForEver's profile image
WhiteForEver

Thank you.

Can you please confirm the user, which was used to configure VAPI endpoint has enough permissions in vCenter? Can you try with administrator@vsphere.local in some test vCenter maybe?

Mike Wilson's profile image
Mike Wilson

The endpoint was created with a specific account with administrative permissions (we use for other things as well the do work).

I confirmed that user has Administrative perms on vCenter from top down for a test and ran it once more with same issue.

I've tested also with the administrator@vsphere.local user created endpoint https://host.name.com/  (I had removed the other so I was sure we only had the one) with the same results.

WhiteForEver's profile image
WhiteForEver

I took your code and checked on 3 different vROs. All is working. The only thing I can think about is either to reinstall the vAPI plugin (can be downloaded, removed and installed or update to the latest vAPI plugin 7.6.0.24140713. If will not help, maybe contact the support.

Sorry I cannot be more useful :)

Brandon Saxe's profile image
Broadcom Employee Brandon Saxe

Run the 'Import vAPI metamodel' workflow and then try your code again.

WhiteForEver's profile image
WhiteForEver

Yes, double-checking metadata is a good idea. I initially thought it was part of verifying the vAPI endpoint, but I might have been mistaken. 🙂. Thank you.

Mike Wilson's profile image
Mike Wilson

I wasnt aware of the metamodel portion and when I attempted to run the mentioned workflow I received a thumprint (cert) error I will attempt to resolve and follow up once that is resolved. Thanks for the suggestion, I hope this leads to a resolution.