/plugins/inventory/vmware.py

https://github.com/ajanthanm/ansible · Python · 205 lines · 148 code · 39 blank · 18 comment · 47 complexity · 860c08373c5fe885e8ad8d73d044b025 MD5 · raw file

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