Using pyvmomi to set metadata on a VirtualMachine in vSphere

Do you need to set some kind of Key, Value info up on a VirtualMachine in vCenter that you can access from the API? I thought with 5.5 and the addition of this that there was going to be some kind of actual Matadata fields added to the vSphere API, but it seems that still hasnt happened, as this is incomplete and missing any way to actually use it. The good news is that since 4.0 there has been a way to add key value pairs to the vm.config.extraConfig. The key has to be a String, and the Value can be an object. I have used this to store all kinds of stuff from Strings to JSON and XML payloads and even base64 encoded files. I wrote a sample for the pyVmomi-community-samples project that uses the vm.config.extraConfig to store some key value pairs. You can get it here until it gets accepted by the project and merged into master.

Thinderhead Bug Release — The Python SDK for VMware vCloud Usage Meter

I ran into an issue the other day when non ascii characters were in the Customer name. I tracked down the issue and put out a bug fix release for that today. You can read more about the bug here. Coming up in the next couple of weeks for version 0.5 will be support for vCloud Director. To update to the latest version of thunderhead simply run:

pip install -U thunderhead

And this will update you from 0.4 to 0.4.1 If you have any questions or need any help please feel free to reach out to me.

Reset vCenter Alarms from red to green using yavijava the vijava fork

I recently added a patch to YAVIJAVA that allows you to reset an alarm status. William Lam has posted in the past about how to hack the perl sdk to add this functionality, so I thought it would be a good idea to add this functionality to YAVIJAVA. I have manually implemented this in Groovy and in python for pyVmomi so adding it to the primary library I use seemed logical. Im still doing a bit more re-work to YAVIJAVA but if you want to use that now you can check out a copy from GitHub and use the gradle build script to build a copy for your self.

Using this new functionality in YAVIJAVA from Groovy (which is how I do it) would look something like this:

ServiceInstance si = new ServiceInstance(new URL(""),"","", true)
Folder rootFolder = si.getRootFolder()
HostSystem hostSystem = rootFolder.getChildEntity()[0].hostFolder.childEntity[0]
AlarmState[] alarmState = hostSystem.triggeredAlarmState
Alarm foo = alarmState[0].alarm as Alarm
AlarmManager am = new AlarmManager(si.getServerConnection(), foo.getMOR())
am.setAlarmStatus(foo, hostSystem, "green")

I havent tested this yet so YMMV. Before I do the next official release of YAVIJAVA I will have tested it out and include a working sample.

Ignore SSL warnings in pyVmomi caused by requests

pyVmomi made a switch to using requests a while back where it used urllib2 in the past. One of the side effects of doing that was that when you connect to a vCenter or ESX/i HostSystem that has a self signed ssl cert (which is the default) you get a warning like:

>>> from pyVim.connect import SmartConnect
>>> si = SmartConnect(host='172.16.214.129', user='administrator@vsphere.local', pwd='password')
/Users/errr/venvs/pyVmomi/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py:730: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html (This warning will only appear once by default.)
  InsecureRequestWarning)

How can you disable that message though? Well thats pretty simple. Let me show you how to do it. Since as I mentioned above pyVmomi now uses requests we can disable this at the top of our script like so:

>>> from pyVim.connect import SmartConnect
>>> import requests
>>> requests.packages.urllib3.disable_warnings()
>>> si = SmartConnect(host='172.16.214.129', user='administrator@vsphere.local', pwd='password')
>>> 

As you can see I imported requests, then I set requests.packages.urllib3.disable_warnings() and that disabled the warning message for my script.

Using the Managed Object ID to create Objects with pyVmomi

I think this is a bad idea to do for several reasons, but I do understand the needs for doing it. Other pyVmomi developers think having to expose the Managed Object ID is bad and that having to expose it shouldn’t ever have to be done, but sometimes you just cant get away from needing it. One such instance would be if you are interacting with a vCloud Director and need to do something with a VirtualMachine, then you find you need to go to the vCenter where that VirtualMachine lives to do something else to it that is not supported from vCloud Director. vCloud Director will give you the ManagedObject Reference ID so how do you take that ID and start working with the actual object using pyVmomi? That question came up the other day in IRC but for another use case. The person who asked the question solved their own problem and left the solution. Ill show you the steps required to go from a ManagedObject Reference ID to the actual object you can work with. Please keep in mind accessing variables in python that begin with an underscore is bad, and anything bad that happens to your code because you decided to do this is your own fault. With that out of the way lets get to the code.

>>> from pyVim.connect import SmartConnect
>>> from pyVmomi import vim
>>> si = SmartConnect(host='10.12.254.137', user='administrator@vsphere.local', pwd='password')
>>> content = si.RetrieveContent()
>>> children = content.rootFolder.childEntity
>>> for child in children:
...   print child
... 
'vim.Datacenter:datacenter-33'
'vim.Datacenter:datacenter-2'
>>> children[0].name
'1000110'
>>> dc = vim.Datacenter('datacenter-33')
>>> dc._stub = si._stub
>>> dc.name
'1000110'

Lets talk about what just happened here. First I import some requirements and then I connect to the vCenter setting up a ServiceInstance (si). Next to show you what Datacenter objects I currently have in my inventory I get the content, then grab the rootFolder and the childEntity of the rootFolder which by default is the Datacenters. Next I simply loop through them printing the object it self so I can see the ManagedObject Reference ID which shows up as the ‘vim.Datacenter:datacenter-33′ where what I need is the ‘datacener-33′. The way its printed is ‘vmwareObjectType: managedObjectRefId’. Next I show you the value of children[0].name which will print the datacenter name for datacenter-33. As we see it has a value of 1000110. Now we are at the stage where I manually create a datacenter object using vim.Datacenter(‘datacecnter-33′) and assign it to dc. Next I do bad things by taking the _stub which is an instance of SoapStubAdapter from the ServiceInstance and assign it to the dc._stub This allows me to call the .name on the new object and prints its name. Thats all there is to it. Again I think doing this is really bad, and your code can break in all kinds of ways if _stub is ever changed on the back end, and it can with out notice which is why the syntax of _stub is used. Just because you can do something doesnt mean you should. Yay python and its slogan “We’re all consenting adults here”.

Using pyVmomi to set a note on a VirtualMachine

Have you ever noticed the “Notes” section when looking at the VirtualMachine view either from the web client or from the vi client? Its a handy little place to leave various bits of information. I like to use it to put in who built the VirtualMachine and when, and if it had a ticket number that I could tie it to.

vCenter Notes

Right now this VirtualMachine has no note set, and I want to set one using pyVmomi, but how do you do that? Well I made a sample that demonstrates how to do it. Lets walk though how to use this sample. First lets see what the options are:

± |master ✗| → python set_note.py -h
usage: set_note.py [-h] -s HOST [-o PORT] -u USER [-p PASSWORD] -j UUID -m
                   MESSAGE

Standard Arguments for talking to vCenter

optional arguments:
  -h, --help            show this help message and exit
  -s HOST, --host HOST  vSphere service to connect to
  -o PORT, --port PORT  Port to connect on
  -u USER, --user USER  User name to use when connecting to host
  -p PASSWORD, --password PASSWORD
                        Password to use when connecting to host
  -j UUID, --uuid UUID  UUID of the VirtualMachine you want to add a note to.
  -m MESSAGE, --message MESSAGE
                        Message to add to the notes field.

Like the last couple of samples I have covered this one takes the same basic options of Host, User, Password, and Port. This sample adds 2 new options though. The first is the -j or –uuid. What is the UUID though and why do you need it? The UUID is a unique identifier given to the VirtualMachine by the vCenter. This makes it a good choice to use for tracking the asset. If you are unsure of where to get the UUID you can use the vminfo_quick script from my previous post. The next option is the -m or –message. This option set the message that will be added to the Notes section. Lets give it a try and see how it works out.

± |master ✗| → python set_note.py -s 10.12.254.137 -u 'administrator@vsphere.local' -p password -j 421b3c9a-3aef-3662-c476-5b564d045c08 -m "Built by: Michael Rice"
Found: vCloud Director
Done.

Which leaves our vCenter with this:

updated vcenter

If you have any questions about this process please feel free to ask me and Ill try to help. Happy note setting!

pyVmomi on FreeBSD

I was looking around online and found someone has added pyVmomi to the FreeBSD ports. Here is how to use it:

root@fbsd-test01-pyvmomi:~ # pkg search pyvmomi
pyvmomi-5.5.0.2014.1.1

root@fbsd-test01-pyvmomi:~ # pkg install pyvmomi
Updating repository catalogue
New version of pkg detected; it needs to be installed first.
The following 1 packages will be installed:

        Upgrading pkg: 1.2.7_3 -> 1.3.8_2

The installation will require 1 MB more space

2 MB to be downloaded

Proceed with installing packages [y/N]: y
pkg-1.3.8_2.txz                                                                                                  100% 2264KB   2.2MB/s   2.2MB/s   00:01    
Checking integrity... done
[1/1] Upgrading pkg from 1.2.7_3 to 1.3.8_2... done
If you are upgrading from the old package format, first run:

  # pkg2ng
Updating FreeBSD repository catalogue...
pkg: Repo "FreeBSD" upgrade schema 2006 to 2007: Add conflicts and provides
pkg: Repo "FreeBSD" upgrade schema 2007 to 2008: Add FTS index
pkg: Repo "FreeBSD" upgrade schema 2008 to 2009: Optimize indicies
pkg: Repo "FreeBSD" upgrade schema 2009 to 2010: Add legacy digest field
FreeBSD repository is up-to-date.
All repositories are up-to-date.
Updating database digests format: 100%
The following 3 packages will be affected (of 0 checked):

New packages to be INSTALLED:
        pyvmomi: 5.5.0.2014.1.1
        py27-requests: 2.3.0
        py27-six: 1.8.0

The process will require 5 MB more space.
727 KB to be downloaded.

Proceed with this action? [y/N]: y
Fetching pyvmomi-5.5.0.2014.1.1.txz: 100%  264 KB 270.1k/s    00:01
Fetching py27-requests-2.3.0.txz: 100%  448 KB 459.0k/s    00:01
Fetching py27-six-1.8.0.txz: 100%   15 KB  15.3k/s    00:01
Checking integrity... done (0 conflicting)
[1/3] Installing py27-requests-2.3.0: 100%
[2/3] Installing py27-six-1.8.0: 100%
[3/3] Installing pyvmomi-5.5.0.2014.1.1: 100%

This added all the dependencies my system needed, and installed pyVmomi. Pretty simple. Now thats all done and we are ready to start running our pyVmomi code from FreeBSD.

If you arent sure where to start check out one of my other posts! Happy coding!

Using pyVmomi to create a cluster and a datacenter in vCenter

Have you ever wanted to automate creating a Datacenter or a Cluster in your vCenter using pyVmomi but didnt know where to start? I created a sample in the community samples project that does just that. It is pretty simple to use, and I will demonstrate that now.

First lets run the script with the -h argument to see what options it takes:

± |master ✗| → python make_dc_and_cluster.py -h
usage: make_dc_and_cluster.py [-h] -s HOST [-o PORT] -u USER [-p PASSWORD] -n
                              DCNAME -c CNAME

Standard Arguments for talking to vCenter

optional arguments:
  -h, --help            show this help message and exit
  -s HOST, --host HOST  vSphere service to connect to
  -o PORT, --port PORT  Port to connect on
  -u USER, --user USER  User name to use when connecting to host
  -p PASSWORD, --password PASSWORD
                        Password to use when connecting to host
  -n DCNAME, --dcname DCNAME
                        Name of the Datacenter to create.
  -c CNAME, --cname CNAME
                        Name to give the cluster to be created.

As we can see you will need to supply a HOST name (this can also be an IP), a PORT number (the default is 443), a USER to connect as, and a PASSWORD for that user. For this to work properly your user will need the following permissions in vCenter Host.Inventory.CreateCluster and Datacenter.Create. We also need to provide a DCNAME which is the name of the Datacenter we want to create, and finally a name for the new (empty) Cluster. This sample does the absolute minimum to create these objects in your inventory. If you want to customize any settings you will need to modify the code to provide your own ClusterConfigSpecEx. If one is not provided which is how the sample works it uses an empty spec which creates a Cluster using all default settings. Enough talk, lets run this and setup a new Datacenter and Cluster. Here is a screenshot of my inventory before we start:

vCenter ScreenShot

 |master ✗| → python make_dc_and_cluster.py -s 172.16.214.129 -u 'administrator@vsphere.local' -p password -n 111222333 -c '111222333 - Prod Cluster'

And here we have our new Datacenter and Cluster

vCenter after ScreenShot

using pyvmomi to get a list of all virtual machines — fast

Something that often comes up from various people new to using the vSphere API is how to get information very quickly about all the VirtualMachines in the inventory. There is a sample that comes with pyvmomi called getallvms.py which is an obvious place to start to get this info. When its run on an inventory that only has 30 VirtualMachines it seems pretty fast. It only takes about .5 seconds to complete. Try it on a larger inventory like something with 500+ VirtualMachines and it really starts to slow down going from .5 seconds all the way up to over 6 seconds. This number just keeps growing the larger the inventory gets. Once the inventory reaches over 1000 VirtualMachines it can take over 10 seconds for this info to be returned. In other words this solution just doesnt scale, but its often the only way new comers know. The good news is that VMware provides other ways to get this info. The bad news is that its not an obvious solution, and its kind of complicated to use, but thats what I am here for :)

Where I work we have over 45,000 vSphere powered Virtual Machines, and its my job as a Sr. Developer there to make sure our code is stream lined, efficient, and scales the way we do. This is why I use property collectors when I need to work with objects from the vSphere inventory. To help new users I provided a sample I call vminfo_quick which as its name implies get info about a VirtualMachine, quickly. To test this lets run the getallvms.py from above on a vCenter with 576 VirtualMachines and time it.


time python getallvms.py -s 10.12.254.119 -u 'administrator@vsphere.local' -p password

real 0m6.300s
user 0m2.476s
sys 0m0.123s

Almost 6 1/2 seconds. Thats not too bad right? Now lets run the vminfo_quick sample I provided against that same vCenter and see how it does. I included a counter and a timer in this sample so we dont have to run time.


python vminfo_quick.py -s 10.12.254.119 -u 'administrator@vsphere.local' -p password

Found 576 VirtualMachines.
Completion time: 0.368282 seconds.

As you can see using a property collector vastly improves performance. I have tested this on an inventory with 1500 VirtualMachines and it still finishes in just under 1 second. I plan to cover details around what the property collector is and how it works in future posts. Stay tuned!

pyvmomi now available in Fedora 19 20 and 21

Back in 2005 I got into making RPMs for Fedora, and by 2006 I became a sponsored packager. It was a hobby I really enjoyed, but back in 2009 or 2010 I just got too busy with work and had to pass the baton. About a month and a half ago I was looking for issues on the pyvmomi project that I could help close when I found this one asking for help making an RPM for Fedora. I got excited all over again about making RPMs so I made one and headed down the path to become sponsored again to package for Fedora. I created this bug report and became re-sponsored, and after a lengthy process I am happy to report that pyvmomi is now available in Fedora 19, 20, and 21. It is still in the testing phases for EPEL 6 and 7 but in another week or so should be available there as well. This puts us one step closer to being able to port the current OpenStack driver for vSphere to pyvmomi!

Be on the lookout for useless Information