Repository: ansible/ansible

Issue:
NX_OS ignoring save_snapshot_locally.
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and devel branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
 - Bug Report

##### COMPONENT NAME
nxos_snapshot

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.4.1.0
  config file = /Users/naruto/Documents/GitHub/customers/uhcs/uhcs-core-refresh/ansible/ansible.cfg
  configured module search path = [u'/Users/naruto/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /Library/Python/2.7/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 2.7.10 (default, Feb  7 2017, 00:08:15) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]
```

##### CONFIGURATION
```
[defaults]
deprecation_warnings = False
host_key_checking = False
inventory = inventory/network
gathering = explicit
callback_whitelist = profile_tasks
[paramiko_connection]
host_key_auto_add = True
```

##### OS / ENVIRONMENT
NX-OS nxos.7.0.3.I2.2d.bin

##### SUMMARY
The module is creating the snapshot but is not saving the snapshot locally.

##### STEPS TO REPRODUCE
Using this:
```
- name: save configuration for nxos
  nxos_snapshot:
    action: create
    snapshot_name: "{{ inventory_hostname }}-{{ timestamp }}"
    description: "snapshot-{{ timestamp }}"
    save_snapshot_locally: true
    path: "{{ playbook_dir }}/nexus-snapshots/"
  when: inventory_hostname in groups['nxos']
```

##### EXPECTED RESULTS
One or more files under the folder **nexus-snapshots**.

##### ACTUAL RESULTS
The snapshot is created but is not copied locally.




Discussion:
Files identified in the description:
* [lib/ansible/modules/network/nxos/nxos_snapshot.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/network/nxos/nxos_snapshot.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @GGabriele @kedarX @mikewiebe @privateip @rahushen @rcarrillocruz @trishnaguha
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Also if the `action=compare` the result is not copied locally either, although it looks like the comparison is happening.
I also found that using this:
```
  nxos_snapshot:
    action: compare
    snapshot2: n9k-leaf1-20180308182236Z
    snapshot1: n9k-leaf1-20180308182052Z
    compare_option: summary
```
Will return an error:
```
fatal: [n9k-leaf1]: FAILED! => {"changed": false, "failed": true, "msg": "snapshot1 and snapshot2 are required when action=create"}
```
That should be another problem, snapshot1 and snapshot2 is only for `action=compare`.
Thanks.

Resolving patch:
diff --git a/lib/ansible/modules/network/nxos/nxos_snapshot.py b/lib/ansible/modules/network/nxos/nxos_snapshot.py
--- a/lib/ansible/modules/network/nxos/nxos_snapshot.py
+++ b/lib/ansible/modules/network/nxos/nxos_snapshot.py
@@ -69,7 +69,7 @@
         default: null
     comparison_results_file:
         description:
-            - Name of the file where snapshots comparison will be store.
+            - Name of the file where snapshots comparison will be stored when C(action=compare).
         required: false
         default: null
     compare_option:
@@ -354,6 +354,11 @@ def main():
 
     argument_spec.update(nxos_argument_spec)
 
+    required_if = [("action", "compare", ["snapshot1", "snapshot2", "comparison_results_file"]),
+                   ("action", "create", ["snapshot_name", "description"]),
+                   ("action", "add", ["section", "show_command", "row_id", "element_key1"]),
+                   ("action", "delete", ["snapshot_name"])]
+
     module = AnsibleModule(argument_spec=argument_spec,
                            supports_check_mode=True)
 
@@ -363,33 +368,10 @@ def main():
     action = module.params['action']
     comparison_results_file = module.params['comparison_results_file']
 
-    CREATE_PARAMS = ['snapshot_name', 'description']
-    ADD_PARAMS = ['section', 'show_command', 'row_id', 'element_key1']
-    COMPARE_PARAMS = ['snapshot1', 'snapshot2', 'comparison_results_file']
-
     if not os.path.isdir(module.params['path']):
         module.fail_json(msg='{0} is not a valid directory name.'.format(
             module.params['path']))
 
-    if action == 'create':
-        for param in CREATE_PARAMS:
-            if not module.params[param]:
-                module.fail_json(msg='snapshot_name and description are '
-                                     'required when action=create')
-    elif action == 'add':
-        for param in ADD_PARAMS:
-            if not module.params[param]:
-                module.fail_json(msg='section, show_command, row_id '
-                                     'and element_key1 are required '
-                                     'when action=add')
-    elif action == 'compare':
-        for param in COMPARE_PARAMS:
-            if not module.params[param]:
-                module.fail_json(msg='snapshot1 and snapshot2 are required '
-                                     'when action=create')
-    elif action == 'delete' and not module.params['snapshot_name']:
-        module.fail_json(msg='snapshot_name is required when action=delete')
-
     existing_snapshots = invoke('get_existing', module)
     action_results = invoke('action_%s' % action, module, existing_snapshots)
 


Test patch: