Repository: ansible/ansible

Issue:
vmware_guest_snapshot fails with no vcenter server and esx version error
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
vmware_guest_snapshot

##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
```
ansible 2.3.0 (devel 4f96ee5e27) last updated 2017/02/08 00:19:00 (GMT +000)
  config file =
  configured module search path = Default w/o overrides
```

##### CONFIGURATION
Ansible built from git clone: git clone git://github.com/ansible/ansible.git --recursive
python 2.7.5
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
Trying to create a snapshot on a stand alone ESXi server using Dag's new vmware_guest_snapshot module and getting an error that "Current license or ESXi version prohibits execution of the requested operation."  Is this the intent?  Are these new vmware_guest* modules not going to support stand alone ESXi servers? 

##### STEPS TO REPRODUCE
Run this playbook to create a snapshot on an existing server.
<!--- Paste example playbooks or commands between quotes below -->
```yaml
---
- hosts: localhost
  gather_facts: False
  connection: local

  tasks:
  - vmware_guest_snapshot:
      hostname: esx.server.local
      username: sysadmin
      password: P@ssword
      datacenter: "ha-datacenter"
      name: test_vm
      uuid: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
      snapshot_name: test_vm.08022017_01
      description: snapshot_test_vm_01_08-02-201
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
Create a snapshot

##### ACTUAL RESULTS

```
TASK [vmware_guest_snapshot] **********************************************************************************************************************************************************************************************************************
task path: /opt/playbooks/vmware_create_snapshot.yml:7
Using module file /opt/ansible/lib/ansible/modules/cloud/vmware/vmware_guest_snapshot.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1486516649.63-80758741961903 `" && echo ansible-tmp-1486516649.63-80758741961903="` echo /root/.ansible/tmp/ansible-tmp-1486516649.63-80758741961903 `" ) && sleep 0'
<localhost> PUT /tmp/tmp7KrDhF TO /root/.ansible/tmp/ansible-tmp-1486516649.63-80758741961903/vmware_guest_snapshot.py
<localhost> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1486516649.63-80758741961903/ /root/.ansible/tmp/ansible-tmp-1486516649.63-80758741961903/vmware_guest_snapshot.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1486516649.63-80758741961903/vmware_guest_snapshot.py; rm -rf "/root/.ansible/tmp/ansible-tmp-1486516649.63-80758741961903/" > /dev/null 2>&1 && sleep 0'
 [WARNING]: Removed unexpected internal key in module return: _ansible_parsed = False

An exception occurred during task execution. The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_Oo1Mks/ansible_module_vmware_guest_snapshot.py", line 312, in <module>
    main()
  File "/tmp/ansible_Oo1Mks/ansible_module_vmware_guest_snapshot.py", line 301, in main
    result = pyv.apply_snapshot_op(vm)
  File "/tmp/ansible_Oo1Mks/ansible_module_vmware_guest_snapshot.py", line 235, in apply_snapshot_op
    task = self.snapshot_vm(vm)
  File "/tmp/ansible_Oo1Mks/ansible_module_vmware_guest_snapshot.py", line 210, in snapshot_vm
    quiesce)
  File "/usr/lib/python2.7/site-packages/pyVmomi/VmomiSupport.py", line 580, in <lambda>
    self.f(*(self.args + (obj,) + args), **kwargs)
  File "/usr/lib/python2.7/site-packages/pyVmomi/VmomiSupport.py", line 386, in _InvokeMethod
    return self._stub.InvokeMethod(self, info, args)
  File "/usr/lib/python2.7/site-packages/pyVmomi/SoapAdapter.py", line 1370, in InvokeMethod
    raise obj # pylint: disable-msg=E0702
pyVmomi.VmomiSupport.RestrictedVersion: (vim.fault.RestrictedVersion) {
   dynamicType = <unset>,
   dynamicProperty = (vmodl.DynamicProperty) [],
   msg = 'Current license or ESXi version prohibits execution of the requested operation.',
   faultCause = <unset>,
   faultMessage = (vmodl.LocalizableMessage) []
}

fatal: [localhost]: FAILED! => {
    "changed": false,
    "failed": true,
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_Oo1Mks/ansible_module_vmware_guest_snapshot.py\", line 312, in <module>\n    main()\n  File \"/tmp/ansible_Oo1Mks/ansible_module_vmware_guest_snapshot.py\", line 301, in main\n    result = pyv.apply_snapshot_op(vm)\n  File \"/tmp/ansible_Oo1Mks/ansible_module_vmware_guest_snapshot.py\", line 235, in apply_snapshot_op\n    task = self.snapshot_vm(vm)\n  File \"/tmp/ansible_Oo1Mks/ansible_module_vmware_guest_snapshot.py\", line 210, in snapshot_vm\n    quiesce)\n  File \"/usr/lib/python2.7/site-packages/pyVmomi/VmomiSupport.py\", line 580, in <lambda>\n    self.f(*(self.args + (obj,) + args), **kwargs)\n  File \"/usr/lib/python2.7/site-packages/pyVmomi/VmomiSupport.py\", line 386, in _InvokeMethod\n    return self._stub.InvokeMethod(self, info, args)\n  File \"/usr/lib/python2.7/site-packages/pyVmomi/SoapAdapter.py\", line 1370, in InvokeMethod\n    raise obj # pylint: disable-msg=E0702\npyVmomi.VmomiSupport.RestrictedVersion: (vim.fault.RestrictedVersion) {\n   dynamicType = <unset>,\n   dynamicProperty = (vmodl.DynamicProperty) [],\n   msg = 'Current license or ESXi version prohibits execution of the requested operation.',\n   faultCause = <unset>,\n   faultMessage = (vmodl.LocalizableMessage) []\n}\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 0
}

```



Discussion:
cc @nerzhul
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
in fact i developed the module (mainly moving code). It seems the API doesn't support snapshoting, error was not from us, but from VMWare API itself look it's "pyVmomi.VmomiSupport.RestrictedVersion" exception.

@dav1x @jctanner do you know this ?
@eastside-hustle What is the status of your VMWare Licence ? AFAIK, `Current license or ESXi version prohibits execution of the requested operation.` seem to be error when Licence is either expired or free one? Very good explanation about this error is given [here](https://benohead.com/esxi-restrictedversionfault/)
@Akasurde I am using the free ESXi license.  

Resolving patch:
diff --git a/lib/ansible/modules/cloud/vmware/vmware_guest_snapshot.py b/lib/ansible/modules/cloud/vmware/vmware_guest_snapshot.py
--- a/lib/ansible/modules/cloud/vmware/vmware_guest_snapshot.py
+++ b/lib/ansible/modules/cloud/vmware/vmware_guest_snapshot.py
@@ -160,9 +160,8 @@
 
 # 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.vmware import connect_to_api
+from ansible.module_utils._text import to_native
 
 try:
     import json
@@ -247,10 +246,18 @@ def snapshot_vm(self, vm):
         if vm.capability.memorySnapshotsSupported:
             memory_dump = self.module.params['memory_dump']
 
-        return vm.CreateSnapshot(self.module.params["snapshot_name"],
-                                 self.module.params["description"],
-                                 memory_dump,
-                                 quiesce)
+        task = None
+        try:
+            task = vm.CreateSnapshot(self.module.params["snapshot_name"],
+                                     self.module.params["description"],
+                                     memory_dump,
+                                     quiesce)
+        except vim.fault.RestrictedVersion as exc:
+            self.module.fail_json(msg="Failed to take snapshot due to VMware Licence: %s" % to_native(exc.msg))
+        except Exception as exc:
+            self.module.fail_json(msg="Failed to create snapshot of VM %s due to %s" % (self.module.params['name'], to_native(exc.msg)))
+
+        return task
 
     def remove_or_revert_snapshot(self, vm):
         if vm.snapshot is None:


Test patch: