Repository: ansible/ansible

Issue:
nxos_vrf issues
<!---
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
<!---
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_vrf
##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.6.0 (devel fed20b825f) last updated 2018/02/15 12:51:12 (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 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)I7(2)

##### SUMMARY
<!--- Explain the problem briefly -->

There are few problems with nxos_vrf module.

1. Even though it is mentioned that 'default' keyword is allowed for vni, rd, it is NOT working.
2. No 'default' keyword for parameter 'description'.
3. interfaces is a new parameter added in 2.5 but no 'default' keyword is supported and so there is no way to remove all the interfaces. 
4. platform differences need to addressed in integration tests as vni and rd are NOT supported on all platforms.

Note: I will open a PR shortly to address these above issues


Discussion:

Resolving patch:
diff --git a/lib/ansible/modules/network/nxos/nxos_vrf.py b/lib/ansible/modules/network/nxos/nxos_vrf.py
--- a/lib/ansible/modules/network/nxos/nxos_vrf.py
+++ b/lib/ansible/modules/network/nxos/nxos_vrf.py
@@ -74,7 +74,7 @@
   interfaces:
     description:
       - List of interfaces to check the VRF has been
-        configured correctly.
+        configured correctly or keyword 'default'.
     version_added: 2.5
   associated_interfaces:
     description:
@@ -98,7 +98,7 @@
     choices: ['present','absent']
   description:
     description:
-      - Description of the VRF.
+      - Description of the VRF or keyword 'default'.
     required: false
     default: null
   delay:
@@ -257,7 +257,7 @@ def map_obj_to_commands(updates, module):
                 commands.append('vrf context {0}'.format(name))
                 for item in args:
                     candidate = w.get(item)
-                    if candidate:
+                    if candidate and candidate != 'default':
                         cmd = item + ' ' + str(candidate)
                         commands.append(cmd)
                 if admin_state == 'up':
@@ -266,7 +266,7 @@ def map_obj_to_commands(updates, module):
                     commands.append('shutdown')
                 commands.append('exit')
 
-                if interfaces:
+                if interfaces and interfaces[0] != 'default':
                     for i in interfaces:
                         commands.append('interface {0}'.format(i))
                         commands.append('no switchport')
@@ -280,7 +280,11 @@ def map_obj_to_commands(updates, module):
 
                 for item in args:
                     candidate = w.get(item)
-                    if candidate and candidate != obj_in_have.get(item):
+                    if candidate == 'default':
+                        if obj_in_have.get(item):
+                            cmd = 'no ' + item + ' ' + obj_in_have.get(item)
+                            commands.append(cmd)
+                    elif candidate and candidate != obj_in_have.get(item):
                         cmd = item + ' ' + str(candidate)
                         commands.append(cmd)
                 if admin_state and admin_state != obj_in_have.get('admin_state'):
@@ -293,7 +297,7 @@ def map_obj_to_commands(updates, module):
                     commands.insert(0, 'vrf context {0}'.format(name))
                     commands.append('exit')
 
-                if interfaces:
+                if interfaces and interfaces[0] != 'default':
                     if not obj_in_have['interfaces']:
                         for i in interfaces:
                             commands.append('vrf context {0}'.format(name))
@@ -318,6 +322,14 @@ def map_obj_to_commands(updates, module):
                             commands.append('interface {0}'.format(i))
                             commands.append('no switchport')
                             commands.append('no vrf member {0}'.format(name))
+                elif interfaces and interfaces[0] == 'default':
+                    if obj_in_have['interfaces']:
+                        for i in obj_in_have['interfaces']:
+                            commands.append('vrf context {0}'.format(name))
+                            commands.append('exit')
+                            commands.append('interface {0}'.format(i))
+                            commands.append('no switchport')
+                            commands.append('no vrf member {0}'.format(name))
 
     if purge:
         existing = get_existing_vrfs(module)


Test patch:
diff --git a/test/integration/targets/nxos_vrf/tests/common/sanity.yaml b/test/integration/targets/nxos_vrf/tests/common/sanity.yaml
--- a/test/integration/targets/nxos_vrf/tests/common/sanity.yaml
+++ b/test/integration/targets/nxos_vrf/tests/common/sanity.yaml
@@ -3,21 +3,39 @@
 - debug: msg="Using provider={{ connection.transport }}"
   when: ansible_connection == "local"
 
-- block:
-  - name: 'Setup: Delete VRF before test'
-    nxos_config:
-      lines:
-        - no vrf context ntc
-      provider: "{{ connection }}"
-    ignore_errors: yes
+- set_fact: intname1="{{ nxos_int1 }}"
+- set_fact: intname2="{{ nxos_int2 }}"
+
+- set_fact: rdnd="1:2"
+  when: (platform is not match("N35|N7K")) and ((imagetag != 'I2'))
+
+- set_fact: rdd="default"
+  when: (platform is not match("N35|N7K")) and ((imagetag != 'I2'))
+
+- set_fact: vnind="5000"
+  when: platform is not match("N35|N7K")
+
+- set_fact: vnid="default"
+  when: platform is not match("N35|N7K")
 
+- name: "Enable feature BGP"
+  nxos_feature:
+    feature: bgp
+    state: enabled
+    provider: "{{ connection }}"
+  ignore_errors: yes
+
+- block:
   - name: Ensure ntc VRF exists on switch
     nxos_vrf: &configure
       vrf: ntc
       admin_state: down
       description: testing
-      #vni: 5000
-      #rd: auto
+      vni: "{{vnind|default(omit)}}"
+      rd: "{{rdnd|default(omit)}}"
+      interfaces:
+        - "{{ intname1 }}"
+        - "{{ intname2 }}"
       provider: "{{ connection }}"
     register: result
 
@@ -33,13 +51,30 @@
       that:
         - "result.changed == false"
 
+  - pause:
+      seconds: 30
+
+  - name: Remove config
+    nxos_vrf: &remconf
+      vrf: ntc
+      admin_state: up
+      vni: "{{vnid|default(omit)}}"
+      rd: "{{rdd|default(omit)}}"
+      interfaces: default
+      provider: "{{ connection }}"
+    register: result
+
+  - assert: *true
+
+  - name: "Conf Idempotence"
+    nxos_vrf: *remconf
+    register: result
+
+  - assert: *false
+
   - name: Ensure ntc VRF does not exist on switch
     nxos_vrf: &remove
       vrf: ntc
-      admin_state: down
-      description: testing
-      #vni: 5000
-      #rd: auto
       state: absent
       provider: "{{ connection }}"
     register: result
@@ -55,11 +90,12 @@
 
   - assert: *false
 
-  - name: 'Teardown: Delete VRF after test'
-    nxos_config:
-      lines:
-        - no vrf context ntc
+  always:
+  - name: "Disable feature BGP"
+    nxos_feature:
+      feature: bgp
+      state: disabled
       provider: "{{ connection }}"
     ignore_errors: yes
 
-- debug: msg="END connection={{ ansible_connection }} nxos_vrf sanity test"
+  - debug: msg="END connection={{ ansible_connection }} nxos_vrf sanity test"