Repository: ansible/ansible

Issue:
Bug with aci_access_port_to_interface_policy_leaf_profile when attaching VPC interface leaf policy group
##### ISSUE TYPE
 - Bug Report


##### COMPONENT NAME
aci_access_port_to_interface_policy_leaf_profile

##### ANSIBLE VERSION

```
ansible 2.5.0
  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 = /usr/lib/python2.7/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.12 (default, Dec  4 2017, 14:50:18) [GCC 5.4.0 20160609]
```

##### CONFIGURATION
```yaml
  - name: Associate an Interface Access Port Selector to an Interface Policy Le$
    aci_access_port_to_interface_policy_leaf_profile:
        <<: *aci_login
        leaf_interface_profile: Leaf-01-02
        access_port_selector: "{{ item.name }}"
        leaf_port_blk: "{{ item.blk }}"
        description: "{{ item.description }}"
        from: "{{ item.port }}"
        to: "{{ item.port }}"
        policy_group: "{{ item.policygroupname }}"
        state: present
    delegate_to: localhost
    with_items:
      - name: tn-10-server2
        blk: server2-blk
        description: Tenant 10 interface selector
        policygroupname: tn-10-pol-grp-vpc
        port: 22
```

##### SUMMARY
When create an interface selector on the interface leaf profile and associating this leaf selector to an interface leaf policy group for a VPC PG, the policy binding is incorrect as seen from the API inspector.
```json
infraAccBaseGrp","tDn":"uni/infra/funcprof/accportgrp-tn-10-pol-grp-vpc
```
In the above for a VPC policy group it should be accbundle instead of accportgrp

When creating this directly on the APIC controller the API inspector shows the output below.
```json
{"infraRsAccBaseGrp":{"attributes":{"tDn":"uni/infra/funcprof/accbundle-tn-10-pol-grp-vpc"
```
##### 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.
-->

create an interface policy group with vpc
```yaml
- name: Create a Virtual Port Channel (VPC) Interface Policy Group (no description)
  aci_interface_policy_leaf_policy_group:
    host: apic
    username: admin
    password: SomeSecretPassword
    policy_group: tn-10-pol-grp-vpc
    lag_type: node
    link_level_policy: whateverlinklevelpolicy
    fibre_channel_interface_policy: whateverfcpolicy
    state: present

  - name: Associate an Interface Access Port Selector to an Interface Policy Le$
    aci_access_port_to_interface_policy_leaf_profile:
        host: apic
        username: admin
        password: SomeSecretPassword
        leaf_interface_profile: Leaf-01-02
        access_port_selector: "{{ item.name }}"
        leaf_port_blk: "{{ item.blk }}"
        description: "{{ item.description }}"
        from: "{{ item.port }}"
        to: "{{ item.port }}"
        policy_group: "{{ item.policygroupname }}"
        state: present
    delegate_to: localhost
    with_items:
      - name: tn-10-server2
        blk: server2-blk
        description: Tenant 10 interface selector
        policygroupname: tn-10-pol-grp-vpc
        port: 22
```
There is a fault which says 
```
Failed to form relation to MO uni/infra/funcprof/accportgrp-tn-10-pol-grp-vpc of class infraAccBaseGrp
```

##### EXPECTED RESULTS
If the policygroupname selected is of type VPC, the MO should be 
```json
{"infraRsAccBaseGrp":{"attributes":{"tDn":"uni/infra/funcprof/accbundle-tn-10-pol-grp-vpc"
```
##### ACTUAL RESULTS
```json
infraAccBaseGrp","tDn":"uni/infra/funcprof/accportgrp-tn-10-pol-grp-vpc
```


Discussion:
Files identified in the description:
* [lib/ansible/modules/network/aci/aci_access_port_to_interface_policy_leaf_profile.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/network/aci/aci_access_port_to_interface_policy_leaf_profile.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 @brunocalogero @dagwieers @jmcgill298 @schunduri
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
I can confirm this problem, too! Just ran into it and send a mail to dag privately. Same situation - APIC error when trying to provision a VPC configuration.

Resolving patch:
diff --git a/lib/ansible/modules/network/aci/aci_access_port_to_interface_policy_leaf_profile.py b/lib/ansible/modules/network/aci/aci_access_port_to_interface_policy_leaf_profile.py
--- a/lib/ansible/modules/network/aci/aci_access_port_to_interface_policy_leaf_profile.py
+++ b/lib/ansible/modules/network/aci/aci_access_port_to_interface_policy_leaf_profile.py
@@ -60,6 +60,12 @@
     description:
     - The name of the fabric access policy group to be associated with the leaf interface profile interface selector.
     aliases: [ policy_group_name ]
+  interface_type:
+    version_added: '2.6'
+    description:
+    - The type of interface for the static EPG deployement.
+    choices: [ fex, port_channel, switch_port, vpc ]
+    default: switch_port
   state:
     description:
     - Use C(present) or C(absent) for adding or removing.
@@ -235,6 +241,7 @@ def main():
         'from': dict(type='str', aliases=['fromPort', 'from_port_range']),
         'to': dict(type='str', aliases=['toPort', 'to_port_range']),
         'policy_group': dict(type='str', aliases=['policy_group_name']),
+        'interface_type': dict(type='str', default='switch_port', choices=['fex', 'port_channel', 'switch_port', 'vpc']),
         'state': dict(type='str', default='present', choices=['absent', 'present', 'query']),
     })
 
@@ -255,6 +262,7 @@ def main():
     from_ = module.params['from']
     to_ = module.params['to']
     policy_group = module.params['policy_group']
+    interface_type = module.params['interface_type']
     state = module.params['state']
 
     aci = ACIModule(module)
@@ -274,6 +282,14 @@ def main():
         ),
         child_classes=['infraPortBlk', 'infraRsAccBaseGrp']
     )
+
+    INTERFACE_TYPE_MAPPING = dict(
+        fex='uni/infra/funcprof/accportgrp-{0}'.format(policy_group),
+        port_channel='uni/infra/funcprof/accbundle-{0}'.format(policy_group),
+        switch_port='uni/infra/funcprof/accportgrp-{0}'.format(policy_group),
+        vpc='uni/infra/funcprof/accbundle-{0}'.format(policy_group),
+    )
+
     aci.get_existing()
 
     if state == 'present':
@@ -297,7 +313,7 @@ def main():
                 dict(
                     infraRsAccBaseGrp=dict(
                         attributes=dict(
-                            tDn='uni/infra/funcprof/accportgrp-{0}'.format(policy_group),
+                            tDn=INTERFACE_TYPE_MAPPING[interface_type],
                         ),
                     ),
                 ),


Test patch: