Repository: ansible/ansible

Issue:
aci_epg module needs to support PreferredGroup

##### ISSUE TYPE
 - Feature Idea

##### COMPONENT NAME
aci_epg

##### ANSIBLE VERSION
```
[root@ansible-server ~]# ansible --version
ansible 2.4.0.0
  config file = None
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Aug  4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
[root@ansible-server ~]#
```

##### CONFIGURATION

[root@ansible-server ~]# ansible-config dump --only-changed
[root@ansible-server ~]#

##### OS / ENVIRONMENT
Ansible server on CentOS 7.3 and ACI version 3.0 or 3.1

##### SUMMARY

Since ACI 2.3 it is possible to configure EPGs to be part of a Preferred Group. This is a new attribute of the fvAEPg object. EPGs that are part of the Preferred Group can communicate without contracts. This is very convenient for migration scenarios as well as customers that implement ACI for network automation but not for policy.

##### STEPS TO REPRODUCE



##### EXPECTED RESULTS

The module should have a new option to configure.

preferred_group: yes, no

The object to configure is:

fvAEPg.attributes.prefGrMemb and the option is "include" or "exclude".

##### ACTUAL RESULTS

```

```



Discussion:
@dagwieers 
cc @brunocalogero @jmcgill298 @schunduri
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
This would be brilliant!
@nilloBE have you found a workaround? I suppose either the source for the module needs to be changed or the aci_rest module has to be used instead. 
~@nilloBE @spidernik84 It would speed up the implementation if XML or JSON fragments are added so we know exactly what we need to do for this to work. Not all of us are ACI experts (I know I am not ;-)).~

Forgive me, some details are already included, I'll get to it now.

Resolving patch:
diff --git a/lib/ansible/modules/network/aci/aci_epg.py b/lib/ansible/modules/network/aci/aci_epg.py
--- a/lib/ansible/modules/network/aci/aci_epg.py
+++ b/lib/ansible/modules/network/aci/aci_epg.py
@@ -64,6 +64,13 @@
     - The APIC defaults new EPGs to C(none).
     choices: [ none, proxy-arp ]
     default: none
+  preferred_group:
+    description:
+    - Whether ot not the EPG is part of the Preferred Group and can communicate without contracts.
+    - This is very convenient for migration scenarios, or when ACI is used for network automation but not for policy.
+    type: bool
+    default: 'no'
+    version_added: '2.5'
   state:
     description:
     - Use C(present) or C(absent) for adding or removing.
@@ -84,6 +91,7 @@
     epg: web_epg
     description: Web Intranet EPG
     bd: prod_bd
+    preferred_group: yes
 
 - aci_epg:
     host: apic
@@ -169,6 +177,7 @@ def main():
         priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']),
         intra_epg_isolation=dict(choices=['enforced', 'unenforced']),
         fwd_control=dict(type='str', choices=['none', 'proxy-arp']),
+        preferred_group=dict(type='bool'),
         state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
         method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'),  # Deprecated starting from v2.6
         protocol=dict(type='str', removed_in_version='2.6'),  # Deprecated in v2.6
@@ -183,17 +192,19 @@ def main():
         ],
     )
 
+    aci = ACIModule(module)
+
     epg = module.params['epg']
     bd = module.params['bd']
     description = module.params['description']
     priority = module.params['priority']
     intra_epg_isolation = module.params['intra_epg_isolation']
     fwd_control = module.params['fwd_control']
+    preferred_group = aci.boolean(module.params['preferred_group'], 'include', 'exclude')
     state = module.params['state']
     tenant = module.params['tenant']
     ap = module.params['ap']
 
-    aci = ACIModule(module)
     aci.construct_url(
         root_class=dict(
             aci_class='fvTenant',
@@ -228,6 +239,7 @@ def main():
                 prio=priority,
                 pcEnfPref=intra_epg_isolation,
                 fwdCtrl=fwd_control,
+                prefGrMemb=preferred_group,
             ),
             child_configs=[
                 dict(fvRsBd=dict(attributes=dict(tnFvBDName=bd))),


Test patch: