mirror of
https://github.com/ansible/awx.git
synced 2026-02-14 17:50:02 -03:30
bump vmware inventory script
This commit is contained in:
@@ -42,6 +42,7 @@ HAS_PYVMOMI = False
|
|||||||
try:
|
try:
|
||||||
from pyVmomi import vim
|
from pyVmomi import vim
|
||||||
from pyVim.connect import SmartConnect, Disconnect
|
from pyVim.connect import SmartConnect, Disconnect
|
||||||
|
|
||||||
HAS_PYVMOMI = True
|
HAS_PYVMOMI = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
@@ -54,15 +55,17 @@ except ImportError:
|
|||||||
hasvcr = False
|
hasvcr = False
|
||||||
try:
|
try:
|
||||||
import vcr
|
import vcr
|
||||||
|
|
||||||
hasvcr = True
|
hasvcr = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class VMwareMissingHostException(Exception):
|
class VMwareMissingHostException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class VMWareInventory(object):
|
|
||||||
|
|
||||||
|
class VMWareInventory(object):
|
||||||
__name__ = 'VMWareInventory'
|
__name__ = 'VMWareInventory'
|
||||||
|
|
||||||
guest_props = False
|
guest_props = False
|
||||||
@@ -76,28 +79,30 @@ class VMWareInventory(object):
|
|||||||
cache_max_age = None
|
cache_max_age = None
|
||||||
cache_path_cache = None
|
cache_path_cache = None
|
||||||
cache_path_index = None
|
cache_path_index = None
|
||||||
|
cache_dir = None
|
||||||
server = None
|
server = None
|
||||||
port = None
|
port = None
|
||||||
username = None
|
username = None
|
||||||
password = None
|
password = None
|
||||||
|
validate_certs = True
|
||||||
host_filters = []
|
host_filters = []
|
||||||
|
skip_keys = []
|
||||||
groupby_patterns = []
|
groupby_patterns = []
|
||||||
|
|
||||||
if (sys.version_info > (3, 0)):
|
if sys.version_info > (3, 0):
|
||||||
safe_types = [int, bool, str, float, None]
|
safe_types = [int, bool, str, float, None]
|
||||||
else:
|
else:
|
||||||
safe_types = [int, long, bool, str, float, None]
|
safe_types = [int, long, bool, str, float, None]
|
||||||
iter_types = [dict, list]
|
iter_types = [dict, list]
|
||||||
|
|
||||||
bad_types = ['Array', 'disabledMethod', 'declaredAlarmState']
|
bad_types = ['Array', 'disabledMethod', 'declaredAlarmState']
|
||||||
skip_keys = ['declaredalarmstate',
|
|
||||||
'disabledmethod',
|
vimTableMaxDepth = {
|
||||||
'dynamicproperty',
|
"vim.HostSystem": 2,
|
||||||
'dynamictype',
|
"vim.VirtualMachine": 2,
|
||||||
'environmentbrowser',
|
}
|
||||||
'managedby',
|
|
||||||
'parent',
|
custom_fields = {}
|
||||||
'childtype']
|
|
||||||
|
|
||||||
# translation table for attributes to fetch for known vim types
|
# translation table for attributes to fetch for known vim types
|
||||||
if not HAS_PYVMOMI:
|
if not HAS_PYVMOMI:
|
||||||
@@ -106,14 +111,15 @@ class VMWareInventory(object):
|
|||||||
vimTable = {
|
vimTable = {
|
||||||
vim.Datastore: ['_moId', 'name'],
|
vim.Datastore: ['_moId', 'name'],
|
||||||
vim.ResourcePool: ['_moId', 'name'],
|
vim.ResourcePool: ['_moId', 'name'],
|
||||||
|
vim.HostSystem: ['_moId', 'name'],
|
||||||
}
|
}
|
||||||
|
|
||||||
def _empty_inventory(self):
|
@staticmethod
|
||||||
return {"_meta" : {"hostvars" : {}}}
|
def _empty_inventory():
|
||||||
|
return {"_meta": {"hostvars": {}}}
|
||||||
|
|
||||||
def __init__(self, load=True):
|
def __init__(self, load=True):
|
||||||
self.inventory = self._empty_inventory()
|
self.inventory = VMWareInventory._empty_inventory()
|
||||||
|
|
||||||
if load:
|
if load:
|
||||||
# Read settings and parse CLI arguments
|
# Read settings and parse CLI arguments
|
||||||
@@ -135,7 +141,7 @@ class VMWareInventory(object):
|
|||||||
try:
|
try:
|
||||||
text = str(text)
|
text = str(text)
|
||||||
except UnicodeEncodeError:
|
except UnicodeEncodeError:
|
||||||
text = text.encode('ascii','ignore')
|
text = text.encode('ascii', 'ignore')
|
||||||
print('%s %s' % (datetime.datetime.now(), text))
|
print('%s %s' % (datetime.datetime.now(), text))
|
||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
@@ -149,7 +155,6 @@ class VMWareInventory(object):
|
|||||||
data_to_print = self.inventory
|
data_to_print = self.inventory
|
||||||
return json.dumps(data_to_print, indent=2)
|
return json.dumps(data_to_print, indent=2)
|
||||||
|
|
||||||
|
|
||||||
def is_cache_valid(self):
|
def is_cache_valid(self):
|
||||||
|
|
||||||
''' Determines if the cache files have expired, or if it is still valid '''
|
''' Determines if the cache files have expired, or if it is still valid '''
|
||||||
@@ -164,25 +169,20 @@ class VMWareInventory(object):
|
|||||||
|
|
||||||
return valid
|
return valid
|
||||||
|
|
||||||
|
|
||||||
def do_api_calls_update_cache(self):
|
def do_api_calls_update_cache(self):
|
||||||
|
|
||||||
''' Get instances and cache the data '''
|
''' Get instances and cache the data '''
|
||||||
|
|
||||||
instances = self.get_instances()
|
self.inventory = self.instances_to_inventory(self.get_instances())
|
||||||
self.instances = instances
|
self.write_to_cache(self.inventory)
|
||||||
self.inventory = self.instances_to_inventory(instances)
|
|
||||||
self.write_to_cache(self.inventory, self.cache_path_cache)
|
|
||||||
|
|
||||||
|
def write_to_cache(self, data):
|
||||||
def write_to_cache(self, data, cache_path):
|
|
||||||
|
|
||||||
''' Dump inventory to json file '''
|
''' Dump inventory to json file '''
|
||||||
|
|
||||||
with open(self.cache_path_cache, 'wb') as f:
|
with open(self.cache_path_cache, 'wb') as f:
|
||||||
f.write(json.dumps(data))
|
f.write(json.dumps(data))
|
||||||
|
|
||||||
|
|
||||||
def get_inventory_from_cache(self):
|
def get_inventory_from_cache(self):
|
||||||
|
|
||||||
''' Read in jsonified inventory '''
|
''' Read in jsonified inventory '''
|
||||||
@@ -192,7 +192,6 @@ class VMWareInventory(object):
|
|||||||
jdata = f.read()
|
jdata = f.read()
|
||||||
return json.loads(jdata)
|
return json.loads(jdata)
|
||||||
|
|
||||||
|
|
||||||
def read_settings(self):
|
def read_settings(self):
|
||||||
|
|
||||||
''' Reads the settings from the vmware_inventory.ini file '''
|
''' Reads the settings from the vmware_inventory.ini file '''
|
||||||
@@ -211,13 +210,24 @@ class VMWareInventory(object):
|
|||||||
'cache_name': 'ansible-vmware',
|
'cache_name': 'ansible-vmware',
|
||||||
'cache_path': '~/.ansible/tmp',
|
'cache_path': '~/.ansible/tmp',
|
||||||
'cache_max_age': 3600,
|
'cache_max_age': 3600,
|
||||||
'max_object_level': 1,
|
'max_object_level': 1,
|
||||||
'alias_pattern': '{{ config.name + "_" + config.uuid }}',
|
'skip_keys': 'declaredalarmstate,'
|
||||||
'host_pattern': '{{ guest.ipaddress }}',
|
'disabledmethod,'
|
||||||
'host_filters': '{{ guest.gueststate == "running" }}',
|
'dynamicproperty,'
|
||||||
'groupby_patterns': '{{ guest.guestid }},{{ "templates" if config.template else "guests"}}',
|
'dynamictype,'
|
||||||
'lower_var_keys': True }
|
'environmentbrowser,'
|
||||||
}
|
'managedby,'
|
||||||
|
'parent,'
|
||||||
|
'childtype,'
|
||||||
|
'resourceconfig',
|
||||||
|
'alias_pattern': '{{ config.name + "_" + config.uuid }}',
|
||||||
|
'host_pattern': '{{ guest.ipaddress }}',
|
||||||
|
'host_filters': '{{ guest.gueststate == "running" }}',
|
||||||
|
'groupby_patterns': '{{ guest.guestid }},{{ "templates" if config.template else "guests"}}',
|
||||||
|
'lower_var_keys': True,
|
||||||
|
'custom_field_group_prefix': 'vmware_tag_',
|
||||||
|
'groupby_custom_field': False}
|
||||||
|
}
|
||||||
|
|
||||||
if six.PY3:
|
if six.PY3:
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
@@ -230,9 +240,9 @@ class VMWareInventory(object):
|
|||||||
config.read(vmware_ini_path)
|
config.read(vmware_ini_path)
|
||||||
|
|
||||||
# apply defaults
|
# apply defaults
|
||||||
for k,v in defaults['vmware'].items():
|
for k, v in defaults['vmware'].items():
|
||||||
if not config.has_option('vmware', k):
|
if not config.has_option('vmware', k):
|
||||||
config.set('vmware', k, str(v))
|
config.set('vmware', k, str(v))
|
||||||
|
|
||||||
# where is the cache?
|
# where is the cache?
|
||||||
self.cache_dir = os.path.expanduser(config.get('vmware', 'cache_path'))
|
self.cache_dir = os.path.expanduser(config.get('vmware', 'cache_path'))
|
||||||
@@ -245,8 +255,8 @@ class VMWareInventory(object):
|
|||||||
self.debugl('cache path is %s' % self.cache_path_cache)
|
self.debugl('cache path is %s' % self.cache_path_cache)
|
||||||
self.cache_max_age = int(config.getint('vmware', 'cache_max_age'))
|
self.cache_max_age = int(config.getint('vmware', 'cache_max_age'))
|
||||||
|
|
||||||
# mark the connection info
|
# mark the connection info
|
||||||
self.server = os.environ.get('VMWARE_SERVER', config.get('vmware', 'server'))
|
self.server = os.environ.get('VMWARE_SERVER', config.get('vmware', 'server'))
|
||||||
self.debugl('server is %s' % self.server)
|
self.debugl('server is %s' % self.server)
|
||||||
self.port = int(os.environ.get('VMWARE_PORT', config.get('vmware', 'port')))
|
self.port = int(os.environ.get('VMWARE_PORT', config.get('vmware', 'port')))
|
||||||
self.username = os.environ.get('VMWARE_USERNAME', config.get('vmware', 'username'))
|
self.username = os.environ.get('VMWARE_USERNAME', config.get('vmware', 'username'))
|
||||||
@@ -255,8 +265,7 @@ class VMWareInventory(object):
|
|||||||
self.validate_certs = os.environ.get('VMWARE_VALIDATE_CERTS', config.get('vmware', 'validate_certs'))
|
self.validate_certs = os.environ.get('VMWARE_VALIDATE_CERTS', config.get('vmware', 'validate_certs'))
|
||||||
if self.validate_certs in ['no', 'false', 'False', False]:
|
if self.validate_certs in ['no', 'false', 'False', False]:
|
||||||
self.validate_certs = False
|
self.validate_certs = False
|
||||||
else:
|
|
||||||
self.validate_certs = True
|
|
||||||
self.debugl('cert validation is %s' % self.validate_certs)
|
self.debugl('cert validation is %s' % self.validate_certs)
|
||||||
|
|
||||||
# behavior control
|
# behavior control
|
||||||
@@ -266,10 +275,11 @@ class VMWareInventory(object):
|
|||||||
if type(self.lowerkeys) != bool:
|
if type(self.lowerkeys) != bool:
|
||||||
if str(self.lowerkeys).lower() in ['yes', 'true', '1']:
|
if str(self.lowerkeys).lower() in ['yes', 'true', '1']:
|
||||||
self.lowerkeys = True
|
self.lowerkeys = True
|
||||||
else:
|
else:
|
||||||
self.lowerkeys = False
|
self.lowerkeys = False
|
||||||
self.debugl('lower keys is %s' % self.lowerkeys)
|
self.debugl('lower keys is %s' % self.lowerkeys)
|
||||||
|
self.skip_keys = list(config.get('vmware', 'skip_keys').split(','))
|
||||||
|
self.debugl('skip keys is %s' % self.skip_keys)
|
||||||
self.host_filters = list(config.get('vmware', 'host_filters').split(','))
|
self.host_filters = list(config.get('vmware', 'host_filters').split(','))
|
||||||
self.debugl('host filters are %s' % self.host_filters)
|
self.debugl('host filters are %s' % self.host_filters)
|
||||||
self.groupby_patterns = list(config.get('vmware', 'groupby_patterns').split(','))
|
self.groupby_patterns = list(config.get('vmware', 'groupby_patterns').split(','))
|
||||||
@@ -284,8 +294,7 @@ class VMWareInventory(object):
|
|||||||
self.guest_props.append(prop[1])
|
self.guest_props.append(prop[1])
|
||||||
|
|
||||||
# save the config
|
# save the config
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
|
|
||||||
def parse_cli_args(self):
|
def parse_cli_args(self):
|
||||||
|
|
||||||
@@ -293,37 +302,31 @@ class VMWareInventory(object):
|
|||||||
|
|
||||||
parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on PyVmomi')
|
parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on PyVmomi')
|
||||||
parser.add_argument('--debug', action='store_true', default=False,
|
parser.add_argument('--debug', action='store_true', default=False,
|
||||||
help='show debug info')
|
help='show debug info')
|
||||||
parser.add_argument('--list', action='store_true', default=True,
|
parser.add_argument('--list', action='store_true', default=True,
|
||||||
help='List instances (default: True)')
|
help='List instances (default: True)')
|
||||||
parser.add_argument('--host', action='store',
|
parser.add_argument('--host', action='store',
|
||||||
help='Get all the variables about a specific instance')
|
help='Get all the variables about a specific instance')
|
||||||
parser.add_argument('--refresh-cache', action='store_true', default=False,
|
parser.add_argument('--refresh-cache', action='store_true', default=False,
|
||||||
help='Force refresh of cache by making API requests to VSphere (default: False - use cache files)')
|
help='Force refresh of cache by making API requests to VSphere (default: False - use cache files)')
|
||||||
parser.add_argument('--max-instances', default=None, type=int,
|
parser.add_argument('--max-instances', default=None, type=int,
|
||||||
help='maximum number of instances to retrieve')
|
help='maximum number of instances to retrieve')
|
||||||
self.args = parser.parse_args()
|
self.args = parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
def get_instances(self):
|
def get_instances(self):
|
||||||
|
|
||||||
''' Get a list of vm instances with pyvmomi '''
|
''' Get a list of vm instances with pyvmomi '''
|
||||||
|
|
||||||
instances = []
|
|
||||||
|
|
||||||
kwargs = {'host': self.server,
|
kwargs = {'host': self.server,
|
||||||
'user': self.username,
|
'user': self.username,
|
||||||
'pwd': self.password,
|
'pwd': self.password,
|
||||||
'port': int(self.port) }
|
'port': int(self.port)}
|
||||||
|
|
||||||
if hasattr(ssl, 'SSLContext') and not self.validate_certs:
|
if hasattr(ssl, 'SSLContext') and not self.validate_certs:
|
||||||
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
||||||
context.verify_mode = ssl.CERT_NONE
|
context.verify_mode = ssl.CERT_NONE
|
||||||
kwargs['sslContext'] = context
|
kwargs['sslContext'] = context
|
||||||
|
|
||||||
instances = self._get_instances(kwargs)
|
return self._get_instances(kwargs)
|
||||||
return instances
|
|
||||||
|
|
||||||
|
|
||||||
def _get_instances(self, inkwargs):
|
def _get_instances(self, inkwargs):
|
||||||
|
|
||||||
@@ -335,7 +338,7 @@ class VMWareInventory(object):
|
|||||||
self.debugl('retrieving all instances')
|
self.debugl('retrieving all instances')
|
||||||
if not si:
|
if not si:
|
||||||
print("Could not connect to the specified host using specified "
|
print("Could not connect to the specified host using specified "
|
||||||
"username and password")
|
"username and password")
|
||||||
return -1
|
return -1
|
||||||
atexit.register(Disconnect, si)
|
atexit.register(Disconnect, si)
|
||||||
content = si.RetrieveContent()
|
content = si.RetrieveContent()
|
||||||
@@ -350,7 +353,7 @@ class VMWareInventory(object):
|
|||||||
for child in children:
|
for child in children:
|
||||||
# If requested, limit the total number of instances
|
# If requested, limit the total number of instances
|
||||||
if self.args.max_instances:
|
if self.args.max_instances:
|
||||||
if len(instances) >= (self.args.max_instances):
|
if len(instances) >= self.args.max_instances:
|
||||||
break
|
break
|
||||||
instances.append(child)
|
instances.append(child)
|
||||||
self.debugl("%s total instances in container view" % len(instances))
|
self.debugl("%s total instances in container view" % len(instances))
|
||||||
@@ -358,29 +361,32 @@ class VMWareInventory(object):
|
|||||||
if self.args.host:
|
if self.args.host:
|
||||||
instances = [x for x in instances if x.name == self.args.host]
|
instances = [x for x in instances if x.name == self.args.host]
|
||||||
|
|
||||||
instance_tuples = []
|
instance_tuples = []
|
||||||
for instance in sorted(instances):
|
for instance in sorted(instances):
|
||||||
if self.guest_props != False:
|
if self.guest_props:
|
||||||
ifacts = self.facts_from_proplist(instance)
|
ifacts = self.facts_from_proplist(instance)
|
||||||
else:
|
else:
|
||||||
ifacts = self.facts_from_vobj(instance)
|
ifacts = self.facts_from_vobj(instance)
|
||||||
instance_tuples.append((instance, ifacts))
|
instance_tuples.append((instance, ifacts))
|
||||||
self.debugl('facts collected for all instances')
|
self.debugl('facts collected for all instances')
|
||||||
return instance_tuples
|
|
||||||
|
|
||||||
|
cfm = content.customFieldsManager
|
||||||
|
if cfm is not None and cfm.field:
|
||||||
|
for f in cfm.field:
|
||||||
|
if f.managedObjectType == vim.VirtualMachine:
|
||||||
|
self.custom_fields[f.key] = f.name;
|
||||||
|
self.debugl('%d custom fieds collected' % len(self.custom_fields))
|
||||||
|
return instance_tuples
|
||||||
|
|
||||||
def instances_to_inventory(self, instances):
|
def instances_to_inventory(self, instances):
|
||||||
|
|
||||||
''' Convert a list of vm objects into a json compliant inventory '''
|
''' Convert a list of vm objects into a json compliant inventory '''
|
||||||
|
|
||||||
self.debugl('re-indexing instances based on ini settings')
|
self.debugl('re-indexing instances based on ini settings')
|
||||||
inventory = self._empty_inventory()
|
inventory = VMWareInventory._empty_inventory()
|
||||||
inventory['all'] = {}
|
inventory['all'] = {}
|
||||||
inventory['all']['hosts'] = []
|
inventory['all']['hosts'] = []
|
||||||
last_idata = None
|
for idx, instance in enumerate(instances):
|
||||||
total = len(instances)
|
|
||||||
for idx,instance in enumerate(instances):
|
|
||||||
|
|
||||||
# make a unique id for this object to avoid vmware's
|
# make a unique id for this object to avoid vmware's
|
||||||
# numerous uuid's which aren't all unique.
|
# numerous uuid's which aren't all unique.
|
||||||
thisid = str(uuid.uuid4())
|
thisid = str(uuid.uuid4())
|
||||||
@@ -392,16 +398,19 @@ class VMWareInventory(object):
|
|||||||
inventory['_meta']['hostvars'][thisid]['ansible_uuid'] = thisid
|
inventory['_meta']['hostvars'][thisid]['ansible_uuid'] = thisid
|
||||||
|
|
||||||
# Make a map of the uuid to the alias the user wants
|
# Make a map of the uuid to the alias the user wants
|
||||||
name_mapping = self.create_template_mapping(inventory,
|
name_mapping = self.create_template_mapping(
|
||||||
self.config.get('vmware', 'alias_pattern'))
|
inventory,
|
||||||
|
self.config.get('vmware', 'alias_pattern')
|
||||||
|
)
|
||||||
|
|
||||||
# Make a map of the uuid to the ssh hostname the user wants
|
# Make a map of the uuid to the ssh hostname the user wants
|
||||||
host_mapping = self.create_template_mapping(inventory,
|
host_mapping = self.create_template_mapping(
|
||||||
self.config.get('vmware', 'host_pattern'))
|
inventory,
|
||||||
|
self.config.get('vmware', 'host_pattern')
|
||||||
|
)
|
||||||
|
|
||||||
# Reset the inventory keys
|
# Reset the inventory keys
|
||||||
for k,v in name_mapping.items():
|
for k, v in name_mapping.items():
|
||||||
|
|
||||||
if not host_mapping or not k in host_mapping:
|
if not host_mapping or not k in host_mapping:
|
||||||
continue
|
continue
|
||||||
@@ -411,7 +420,7 @@ class VMWareInventory(object):
|
|||||||
inventory['_meta']['hostvars'][k]['ansible_host'] = host_mapping[k]
|
inventory['_meta']['hostvars'][k]['ansible_host'] = host_mapping[k]
|
||||||
# 1.9.x backwards compliance
|
# 1.9.x backwards compliance
|
||||||
inventory['_meta']['hostvars'][k]['ansible_ssh_host'] = host_mapping[k]
|
inventory['_meta']['hostvars'][k]['ansible_ssh_host'] = host_mapping[k]
|
||||||
except Exception as e:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if k == v:
|
if k == v:
|
||||||
@@ -434,7 +443,7 @@ class VMWareInventory(object):
|
|||||||
continue
|
continue
|
||||||
self.debugl('filter: %s' % hf)
|
self.debugl('filter: %s' % hf)
|
||||||
filter_map = self.create_template_mapping(inventory, hf, dtype='boolean')
|
filter_map = self.create_template_mapping(inventory, hf, dtype='boolean')
|
||||||
for k,v in filter_map.items():
|
for k, v in filter_map.items():
|
||||||
if not v:
|
if not v:
|
||||||
# delete this host
|
# delete this host
|
||||||
inventory['all']['hosts'].remove(k)
|
inventory['all']['hosts'].remove(k)
|
||||||
@@ -447,25 +456,51 @@ class VMWareInventory(object):
|
|||||||
# Create groups
|
# Create groups
|
||||||
for gbp in self.groupby_patterns:
|
for gbp in self.groupby_patterns:
|
||||||
groupby_map = self.create_template_mapping(inventory, gbp)
|
groupby_map = self.create_template_mapping(inventory, gbp)
|
||||||
for k,v in groupby_map.items():
|
for k, v in groupby_map.items():
|
||||||
if v not in inventory:
|
if v not in inventory:
|
||||||
inventory[v] = {}
|
inventory[v] = {}
|
||||||
inventory[v]['hosts'] = []
|
inventory[v]['hosts'] = []
|
||||||
if k not in inventory[v]['hosts']:
|
if k not in inventory[v]['hosts']:
|
||||||
inventory[v]['hosts'].append(k)
|
inventory[v]['hosts'].append(k)
|
||||||
|
|
||||||
|
if self.config.get('vmware', 'groupby_custom_field'):
|
||||||
|
for k, v in inventory['_meta']['hostvars'].items():
|
||||||
|
if 'customvalue' in v:
|
||||||
|
for tv in v['customvalue']:
|
||||||
|
if not isinstance(tv['value'], str) and not isinstance(tv['value'], unicode):
|
||||||
|
continue
|
||||||
|
|
||||||
|
newkey = None
|
||||||
|
field_name = self.custom_fields[tv['key']] if tv['key'] in self.custom_fields else tv['key']
|
||||||
|
values = []
|
||||||
|
keylist = map(lambda x: x.strip(), tv['value'].split(','))
|
||||||
|
for kl in keylist:
|
||||||
|
try:
|
||||||
|
newkey = self.config.get('vmware', 'custom_field_group_prefix') + field_name + '_' + kl
|
||||||
|
newkey = newkey.strip()
|
||||||
|
except Exception as e:
|
||||||
|
self.debugl(e)
|
||||||
|
values.append(newkey)
|
||||||
|
for tag in values:
|
||||||
|
if not tag:
|
||||||
|
continue
|
||||||
|
if tag not in inventory:
|
||||||
|
inventory[tag] = {}
|
||||||
|
inventory[tag]['hosts'] = []
|
||||||
|
if k not in inventory[tag]['hosts']:
|
||||||
|
inventory[tag]['hosts'].append(k)
|
||||||
|
|
||||||
return inventory
|
return inventory
|
||||||
|
|
||||||
|
|
||||||
def create_template_mapping(self, inventory, pattern, dtype='string'):
|
def create_template_mapping(self, inventory, pattern, dtype='string'):
|
||||||
|
|
||||||
''' Return a hash of uuid to templated string from pattern '''
|
''' Return a hash of uuid to templated string from pattern '''
|
||||||
|
|
||||||
mapping = {}
|
mapping = {}
|
||||||
for k,v in inventory['_meta']['hostvars'].items():
|
for k, v in inventory['_meta']['hostvars'].items():
|
||||||
t = jinja2.Template(pattern)
|
t = jinja2.Template(pattern)
|
||||||
newkey = None
|
newkey = None
|
||||||
try:
|
try:
|
||||||
newkey = t.render(v)
|
newkey = t.render(v)
|
||||||
newkey = newkey.strip()
|
newkey = newkey.strip()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -478,9 +513,9 @@ class VMWareInventory(object):
|
|||||||
if newkey.lower() == 'false':
|
if newkey.lower() == 'false':
|
||||||
newkey = False
|
newkey = False
|
||||||
elif newkey.lower() == 'true':
|
elif newkey.lower() == 'true':
|
||||||
newkey = True
|
newkey = True
|
||||||
elif dtype == 'string':
|
elif dtype == 'string':
|
||||||
pass
|
pass
|
||||||
mapping[k] = newkey
|
mapping[k] = newkey
|
||||||
return mapping
|
return mapping
|
||||||
|
|
||||||
@@ -494,7 +529,7 @@ class VMWareInventory(object):
|
|||||||
if self.lowerkeys:
|
if self.lowerkeys:
|
||||||
key = key.lower()
|
key = key.lower()
|
||||||
|
|
||||||
if not '.' in prop:
|
if '.' not in prop:
|
||||||
# props without periods are direct attributes of the parent
|
# props without periods are direct attributes of the parent
|
||||||
rdata[key] = getattr(vm, prop)
|
rdata[key] = getattr(vm, prop)
|
||||||
else:
|
else:
|
||||||
@@ -507,7 +542,7 @@ class VMWareInventory(object):
|
|||||||
# pointer to the current result key
|
# pointer to the current result key
|
||||||
lastref = rdata
|
lastref = rdata
|
||||||
|
|
||||||
for idx,x in enumerate(parts):
|
for idx, x in enumerate(parts):
|
||||||
|
|
||||||
# if the val wasn't set yet, get it from the parent
|
# if the val wasn't set yet, get it from the parent
|
||||||
if not val:
|
if not val:
|
||||||
@@ -533,7 +568,6 @@ class VMWareInventory(object):
|
|||||||
|
|
||||||
return rdata
|
return rdata
|
||||||
|
|
||||||
|
|
||||||
def facts_from_vobj(self, vobj, level=0):
|
def facts_from_vobj(self, vobj, level=0):
|
||||||
|
|
||||||
''' Traverse a VM object and return a json compliant data structure '''
|
''' Traverse a VM object and return a json compliant data structure '''
|
||||||
@@ -556,7 +590,7 @@ class VMWareInventory(object):
|
|||||||
|
|
||||||
methods = dir(vobj)
|
methods = dir(vobj)
|
||||||
methods = [str(x) for x in methods if not x.startswith('_')]
|
methods = [str(x) for x in methods if not x.startswith('_')]
|
||||||
methods = [x for x in methods if not x in self.bad_types]
|
methods = [x for x in methods if x not in self.bad_types]
|
||||||
methods = [x for x in methods if not x.lower() in self.skip_keys]
|
methods = [x for x in methods if not x.lower() in self.skip_keys]
|
||||||
methods = sorted(methods)
|
methods = sorted(methods)
|
||||||
|
|
||||||
@@ -575,21 +609,22 @@ class VMWareInventory(object):
|
|||||||
method = method.lower()
|
method = method.lower()
|
||||||
|
|
||||||
rdata[method] = self._process_object_types(
|
rdata[method] = self._process_object_types(
|
||||||
methodToCall,
|
methodToCall,
|
||||||
thisvm=vobj,
|
thisvm=vobj,
|
||||||
inkey=method
|
inkey=method,
|
||||||
)
|
)
|
||||||
|
|
||||||
return rdata
|
return rdata
|
||||||
|
|
||||||
|
|
||||||
def _process_object_types(self, vobj, thisvm=None, inkey=None, level=0):
|
def _process_object_types(self, vobj, thisvm=None, inkey=None, level=0):
|
||||||
''' Serialize an object '''
|
''' Serialize an object '''
|
||||||
rdata = {}
|
rdata = {}
|
||||||
|
|
||||||
|
if type(vobj).__name__ in self.vimTableMaxDepth and level >= self.vimTableMaxDepth[type(vobj).__name__]:
|
||||||
|
return rdata
|
||||||
|
|
||||||
if vobj is None:
|
if vobj is None:
|
||||||
rdata = None
|
rdata = None
|
||||||
|
|
||||||
elif type(vobj) in self.vimTable:
|
elif type(vobj) in self.vimTable:
|
||||||
rdata = {}
|
rdata = {}
|
||||||
for key in self.vimTable[type(vobj)]:
|
for key in self.vimTable[type(vobj)]:
|
||||||
@@ -612,19 +647,17 @@ class VMWareInventory(object):
|
|||||||
rdata = []
|
rdata = []
|
||||||
try:
|
try:
|
||||||
vobj = sorted(vobj)
|
vobj = sorted(vobj)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
for idv, vii in enumerate(vobj):
|
for idv, vii in enumerate(vobj):
|
||||||
|
if level + 1 <= self.maxlevel:
|
||||||
if (level+1 <= self.maxlevel):
|
|
||||||
|
|
||||||
vid = self._process_object_types(
|
vid = self._process_object_types(
|
||||||
vii,
|
vii,
|
||||||
thisvm=thisvm,
|
thisvm=thisvm,
|
||||||
inkey=inkey+'['+str(idv)+']',
|
inkey=inkey + '[' + str(idv) + ']',
|
||||||
level=(level+1)
|
level=(level + 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
if vid:
|
if vid:
|
||||||
rdata.append(vid)
|
rdata.append(vid)
|
||||||
@@ -635,8 +668,8 @@ class VMWareInventory(object):
|
|||||||
elif issubclass(type(vobj), object):
|
elif issubclass(type(vobj), object):
|
||||||
methods = dir(vobj)
|
methods = dir(vobj)
|
||||||
methods = [str(x) for x in methods if not x.startswith('_')]
|
methods = [str(x) for x in methods if not x.startswith('_')]
|
||||||
methods = [x for x in methods if not x in self.bad_types]
|
methods = [x for x in methods if x not in self.bad_types]
|
||||||
methods = [x for x in methods if not x.lower() in self.skip_keys]
|
methods = [x for x in methods if not inkey + '.' + x.lower() in self.skip_keys]
|
||||||
methods = sorted(methods)
|
methods = sorted(methods)
|
||||||
|
|
||||||
for method in methods:
|
for method in methods:
|
||||||
@@ -645,33 +678,33 @@ class VMWareInventory(object):
|
|||||||
methodToCall = getattr(vobj, method)
|
methodToCall = getattr(vobj, method)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if callable(methodToCall):
|
if callable(methodToCall):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self.lowerkeys:
|
if self.lowerkeys:
|
||||||
method = method.lower()
|
method = method.lower()
|
||||||
if (level+1 <= self.maxlevel):
|
if level + 1 <= self.maxlevel:
|
||||||
rdata[method] = self._process_object_types(
|
rdata[method] = self._process_object_types(
|
||||||
methodToCall,
|
methodToCall,
|
||||||
thisvm=thisvm,
|
thisvm=thisvm,
|
||||||
inkey=inkey+'.'+method,
|
inkey=inkey + '.' + method,
|
||||||
level=(level+1)
|
level=(level + 1)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return rdata
|
return rdata
|
||||||
|
|
||||||
def get_host_info(self, host):
|
def get_host_info(self, host):
|
||||||
|
|
||||||
''' Return hostvars for a single host '''
|
''' Return hostvars for a single host '''
|
||||||
|
|
||||||
if host in self.inventory['_meta']['hostvars']:
|
if host in self.inventory['_meta']['hostvars']:
|
||||||
return self.inventory['_meta']['hostvars'][host]
|
return self.inventory['_meta']['hostvars'][host]
|
||||||
elif self.args.host and self.inventory['_meta']['hostvars']:
|
elif self.args.host and self.inventory['_meta']['hostvars']:
|
||||||
# check if the machine has the name requested
|
|
||||||
keys = self.inventory['_meta']['hostvars'].keys()
|
|
||||||
match = None
|
match = None
|
||||||
for k,v in self.inventory['_meta']['hostvars'].items():
|
for k, v in self.inventory['_meta']['hostvars']:
|
||||||
if self.inventory['_meta']['hostvars'][k]['name'] == self.args.host:
|
if self.inventory['_meta']['hostvars'][k]['name'] == self.args.host:
|
||||||
match = k
|
match = k
|
||||||
break
|
break
|
||||||
|
|||||||
Reference in New Issue
Block a user