Repository: ansible/ansible

Issue:
nxos_gir issues
<!---
Verify first that your issue/request is not already reported on GitHub.
THIS FORM WILL BE READ BY A MACHINE, COMPLETE ALL SECTIONS AS DESCRIBED.
Also test if the latest release, and devel branch are affected too.
ALWAYS add information AFTER (OUTSIDE) these html comments.
Otherwise it may end up being automatically closed by our bot. -->

##### SUMMARY
<!--- Explain the problem briefly -->

##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
<!--- Insert, BELOW THIS COMMENT, the name of the module, plugin, task or feature.
Do not include extra details here, e.g. "vyos_command" not "the network module vyos_command" or the full path-->
nxos_gir
##### ANSIBLE VERSION
<!--- Paste, BELOW THIS COMMENT, verbatim output from "ansible --version" between quotes below -->
```
ansible 2.7.0.dev0 (devel 8f144976df) last updated 2018/06/21 13:23:19 (GMT -400)
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /root/agents-ci/ansible/lib/ansible
  executable location = /root/agents-ci/ansible/bin/ansible
  python version = 2.7.6 (default, Oct 26 2016, 20:30:19) [GCC 4.8.4]
```

##### OS / ENVIRONMENT
<!--- Mention, BELOW THIS COMMENT, the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.-->
Ansible Server : Ubuntu 14.04
Device: N9K running 7.0(3)F3(4)

##### STEPS TO REPRODUCE
<!--- For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used. -->
There are few issues with nxos_gir module.

* system_mode_maintenance_on_reload_reset_reason has more choices in newer platforms.
* system_mode_maintenance_shutdown is not idempotent
* Dead code
* Documentation is not complete for system_mode_maintenance_on_reload_reset_reason
* Integration test cases are incomplete.

Note: I will open a PR shortly to address the above issues

nxos_gir issues
<!---
Verify first that your issue/request is not already reported on GitHub.
THIS FORM WILL BE READ BY A MACHINE, COMPLETE ALL SECTIONS AS DESCRIBED.
Also test if the latest release, and devel branch are affected too.
ALWAYS add information AFTER (OUTSIDE) these html comments.
Otherwise it may end up being automatically closed by our bot. -->

##### SUMMARY
<!--- Explain the problem briefly -->

##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
<!--- Insert, BELOW THIS COMMENT, the name of the module, plugin, task or feature.
Do not include extra details here, e.g. "vyos_command" not "the network module vyos_command" or the full path-->
nxos_gir
##### ANSIBLE VERSION
<!--- Paste, BELOW THIS COMMENT, verbatim output from "ansible --version" between quotes below -->
```
ansible 2.7.0.dev0 (devel 8f144976df) last updated 2018/06/21 13:23:19 (GMT -400)
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /root/agents-ci/ansible/lib/ansible
  executable location = /root/agents-ci/ansible/bin/ansible
  python version = 2.7.6 (default, Oct 26 2016, 20:30:19) [GCC 4.8.4]
```

##### OS / ENVIRONMENT
<!--- Mention, BELOW THIS COMMENT, the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.-->
Ansible Server : Ubuntu 14.04
Device: N9K running 7.0(3)F3(4)

##### STEPS TO REPRODUCE
<!--- For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used. -->
There are few issues with nxos_gir module.

* system_mode_maintenance_on_reload_reset_reason has more choices in newer platforms.
* system_mode_maintenance_shutdown is not idempotent
* Dead code
* Documentation is not complete for system_mode_maintenance_on_reload_reset_reason
* Integration test cases are incomplete.

Note: I will open a PR shortly to address the above issues



Discussion:

Resolving patch:
diff --git a/lib/ansible/modules/network/nxos/nxos_gir.py b/lib/ansible/modules/network/nxos/nxos_gir.py
--- a/lib/ansible/modules/network/nxos/nxos_gir.py
+++ b/lib/ansible/modules/network/nxos/nxos_gir.py
@@ -74,9 +74,14 @@
     system_mode_maintenance_on_reload_reset_reason:
         description:
             - Boots the switch into maintenance mode automatically in the
-              event of a specified system crash.
+              event of a specified system crash. Note that not all reset
+              reasons are applicable for all platforms. Also if reset
+              reason is set to match_any, it is not idempotent as it turns
+              on all reset reasons. If reset reason is match_any and state
+              is absent, it turns off all the reset reasons.
         choices: ['hw_error','svc_failure','kern_failure','wdog_timeout',
-                  'fatal_error','lc_failure','match_any','manual_reload']
+                  'fatal_error','lc_failure','match_any','manual_reload',
+                  'any_other', 'maintenance']
     state:
         description:
             - Specify desired state of the resource.
@@ -159,23 +164,10 @@
 from ansible.module_utils.basic import AnsibleModule
 
 
-def execute_show_command(command, module, command_type='cli_show_ascii'):
-    cmds = [command]
-    device_info = get_capabilities(module)
-    network_api = device_info.get('network_api', 'nxapi')
-
-    if network_api == 'cliconf':
-        body = run_commands(module, cmds)
-    elif network_api == 'nxapi':
-        body = run_commands(module, cmds)
-
-    return body
-
-
 def get_system_mode(module):
-    command = 'show system mode'
-    body = execute_show_command(command, module)[0]
-    if 'normal' in body.lower():
+    command = {'command': 'show system mode', 'output': 'text'}
+    body = run_commands(module, [command])[0]
+    if body and 'normal' in body.lower():
         mode = 'normal'
     else:
         mode = 'maintenance'
@@ -183,15 +175,15 @@ def get_system_mode(module):
 
 
 def get_maintenance_timeout(module):
-    command = 'show maintenance timeout'
-    body = execute_show_command(command, module)[0]
+    command = {'command': 'show maintenance timeout', 'output': 'text'}
+    body = run_commands(module, [command])[0]
     timeout = body.split()[4]
     return timeout
 
 
 def get_reset_reasons(module):
-    command = 'show maintenance on-reload reset-reasons'
-    body = execute_show_command(command, module)[0]
+    command = {'command': 'show maintenance on-reload reset-reasons', 'output': 'text'}
+    body = run_commands(module, [command])[0]
     return body
 
 
@@ -224,8 +216,13 @@ def get_commands(module, state, mode):
             commands.append('no system mode maintenance timeout {0}'.format(
                             module.params['system_mode_maintenance_timeout']))
 
-    elif module.params['system_mode_maintenance_shutdown'] is True:
+    elif (module.params['system_mode_maintenance_shutdown'] and
+            mode == 'normal'):
         commands.append('system mode maintenance shutdown')
+    elif (module.params[
+          'system_mode_maintenance_shutdown'] is False and
+          mode == 'maintenance'):
+        commands.append('no system mode maintenance')
 
     elif module.params['system_mode_maintenance_on_reload_reset_reason']:
         reset_reasons = get_reset_reasons(module)
@@ -259,7 +256,8 @@ def main():
         system_mode_maintenance_on_reload_reset_reason=dict(required=False,
                                                             choices=['hw_error', 'svc_failure', 'kern_failure',
                                                                      'wdog_timeout', 'fatal_error', 'lc_failure',
-                                                                     'match_any', 'manual_reload']),
+                                                                     'match_any', 'manual_reload', 'any_other',
+                                                                     'maintenance']),
         state=dict(choices=['absent', 'present', 'default'],
                    default='present', required=False)
     )


Test patch:
diff --git a/test/integration/targets/nxos_gir/tests/common/sanity.yaml b/test/integration/targets/nxos_gir/tests/common/sanity.yaml
--- a/test/integration/targets/nxos_gir/tests/common/sanity.yaml
+++ b/test/integration/targets/nxos_gir/tests/common/sanity.yaml
@@ -1,101 +1,119 @@
-#---
-#- debug: msg="START connection={{ ansible_connection }} nxos_gir sanity test"
+---
+- debug: msg="START connection={{ ansible_connection }} nxos_gir sanity test"
 - debug: msg="Using provider={{ connection.transport }}"
   when: ansible_connection == "local"
-#
+
+- set_fact: gir_run="true"
+- set_fact: gir_run="false"
+  when: platform is search("N35")
 #- name: "Setup"
 #  nxos_gir: &setup
 #    system_mode_maintenance: false
+#    provider: "{{ connection }}"
 #  ignore_errors: yes
-#
-#- block:
+
+- block:
+  - name: "Put system in maintenance mode with reload reset reason"
+    nxos_gir: &reset_reason
+      system_mode_maintenance_on_reload_reset_reason: manual_reload
+      provider: "{{ connection }}"
+    register: result
+
+  - assert: &true
+      that:
+        - "result.changed == true"
+
+  - name: "Check Idempotence"
+    nxos_gir: *reset_reason
+    register: result
+
+  - assert: &false
+      that:
+        - "result.changed == false"
+
+  - name: "Remove reload reason"
+    nxos_gir: &remove_reason
+      system_mode_maintenance_on_reload_reset_reason: manual_reload
+      state: absent
+      provider: "{{ connection }}"
+    register: result
+
+  - assert: *true
+
+  - name: "Check Idempotence"
+    nxos_gir: *remove_reason
+    register: result
+
+  - assert: *false
+
+  - name: "Put system in maintenance mode with timeout"
+    nxos_gir: &mtime
+      system_mode_maintenance_timeout: 30
+      provider: "{{ connection }}"
+    register: result
+
+  - assert: *true
+
+  - name: "Check Idempotence"
+    nxos_gir: *mtime
+    register: result
+
+  - assert: *false
+
+  - name: "Remove maintenance mode timeout"
+    nxos_gir: &remove_timeout
+      system_mode_maintenance_timeout: 30
+      state: absent
+      provider: "{{ connection }}"
+    register: result
+
+  - assert: *true
+
+  - name: "Check Idempotence"
+    nxos_gir: *remove_timeout
+    register: result
+
+  - assert: *false
+
 #  - name: "Put system in maintenance mode"
 #    nxos_gir: &configure_system_mode_maintenance
 #      system_mode_maintenance: true
+#      provider: "{{ connection }}"
 #    register: result
 #
-#  - assert: &true
-#      that:
-#        - "result.changed == true"
-#
-#  - name: "Check Idempotence"
-#    nxos_gir: *configure_system_mode_maintenance
-#    register: result
-#
-#  - assert: &false
-#      that:
-#        - "result.changed == false"
-#
-#  - name: "Put system back in normal mode"
-#    nxos_gir: *setup
-#    register: result
-#  
 #  - assert: *true
-#
-#  - name: "Check Idempotence"
-#    nxos_gir: *setup
-#    register: result
-#
-#  - assert: *false
-#
-#  - name: "Put system in maintenance mode with reload reset reason"
-#    nxos_gir:
-#      system_mode_maintenance: true
-#      system_mode_maintenance_on_reload_reset_reason: manual_reload
-#    register: result
-#
-#  - assert: *true
-#
-#  - name: "Remove reload reason"
-#    nxos_gir: &remove_reason
-#      system_mode_maintenance_on_reload_reset_reason: manual_reload
-#      state: absent
-#    register: result
-#   
-#  - assert: *true
-#
-#  - name: "Check Idempotence"
-#    nxos_gir: *remove_reason
-#    register: result
-#
-#  - assert: *false
-#
-#  - name: "Put system in maintenance mode with timeout"
-#    nxos_gir:
-#      system_mode_maintenance: true
-#      system_mode_maintenance_timeout: 30
-#    register: result 
-#
-#  - assert: *true
-#
-#  - name: "Remove maintenance mode timeout"
-#    nxos_gir: &remove_timeout
-#      system_mode_maintenance_timeout: 30
-#      state: absent
-#    register: result
-#
-#  - assert: *true
-#    
-#  - name: "Check Idempotence"
-#    nxos_gir: *remove_timeout
-#    register: result
-#
-#  - assert: *false
-#
+
+  when: gir_run
+
+  rescue:
+
+  - debug: msg="connection={{ ansible_connection }} nxos_gir failure detected"
+
+  always:
+
+  - name: "Remove snapshots"
+    nxos_snapshot:
+      action: delete_all
+      provider: "{{ connection }}"
+    ignore_errors: yes
+
+  - name: "Remove other config1"
+    nxos_config:
+      lines: no configure maintenance profile normal-mode
+      match: none
+      provider: "{{ connection }}"
+    ignore_errors: yes
+
+  - name: "Remove other config2"
+    nxos_config:
+      lines: no configure maintenance profile maintenance-mode
+      match: none
+      provider: "{{ connection }}"
+    ignore_errors: yes
+
 #  - name: "Put system back in normal mode"
 #    nxos_gir: *setup
 #    register: result
-#
-#  - assert: *true
-#
-#  rescue:
-#
-#  - debug: msg="connection={{ ansible_connection }} nxos_gir failure detected"
-#
-#  always:
-#
-#  - name: "Put system back in normal mode"
-#    nxos_gir: *setup
-#    register: result
-#
-#  - debug: msg="END connection={{ ansible_connection }} nxos_gir sanity test"  
+#    ignore_errors: yes
+
+- debug: msg="END connection={{ ansible_connection }} nxos_gir sanity test"