Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I add tags to the just created virtual machine with pyvmomi? #307

Closed
stanislavhordiyenko opened this issue Nov 12, 2015 · 43 comments

Comments

@stanislavhordiyenko
Copy link

Hello all,

Spent almost whole day trying to find out how can I add tags to the just created virtual machine and all in vain. We use vSphere 6.0.0 at work. I tried to assign tags via vm.config.extraConfig, they were set successfully but are not available in Tags section of Summary tab.

Could you share a piece of code how can I achieve this.

Thank you. Look forward to hearing from you.

@michaelrice
Copy link
Contributor

@stanislavhordiyenko
Copy link
Author

Hi @michaelrice thanks for you response. I downloaded that library and it is a complete mess. First of all, there are too much code for such a small feature like assign a tag. Secondly, the issue with wsdl urls and where can I find them. It seems like it doesn't use pyvmomi library at all.

Are there any simpler solutions for this? Use direct REST API call?

@michaelrice
Copy link
Contributor

Sorry @stagor thats the only thing I know of. As for URLs and such you might dig through that code to see if you can find anything relevant in it.. I have never looked into that lib, but I would imagine it is auto generated code..

@aryaanand
Copy link

Hi @stagor sorry for asking a different question but I was looking for someone who has tried deploying ovf using pyvmomi on vsphere 6.0. I think you might have successfully executed it. I am facing this issue #322 Hope u won't mind helping me out. Thanks is advance.

@tianhao64
Copy link
Contributor

@stagor vCloud Suite Java SDK sdk has an example about tagging lifecycle. Check it out see if can you that: https://developercenter.vmware.com/web/sdk/60/vcloudsuite-java

@stanislavhordiyenko
Copy link
Author

Hi all, really I cannot understand why such things that supposed to be implemented so simple in reality are so complicated?? Unfortunately, this makes me frustrated and I would really avoid such products in future.

@sameertikoo
Copy link

Hi @stagor .I am also beating my head around to get this working.
Have you found a way to do this ?

@prziborowski
Copy link

Unfortunately, I don't think pyVmomi supports adding those tags.
You can add to the vim.vm.ConfigSpec#annotation (a slightly different panel in the UI).
Tags are stored in the Inventory Service, which is separate and I'm not sure if there are python bindings for it.

@tianhao64
Copy link
Contributor

Tagging is not supported by pyvmomi. It is supported by the vCloud Suite Python SDK. Refer to the doc for managing tagging workflows.

@stanislavhordiyenko
Copy link
Author

Hi @sameertikoo I decided to skip this functionality.

As to vCloud Suite Python SDK the way how to deal with tags is a nightmare. Does somebody can provide with an example how to add, modeify and delete tags? Cheers.

@tianhao64
Copy link
Contributor

@stagor Sorry to hear this. Could you elaborate the issue you are facing with vCloud Suite SDK? Your feedback is much welcomed. It will helps to improve the SDK and samples in future releases.

@tianhao64
Copy link
Contributor

vCloud Suite SDK is a newer feature with a different SDK to access features introduced in vSphere 6.0. The Tagging and Content Library features were introduced as part of this SDK and are implemented via vCloud Suite SDK only. In future releases you will see more features available via the vCloud Suite SDKs.

@stanislavhordiyenko
Copy link
Author

Hi @tianhao64, I do not want to. Libraries should simplify our interaction with a system not making it more complicated and cumbersome. It was not easy to catch up for me with pyvmomi, I pretty believe that the code could be more simpler and prettier, but vCloud Suite SDK library is a nightmare.

@tianhao64
Copy link
Contributor

Hi @stagor, current tagging and content library samples in vCloud Suite SDK are using lookup service and sso to login to vsphere. The wsdl files(inside the download package) are required because of that. We understand that login in through sso is not straight forward and is not related to the samples themselves, so we are refactoring the existing samples and new samples to use username/password login mode in 6.5 release. It will be much simpler and easier to use.

@stanislavhordiyenko
Copy link
Author

Hi @tianhao64 Awesome. When the new release is going to be available?? Cheers.

@stanislavhordiyenko
Copy link
Author

@tianhao64 is it possible meanwhile to get a code with username and password how to attach tags to the machine. Cheers.

@tianhao64
Copy link
Contributor

@stagor Yes. Let me convert the existing tagging sample and share it in the next couple of days.

@dav1x
Copy link

dav1x commented Jul 25, 2016

@tianhao64 I would also be interested in some examples as well.

@haiwu
Copy link

haiwu commented Aug 2, 2016

Would vSphere 5.5 be supported with that new release for vCloud Suite SDK? Or this tagging support is only for vSphere 6.0?

@belminf
Copy link

belminf commented Aug 12, 2016

Is there a technical reason why the tagging API is only available via pyvcloud and not this project?

Agree with @stagor's sentiment that having the functionality available in pyvmomi would be preferable since it has a more substantial community following and significantly better documentation (e.g., community examples and StackOverflow QAs).

Also, @tianhao64, can you please post a link to the non-SSO example? I'd like to take a look. TIA.

@btully
Copy link

btully commented Aug 16, 2016

I am also in agreement that pyvmomi should natively support tagging. In vCenter 6.0 my infrastructure admins are now forced to use tags over custom attributes which puts the developer community in a precarious situation. Requiring us to use pyvcloud for just tagging is going result in an expensive & messy code refactoring effort.

@stanislavhordiyenko
Copy link
Author

Hi @tianhao64 Any update on this?
Agree with @belminf it should be part of pyvmomi.

@tianhao64
Copy link
Contributor

Sorry for the delay. It's been pretty busy recently. I will try to post the non-SSO sample this week.

@schmiter
Copy link

schmiter commented Aug 19, 2016

You can manipulate tags using VMWare's DCLI (Datacenter CLI). You can use it by putting a vMA into your environment and running tag commands from there. To run the tag commands manually, you can simply ssh to the DCLI and run the commands, and I'm currently working on writing a Python script that runs the DCLI commands. It's a much better alternative to trying to swim through VMWare's SDK.

DCLI tag command docs: https://pubs.vmware.com/vsphere-60/index.jsp?topic=%2Fcom.vmware.dcli.cmdref.doc%2Fcom%2Fvmware%2Fcis%2Ftagging%2FTag.html

@tianhao64
Copy link
Contributor

tianhao64 commented Aug 21, 2016

Here is a sample to show how to create a Tag, a Tag Category and tag a Cluster/VM using basic auth(username/password). The sample skips the server certificate verification for simplicity sake which should be avoided in production code:

import ssl
import time

import requests
from com.vmware.cis.tagging_client import (
    Category, Tag, TagAssociation, CategoryModel)
from com.vmware.cis_client import Session
from com.vmware.vapi.std_client import DynamicID
from pyVim import connect
from pyVmomi import vim
from vmware.vapi.lib.connect import get_requests_connector
from vmware.vapi.security.session import create_session_security_context
from vmware.vapi.security.user_password import \
    create_user_password_security_context
from vmware.vapi.stdlib.client.factories import StubConfigurationFactory

server = '<server_ip>'
url = 'https://{}/api'.format(server)
username = '<username>'
password = '<password>'
category_name = 'sample category'
category_desc = 'sample category description'
tag_name = 'sample tag'
tag_desc = 'sample tag description'
cluster_name = 'cluster'
vm_name = 'vm1'


def create_tag_category(name, description, cardinality):
    """create a category. User who invokes this needs create category privilege."""
    create_spec = category_svc.CreateSpec()
    create_spec.name = name
    create_spec.description = description
    create_spec.cardinality = cardinality
    associableTypes = set()
    create_spec.associable_types = associableTypes
    return category_svc.create(create_spec)


def delete_tag_category(category_id):
    """Deletes an existing tag category; User who invokes this API needs
    delete privilege on the tag category.
    """
    category_svc.delete(category_id)


def create_tag(name, description, category_id):
    """Creates a Tag"""
    create_spec = tag_svc.CreateSpec()
    create_spec.name = name
    create_spec.description = description
    create_spec.category_id = category_id
    return tag_svc.create(create_spec)


def update_tag(tag_id, description):
    """Update the description of an existing tag.
    User who invokes this API needs edit privilege on the tag.
    """
    update_spec = tag_svc.UpdateSpec()
    update_spec.setDescription = description
    tag_svc.update(tag_id, update_spec)


def delete_tag(tag_id):
    """Delete an existing tag.
    User who invokes this API needs delete privilege on the tag."""
    tag_svc.delete(tag_id)


def get_cluster_id(name):
    """Find cluster id by given name using pyVmomi."""
    context = None
    if hasattr(ssl, '_create_unverified_context'):
        context = ssl._create_unverified_context()

    si = connect.Connect(host=server, user=username, pwd=password,
                         sslContext=context)
    content = si.content
    container = content.rootFolder
    viewType = [vim.ClusterComputeResource]
    recursive = True
    clusterView = content.viewManager.CreateContainerView(container,
                                                          viewType,
                                                          recursive)
    clusters = clusterView.view
    for cluster in clusters:
        if cluster.name == name:
            return cluster._GetMoId()
    raise Exception('Cluster with name {} could not be found'.format(name))


def get_vm_id(name):
    """Find vm id by given name using pyVmomi."""
    context = None
    if hasattr(ssl, '_create_unverified_context'):
        context = ssl._create_unverified_context()

    si = connect.Connect(host=server, user=username, pwd=password,
                         sslContext=context)
    content = si.content
    container = content.rootFolder
    viewType = [vim.VirtualMachine]
    recursive = True
    vmView = content.viewManager.CreateContainerView(container,
                                                     viewType,
                                                     recursive)
    vms = vmView.view
    for vm in vms:
        if vm.name == name:
            return vm._GetMoId()
    raise Exception('VM with name {} could not be found'.format(name))


"""
Create an authenticated stub configuration object that can be used to issue
requests against vCenter.
Returns a stub_config that stores the session identifier that can be used
to issue authenticated requests against vCenter.
"""
session = requests.Session()
session.verify = False
connector = get_requests_connector(session=session, url=url)
stub_config = StubConfigurationFactory.new_std_configuration(connector)

# Pass user credentials (user/password) in the security context to authenticate.
# login to vAPI endpoint
user_password_security_context = create_user_password_security_context(username,
                                                                       password)
stub_config.connector.set_security_context(user_password_security_context)

# Create the stub for the session service and login by creating a session.
session_svc = Session(stub_config)
session_id = session_svc.create()

# Successful authentication.  Store the session identifier in the security
# context of the stub and use that for all subsequent remote requests
session_security_context = create_session_security_context(session_id)
stub_config.connector.set_security_context(session_security_context)

# Create Tagging services
tag_svc = Tag(stub_config)
category_svc = Category(stub_config)
tag_association = TagAssociation(stub_config)

print('List all the existing categories user has access to...')
categories = category_svc.list()
if len(categories) > 0:
    for category in categories:
        print('Found Category: {0}'.format(category))
else:
    print('No Tag Category Found...')

print('List all the existing tags user has access to...')
tags = tag_svc.list()
if len(tags) > 0:
    for tag in tags:
        print('Found Tag: {0}'.format(tag))
else:
    print('No Tag Found...')

print('creating a new tag category...')
category_id = create_tag_category(category_name,
                                  category_desc,
                                  CategoryModel.Cardinality.MULTIPLE)
assert category_id is not None
print('Tag category created; Id: {0}'.format(category_id))

print("creating a new Tag...")
tag_id = create_tag(tag_name, tag_desc, category_id)
assert tag_id is not None
print('Tag created; Id: {0}'.format(tag_id))

print('updating the tag...')
date_time = time.strftime('%d/%m/%Y %H:%M:%S')
update_tag(tag_id, 'Server Tag updated at ' + date_time)
print('Tag updated; Id: {0}'.format(tag_id))

print('finding the cluster {0}'.format(cluster_name))
cluster_moid = get_cluster_id(cluster_name)
assert cluster_moid is not None
print('Found cluster:{0} mo_id:{1}'.format('vAPISDKCluster', cluster_moid))

print('finding the vm {0}'.format(vm_name))
vm_moid = get_vm_id(vm_name)
assert vm_moid is not None
print('Found vm:{0} mo_id:{1}'.format('vAPISDKVM', vm_moid))

print('Tagging the cluster {0}...'.format(cluster_name))
dynamic_id = DynamicID(type='ClusterComputeResource', id=cluster_moid)
tag_association.attach(tag_id=tag_id, object_id=dynamic_id)
for tag_id in tag_association.list_attached_tags(dynamic_id):
    if tag_id == tag_id:
        tag_attached = True
        break

assert tag_attached
print('Tagged cluster: {0}'.format(cluster_moid))

print('Tagging the vm {0}...'.format(vm_moid))
dynamic_id = DynamicID(type='VirtualMachine', id=vm_moid)
tag_association.attach(tag_id=tag_id, object_id=dynamic_id)
for tag_id in tag_association.list_attached_tags(dynamic_id):
    if tag_id == tag_id:
        tag_attached = True
        break

assert tag_attached
print('Tagged vm: {0}'.format(vm_moid))

@kippie538
Copy link

Hi @tianhao64 ,

Is there a way to get this working against vCenter 5.5?

Thanks in advanced

@tianhao64
Copy link
Contributor

@kippie538 I have not tried this code with 5.5 yet. Have you tried it out? Do you see any error?

@kippie538
Copy link

Hi @tianhao64 ,

Thanks for the repy.

I tested it against a 6.0 server and it worked perfect, then i changed the server to a 5.5 vCenter and i get this error:

session_id = session_svc.create()
File "/usr/lib/python2.7/site-packages/com/vmware/cis_client.py", line 188, in create
return self._invoke('create', None)
File "/usr/lib/python2.7/site-packages/vmware/vapi/bindings/stub.py", line 238, in _invoke
return self._api_interface.native_invoke(ctx, _method_name, kwargs)
File "/usr/lib/python2.7/site-packages/vmware/vapi/bindings/stub.py", line 169, in native_invoke
method_result = self.invoke(ctx, method_id, data_val)
File "/usr/lib/python2.7/site-packages/vmware/vapi/bindings/stub.py", line 134, in invoke
ctx)
File "/usr/lib/python2.7/site-packages/vmware/vapi/protocol/client/msg/json_connector.py", line 71, in invoke
response = self._do_request(VAPI_INVOKE, params)
File "/usr/lib/python2.7/site-packages/vmware/vapi/protocol/client/msg/json_connector.py", line 107, in _do_request
_, response_msg = self.rpc_provider.do_request(request_ctx, request_msg)
File "/usr/lib/python2.7/site-packages/vmware/vapi/protocol/client/rpc/requests_provider.py", line 90, in do_request
output.raise_for_status()
File "/usr/lib/python2.7/site-packages/requests/models.py", line 808, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request

@tianhao64
Copy link
Contributor

@kippie538, just realized the tagging API was introduced in 6.0. Although the feature was available since 5.1 through UI, the API was only available since 6.0. Sorry about the confusion.

@kippie538
Copy link

Ok, thanks. Then i can stop looking for it.

@jbilbro
Copy link

jbilbro commented Oct 12, 2016

To make sure I'm reading all of this right, pyvmomi still doesn't support creating tags for vCenter 6.0? Any ETA on getting it baked in? Is it possible to at least read tags?

@dav1x
Copy link

dav1x commented Oct 12, 2016

I believe you can only modify tags with the SOAP API and that is the difference between the python SDK and pyvmomi. Pyvmomi uses the REST API.

I'm told VMware is working on a new REST API with all of the functionality simplified.

@va1ha11a
Copy link

Hi,

I have an alternate version of the code tianhao64 posted above.
This may be more suite for some applications.

I have not tested it outside of my own use case so YMMV.

It does some dodgy under covers stuff to get the vm name in the helpers.py. If anyone can improve on this (or any part of it please let me know as this is going into production in my workplace soon.

Code Here

@robert4man
Copy link

Will this ever be possible with just pyvmomi or will it only ever be possible with the full SDK? I would like to see this capability added to Ansible, but I doubt that will be possible unless it can be done via pyvmomi.

@tianhao64
Copy link
Contributor

@robert4man Unfortunately there is no plan to add the tagging and other REST based APIs to pyvmomi at this point. All REST based API are supported via vSphere Automation SDK. It was open sourced a while ago. It supports basic authentication and it is much easier to use than the previous zipped version. Feel free to take a look: https://github.com/vmware/vsphere-automation-sdk-python. Feedbacks are highly welcomed.

@DashThink
Copy link

@tianhao64 Is there any way to attach tag to vm in java sdk. I was trying it from last 2-3 days and am not able to do it. Could please help me here.

@tianhao64
Copy link
Contributor

@DashThink
Copy link

@tianhao64 Thank you very much for quick response. From the above link I understood that how to create and delete tag. But I am still unclear about how can we assign this tag to VM?? This is the main question. Can you please share your views. Thanks

@balucio
Copy link

balucio commented Mar 3, 2018

Hi,
if you are interested I have written a wrapper for each SDK, https://github.com/balucio/vsphere_pylib.
For now this library can add or remove category and tag from VM and other few functions. I also written a few scripts that manage snapshot and create Ansible host and hosts_vars files from VM tags and category.

@gbhat618
Copy link

gbhat618 commented Nov 12, 2018

If I want to change the tag for the same category on a cluster, do I need to remove the tag first and then attach the latest tag?
Ex- Category - PriorityLevel
Tags - High, Low, Medium

to change the tag from High to Low or High to Medium.

@tianhao64
Copy link
Contributor

FYI, the above tagging sample can be found at the vSphere Automation Python SDK repo: https://github.com/vmware/vsphere-automation-sdk-python/blob/master/samples/vsphere/tagging/tagging_workflow.py

@InvisibleFunction
Copy link

FYI, the above tagging sample can be found at the vSphere Automation Python SDK repo: https://github.com/vmware/vsphere-automation-sdk-python/blob/master/samples/vsphere/tagging/tagging_workflow.py

That doesn't appear to show how to tag a vm, which is the subject of this issue?

@balucio
Copy link

balucio commented Oct 6, 2020

Hi,
I wrote a library in order to use tag in Vcenter.

https://github.com/balucio/vsphere_pylib

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests