Repository: ansible/ansible

Issue:
vmware_guest state fails with exception
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
vmware_guestansib

##### ANSIBLE VERSION
```
ansible 2.3.0
  config file =
  configured module search path = Default w/o overrides
```

##### CONFIGURATION
Ansible built from devel tarball @ https://github.com/ansible/ansible/archive/devel.tar.gz
pyshere 0.1.7
pyvmomi 6.5
ESX 6.0.0

##### OS / ENVIRONMENT
CentOS Linux release 7.3.1611 (Core) patched and up to date

##### SUMMARY
vmware_guest states poweredon, poweredoff, restarted do not work if the current state is different than the intended state.  Ie., poweredon does not work for a vm that is poweredoff.  Throws this error: "global name 'get_exception' is not defined".  If the module doesn't need to change state (ie running poweredon on a vm that is powered on) you get no error and the status is green unchanged.

##### STEPS TO REPRODUCE
Run this playbook:
<!--- Paste example playbooks or commands between quotes below -->
```yaml
---
- hosts: localhost
  gather_facts: False
  connection: local

  tasks:
  - vmware_guest:
     hostname: 10.0.0.25
     username: sysadmin
     password: p@ssword
     validate_certs: False
     name: testvm
     state: restarted
```


##### EXPECTED RESULTS
Restart, power on or power off vm guests

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
Throws error:  
<!--- Paste verbatim command output between quotes below -->
```
TASK [vmware_guest] *************************************************************************************************************************************************************************************************************************************************
task path: /opt/playbooks/vmware_poweron.yml:7
Using module file /opt/ansible-devel/lib/ansible/modules/cloud/vmware/vmware_guest.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo ~/.ansible/tmp/ansible-tmp-1484045789.62-15924742279620 `" && echo ansible-tmp-1484045789.62-15924742279620="` echo ~/.ansible/tmp/ansible-tmp-1484045789.62-15924742279620 `" ) && sleep 0'
<localhost> PUT /tmp/tmpEnTUQ4 TO /root/.ansible/tmp/ansible-tmp-1484045789.62-15924742279620/vmware_guest.py
<localhost> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1484045789.62-15924742279620/ /root/.ansible/tmp/ansible-tmp-1484045789.62-15924742279620/vmware_guest.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1484045789.62-15924742279620/vmware_guest.py; rm -rf "/root/.ansible/tmp/ansible-tmp-1484045789.62-15924742279620/" > /dev/null 2>&1 && sleep 0'
An exception occurred during task execution. The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_oWcaJm/ansible_module_vmware_guest.py", line 1848, in <module>
    main()
  File "/tmp/ansible_oWcaJm/ansible_module_vmware_guest.py", line 1814, in main
    tmp_result = pyv.set_powerstate(vm, module.params['state'], module.params['force'])
  File "/tmp/ansible_oWcaJm/ansible_module_vmware_guest.py", line 762, in set_powerstate
    'msg': get_exception()}
NameError: global name 'get_exception' is not defined

fatal: [localhost]: FAILED! => {
    "changed": false,
    "failed": true,
    "invocation": {
        "module_name": "vmware_guest"
    },
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_oWcaJm/ansible_module_vmware_guest.py\", line 1848, in <module>\n    main()\n  File \"/tmp/ansible_oWcaJm/ansible_module_vmware_guest.py\", line 1814, in main\n    tmp_result = pyv.set_powerstate(vm, module.params['state'], module.params['force'])\n  File \"/tmp/ansible_oWcaJm/ansible_module_vmware_guest.py\", line 762, in set_powerstate\n    'msg': get_exception()}\nNameError: global name 'get_exception' is not defined\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 0
}
```



Discussion:

Resolving patch:
diff --git a/lib/ansible/modules/cloud/vmware/vmware_guest.py b/lib/ansible/modules/cloud/vmware/vmware_guest.py
--- a/lib/ansible/modules/cloud/vmware/vmware_guest.py
+++ b/lib/ansible/modules/cloud/vmware/vmware_guest.py
@@ -352,6 +352,7 @@
 
 # import module snippets
 from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.pycompat24 import get_exception
 from ansible.module_utils.six import iteritems
 from ansible.module_utils.urls import fetch_url
 from ansible.module_utils.vmware import get_all_objs, connect_to_api
@@ -731,8 +732,8 @@ def set_powerstate(self, vm, state, force):
                                   'msg': 'Cannot suspend VM in the current state %s' % current_state}
 
             except Exception:
-                result = {'changed': False, 'failed': True,
-                          'msg': get_exception()}
+                e = get_exception()
+                result = {'changed': False, 'failed': True, 'msg': e}
 
             if task:
                 self.wait_for_task(task)


Test patch: