Repository: ansible/ansible

Issue:
(P2) nxos_vrf_af not idempotent
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
nxos_vrf_af

##### ANSIBLE VERSION
```
ansible 2.4.0 (devel 54cd641df4) last updated 2017/07/19 18:06:44 (GMT -400)
  config file = None
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /root/p2/Projects/nxos_ansible/p1_ansible/lib/ansible
  executable location = /root/p2/Projects/nxos_ansible/p1_ansible/bin/ansible
  python version = 2.7.6 (default, Oct 26 2016, 20:30:19) [GCC 4.8.4]
```

##### OS / ENVIRONMENT
Ansible Server : Ubuntu 14.04
Device: NX-OSv9K running 7.0(3)I4(6)

##### SUMMARY
- nxos_vrf_af is not idempotent. It keeps changing the configuration repeatedly

##### STEPS TO REPRODUCE
Playbook:

```
- name: Configure feature bgp
  nxos_feature:
    feature: bgp
    state: enabled
    provider: "{{ cli }}"

- name: Configure feature nv overlay
  nxos_config:
    commands: "feature nv overlay"
    provider: "{{ cli }}"

- name: Configure nv overlay evpn
  nxos_config:
    commands: "nv overlay evpn"
    provider: "{{ cli }}"

- block:
  - name: Configure vrf af
    nxos_vrf_af: &configure
      vrf: ansible
      afi: ipv4
      route_target_both_auto_evpn: true
      provider: "{{ cli }}"
    register: result

  - assert: &true
      that:
        - "result.changed == true"

  - name: "Conf Idempotence"
    nxos_vrf_af: *configure
    register: result

  - assert: &false
      that:
        - "result.changed == false"

  - name: Remove vrf af
    nxos_vrf_af: &remove
      vrf: ansible
      afi: ipv4
      route_target_both_auto_evpn: true
      state: absent
      provider: "{{ cli }}"
    register: result

  - assert: *true

  - pause:
      seconds: 30

  - name: "Remove Idempotence"
    nxos_vrf_af: *remove
    register: result

  - assert: *false

  always:
  - name: Remove feature bgp
    nxos_feature:
      feature: bgp
      state: disabled
      provider: "{{ cli }}"

  - name: Remove feature nv overlay
    nxos_config:
      commands: "no feature nv overlay"
      provider: "{{ cli }}"
    ignore_errors: yes

  - name: Remove nv overlay evpn
    nxos_config:
      commands: "no nv overlay evpn"
      provider: "{{ cli }}"
    ignore_errors: yes
```

##### EXPECTED RESULTS
```
PLAY RECAP ********************************************************************************************************************************************
n9k.example.com       : ok=23   changed=10    unreachable=0    failed=0
```

##### ACTUAL RESULTS
```
TASK [nxos_vrf_af : Conf Idempotence] *****************************************************************************************************************
changed: [n9k.example.com]                                                                                                                        

TASK [nxos_vrf_af : assert] ***************************************************************************************************************************
fatal: [n9k.example.com]: FAILED! => {                                                                                                            
    "assertion": "result.changed == false",                                                                                                            
    "changed": false,                                                                                                                                  
    "evaluated_to": false,                                                                                                                             
    "failed": true                                                                                                                                     
}                     
```



Discussion:
cc @GGabriele @jedelman8 @mikewiebe @privateip @rahushen @rcarrillocruz @trishnaguha
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/lib/ansible/modules/network/nxos/nxos_vrf_af.py b/lib/ansible/modules/network/nxos/nxos_vrf_af.py
--- a/lib/ansible/modules/network/nxos/nxos_vrf_af.py
+++ b/lib/ansible/modules/network/nxos/nxos_vrf_af.py
@@ -90,13 +90,11 @@ def main():
     argument_spec = dict(
         vrf=dict(required=True),
         afi=dict(required=True, choices=['ipv4', 'ipv6']),
-
         route_target_both_auto_evpn=dict(required=False, type='bool'),
+        state=dict(choices=['present', 'absent'], default='present'),
 
-        m_facts=dict(default=False, type='bool'),
+        m_facts=dict(default=False, type='bool', removed_in_version="2.4"),
         safi=dict(choices=['unicast', 'multicast'], removed_in_version="2.4"),
-
-        state=dict(choices=['present', 'absent'], default='present')
     )
 
     argument_spec.update(nxos_argument_spec)
@@ -120,23 +118,27 @@ def main():
         current = None
 
     commands = list()
+    if current and module.params['state'] == 'absent':
+        commands.append('no address-family %s unicast' % module.params['afi'])
 
-    if not current and module.params['state'] == 'present':
-        commands.append('address-family %s unicast' % module.params['afi'])
-        if module.params['route_target_both_auto_evpn']:
-            commands.append('route-target both auto evpn')
+    elif module.params['state'] == 'present':
 
-    elif current and module.params['state'] == 'absent':
-        commands.append('no address-family %s unicast' % module.params['afi'])
+        if current:
+            have = 'route-target both auto evpn' in current
+            want = bool(module.params['route_target_both_auto_evpn'])
 
-    elif current:
-        if module.params['route_target_both_auto_evpn']:
-            commands.append('address-family %s unicast' % module.params['afi'])
-            if 'route-target both auto evpn' in current:
+            if want and not have:
+                commands.append('address-family %s unicast' % module.params['afi'])
                 commands.append('route-target both auto evpn')
-            else:
+            elif have and not want:
+                commands.append('address-family %s unicast' % module.params['afi'])
                 commands.append('no route-target both auto evpn')
 
+        else:
+            commands.append('address-family %s unicast' % module.params['afi'])
+            if module.params['route_target_both_auto_evpn']:
+                commands.append('route-target both auto evpn')
+
     if commands:
         commands.insert(0, 'vrf context %s' % module.params['vrf'])
         if not module.check_mode:


Test patch: