Get VM tags using pyvmomi in vSphere 6.5

I am trying to filter VMs with a Python3 script by using pyvmomi.

Environment:

Versions:
vSphere: 6.5
Python: 3.7.7
pyvmomi: 6.5

At this very moment this is the code I bet for:

    si = SmartConnectNoSSL(
        host=config['host'],
        user=config['username'],
        pwd=password,
        port=int(config['port']),
    )
    # disconnect vc
    atexit.register(Disconnect, si)

    content = si.RetrieveContent()
    obj_view = content.viewManager.CreateContainerView(
        content.rootFolder, [vim.VirtualMachine], True)
    vms_list = obj_view.view
    obj_view.Destroy()
    for vm in vms_list:
        print(vm.name)
        print(vm.tag)

Presumably, vm.tag should return an array of all vim.Tag objects. Nonetheless, all the arrays are empty but the following one:

vCenter 6.5                                                                                                         
(vim.Tag) [                                                                                                         
   (vim.Tag) {                                                                                                      
      dynamicType = <unset>,                                                                                        
      dynamicProperty = (vmodl.DynamicProperty) [],                                                                 
      key = 'SYSTEM/COM.VMWARE.VIM.VC'                                                                              
   }                                                                                                                
]

After going through all VMs in the cluster, this is the only machine that is apparently having a tag. Btw, I already created a few tags and assigned them to some VMs as a test. But still, pyvmomi is not retrieving the tags from the VMs.

How can this be possible? Am I missing any detail?

Upvotes: 1

Views: 4613

Answers (1)

em2er
em2er

Reputation: 881

It is sad, but

A tag association is not stored with its object and is not a part of the object's lifecycle.

However, as @sky_jokerxx said, you may use vSphere Automation SDK for Python. The following code demonstrates obtaining tag names and their categories for all virtual machines in vCenter:

from vmware.vapi.vsphere.client import create_vsphere_client

client = create_vsphere_client(
    server='my-company-vcenter.com',
    username='my_login',
    password='my_password',
    session=None)

cat_dict = {}
for id in client.tagging.Category.list():
    cat = client.tagging.Category.get(id)
    cat_dict[cat.id] = cat.name

tag_dict = {}
for id in client.tagging.Tag.list():
    tag = client.tagging.Tag.get(id)
    tag_dict[id] = tag

vms = client.vcenter.VM.list()
vm_objs = [{'id': v.vm, 'type': 'VirtualMachine'} for v in vms]

vm_tags = {}
for vm in client.tagging.TagAssociation.list_attached_tags_on_objects(vm_objs):
    cat_tag_dict = {}
    for ti in vm.tag_ids:
        cat_name = cat_dict[tag_dict[ti].category_id]
        if cat_name not in cat_tag_dict:
            cat_tag_dict[cat_name] = []
        cat_tag_dict[cat_name].append(tag_dict[ti].name)
    vm_tags[vm.object_id.id] = cat_tag_dict

vm_tags contains Dict{vm.id: Dict{category_name: List[tag_name]}} as a result, for example we have 2 VMs with following category=tags accordingly:

  • vm-30116: TEAM=backend, BACKUP=daily, BACKUP=weekly
  • vm-31423: TEAM=frontend

Your vm_tags will look like:

"vm-30116": 
{
  "TEAM": ["backend"],
  "BACKUP": ["daily", "weekly"]
}, 
"vm-31423": 
{
  "TEAM": ["frontend"],
}

Also, you can use pure REST API. Full example can be found here.

Upvotes: 3

Related Questions