vmware_guest: Fix "KeyError: 'changed'" (#22564)

Due to how the result-dictionary is being used, in some codepaths it would have an empty dictionary.
This then is problematic if the code expects the 'changed' key later on.

I also improved the docs a bit, by clearly marking the parameter names and URL in the documentation.
This commit is contained in:
Dag Wieers 2017-03-16 15:55:07 +01:00 committed by jctanner
parent 001be55ef0
commit 895664f539

View file

@ -108,7 +108,6 @@ options:
datacenter: datacenter:
description: description:
- Destination datacenter for the deploy operation - Destination datacenter for the deploy operation
required: False
default: ha-datacenter default: ha-datacenter
cluster: cluster:
description: description:
@ -139,23 +138,23 @@ options:
description: description:
- "Parameters to customize template" - "Parameters to customize template"
- "Common parameters (Linux/Windows):" - "Common parameters (Linux/Windows):"
- " dns_servers (list): List of DNS servers to configure" - " C(dns_servers) (list): List of DNS servers to configure"
- " dns_suffix (list): List of domain suffixes, aka DNS search path (default: C(domain) parameter)" - " C(dns_suffix) (list): List of domain suffixes, aka DNS search path (default: C(domain) parameter)"
- " domain (string): DNS domain name to use" - " C(domain) (string): DNS domain name to use"
- " hostname (string): Computer hostname (default: C(name) parameter)" - " C(hostname) (string): Computer hostname (default: C(name) parameter)"
- "Parameters related to windows customization:" - "Parameters related to windows customization:"
- " autologon (bool): Auto logon after VM customization (default: False)" - " C(autologon) (bool): Auto logon after VM customization (default: False)"
- " autologoncount (int): Number of autologon after reboot (default: 1)" - " C(autologoncount) (int): Number of autologon after reboot (default: 1)"
- " domainadmin (string): User used to join in AD domain (mandatory with joindomain)" - " C(domainadmin) (string): User used to join in AD domain (mandatory with joindomain)"
- " domainadminpassword (string): Password used to join in AD domain (mandatory with joindomain)" - " C(domainadminpassword) (string): Password used to join in AD domain (mandatory with joindomain)"
- " fullname (string): Server owner name (default: Administrator)" - " C(fullname) (string): Server owner name (default: Administrator)"
- " joindomain (string): AD domain to join (Not compatible with C(joinworkgroup))" - " C(joindomain) (string): AD domain to join (Not compatible with C(joinworkgroup))"
- " joinworkgroup (string): Workgroup to join (Not compatible with C(joindomain), default: WORKGROUP)" - " C(joinworkgroup) (string): Workgroup to join (Not compatible with C(joindomain), default: WORKGROUP)"
- " orgname (string): Organisation name (default: ACME)" - " C(orgname) (string): Organisation name (default: ACME)"
- " password (string): Local administrator password (mandatory)" - " C(password) (string): Local administrator password (mandatory)"
- " productid (string): Product ID" - " C(productid) (string): Product ID"
- " runonce (list): List of commands to run at first user logon" - " C(runonce) (list): List of commands to run at first user logon"
- " timezone (int): Timezone (default: 85) See https://msdn.microsoft.com/en-us/library/ms912391(v=winembedded.11).aspx" - " C(timezone) (int): Timezone (default: 85) See U(https://msdn.microsoft.com/en-us/library/ms912391(v=winembedded.11).aspx)"
version_added: "2.3" version_added: "2.3"
extends_documentation_fragment: vmware.documentation extends_documentation_fragment: vmware.documentation
''' '''
@ -485,17 +484,19 @@ class PyVmomiHelper(object):
facts = self.gather_facts(vm) facts = self.gather_facts(vm)
expected_state = state.replace('_', '').lower() expected_state = state.replace('_', '').lower()
current_state = facts['hw_power_status'].lower() current_state = facts['hw_power_status'].lower()
result = {} result = dict(
changed=False,
failed=False,
)
# Need Force # Need Force
if not force and current_state not in ['poweredon', 'poweredoff']: if not force and current_state not in ['poweredon', 'poweredoff']:
return "VM is in %s power state. Force is required!" % current_state result['failed'] = True
result['msg'] = "VM is in %s power state. Force is required!" % current_state
return result
# State is already true # State is not already true
if current_state == expected_state: if current_state != expected_state:
result['changed'] = False
result['failed'] = False
else:
task = None task = None
try: try:
if expected_state == 'poweredoff': if expected_state == 'poweredoff':
@ -508,15 +509,15 @@ class PyVmomiHelper(object):
if current_state in ('poweredon', 'poweringon', 'resetting', 'poweredoff'): if current_state in ('poweredon', 'poweringon', 'resetting', 'poweredoff'):
task = vm.Reset() task = vm.Reset()
else: else:
result = {'changed': False, 'failed': True, result['failed'] = True
'msg': "Cannot restart VM in the current state %s" % current_state} result['msg'] = "Cannot restart VM in the current state %s" % current_state
elif expected_state == 'suspended': elif expected_state == 'suspended':
if current_state in ('poweredon', 'poweringon'): if current_state in ('poweredon', 'poweringon'):
task = vm.Suspend() task = vm.Suspend()
else: else:
result = {'changed': False, 'failed': True, result['failed'] = True
'msg': 'Cannot suspend VM in the current state %s' % current_state} result['msg'] = 'Cannot suspend VM in the current state %s' % current_state
elif expected_state in ['shutdownguest', 'rebootguest']: elif expected_state in ['shutdownguest', 'rebootguest']:
if current_state == 'poweredon' and vm.guest.toolsRunningStatus == 'guestToolsRunning': if current_state == 'poweredon' and vm.guest.toolsRunningStatus == 'guestToolsRunning':
@ -525,25 +526,28 @@ class PyVmomiHelper(object):
else: else:
task = vm.RebootGuest() task = vm.RebootGuest()
else: else:
result = {'changed': False, 'failed': True, result['failed'] = True
'msg': "VM %s must be in poweredon state & tools should be installed for guest shutdown/reboot" % vm.name} result['msg'] = "VM %s must be in poweredon state & tools should be installed for guest shutdown/reboot" % vm.name
except Exception: except Exception:
e = get_exception() e = get_exception()
result = {'changed': False, 'failed': True, 'msg': e} result['failed'] = True
result['msg'] = str(e)
if task: if task:
self.wait_for_task(task) self.wait_for_task(task)
if task.info.state == 'error': if task.info.state == 'error':
result = {'changed': False, 'failed': True, 'msg': task.info.error.msg} result['failed'] = True
result['msg'] = str(task.info.error.msg)
else: else:
result = {'changed': True, 'failed': False} result['changed'] = True
# need to get new metadata if changed # need to get new metadata if changed
if result['changed']: if result['changed']:
newvm = self.getvm(uuid=vm.config.uuid) newvm = self.getvm(uuid=vm.config.uuid)
facts = self.gather_facts(newvm) facts = self.gather_facts(newvm)
result['instance'] = facts result['instance'] = facts
return result return result
def gather_facts(self, vm): def gather_facts(self, vm):
@ -1250,26 +1254,26 @@ def main():
'rebootguest' 'rebootguest'
], ],
default='present'), default='present'),
validate_certs=dict(required=False, type='bool', default=True), validate_certs=dict(type='bool', default=True),
template_src=dict(required=False, type='str', aliases=['template'], default=None), template_src=dict(type='str', aliases=['template']),
is_template=dict(required=False, type='bool', default=False), is_template=dict(type='bool', default=False),
annotation=dict(required=False, type='str', aliases=['notes']), annotation=dict(type='str', aliases=['notes']),
customvalues=dict(required=False, type='list', default=[]), customvalues=dict(type='list', default=[]),
name=dict(required=True, type='str'), name=dict(required=True, type='str'),
name_match=dict(required=False, type='str', default='first'), name_match=dict(type='str', default='first'),
uuid=dict(required=False, type='str'), uuid=dict(type='str'),
folder=dict(required=False, type='str', default='/vm'), folder=dict(type='str', default='/vm'),
guest_id=dict(required=False, type='str', default=None), guest_id=dict(type='str'),
disk=dict(required=False, type='list', default=[]), disk=dict(type='list', default=[]),
hardware=dict(required=False, type='dict', default={}), hardware=dict(type='dict', default={}),
force=dict(required=False, type='bool', default=False), force=dict(type='bool', default=False),
datacenter=dict(required=False, type='str', default='ha-datacenter'), datacenter=dict(type='str', default='ha-datacenter'),
esxi_hostname=dict(required=False, type='str', default=None), esxi_hostname=dict(type='str'),
cluster=dict(required=False, type='str', default=None), cluster=dict(type='str'),
wait_for_ip_address=dict(required=False, type='bool', default=False), wait_for_ip_address=dict(type='bool', default=False),
networks=dict(required=False, type='list', default=[]), networks=dict(type='list', default=[]),
resource_pool=dict(required=False, type='str', default=None), resource_pool=dict(type='str'),
customization=dict(required=False, type='dict', no_log=True, default={}), customization=dict(type='dict', no_log=True, default={}),
), ),
supports_check_mode=True, supports_check_mode=True,
mutually_exclusive=[ mutually_exclusive=[