Hi Michael,
I'm running into an ugly exception while trying to assign a few static paths to an EPG. Here's a piece of code that works fine and a modified version that crashes.
#############################################
# This code runs fine
#############################################
# Create the Tenant, App Profile, and EPG
tenant =Tenant("dummy")
app = AppProfile("myapp", tenant)
epg = EPG("myepg", app)
# Leaf-1, port1 goes with VLAN-2
intf1 = Interface("eth", "1", "101", "1", "1")
vlan_intf1 = L2Interface("vlan-2", "vlan", "2")
vlan_intf1.attach(intf1)
# Leaf-1, port2 goes with VLAN-3
intf2 = Interface("eth", "1", "101", "1", "2")
vlan_intf2 = L2Interface("vlan-3", "vlan", "3")
vlan_intf2.attach(intf2)
# Leaf-2, port20, goes with VLAN-4
intf3 = Interface("eth", "1", "102", "1", "20")
vlan_intf3 = L2Interface("vlan-4", "vlan", "4")
vlan_intf3.attach(intf3)
# Leaf-2, port 21, goes with VLAN-5
intf4 = Interface("eth", "1", "102", "1", "21")
vlan_intf4 = L2Interface("vlan-5", "vlan", "5")
vlan_intf4.attach(intf4)
# Now associate all VLAN ifaces with the EPG
epg.attach(vlan_intf1)
epg.attach(vlan_intf2)
epg.attach(vlan_intf3)
epg.attach(vlan_intf4)
print("The code above runs just fine!")
This code raises an exception:
#############################################
# This code raises an exception:
# ValueError: list.remove(x): x not in list
#############################################
# Create the Tenant, App Profile, and EPG
tenant =Tenant("dummy2")
app = AppProfile("myapp2", tenant)
epg = EPG("myepg2", app)
# Leaf-1, port1 goes with VLAN-2
intf1 = Interface("eth", "1", "101", "1", "1")
vlan_intf1 = L2Interface("vlan-2", "vlan", "2")
vlan_intf1.attach(intf1)
# Leaf-1, port2 goes with VLAN-2
intf2 = Interface("eth", "1", "101", "1", "2")
vlan_intf2 = L2Interface("vlan-2", "vlan", "2")
vlan_intf2.attach(intf2)
# Leaf-2, port20, goes with VLAN-3
intf3 = Interface("eth", "1", "102", "1", "20")
vlan_intf3 = L2Interface("vlan-3", "vlan", "3")
vlan_intf3.attach(intf3)
# Leaf-2, port 21, goes with VLAN-3
intf4 = Interface("eth", "1", "102", "1", "21")
vlan_intf4 = L2Interface("vlan-3", "vlan", "3")
vlan_intf4.attach(intf4)
# Now associate all VLAN ifaces with the EPG
epg.attach(vlan_intf1)
epg.attach(vlan_intf2)
epg.attach(vlan_intf3)
epg.attach(vlan_intf4)
print("This is never printed because an exception is raised!")
Exception raised looks like:
File "C:\code\deploy.py", line 539, in _load_policies
epg.attach(vlan_intf2)
File "build\bdist.win32\egg\acitoolkit\acibaseobject.py", line 425, in attach
ValueError: list.remove(x): x not in list
The documentation states: "Multiple logical L2 network attachments can occur on the same Ethernet interface. When this occurs, the L2Interface instances must use different encapsulation identifiers and/or different encapsulation types"
The statement above does not apply to this case, since the same encap is being applied to different interfaces, not to the same one. If I recall correctly, there is a limitation in ACI that prevents having two different VLAN encaps assigned to the same EPG on the same leaf, or something along those lines, but this isn't even the case here.
My use case is: I have a few endpoints connected to the same leaf, that belong to the same EPG and use the same encap. On other leaves, there may be other endpoints of that EPG using either the same or different encap. This currently can't be implemented, or at least I haven't been able to successfully run the code. (Note that since this raises and Exception, I haven't even tried to push the config to an APIC).
I've been trying to figure out how the whole "is already attached?" check works, looking at BaseACIObject::attach(), is_attached(), _check_relation(), etc, all the way down to BaseRelation(), but I'm having trouble even understanding how the comparison "return check in self._relations" will ever return true.
Could you please have a look at it? Thanks a lot. Best regards,
Luis.