vsphere/vmware inventory plugin

Signed-off-by: Brian Coca <briancoca+ansible@gmail.com>
This commit is contained in:
Brian Coca 2013-12-24 14:29:30 -05:00
parent 36250c6b86
commit f3c2256554
2 changed files with 220 additions and 0 deletions

View file

@ -0,0 +1,15 @@
# Ansible vmware external inventory script settings
#
[defaults]
guests_only = True
#vm_group =
#hw_group =
[cache]
cache_max_age = 3600
cache_dir = /var/tmp
[auth]
host = vcenter.example.com
user = ihasaccess
password = ssshverysecret

205
plugins/inventory/vmware.py Executable file
View file

@ -0,0 +1,205 @@
#!/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.
'''
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 '''
dpath = config.get('defaults', 'cache_dir')
try:
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
def get_cache(cache_item, config):
''' returns cached item '''
dpath = config.get('defaults', 'cache_dir')
inv = {}
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('defaults', 'cache_dir'):
dpath = config.get('defaults', 'cache_dir')
try:
existing = os.stat( '/'.join([dpath,cache_item]))
except:
# cache doesn't exist or isn't accessible
return False
if config.has_option('defaults', 'cache_max_age'):
maxage = config.get('defaults', 'cache_max_age')
if (existing.st_mtime - int(time.time())) <= maxage:
return True
return False
def get_host_info(host):
''' Get variables about a specific host '''
hostinfo = {
'vmware_name' : host.name,
'vmware_tag' : host.tag,
'vmware_parent': host.parent.name,
}
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 '''
if cache_available('inventory', config):
inv = get_cache('inventory',config)
else:
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)
if host.tag:
taggroup = 'vmware_' + host.tag
if taggroup in inv:
inv[taggroup].append(host.name)
else:
inv[taggroup] = [ 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)
if vm.tag:
taggroup = 'vmware_' + vm.tag
if taggroup in inv:
inv[taggroup].append(vm.name)
else:
inv[taggroup] = [ vm.name ]
inv['_meta']['hostvars'][vm.name] = get_host_info(host)
save_cache(vm.name, inv['_meta']['hostvars'][vm.name], config)
save_cache('inventory', inv, config)
return json.dumps(inv)
def get_single_host(client, config, hostname):
inv = {}
if cache_available(hostname, config):
inv = get_cache(hostname,config)
else:
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(host)
break
save_cache(hostname,inv,config)
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()
for configfilename in [os.path.abspath(sys.argv[0]).rstrip('.py') + '.ini', 'vmware.ini']:
if os.path.exists(configfilename):
config.read(configfilename)
break
try:
client = Client( config.get('auth','host'),
config.get('auth','user'),
config.get('auth','password'),
)
except Exception, e:
client = None
#print >> STDERR "Unable to login (only cache avilable): %s", str(e)
# acitually 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