2013-12-24 20:29:30 +01:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
'''
|
|
|
|
VMWARE external inventory script
|
|
|
|
=================================
|
|
|
|
|
|
|
|
shamelessly copied from existing inventory scripts.
|
|
|
|
|
|
|
|
This script and it's ini can be used more than once,
|
|
|
|
|
|
|
|
i.e vmware.py/vmware_colo.ini vmware_idf.py/vmware_idf.ini
|
|
|
|
(script can be link)
|
|
|
|
|
|
|
|
so if you don't have clustered vcenter but multiple esx machines or
|
|
|
|
just diff clusters you can have a inventory per each and automatically
|
|
|
|
group hosts based on file name or specify a group in the ini.
|
2014-07-15 02:15:35 +02:00
|
|
|
|
|
|
|
You can also use <SCRIPT_NAME>_HOST|USER|PASSWORD environment variables
|
|
|
|
to override the ini.
|
2013-12-24 20:29:30 +01:00
|
|
|
'''
|
|
|
|
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import time
|
|
|
|
import ConfigParser
|
|
|
|
from psphere.client import Client
|
|
|
|
from psphere.managedobjects import HostSystem
|
|
|
|
|
|
|
|
try:
|
|
|
|
import json
|
|
|
|
except ImportError:
|
|
|
|
import simplejson as json
|
|
|
|
|
|
|
|
|
|
|
|
def save_cache(cache_item, data, config):
|
|
|
|
''' saves item to cache '''
|
2014-07-15 02:15:35 +02:00
|
|
|
|
|
|
|
if config.has_option('cache', 'dir'):
|
|
|
|
dpath = os.path.expanduser(config.get('cache', 'dir'))
|
|
|
|
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
|
2013-12-24 20:29:30 +01:00
|
|
|
|
|
|
|
|
|
|
|
def get_cache(cache_item, config):
|
|
|
|
''' returns cached item '''
|
2014-07-15 02:15:35 +02:00
|
|
|
|
2013-12-24 20:29:30 +01:00
|
|
|
inv = {}
|
2014-07-15 02:15:35 +02:00
|
|
|
if config.has_option('cache', 'dir'):
|
|
|
|
dpath = os.path.expanduser(config.get('cache', 'dir'))
|
|
|
|
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
|
2013-12-24 20:29:30 +01:00
|
|
|
|
|
|
|
return inv
|
|
|
|
|
|
|
|
def cache_available(cache_item, config):
|
|
|
|
''' checks if we have a 'fresh' cache available for item requested '''
|
|
|
|
|
2014-07-15 02:15:35 +02:00
|
|
|
if config.has_option('cache', 'dir'):
|
|
|
|
dpath = os.path.expanduser(config.get('cache', 'dir'))
|
2013-12-24 20:29:30 +01:00
|
|
|
|
|
|
|
try:
|
2014-07-19 21:54:58 +02:00
|
|
|
existing = os.stat('/'.join([dpath,cache_item]))
|
2013-12-24 20:29:30 +01:00
|
|
|
except:
|
|
|
|
# cache doesn't exist or isn't accessible
|
|
|
|
return False
|
|
|
|
|
2014-07-15 02:15:35 +02:00
|
|
|
if config.has_option('cache', 'max_age'):
|
|
|
|
maxage = config.get('cache', 'max_age')
|
2014-07-19 21:54:58 +02:00
|
|
|
fileage = int( time.time() - existing.st_mtime )
|
|
|
|
if (maxage > fileage):
|
2013-12-24 20:29:30 +01:00
|
|
|
return True
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
def get_host_info(host):
|
|
|
|
''' Get variables about a specific host '''
|
|
|
|
|
|
|
|
hostinfo = {
|
2014-07-19 21:54:58 +02:00
|
|
|
'vmware_name' : host.name,
|
|
|
|
}
|
2013-12-24 20:29:30 +01:00
|
|
|
for k in host.capability.__dict__.keys():
|
|
|
|
if k.startswith('_'):
|
|
|
|
continue
|
|
|
|
try:
|
|
|
|
hostinfo['vmware_' + k] = str(host.capability[k])
|
|
|
|
except:
|
|
|
|
continue
|
|
|
|
|
|
|
|
return hostinfo
|
|
|
|
|
|
|
|
|
|
|
|
def get_inventory(client, config):
|
|
|
|
''' Reads the inventory from cache or vmware api '''
|
|
|
|
|
2014-07-15 02:15:35 +02:00
|
|
|
inv = {}
|
|
|
|
|
2013-12-24 20:29:30 +01:00
|
|
|
if cache_available('inventory', config):
|
|
|
|
inv = get_cache('inventory',config)
|
2014-07-15 02:15:35 +02:00
|
|
|
elif client:
|
2013-12-24 20:29:30 +01:00
|
|
|
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')
|
|
|
|
else:
|
|
|
|
hw_group = default_group + '_hw'
|
|
|
|
inv[hw_group] = []
|
|
|
|
|
|
|
|
if config.has_option('defaults','vm_group'):
|
|
|
|
vm_group = 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 vm in host.vm:
|
|
|
|
inv['all']['hosts'].append(vm.name)
|
|
|
|
inv[vm_group].append(vm.name)
|
2014-07-15 02:15:35 +02:00
|
|
|
inv['_meta']['hostvars'][vm.name] = get_host_info(vm)
|
2013-12-24 20:29:30 +01:00
|
|
|
save_cache(vm.name, inv['_meta']['hostvars'][vm.name], config)
|
|
|
|
|
2014-07-15 02:15:35 +02:00
|
|
|
save_cache('inventory', inv, config)
|
|
|
|
|
2013-12-24 20:29:30 +01:00
|
|
|
return json.dumps(inv)
|
|
|
|
|
|
|
|
def get_single_host(client, config, hostname):
|
|
|
|
|
|
|
|
inv = {}
|
|
|
|
if cache_available(hostname, config):
|
|
|
|
inv = get_cache(hostname,config)
|
2014-07-15 02:15:35 +02:00
|
|
|
elif client:
|
2013-12-24 20:29:30 +01:00
|
|
|
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:
|
2014-07-15 02:15:35 +02:00
|
|
|
inv = get_host_info(vm)
|
2013-12-24 20:29:30 +01:00
|
|
|
break
|
|
|
|
save_cache(hostname,inv,config)
|
|
|
|
|
|
|
|
return json.dumps(inv)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2014-07-15 02:15:35 +02:00
|
|
|
|
2013-12-24 20:29:30 +01:00
|
|
|
inventory = {}
|
|
|
|
hostname = None
|
|
|
|
|
|
|
|
if len(sys.argv) > 1:
|
|
|
|
if sys.argv[1] == "--host":
|
|
|
|
hostname = sys.argv[2]
|
|
|
|
|
|
|
|
# Read config
|
|
|
|
config = ConfigParser.SafeConfigParser()
|
2014-07-15 02:15:35 +02:00
|
|
|
me = os.path.abspath(sys.argv[0]).rstrip('.py')
|
|
|
|
for configfilename in [me + '.ini', 'vmware.ini']:
|
2013-12-24 20:29:30 +01:00
|
|
|
if os.path.exists(configfilename):
|
|
|
|
config.read(configfilename)
|
|
|
|
break
|
|
|
|
|
2014-07-15 02:15:35 +02:00
|
|
|
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')))
|
|
|
|
|
2013-12-24 20:29:30 +01:00
|
|
|
try:
|
2014-07-15 02:15:35 +02:00
|
|
|
client = Client( host,user,password )
|
2013-12-24 20:29:30 +01:00
|
|
|
except Exception, e:
|
|
|
|
client = None
|
|
|
|
#print >> STDERR "Unable to login (only cache avilable): %s", str(e)
|
|
|
|
|
2014-07-15 02:15:35 +02:00
|
|
|
# Actually do the work
|
2013-12-24 20:29:30 +01:00
|
|
|
if hostname is None:
|
|
|
|
inventory = get_inventory(client, config)
|
|
|
|
else:
|
|
|
|
inventory = get_single_host(client, config, hostname)
|
|
|
|
|
2014-07-15 02:15:35 +02:00
|
|
|
# Return to ansible
|
2013-12-24 20:29:30 +01:00
|
|
|
print inventory
|