PageRenderTime 26ms CodeModel.GetById 9ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

/plugins/inventory/vmware.py

https://github.com/ajanthanm/ansible
Python | 205 lines | 195 code | 2 blank | 8 comment | 2 complexity | 860c08373c5fe885e8ad8d73d044b025 MD5 | raw file
  1#!/usr/bin/env python
  2# -*- coding: utf-8 -*-
  3'''
  4VMWARE external inventory script
  5=================================
  6
  7shamelessly copied from existing inventory scripts.
  8
  9This script and it's ini can be used more than once,
 10
 11i.e vmware.py/vmware_colo.ini vmware_idf.py/vmware_idf.ini
 12(script can be link)
 13
 14so if you don't have clustered vcenter  but multiple esx machines or
 15just diff clusters you can have a inventory  per each and automatically
 16group hosts based on file name or specify a group in the ini.
 17'''
 18
 19import os
 20import sys
 21import time
 22import ConfigParser
 23from psphere.client import Client
 24from psphere.managedobjects import HostSystem
 25
 26try:
 27    import json
 28except ImportError:
 29    import simplejson as json
 30
 31
 32def save_cache(cache_item, data, config):
 33    ''' saves item to cache '''
 34    dpath = config.get('defaults', 'cache_dir')
 35    try:
 36        cache = open('/'.join([dpath,cache_item]), 'w')
 37        cache.write(json.dumps(data))
 38        cache.close()
 39    except IOError, e:
 40        pass # not really sure what to do here
 41
 42
 43def get_cache(cache_item, config):
 44    ''' returns cached item  '''
 45    dpath = config.get('defaults', 'cache_dir')
 46    inv = {}
 47    try:
 48        cache = open('/'.join([dpath,cache_item]), 'r')
 49        inv = json.loads(cache.read())
 50        cache.close()
 51    except IOError, e:
 52        pass # not really sure what to do here
 53
 54    return inv
 55
 56def cache_available(cache_item, config):
 57    ''' checks if we have a 'fresh' cache available for item requested '''
 58
 59    if config.has_option('defaults', 'cache_dir'):
 60        dpath = config.get('defaults', 'cache_dir')
 61
 62        try:
 63            existing = os.stat( '/'.join([dpath,cache_item]))
 64        except:
 65            # cache doesn't exist or isn't accessible
 66            return False
 67
 68        if config.has_option('defaults', 'cache_max_age'):
 69            maxage = config.get('defaults', 'cache_max_age')
 70
 71            if (existing.st_mtime - int(time.time())) <= maxage:
 72                return True
 73
 74    return False
 75
 76def get_host_info(host):
 77    ''' Get variables about a specific host '''
 78
 79    hostinfo = {
 80                'vmware_name' : host.name,
 81                'vmware_tag' : host.tag,
 82                'vmware_parent': host.parent.name,
 83               }
 84    for k in host.capability.__dict__.keys():
 85        if k.startswith('_'):
 86           continue
 87        try:
 88            hostinfo['vmware_' + k] = str(host.capability[k])
 89        except:
 90           continue
 91
 92    return hostinfo
 93
 94
 95def get_inventory(client, config):
 96    ''' Reads the inventory from cache or vmware api '''
 97
 98    if cache_available('inventory', config):
 99        inv = get_cache('inventory',config)
100    else:
101        inv= { 'all': {'hosts': []}, '_meta': { 'hostvars': {} } }
102        default_group = os.path.basename(sys.argv[0]).rstrip('.py')
103
104        if config.has_option('defaults', 'guests_only'):
105            guests_only = config.get('defaults', 'guests_only')
106        else:
107            guests_only = True
108
109        if not guests_only:
110            if config.has_option('defaults','hw_group'):
111                hw_group = config.get('defaults','hw_group')
112            else:
113                hw_group = default_group + '_hw'
114            inv[hw_group] = []
115
116        if config.has_option('defaults','vm_group'):
117            vm_group = config.get('defaults','vm_group')
118        else:
119            vm_group = default_group + '_vm'
120        inv[vm_group] = []
121
122        # Loop through physical hosts:
123        hosts = HostSystem.all(client)
124        for host in hosts:
125            if not guests_only:
126                inv['all']['hosts'].append(host.name)
127                inv[hw_group].append(host.name)
128                if host.tag:
129                    taggroup = 'vmware_' + host.tag
130                    if taggroup in inv:
131                        inv[taggroup].append(host.name)
132                    else:
133                        inv[taggroup] = [ host.name ]
134
135                inv['_meta']['hostvars'][host.name] = get_host_info(host)
136                save_cache(vm.name, inv['_meta']['hostvars'][host.name], config)
137
138            for vm in host.vm:
139                inv['all']['hosts'].append(vm.name)
140                inv[vm_group].append(vm.name)
141                if vm.tag:
142                    taggroup = 'vmware_' + vm.tag
143                    if taggroup in inv:
144                        inv[taggroup].append(vm.name)
145                    else:
146                        inv[taggroup] = [ vm.name ]
147
148                inv['_meta']['hostvars'][vm.name] = get_host_info(host)
149                save_cache(vm.name, inv['_meta']['hostvars'][vm.name], config)
150
151    save_cache('inventory', inv, config)
152    return json.dumps(inv)
153
154def get_single_host(client, config, hostname):
155
156    inv = {}
157
158    if cache_available(hostname, config):
159        inv = get_cache(hostname,config)
160    else:
161        hosts = HostSystem.all(client) #TODO: figure out single host getter
162        for host in hosts:
163            if hostname == host.name:
164                inv = get_host_info(host)
165                break
166            for vm in host.vm:
167                if hostname == vm.name:
168                    inv = get_host_info(host)
169                    break
170        save_cache(hostname,inv,config)
171
172    return json.dumps(inv)
173
174if __name__ == '__main__':
175    inventory = {}
176    hostname = None
177
178    if len(sys.argv) > 1:
179        if sys.argv[1] == "--host":
180            hostname = sys.argv[2]
181
182    # Read config
183    config = ConfigParser.SafeConfigParser()
184    for configfilename in [os.path.abspath(sys.argv[0]).rstrip('.py') + '.ini', 'vmware.ini']:
185        if os.path.exists(configfilename):
186            config.read(configfilename)
187            break
188
189    try:
190        client =  Client( config.get('auth','host'),
191                          config.get('auth','user'),
192                          config.get('auth','password'),
193                        )
194    except Exception, e:
195        client = None
196        #print >> STDERR "Unable to login (only cache avilable): %s", str(e)
197
198    # acitually do the work
199    if hostname is None:
200        inventory = get_inventory(client, config)
201    else:
202        inventory = get_single_host(client, config, hostname)
203
204    # return to ansible
205    print inventory