/plugins/inventory/vmware.py
https://github.com/ajanthanm/ansible · Python · 205 lines · 148 code · 39 blank · 18 comment · 47 complexity · 860c08373c5fe885e8ad8d73d044b025 MD5 · raw file
- #!/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