mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Merge pull request #10212 from cchurch/vmware_inventory_improvements
VMware inventory script updates from Tower.
This commit is contained in:
commit
bbe19f8ed2
2 changed files with 409 additions and 166 deletions
|
@ -1,15 +1,39 @@
|
|||
# Ansible vmware external inventory script settings
|
||||
#
|
||||
[defaults]
|
||||
guests_only = True
|
||||
#vm_group =
|
||||
#hw_group =
|
||||
# Ansible VMware external inventory script settings
|
||||
|
||||
[cache]
|
||||
max_age = 3600
|
||||
dir = ~/.cache/ansible
|
||||
[defaults]
|
||||
|
||||
# If true (the default), return only guest VMs. If false, also return host
|
||||
# systems in the results.
|
||||
guests_only = True
|
||||
|
||||
# Specify an alternate group name for guest VMs. If not defined, defaults to
|
||||
# the basename of the inventory script + "_vm", e.g. "vmware_vm".
|
||||
#vm_group = vm_group_name
|
||||
|
||||
# Specify an alternate group name for host systems when guests_only=false.
|
||||
# If not defined, defaults to the basename of the inventory script + "_hw",
|
||||
# e.g. "vmware_hw".
|
||||
#hw_group = hw_group_name
|
||||
|
||||
# Specify the number of seconds to use the inventory cache before it is
|
||||
# considered stale. If not defined, defaults to 0 seconds.
|
||||
#cache_max_age = 3600
|
||||
|
||||
# Specify the directory used for storing the inventory cache. If not defined,
|
||||
# caching will be disabled.
|
||||
#cache_dir = ~/.cache/ansible
|
||||
|
||||
[auth]
|
||||
|
||||
# Specify hostname or IP address of vCenter/ESXi server. A port may be
|
||||
# included with the hostname, e.g.: vcenter.example.com:8443. This setting
|
||||
# may also be defined via the VMWARE_HOST environment variable.
|
||||
host = vcenter.example.com
|
||||
|
||||
# Specify a username to access the vCenter host. This setting may also be
|
||||
# defined with the VMWARE_USER environment variable.
|
||||
user = ihasaccess
|
||||
|
||||
# Specify a password to access the vCenter host. This setting may also be
|
||||
# defined with the VMWARE_PASSWORD environment variable.
|
||||
password = ssshverysecret
|
||||
|
|
|
@ -1,205 +1,424 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
VMWARE external inventory script
|
||||
=================================
|
||||
VMware Inventory Script
|
||||
=======================
|
||||
|
||||
shamelessly copied from existing inventory scripts.
|
||||
Retrieve information about virtual machines from a vCenter server or
|
||||
standalone ESX host. When `group_by=false` (in the INI file), host systems
|
||||
are also returned in addition to VMs.
|
||||
|
||||
This script and it's ini can be used more than once,
|
||||
This script will attempt to read configuration from an INI file with the same
|
||||
base filename if present, or `vmware.ini` if not. It is possible to create
|
||||
symlinks to the inventory script to support multiple configurations, e.g.:
|
||||
|
||||
i.e. vmware.py/vmware_colo.ini vmware_idf.py/vmware_idf.ini
|
||||
(script can be link)
|
||||
* `vmware.py` (this script)
|
||||
* `vmware.ini` (default configuration, will be read by `vmware.py`)
|
||||
* `vmware_test.py` (symlink to `vmware.py`)
|
||||
* `vmware_test.ini` (test configuration, will be read by `vmware_test.py`)
|
||||
* `vmware_other.py` (symlink to `vmware.py`, will read `vmware.ini` since no
|
||||
`vmware_other.ini` exists)
|
||||
|
||||
so if you don't have clustered vcenter but multiple esx machines or
|
||||
just diff clusters you can have an inventory per each and automatically
|
||||
group hosts based on file name or specify a group in the ini.
|
||||
The path to an INI file may also be specified via the `VMWARE_INI` environment
|
||||
variable, in which case the filename matching rules above will not apply.
|
||||
|
||||
You can also use <SCRIPT_NAME>_HOST|USER|PASSWORD environment variables
|
||||
to override the ini.
|
||||
Host and authentication parameters may be specified via the `VMWARE_HOST`,
|
||||
`VMWARE_USER` and `VMWARE_PASSWORD` environment variables; these options will
|
||||
take precedence over options present in the INI file. An INI file is not
|
||||
required if these options are specified using environment variables.
|
||||
'''
|
||||
|
||||
import collections
|
||||
import json
|
||||
import logging
|
||||
import optparse
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import ConfigParser
|
||||
from psphere.client import Client
|
||||
from psphere.managedobjects import HostSystem
|
||||
|
||||
# Disable logging message trigged by pSphere/suds.
|
||||
try:
|
||||
import json
|
||||
from logging import NullHandler
|
||||
except ImportError:
|
||||
import simplejson as json
|
||||
from logging import Handler
|
||||
class NullHandler(Handler):
|
||||
def emit(self, record):
|
||||
pass
|
||||
logging.getLogger('psphere').addHandler(NullHandler())
|
||||
logging.getLogger('suds').addHandler(NullHandler())
|
||||
|
||||
from psphere.client import Client
|
||||
from psphere.errors import ObjectNotFoundError
|
||||
from psphere.managedobjects import HostSystem, VirtualMachine, ManagedObject, Network
|
||||
from suds.sudsobject import Object as SudsObject
|
||||
|
||||
|
||||
def save_cache(cache_item, data, config):
|
||||
''' saves item to cache '''
|
||||
class VMwareInventory(object):
|
||||
|
||||
if config.has_option('cache', 'dir'):
|
||||
dpath = os.path.expanduser(config.get('cache', 'dir'))
|
||||
def __init__(self, guests_only=None):
|
||||
self.config = ConfigParser.SafeConfigParser()
|
||||
if os.environ.get('VMWARE_INI', ''):
|
||||
config_files = [os.environ['VMWARE_INI']]
|
||||
else:
|
||||
config_files = [os.path.abspath(sys.argv[0]).rstrip('.py') + '.ini', 'vmware.ini']
|
||||
for config_file in config_files:
|
||||
if os.path.exists(config_file):
|
||||
self.config.read(config_file)
|
||||
break
|
||||
|
||||
# Retrieve only guest VMs, or include host systems?
|
||||
if guests_only is not None:
|
||||
self.guests_only = guests_only
|
||||
elif self.config.has_option('defaults', 'guests_only'):
|
||||
self.guests_only = self.config.getboolean('defaults', 'guests_only')
|
||||
else:
|
||||
self.guests_only = True
|
||||
|
||||
# Read authentication information from VMware environment variables
|
||||
# (if set), otherwise from INI file.
|
||||
auth_host = os.environ.get('VMWARE_HOST')
|
||||
if not auth_host and self.config.has_option('auth', 'host'):
|
||||
auth_host = self.config.get('auth', 'host')
|
||||
auth_user = os.environ.get('VMWARE_USER')
|
||||
if not auth_user and self.config.has_option('auth', 'user'):
|
||||
auth_user = self.config.get('auth', 'user')
|
||||
auth_password = os.environ.get('VMWARE_PASSWORD')
|
||||
if not auth_password and self.config.has_option('auth', 'password'):
|
||||
auth_password = self.config.get('auth', 'password')
|
||||
|
||||
# Create the VMware client connection.
|
||||
self.client = Client(auth_host, auth_user, auth_password)
|
||||
|
||||
def _put_cache(self, name, value):
|
||||
'''
|
||||
Saves the value to cache with the name given.
|
||||
'''
|
||||
if self.config.has_option('defaults', 'cache_dir'):
|
||||
cache_dir = self.config.get('defaults', 'cache_dir')
|
||||
if not os.path.exists(cache_dir):
|
||||
os.makedirs(cache_dir)
|
||||
cache_file = os.path.join(cache_dir, name)
|
||||
with open(cache_file, 'w') as cache:
|
||||
json.dump(value, cache)
|
||||
|
||||
def _get_cache(self, name, default=None):
|
||||
'''
|
||||
Retrieves the value from cache for the given name.
|
||||
'''
|
||||
if self.config.has_option('defaults', 'cache_dir'):
|
||||
cache_dir = self.config.get('defaults', 'cache_dir')
|
||||
cache_file = os.path.join(cache_dir, name)
|
||||
if os.path.exists(cache_file):
|
||||
if self.config.has_option('defaults', 'cache_max_age'):
|
||||
cache_max_age = self.config.getint('defaults', 'cache_max_age')
|
||||
else:
|
||||
cache_max_age = 0
|
||||
cache_stat = os.stat(cache_file)
|
||||
if (cache_stat.st_mtime + cache_max_age) < time.time():
|
||||
with open(cache_file) as cache:
|
||||
return json.load(cache)
|
||||
return default
|
||||
|
||||
def _flatten_dict(self, d, parent_key='', sep='_'):
|
||||
'''
|
||||
Flatten nested dicts by combining keys with a separator. Lists with
|
||||
only string items are included as is; any other lists are discarded.
|
||||
'''
|
||||
items = []
|
||||
for k, v in d.items():
|
||||
if k.startswith('_'):
|
||||
continue
|
||||
new_key = parent_key + sep + k if parent_key else k
|
||||
if isinstance(v, collections.MutableMapping):
|
||||
items.extend(self._flatten_dict(v, new_key, sep).items())
|
||||
elif isinstance(v, (list, tuple)):
|
||||
if all([isinstance(x, basestring) for x in v]):
|
||||
items.append((new_key, v))
|
||||
else:
|
||||
items.append((new_key, v))
|
||||
return dict(items)
|
||||
|
||||
def _get_obj_info(self, obj, depth=99, seen=None):
|
||||
'''
|
||||
Recursively build a data structure for the given pSphere object (depth
|
||||
only applies to ManagedObject instances).
|
||||
'''
|
||||
seen = seen or set()
|
||||
if isinstance(obj, ManagedObject):
|
||||
try:
|
||||
obj_unicode = unicode(getattr(obj, 'name'))
|
||||
except AttributeError:
|
||||
obj_unicode = ()
|
||||
if obj in seen:
|
||||
return obj_unicode
|
||||
seen.add(obj)
|
||||
if depth <= 0:
|
||||
return obj_unicode
|
||||
d = {}
|
||||
for attr in dir(obj):
|
||||
if attr.startswith('_'):
|
||||
continue
|
||||
try:
|
||||
val = getattr(obj, attr)
|
||||
obj_info = self._get_obj_info(val, depth - 1, seen)
|
||||
if obj_info != ():
|
||||
d[attr] = obj_info
|
||||
except Exception, e:
|
||||
pass
|
||||
return d
|
||||
elif isinstance(obj, SudsObject):
|
||||
d = {}
|
||||
for key, val in iter(obj):
|
||||
obj_info = self._get_obj_info(val, depth, seen)
|
||||
if obj_info != ():
|
||||
d[key] = obj_info
|
||||
return d
|
||||
elif isinstance(obj, (list, tuple)):
|
||||
l = []
|
||||
for val in iter(obj):
|
||||
obj_info = self._get_obj_info(val, depth, seen)
|
||||
if obj_info != ():
|
||||
l.append(obj_info)
|
||||
return l
|
||||
elif isinstance(obj, (type(None), bool, int, long, float, basestring)):
|
||||
return obj
|
||||
else:
|
||||
return ()
|
||||
|
||||
def _get_host_info(self, host, prefix='vmware'):
|
||||
'''
|
||||
Return a flattened dict with info about the given host system.
|
||||
'''
|
||||
host_info = {
|
||||
'name': host.name,
|
||||
}
|
||||
for attr in ('datastore', 'network', 'vm'):
|
||||
try:
|
||||
value = getattr(host, attr)
|
||||
host_info['%ss' % attr] = self._get_obj_info(value, depth=0)
|
||||
except AttributeError:
|
||||
host_info['%ss' % attr] = []
|
||||
for k, v in self._get_obj_info(host.summary, depth=0).items():
|
||||
if isinstance(v, collections.MutableMapping):
|
||||
for k2, v2 in v.items():
|
||||
host_info[k2] = v2
|
||||
elif k != 'host':
|
||||
host_info[k] = v
|
||||
try:
|
||||
if not os.path.exists(dpath):
|
||||
os.makedirs(dpath)
|
||||
if os.path.isdir(dpath):
|
||||
cache = open('/'.join([dpath,cache_item]), 'w')
|
||||
cache.write(json.dumps(data))
|
||||
cache.close()
|
||||
except IOError, e:
|
||||
pass # not really sure what to do here
|
||||
host_info['ipAddress'] = host.config.network.vnic[0].spec.ip.ipAddress
|
||||
except Exception, e:
|
||||
print >> sys.stderr, e
|
||||
host_info = self._flatten_dict(host_info, prefix)
|
||||
if ('%s_ipAddress' % prefix) in host_info:
|
||||
host_info['ansible_ssh_host'] = host_info['%s_ipAddress' % prefix]
|
||||
return host_info
|
||||
|
||||
|
||||
def get_cache(cache_item, config):
|
||||
''' returns cached item '''
|
||||
|
||||
inv = {}
|
||||
if config.has_option('cache', 'dir'):
|
||||
dpath = os.path.expanduser(config.get('cache', 'dir'))
|
||||
def _get_vm_info(self, vm, prefix='vmware'):
|
||||
'''
|
||||
Return a flattened dict with info about the given virtual machine.
|
||||
'''
|
||||
vm_info = {
|
||||
'name': vm.name,
|
||||
}
|
||||
for attr in ('datastore', 'network'):
|
||||
try:
|
||||
value = getattr(vm, attr)
|
||||
vm_info['%ss' % attr] = self._get_obj_info(value, depth=0)
|
||||
except AttributeError:
|
||||
vm_info['%ss' % attr] = []
|
||||
try:
|
||||
cache = open('/'.join([dpath,cache_item]), 'r')
|
||||
inv = json.loads(cache.read())
|
||||
cache.close()
|
||||
except IOError, e:
|
||||
pass # not really sure what to do here
|
||||
|
||||
return inv
|
||||
|
||||
def cache_available(cache_item, config):
|
||||
''' checks if we have a 'fresh' cache available for item requested '''
|
||||
|
||||
if config.has_option('cache', 'dir'):
|
||||
dpath = os.path.expanduser(config.get('cache', 'dir'))
|
||||
|
||||
vm_info['resourcePool'] = self._get_obj_info(vm.resourcePool, depth=0)
|
||||
except AttributeError:
|
||||
vm_info['resourcePool'] = ''
|
||||
try:
|
||||
existing = os.stat('/'.join([dpath,cache_item]))
|
||||
except:
|
||||
# cache doesn't exist or isn't accessible
|
||||
return False
|
||||
vm_info['guestState'] = vm.guest.guestState
|
||||
except AttributeError:
|
||||
vm_info['guestState'] = ''
|
||||
for k, v in self._get_obj_info(vm.summary, depth=0).items():
|
||||
if isinstance(v, collections.MutableMapping):
|
||||
for k2, v2 in v.items():
|
||||
if k2 == 'host':
|
||||
k2 = 'hostSystem'
|
||||
vm_info[k2] = v2
|
||||
elif k != 'vm':
|
||||
vm_info[k] = v
|
||||
vm_info = self._flatten_dict(vm_info, prefix)
|
||||
if ('%s_ipAddress' % prefix) in vm_info:
|
||||
vm_info['ansible_ssh_host'] = vm_info['%s_ipAddress' % prefix]
|
||||
return vm_info
|
||||
|
||||
if config.has_option('cache', 'max_age'):
|
||||
maxage = config.get('cache', 'max_age')
|
||||
fileage = int( time.time() - existing.st_mtime )
|
||||
if (maxage > fileage):
|
||||
return True
|
||||
def _add_host(self, inv, parent_group, host_name):
|
||||
'''
|
||||
Add the host to the parent group in the given inventory.
|
||||
'''
|
||||
p_group = inv.setdefault(parent_group, [])
|
||||
if isinstance(p_group, dict):
|
||||
group_hosts = p_group.setdefault('hosts', [])
|
||||
else:
|
||||
group_hosts = p_group
|
||||
if host_name not in group_hosts:
|
||||
group_hosts.append(host_name)
|
||||
|
||||
return False
|
||||
def _add_child(self, inv, parent_group, child_group):
|
||||
'''
|
||||
Add a child group to a parent group in the given inventory.
|
||||
'''
|
||||
if parent_group != 'all':
|
||||
p_group = inv.setdefault(parent_group, {})
|
||||
if not isinstance(p_group, dict):
|
||||
inv[parent_group] = {'hosts': p_group}
|
||||
p_group = inv[parent_group]
|
||||
group_children = p_group.setdefault('children', [])
|
||||
if child_group not in group_children:
|
||||
group_children.append(child_group)
|
||||
inv.setdefault(child_group, [])
|
||||
|
||||
def get_host_info(host):
|
||||
''' Get variables about a specific host '''
|
||||
def get_inventory(self, meta_hostvars=True):
|
||||
'''
|
||||
Reads the inventory from cache or VMware API via pSphere.
|
||||
'''
|
||||
# Use different cache names for guests only vs. all hosts.
|
||||
if self.guests_only:
|
||||
cache_name = '__inventory_guests__'
|
||||
else:
|
||||
cache_name = '__inventory_all__'
|
||||
|
||||
hostinfo = {
|
||||
'vmware_name' : host.name,
|
||||
}
|
||||
for k in host.capability.__dict__.keys():
|
||||
if k.startswith('_'):
|
||||
continue
|
||||
try:
|
||||
hostinfo['vmware_' + k] = str(host.capability[k])
|
||||
except:
|
||||
continue
|
||||
inv = self._get_cache(cache_name, None)
|
||||
if inv is not None:
|
||||
return inv
|
||||
|
||||
return hostinfo
|
||||
inv = {'all': {'hosts': []}}
|
||||
if meta_hostvars:
|
||||
inv['_meta'] = {'hostvars': {}}
|
||||
|
||||
|
||||
def get_inventory(client, config):
|
||||
''' Reads the inventory from cache or vmware api '''
|
||||
|
||||
inv = {}
|
||||
|
||||
if cache_available('inventory', config):
|
||||
inv = get_cache('inventory',config)
|
||||
elif client:
|
||||
inv= { 'all': {'hosts': []}, '_meta': { 'hostvars': {} } }
|
||||
default_group = os.path.basename(sys.argv[0]).rstrip('.py')
|
||||
|
||||
if config.has_option('defaults', 'guests_only'):
|
||||
guests_only = config.get('defaults', 'guests_only')
|
||||
else:
|
||||
guests_only = True
|
||||
|
||||
if not guests_only:
|
||||
if config.has_option('defaults','hw_group'):
|
||||
hw_group = config.get('defaults','hw_group')
|
||||
if not self.guests_only:
|
||||
if self.config.has_option('defaults', 'hw_group'):
|
||||
hw_group = self.config.get('defaults', 'hw_group')
|
||||
else:
|
||||
hw_group = default_group + '_hw'
|
||||
inv[hw_group] = []
|
||||
|
||||
if config.has_option('defaults','vm_group'):
|
||||
vm_group = config.get('defaults','vm_group')
|
||||
if self.config.has_option('defaults', 'vm_group'):
|
||||
vm_group = self.config.get('defaults', 'vm_group')
|
||||
else:
|
||||
vm_group = default_group + '_vm'
|
||||
inv[vm_group] = []
|
||||
|
||||
# Loop through physical hosts:
|
||||
hosts = HostSystem.all(client)
|
||||
for host in hosts:
|
||||
if not guests_only:
|
||||
inv['all']['hosts'].append(host.name)
|
||||
inv[hw_group].append(host.name)
|
||||
inv['_meta']['hostvars'][host.name] = get_host_info(host)
|
||||
save_cache(vm.name, inv['_meta']['hostvars'][host.name], config)
|
||||
for host in HostSystem.all(self.client):
|
||||
|
||||
if not self.guests_only:
|
||||
self._add_host(inv, 'all', host.name)
|
||||
self._add_host(inv, hw_group, host.name)
|
||||
host_info = self._get_host_info(host)
|
||||
if meta_hostvars:
|
||||
inv['_meta']['hostvars'][host.name] = host_info
|
||||
self._put_cache(host.name, host_info)
|
||||
|
||||
# Loop through all VMs on physical host.
|
||||
for vm in host.vm:
|
||||
inv['all']['hosts'].append(vm.name)
|
||||
inv[vm_group].append(vm.name)
|
||||
inv['_meta']['hostvars'][vm.name] = get_host_info(vm)
|
||||
save_cache(vm.name, inv['_meta']['hostvars'][vm.name], config)
|
||||
self._add_host(inv, 'all', vm.name)
|
||||
self._add_host(inv, vm_group, vm.name)
|
||||
vm_info = self._get_vm_info(vm)
|
||||
if meta_hostvars:
|
||||
inv['_meta']['hostvars'][vm.name] = vm_info
|
||||
self._put_cache(vm.name, vm_info)
|
||||
|
||||
save_cache('inventory', inv, config)
|
||||
# Group by resource pool.
|
||||
vm_resourcePool = vm_info.get('vmware_resourcePool', None)
|
||||
if vm_resourcePool:
|
||||
self._add_child(inv, vm_group, 'resource_pools')
|
||||
self._add_child(inv, 'resource_pools', vm_resourcePool)
|
||||
self._add_host(inv, vm_resourcePool, vm.name)
|
||||
|
||||
return json.dumps(inv)
|
||||
# Group by datastore.
|
||||
for vm_datastore in vm_info.get('vmware_datastores', []):
|
||||
self._add_child(inv, vm_group, 'datastores')
|
||||
self._add_child(inv, 'datastores', vm_datastore)
|
||||
self._add_host(inv, vm_datastore, vm.name)
|
||||
|
||||
def get_single_host(client, config, hostname):
|
||||
# Group by network.
|
||||
for vm_network in vm_info.get('vmware_networks', []):
|
||||
self._add_child(inv, vm_group, 'networks')
|
||||
self._add_child(inv, 'networks', vm_network)
|
||||
self._add_host(inv, vm_network, vm.name)
|
||||
|
||||
inv = {}
|
||||
if cache_available(hostname, config):
|
||||
inv = get_cache(hostname,config)
|
||||
elif client:
|
||||
hosts = HostSystem.all(client) #TODO: figure out single host getter
|
||||
for host in hosts:
|
||||
if hostname == host.name:
|
||||
inv = get_host_info(host)
|
||||
break
|
||||
for vm in host.vm:
|
||||
if hostname == vm.name:
|
||||
inv = get_host_info(vm)
|
||||
break
|
||||
save_cache(hostname,inv,config)
|
||||
# Group by guest OS.
|
||||
vm_guestId = vm_info.get('vmware_guestId', None)
|
||||
if vm_guestId:
|
||||
self._add_child(inv, vm_group, 'guests')
|
||||
self._add_child(inv, 'guests', vm_guestId)
|
||||
self._add_host(inv, vm_guestId, vm.name)
|
||||
|
||||
# Group all VM templates.
|
||||
vm_template = vm_info.get('vmware_template', False)
|
||||
if vm_template:
|
||||
self._add_child(inv, vm_group, 'templates')
|
||||
self._add_host(inv, 'templates', vm.name)
|
||||
|
||||
self._put_cache(cache_name, inv)
|
||||
return inv
|
||||
|
||||
def get_host(self, hostname):
|
||||
'''
|
||||
Read info about a specific host or VM from cache or VMware API.
|
||||
'''
|
||||
inv = self._get_cache(hostname, None)
|
||||
if inv is not None:
|
||||
return inv
|
||||
|
||||
if not self.guests_only:
|
||||
try:
|
||||
host = HostSystem.get(self.client, name=hostname)
|
||||
inv = self._get_host_info(host)
|
||||
except ObjectNotFoundError:
|
||||
pass
|
||||
|
||||
if inv is None:
|
||||
try:
|
||||
vm = VirtualMachine.get(self.client, name=hostname)
|
||||
inv = self._get_vm_info(vm)
|
||||
except ObjectNotFoundError:
|
||||
pass
|
||||
|
||||
if inv is not None:
|
||||
self._put_cache(hostname, inv)
|
||||
return inv or {}
|
||||
|
||||
|
||||
def main():
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option('--list', action='store_true', dest='list',
|
||||
default=False, help='Output inventory groups and hosts')
|
||||
parser.add_option('--host', dest='host', default=None, metavar='HOST',
|
||||
help='Output variables only for the given hostname')
|
||||
# Additional options for use when running the script standalone, but never
|
||||
# used by Ansible.
|
||||
parser.add_option('--pretty', action='store_true', dest='pretty',
|
||||
default=False, help='Output nicely-formatted JSON')
|
||||
parser.add_option('--include-host-systems', action='store_true',
|
||||
dest='include_host_systems', default=False,
|
||||
help='Include host systems in addition to VMs')
|
||||
parser.add_option('--no-meta-hostvars', action='store_false',
|
||||
dest='meta_hostvars', default=True,
|
||||
help='Exclude [\'_meta\'][\'hostvars\'] with --list')
|
||||
options, args = parser.parse_args()
|
||||
|
||||
if options.include_host_systems:
|
||||
vmware_inventory = VMwareInventory(guests_only=False)
|
||||
else:
|
||||
vmware_inventory = VMwareInventory()
|
||||
if options.host is not None:
|
||||
inventory = vmware_inventory.get_host(options.host)
|
||||
else:
|
||||
inventory = vmware_inventory.get_inventory(options.meta_hostvars)
|
||||
|
||||
json_kwargs = {}
|
||||
if options.pretty:
|
||||
json_kwargs.update({'indent': 4, 'sort_keys': True})
|
||||
json.dump(inventory, sys.stdout, **json_kwargs)
|
||||
|
||||
return json.dumps(inv)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
inventory = {}
|
||||
hostname = None
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
if sys.argv[1] == "--host":
|
||||
hostname = sys.argv[2]
|
||||
|
||||
# Read config
|
||||
config = ConfigParser.SafeConfigParser()
|
||||
me = os.path.abspath(sys.argv[0]).rstrip('.py')
|
||||
for configfilename in [me + '.ini', 'vmware.ini']:
|
||||
if os.path.exists(configfilename):
|
||||
config.read(configfilename)
|
||||
break
|
||||
|
||||
mename = os.path.basename(me).upper()
|
||||
host = os.getenv('VMWARE_' + mename + '_HOST',os.getenv('VMWARE_HOST', config.get('auth','host')))
|
||||
user = os.getenv('VMWARE_' + mename + '_USER', os.getenv('VMWARE_USER', config.get('auth','user')))
|
||||
password = os.getenv('VMWARE_' + mename + '_PASSWORD',os.getenv('VMWARE_PASSWORD', config.get('auth','password')))
|
||||
|
||||
try:
|
||||
client = Client( host,user,password )
|
||||
except Exception, e:
|
||||
client = None
|
||||
#print >> STDERR "Unable to login (only cache available): %s", str(e)
|
||||
|
||||
# Actually do the work
|
||||
if hostname is None:
|
||||
inventory = get_inventory(client, config)
|
||||
else:
|
||||
inventory = get_single_host(client, config, hostname)
|
||||
|
||||
# Return to ansible
|
||||
print inventory
|
||||
main()
|
||||
|
|
Loading…
Reference in a new issue