From a40ce1ba5e496fa0261dcc237eada69eb7db8a52 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Fri, 17 Nov 2017 06:02:30 +0000 Subject: [PATCH] Handle virtual machine config element gracefully (#32924) This fix uses '_get_vm_prop' API to handle virtual machine related properties rather than failing with AttributeError. Handled invalid request type while connecting to ESXi server, which is caused by malformed request. Fixes: #32477 Signed-off-by: Abhijeet Kasurde --- lib/ansible/module_utils/vmware.py | 10 +++++++--- lib/ansible/modules/cloud/vmware/vmware_vm_facts.py | 11 ++++++----- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/ansible/module_utils/vmware.py b/lib/ansible/module_utils/vmware.py index 4d070a47e15..b3451e37e7b 100644 --- a/lib/ansible/module_utils/vmware.py +++ b/lib/ansible/module_utils/vmware.py @@ -26,7 +26,7 @@ try: # requests is required for exception handling of the ConnectionError import requests from pyVim import connect - from pyVmomi import vim + from pyVmomi import vim, vmodl HAS_PYVMOMI = True except ImportError: HAS_PYVMOMI = False @@ -420,11 +420,15 @@ def connect_to_api(module, disconnect_atexit=True): " to log on to vCenter or ESXi API at %s: %s" % (username, hostname, e.msg)) except (requests.ConnectionError, ssl.SSLError) as e: module.fail_json(msg="Unable to connect to vCenter or ESXi API at %s on TCP/443: %s" % (hostname, e)) + except vmodl.fault.InvalidRequest as e: + # Request is malformed + module.fail_json(msg="Failed to get a response from server %s as " + "request is malformed: %s" % (hostname, e.msg)) except Exception as e: - module.fail_json(msg="Unknown error connecting to vCenter or ESXi API at %s: %s" % (hostname, e)) + module.fail_json(msg="Unknown error while connecting to vCenter or ESXi API at %s: %s" % (hostname, e)) if service_instance is None: - module.fail_json(msg="Unknown error connecting to vCenter or ESXi API at %s" % hostname) + module.fail_json(msg="Unknown error while connecting to vCenter or ESXi API at %s" % hostname) # Disabling atexit should be used in special cases only. # Such as IP change of the ESXi host which removes the connection anyway. diff --git a/lib/ansible/modules/cloud/vmware/vmware_vm_facts.py b/lib/ansible/modules/cloud/vmware/vmware_vm_facts.py index 4c5cacf60d8..623f5f4c901 100644 --- a/lib/ansible/modules/cloud/vmware/vmware_vm_facts.py +++ b/lib/ansible/modules/cloud/vmware/vmware_vm_facts.py @@ -51,12 +51,12 @@ virtual_machines: try: from pyVmomi import vim, vmodl - HAS_PYVMOMI = True except ImportError: - HAS_PYVMOMI = False + pass from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.vmware import HAS_PYVMOMI, connect_to_api, get_all_objs, vmware_argument_spec +from ansible.module_utils.vmware import (HAS_PYVMOMI, connect_to_api, get_all_objs, + vmware_argument_spec, _get_vm_prop) # https://github.com/vmware/pyvmomi-community-samples/blob/master/samples/getallvms.py @@ -72,8 +72,9 @@ def get_all_virtual_machines(content): if _ip_address is None: _ip_address = "" _mac_address = [] - if vm.config is not None: - for dev in vm.config.hardware.device: + all_devices = _get_vm_prop(vm, ('config', 'hardware', 'device')) + if all_devices: + for dev in all_devices: if isinstance(dev, vim.vm.device.VirtualEthernetCard): _mac_address.append(dev.macAddress)