Two More Jython Samples Managing VMware vSphere

Yesterday I posted an article introducing the virtual appliance Timo created last week. I am sure some of you have given it a try. I hope you liked it. If you haven’t done so, you can download it from Timo’s post.

The virtual appliance ships with only two samples. Definitely not enough. That is why the community needs to work together so that we can match the functionalities of vSphere PowerCLI.

Bothered by SLOW Web UI to manage vSphere? Want to manage ALL your VMware vCenters, AWS, Azure, Openstack, container behind a SINGLE pane of glass? Want to search, analyze, report, visualize VMs, hosts, networks, datastores, events as easily as Google the Web? Find out more about vSearch 3.0: the search engine for all your private and public clouds.

The following are two samples by David Rousseau who is an independent consultant living in Paris. Thanks for his permission to publish his code here. He owns the copyright of the code. If you want to use it, you can contact him or leave a message in this post.

  1. jython_rest.py: This code shows how to use the tiny Client REST API I created. Check out this article for more details of the API itself.
  2. jython_test.py: list all the hosts, resource pools, virtual machines and vApps that are found at the server.

To help you understand the code, I added a little comment before each file.

1. jython_rest.py: This code shows how to use the tiny Client REST API I created. Check out this blog for more details of the API itself.


# pre requisities: xml2dict.py and simplejson lib installed w/ jython
# test variables needed
# please change lines below according to your environment
# get MOB ids using <a href="http://%3cvirtualcenter_ip%3e/mob/">http://<virtualcenter_IP>/mob/</a>

VM_MOB_ID = 'vm-52'
VM_NEW_NAME = 'plop'
DC_MOB_ID = 'datacenter-21'
VIRTUALCENTER = '10.170.232.12'
USERNAME = 'username'
PASSWORD = 'password'

from java.io import StringReader
from java.util import Hashtable
from java.util import Map
from datetime import datetime
from javax.xml.xpath import XPath
from javax.xml.xpath import XPathFactory

from org.xml.sax import InputSource

from com.vmware.vim.rest import CachedManagedObject
from com.vmware.vim.rest import RestClient
from com.vmware.vim.rest import RestManagedObject

def main():
   
    rc = RestClient("<a href="https://%s">https://%s</a>" % VIRTUALCENTER, USERNAME, PASSWORD)
    runRestLevel(rc)
    runMOLevel(rc)
   

def runMOLevel(rc):
    si = RestManagedObject(rc, "ServiceInstance")
    print "name:" + si.getPropertyAsString("content.about.fullName")
    print si.invoke("currentTime")
    print si.invoke("retrieveContent")

    allXml = si.getAllProperties()
    print allXml
    csi = CachedManagedObject(allXml)
    print "name: " + csi.getProperty("content.about.fullName")
    searchIndex_id = si.getPropertyAsString("content.searchIndex")
    searchIndex = RestManagedObject(rc, searchIndex_id)
    print searchIndex.getPropertyAsString("FindByUuid")
    print "cap: " + si.getPropertyAsString("capability.multiHostSupported")
    print "Server clock: " + csi.getProperty("searchIndex.FindAllByUuid")
   
    vm = RestManagedObject(rc, VM_MOB_ID)
    print "reload: " + vm.invoke("reload")
    cvm = CachedManagedObject(vm.getAllProperties())
    print "Roles: " + cvm.getProperty("effectiveRole")

 
def runRestLevel(rc):
   
    contentXml = rc.get("moid=ServiceInstance&doPath=content")
    print contentXml
    print rc.get(None)
   
   
    # retrieve all VM's properties
    vm_properties = rc.get("?moid=%s" % VM_MOB_ID)
    print vm_properties
   
    # get a specific property from vm_properties
    xpath = XPathFactory.newInstance().newXPath()
    # for example retrieve VM name
    print xpath.evaluate("//name/text()", InputSource(StringReader(vm_properties)))
   
    # rename a VM
    para = Hashtable()
    para.put("newName", VM_NEW_NAME)
    print rc.post("moid=%s&method=rename" % VM_MOB_ID, para)

    # retrieve MksTicket for a given VM
    para1 = Hashtable()
    mks = rc.post("?moid=%s&method=acquireMksTicket" % VM_MOB_ID, para1)
    print "XML output"
    print mks
    print
   
    # let's transform this xml in something more readable / user friendly
    import xml2dict
    from xml.etree import ElementTree
    root = ElementTree.XML(mks)
    myDict = xml2dict.XmlDictConfig(root)
    print "python dict output"
    print myDict
    print
    from simplejson import dumps
    print "json output"
    print dumps(myDict)


if __name__ == '__main__':
     main()

2. jython_test.py: list all the hosts, resource pools, virtual machines and vApps that are found at the server.

from com.vmware.vim25 import *
from com.vmware.vim25.mo import *
from com.vmware.vim25.mo.util import *
from java.net import *
from java.util import Hashtable

def mor2mo(si, mor):
    """convert mor to mo
    take 2 arguments:
        si:  ServiceInstance used
        mor: managed object reference to convert to managed object
    return managed object (mo)
    """
    return MorUtil.createExactManagedEntity(si.getServerConnection(), mor)

def displayVM(si, vm):
    print "           %s %svCPU(s) %sMB %s %s" % (
        vm.name,
        vm.summary.config.numCpu,
        vm.summary.config.memorySizeMB,
        vm.runtime.powerState,
        vm.guest.toolsStatus,
        )
    displayNetwork(si, vm)
   
def displayNetwork(si, vm):
    print "               %s network(s): %s" % (
        len(vm.networks),
        ", ".join([net.name for net in vm.networks])
    )
   
def main():
    si = ServiceInstance(URL("<a href="https://10.170.232.12/sdk">https://10.170.232.12/sdk</a>"), "drousseau", "ecocenter", 1)
    rootFolder = si.getRootFolder()

    vms = InventoryNavigator(rootFolder).searchManagedEntities("VirtualMachine");
    hosts = InventoryNavigator(rootFolder).searchManagedEntities("HostSystem");
    pools = InventoryNavigator(rootFolder).searchManagedEntities("ResourcePool")
   
    allVapps = []
    if pools:
        for pool in pools:
            if isinstance(pool, VirtualApp):
                allVapps.append(pool)
    if allVapps:
        print "%s parent vApps found:" % (len(allVapps),)
        for vapp in allVapps:
            i = 0
            print "- %s" % (vapp.name,)
            if vapp.VMs:
                print "  %s VM(s):" % (len(vapp.VMs),)
                for vm in vapp.VMs:
                    i += 1
                    print "   # %s" % (vm.name)
            if vapp.resourcePools:
                print "  this vApp has %s nested vApp(s):" % (len(vapp.resourcePools),)
                for nested in vapp.resourcePools:
                    print "  * %s" % (nested.name,)
                    if nested.VMs:
                        print "   %s VM(s):" % (len(nested.VMs),)
                        for vm in nested.VMs:
                            i += 1
                            print "  # %s" % (vm.name)
            print "    total VM(s): %s" % (i,)
            print
    if pools:
        for curpool in pools:
            if isinstance(curpool, VirtualApp):
                print "vApp %s" % (curpool.name,)
                if curpool.VMs:
                    for vm in curpool.VMs:
                        displayVM(si, vm)
                        host = mor2mo(si, vm.runtime.host)       
                        print "               on host %s" % (host.name,)
                       
                if curpool.resourcePools:
                    for nested in curpool.resourcePools:
                        print "   %s" % (nested.name,)
                        for vm in nested.VMs:
                            displayVM(si, vm)
                            # convert mor to mo
                            host = mor2mo(si, vm.runtime.host)       
                            print "               on host %s" % (host.name,)           
           
                   
    if vms:
        for curvm in vms:
            if curvm.runtime.connectionState.toString() == "connected":
                host = curvm.runtime.host
                print "VM : [%s] | %s | %s | %svCPU(s) | %sMB | %s" % (
                    curvm.getName(),
                    curvm.runtime.powerState,
                    curvm.guest.toolsStatus,
                    curvm.summary.config.numCpu,
                    curvm.summary.config.memorySizeMB,
                    host.val # as an example, use mor2mo in order to retrieve host.name
                )
                print
    if hosts:
        for curhost in hosts:
            print "Host : %s %s" % (
                curhost.name,
                curhost.summary
            )
            print
    vms = InventoryNavigator(rootFolder).searchManagedEntities("VirtualMachine")
       
    if vms == None or len(vms) == 0:
        return
    vm = vms[0]
       
    print "retrieve a property from a single managed object."
    status = vm.getPropertyByPath("guest.toolsStatus")
    print "toolStatus:" + status.toString()
       
    print "\nretrieve multiple properties from a single managed object."
    props = vm.getPropertiesByPaths(["name",
                "config.cpuFeatureMask",
                "guest.toolsStatus",
                "guest.guestId"])
    print vm
    print props
       
    print "\nretrieve multiple properties from multiple managed objects."
    pTables = PropertyCollectorUtil.retrieveProperties(vms, "VirtualMachine",
                ["name",
                "config.cpuFeatureMask",
                "guest.toolsStatus",
                "guest.guestId"
                ])

    i=0
    for vm in vms:
        print vm
        print pTables[i].toString()
        i += 1
       
    si.getServerConnection().logout();
if __name__ == '__main__':
     main()

3. xml2dict.py: a utility used by the above two programs

# hacked by David Rousseau to ignore attributes nodes
# based on ElementTree, by default in Jython 2.5rc2

from xml.etree import ElementTree

class XmlListConfig(list):
    def __init__(self, aList):
        for element in aList:
            if element:
                # treat like dict
                if len(element) == 1 or element[0].tag != element[1].tag:
                    self.append(XmlDictConfig(element))
                # treat like list
                elif element[0].tag == element[1].tag:
                    self.append(XmlListConfig(element))
            elif element.text:
                text = element.text.strip()
                if text:
                    self.append(text)
class XmlDictConfig(dict):
    '''
    Example usage:

    >>> tree = ElementTree.parse('your_file.xml')
    >>> root = tree.getroot()
    >>> xmldict = XmlDictConfig(root)

    Or, if you want to use an XML string:

    >>> root = ElementTree.XML(xml_string)
    >>> xmldict = XmlDictConfig(root)

    And then use xmldict for what it is... a dict.
    '''
    def __init__(self, parent_element):
        if parent_element.items():
            self.update(dict(parent_element.items()))
        for element in parent_element:
            if element:
                # treat like dict - we assume that if the first two tags
                # in a series are different, then they are all different.
                if len(element) == 1 or element[0].tag != element[1].tag:
                    aDict = XmlDictConfig(element)
                # treat like list - we assume that if the first two tags
                # in a series are the same, then the rest are the same.
                else:
                    # here, we put the list in dictionary; the key is the
                    # tag name the list elements all share in common, and
                    # the value is the list itself
                    aDict = {element[0].tag: XmlListConfig(element)}
                # if the tag has attributes, add those to the dict
                if element.items():
                    aDict.update(dict(element.items()))
                self.update({element.tag: aDict})
            # this assumes that if you've got an attribute in a tag,
            # you won't be having any text. This may or may not be a
            # good idea -- time will tell. It works for the way we are
            # currently doing XML configuration files...
      # HACK by DR
            #elif element.items():
            #    self.update({element.tag: dict(element.items())})
            # finally, if there are no child tags and no attributes, extract
            # the text
            else:
                self.update({element.tag: element.text})

This entry was posted in vSphere API and tagged , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

2 Comments

  1. Paul
    Posted May 18, 2010 at 9:33 pm | Permalink

    Good article. Very useful. I’m working on a Java project, and would like to have more sample codes.

    I tried VMSnapshot.java; but found listSnapshots(vm) doesn’t quite work. The compiler complains about method undefined.

    Any idea?

    Thanks.

  2. Posted May 18, 2010 at 10:02 pm | Permalink

    Hi Paul,
    Glad you liked it.
    Did you use this one: http://vijava.svn.sourceforge.net/viewvc/vijava/trunk/src/com/vmware/vim25/mo/samples/vm/VMSnapshot.java?view=markup?
    What method did the compiler complain?
    -Steve

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

  • NEED HELP?


    My company has created products like vSearch ("Super vCenter"), vijavaNG APIs, EAM APIs, ICE tool. We also help clients with virtualization and cloud computing on customized development, training. Should you, or someone you know, need these products and services, please feel free to contact me: steve __AT__ doublecloud.org.

    Me: Steve Jin, VMware vExpert who authored the VMware VI and vSphere SDK by Prentice Hall, and created the de factor open source vSphere Java API while working at VMware engineering. Companies like Cisco, EMC, NetApp, HP, Dell, VMware, are among the users of the API and other tools I developed for their products, internal IT orchestration, and test automation.