#!/usr/bin/env python
# vsphere-vm-list --- display name of all known virtual machines

# Author: Noah Friedman <friedman@splode.com>
# Created: 2018-05-08
# Public domain

# $Id: vsphere-vm-list,v 1.11 2019/08/23 23:00:24 friedman Exp $

# Commentary:
# Code:

from   __future__ import print_function
from   pyVmomi    import vim
import vspherelib     as vsl

poweredOn  = vim.VirtualMachine.PowerState.poweredOn
poweredOff = vim.VirtualMachine.PowerState.poweredOff

def get_args():
    p = vsl.ArgumentParser( loadrc=True )
    p.add_bool( '-v', '--verbose',     help='Display extended info' )
    p.add_bool( '-n', '--on',          help='Display VMs which are powered on' )
    p.add_bool( '-f', '--off',         help='Display VMs which are powered off' )
    p.add_bool( '-t', '--templates',   help='Display templates' )
    p.add_bool( '-a', '--all',         help='Same as -o -f -t; default')
    p.add_bool( '-F', '--folders',     help='Display full path to VM' )
    p.add( 'pattern',  nargs='*',      help='Virtual machine names or patterns' )

    return p.parse()

def main():
    args = get_args()
    if args.all:
        args.on = args.off = args.templates = True
    elif args.on and args.off and args.templates:
        args.all = True
    elif not (args.on or args.off or args.templates):
        args.all = True

    proplist = [ 'name' ]
    if args.verbose or not args.all:
        proplist.extend( ('config.template', 'runtime.powerState') )
    if args.folders:
        proplist.append( 'parent' )

    vsi    = vsl.vmomiConnect( args )

    container = vsi.search_by_name( args.pattern ) if args.pattern else None
    vmlist = vsi.get_obj_props( [vim.VirtualMachine], proplist, root=container )

    if args.all:
        show = vmlist
    else:
        show = []
        for vm in vmlist:
            if ( (args.templates and vm[ 'config.template' ])
                 or (args.on  and vm[ 'runtime.powerState' ] == poweredOn)
                 or (args.off
                     and vm[ 'runtime.powerState' ] == poweredOff
                     and not vm[ 'config.template' ] )):
                show.append( vm )

    if args.folders:
        f2p = vsl.inverted_dict( vsi.path_to_subfolder_map( 'vm' ) )
        for vm in vmlist:
            try:
                vm[ 'name' ] = '/'.join( (f2p[ vm[ 'parent' ] ], vm[ 'name' ] ))
            except KeyError:
                pass

    if show:
        show.sort( lambda a, b: cmp( a[ 'name' ], b[ 'name' ]))
        if args.verbose:
            for vm in show:
                if vm[ 'config.template' ]:
                    flag = '+'
                elif vm[ 'runtime.powerState' ] == poweredOff:
                    flag = 'o'
                else:
                    flag = ' '
                print( flag, vm[ 'name' ] )
        else:
            for vm in show:
                print( vm[ 'name' ] )


if __name__ == '__main__':
    main()

# vsphere-vm-list ends here
