1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

vmware_guest: assorted fixes and improvements (#19842)

A small collection of fixes and improvements:
- Simplify should_deploy_from_template()
- Bugfix for x.config that can be None
- Bugfix for mandatory guest_id (not when using templates)
- Simplify key testing and defaults
- Fix an incorrect reference to the last network
- Duplicate alias 'folder' removed
This commit is contained in:
Dag Wieers 2017-01-04 23:25:09 +01:00 committed by jctanner
parent 02e3f4b526
commit ecaa0202b9

View file

@ -251,6 +251,7 @@ Example from Ansible playbook
password: vmware password: vmware
name: testvm_2 name: testvm_2
esxi_hostname: 192.168.1.117 esxi_hostname: 192.168.1.117
state: gatherfacts
register: facts register: facts
### Snapshot Operations ### Snapshot Operations
@ -490,7 +491,7 @@ class PyVmomiHelper(object):
self.cache = PyVmomiCache(self.content) self.cache = PyVmomiCache(self.content)
def should_deploy_from_template(self): def should_deploy_from_template(self):
return 'template' in self.params and self.params['template'] is not None return self.params.get('template') is not None
def _build_folder_tree(self, folder): def _build_folder_tree(self, folder):
@ -546,6 +547,8 @@ class PyVmomiHelper(object):
self._build_folder_map(x, inpath=thispath) self._build_folder_map(x, inpath=thispath)
elif k == 'virtualmachines': elif k == 'virtualmachines':
for x in v: for x in v:
# Apparently x.config can be None on corrupted VMs
if x.config is None: continue
self.foldermap['uuids'][x.config.uuid] = x.config.name self.foldermap['uuids'][x.config.uuid] = x.config.name
self.foldermap['paths'][thispath].append(x.config.uuid) self.foldermap['paths'][thispath].append(x.config.uuid)
@ -596,11 +599,9 @@ class PyVmomiHelper(object):
# Build the absolute folder path to pass into the search method # Build the absolute folder path to pass into the search method
if self.params['folder'].startswith('/vm'): if self.params['folder'].startswith('/vm'):
searchpath = '%s' % self.params['datacenter'] searchpath = '%(datacenter)s%(folder)s' % self.params
searchpath += self.params['folder']
elif self.params['folder'].startswith('/'): elif self.params['folder'].startswith('/'):
searchpath = '%s' % self.params['datacenter'] searchpath = '%(datacenter)s/vm%(folder)s' % self.params
searchpath += '/vm' + self.params['folder']
else: else:
# need to look for matching absolute path # need to look for matching absolute path
if not self.folders: if not self.folders:
@ -609,8 +610,7 @@ class PyVmomiHelper(object):
paths = [x for x in paths if x.endswith(self.params['folder'])] paths = [x for x in paths if x.endswith(self.params['folder'])]
if len(paths) > 1: if len(paths) > 1:
self.module.fail_json( self.module.fail_json(
msg='%s matches more than one folder. Please use the absolute path starting with /vm/' % msg='%(folder)s matches more than one folder. Please use the absolute path starting with /vm/' % self.params)
self.params['folder'])
elif paths: elif paths:
searchpath = paths[0] searchpath = paths[0]
@ -791,14 +791,17 @@ class PyVmomiHelper(object):
return {'changed': True, 'failed': False} return {'changed': True, 'failed': False}
def configure_guestid(self, vm_obj, vm_creation=False): def configure_guestid(self, vm_obj, vm_creation=False):
# guest_id is not required when using templates
if self.should_deploy_from_template() and self.params.get('guest_id') is None:
return
# guest_id is only mandatory on VM creation # guest_id is only mandatory on VM creation
if vm_creation and self.params['guest_id'] is None: if vm_creation and self.params['guest_id'] is None:
self.module.fail_json(msg="guest_id attribute is mandatory for VM creation") self.module.fail_json(msg="guest_id attribute is mandatory for VM creation")
if vm_obj is None or self.configspec.guestId != vm_obj.summary.guest.guestId: if vm_obj is None or self.configspec.guestId != vm_obj.summary.guest.guestId:
self.change_detected = True self.change_detected = True
self.configspec.guestId = self.params['guest_id']
self.configspec.guestId = self.params['guest_id']
def configure_cpu_and_memory(self, vm_obj, vm_creation=False): def configure_cpu_and_memory(self, vm_obj, vm_creation=False):
# set cpu/memory/etc # set cpu/memory/etc
@ -859,7 +862,7 @@ class PyVmomiHelper(object):
if network_name: if network_name:
self.params['networks'][network]['network'] = network_name self.params['networks'][network]['network'] = network_name
else: else:
self.module.fail_json(msg="VLAN %s doesn't exists" % self.params['networks'][network]['vlan']) self.module.fail_json(msg="VLAN %(vlan)s doesn't exists" % self.params['networks'][network])
else: else:
self.module.fail_json(msg="You need to define a network or a vlan") self.module.fail_json(msg="You need to define a network or a vlan")
@ -876,9 +879,7 @@ class PyVmomiHelper(object):
for key in range(0, len(network_devices)): for key in range(0, len(network_devices)):
# Default device type is vmxnet3, VMWare best practice # Default device type is vmxnet3, VMWare best practice
device_type = network_devices[key]['device_type'] \ device_type = network_devices[key].get('device_type', 'vmxnet3')
if 'device_type' in network_devices[key] else 'vmxnet3'
nic = self.device_helper.create_nic(device_type, nic = self.device_helper.create_nic(device_type,
'Network Adapter %s' % (key + 1), 'Network Adapter %s' % (key + 1),
network_devices[key]) network_devices[key])
@ -925,7 +926,7 @@ class PyVmomiHelper(object):
self.change_detected = True self.change_detected = True
if vm_obj is None or self.should_deploy_from_template(): if vm_obj is None or self.should_deploy_from_template():
if 'ip' in self.params['networks'][network]: if 'ip' in network_devices[key]:
guest_map = vim.vm.customization.AdapterMapping() guest_map = vim.vm.customization.AdapterMapping()
guest_map.adapter = vim.vm.customization.IPSettings() guest_map.adapter = vim.vm.customization.IPSettings()
guest_map.adapter.ip = vim.vm.customization.FixedIp() guest_map.adapter.ip = vim.vm.customization.FixedIp()
@ -998,7 +999,7 @@ class PyVmomiHelper(object):
# No size found but disk, fail # No size found but disk, fail
self.module.fail_json( self.module.fail_json(
msg="no size, size_kb, size_mb, size_gb or size_tb attribute found into disk configuration") msg="No size, size_kb, size_mb, size_gb or size_tb attribute found into disk configuration")
def configure_disks(self, vm_obj): def configure_disks(self, vm_obj):
# Ignore empty disk list, this permits to keep disks when deploying a template/cloning a VM # Ignore empty disk list, this permits to keep disks when deploying a template/cloning a VM
@ -1069,14 +1070,14 @@ class PyVmomiHelper(object):
if self.params['cluster']: if self.params['cluster']:
cluster = self.cache.get_cluster(self.params['cluster']) cluster = self.cache.get_cluster(self.params['cluster'])
if not cluster: if not cluster:
self.module.fail_json(msg="Failed to find a cluster named %s" % self.params['cluster']) self.module.fail_json(msg="Failed to find a cluster named %(cluster)s" % self.params)
hostsystems = [x for x in cluster.host] hostsystems = [x for x in cluster.host]
# TODO: add a policy to select host # TODO: add a policy to select host
hostsystem = hostsystems[0] hostsystem = hostsystems[0]
else: else:
hostsystem = self.cache.get_esx_host(self.params['esxi_hostname']) hostsystem = self.cache.get_esx_host(self.params['esxi_hostname'])
if not hostsystem: if not hostsystem:
self.module.fail_json(msg="Failed to find a host named %s" % self.params['esxi_hostname']) self.module.fail_json(msg="Failed to find a host named %(esxi_hostname)s" % self.params)
return hostsystem return hostsystem
@ -1177,7 +1178,7 @@ class PyVmomiHelper(object):
datacenters = get_all_objs(self.content, [vim.Datacenter]) datacenters = get_all_objs(self.content, [vim.Datacenter])
datacenter = get_obj(self.content, [vim.Datacenter], self.params['datacenter']) datacenter = get_obj(self.content, [vim.Datacenter], self.params['datacenter'])
if not datacenter: if not datacenter:
self.module.fail_json(msg='No datacenter named %s was found' % self.params['datacenter']) self.module.fail_json(msg='No datacenter named %(datacenter)s was found' % self.params)
# find matching folders # find matching folders
if self.params['folder'].startswith('/'): if self.params['folder'].startswith('/'):
@ -1189,7 +1190,7 @@ class PyVmomiHelper(object):
# throw error if more than one match or no matches # throw error if more than one match or no matches
if len(folders) == 0: if len(folders) == 0:
self.module.fail_json(msg='no folder matched the path: %s' % self.params['folder']) self.module.fail_json(msg='No folder matched the path: %(folder)s' % self.params)
elif len(folders) > 1: elif len(folders) > 1:
self.module.fail_json( self.module.fail_json(
msg='too many folders matched "%s", please give the full path starting with /vm/' % self.params[ msg='too many folders matched "%s", please give the full path starting with /vm/' % self.params[
@ -1203,7 +1204,7 @@ class PyVmomiHelper(object):
# FIXME: need to search for this in the same way as guests to ensure accuracy # FIXME: need to search for this in the same way as guests to ensure accuracy
vm_obj = get_obj(self.content, [vim.VirtualMachine], self.params['template']) vm_obj = get_obj(self.content, [vim.VirtualMachine], self.params['template'])
if not vm_obj: if not vm_obj:
self.module.fail_json(msg="Could not find a template named %s" % self.params['template']) self.module.fail_json(msg="Could not find a template named %(template)s" % self.params)
else: else:
vm_obj = None vm_obj = None
@ -1636,7 +1637,7 @@ def main():
name_match=dict(required=False, type='str', default='first'), name_match=dict(required=False, type='str', default='first'),
snapshot_op=dict(required=False, type='dict', default={}), snapshot_op=dict(required=False, type='dict', default={}),
uuid=dict(required=False, type='str'), uuid=dict(required=False, type='str'),
folder=dict(required=False, type='str', default='/vm', aliases=['folder']), folder=dict(required=False, type='str', default='/vm'),
guest_id=dict(required=False, type='str', default=None), guest_id=dict(required=False, type='str', default=None),
disk=dict(required=False, type='list', default=[]), disk=dict(required=False, type='list', default=[]),
hardware=dict(required=False, type='dict', default={}), hardware=dict(required=False, type='dict', default={}),