From bd278816693b27537c787f1d6dc93a3852c707ff Mon Sep 17 00:00:00 2001 From: Sayali Naval <sayalinaval@gmail.com> Date: Sat, 24 Feb 2024 03:29:44 +0000 Subject: [PATCH] Add support for EPG static paths as top level resources Change-Id: Ie347a8e6a70e6870fd8d371991f7acadb3ea625e --- .../drivers/apic_aim/mechanism_driver.py | 65 ++-- .../unit/plugins/ml2plus/test_apic_aim.py | 342 ++++++++++++------ 2 files changed, 273 insertions(+), 134 deletions(-) diff --git a/gbpservice/neutron/plugins/ml2plus/drivers/apic_aim/mechanism_driver.py b/gbpservice/neutron/plugins/ml2plus/drivers/apic_aim/mechanism_driver.py index fd118cada..6ce09fa39 100644 --- a/gbpservice/neutron/plugins/ml2plus/drivers/apic_aim/mechanism_driver.py +++ b/gbpservice/neutron/plugins/ml2plus/drivers/apic_aim/mechanism_driver.py @@ -5665,14 +5665,27 @@ class ApicMechanismDriver(api_plus.MechanismDriver, return epg = self.aim.get(aim_ctx, epg) # Update old host values. - paths = set([(x['path'], x['encap'], x['host']) - for x in epg.static_paths if x['host'] != host]) - # Add new static ports. - paths |= set([(x.link.path, x.encap, x.link.host_name) - for x in static_ports]) - self.aim.update(aim_ctx, epg, static_paths=[ - {'path': x[0], 'encap': x[1], 'host': x[2]} - for x in paths]) + for static_port in static_ports: + static_path = self.aim.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg.tenant_name, + app_profile_name=epg.app_profile_name, + epg_name=epg.name, + path=static_port.link.path)) + if static_path: + # Update old host values. + self.aim.update(aim_ctx, static_path, + host=static_port.link.host_name) + else: + # Add new static ports. + static_path = aim_resource.EPGStaticPath( + tenant_name=epg.tenant_name, + app_profile_name=epg.app_profile_name, + epg_name=epg.name, + path=static_port.link.path, + encap=static_port.encap, + host=static_port.link.host_name) + self.aim.create(aim_ctx, static_path) def _get_topology_from_path(self, path): """Convert path string to toplogy elements. @@ -5962,20 +5975,32 @@ class ApicMechanismDriver(api_plus.MechanismDriver, epg = self.aim.get(aim_ctx, epg) # Static paths configured on an EPG can be uniquely # identified by their path attribute. - to_remove = [static_port.link.path] + to_remove = static_port.link.path if to_remove: - epg.static_paths = [p for p in epg.static_paths - if p.get('path') not in to_remove] + static_path = self.aim.get(aim_ctx, aim_resource.EPGStaticPath( + tenant_name=epg.tenant_name, + app_profile_name=epg.app_profile_name, + epg_name=epg.name, + path=to_remove)) + if static_path: + self.aim.delete(aim_ctx, static_path) + LOG.debug('Removing static path %s for EPG %s', + static_path, epg) if not remove and static_port: - static_info = {'path': static_port.link.path, - 'encap': static_port.encap, - 'mode': static_port.mode} + host = "" if static_port.link.host_name: - static_info['host'] = static_port.link.host_name - epg.static_paths.append(static_info) - LOG.debug('Setting static paths for EPG %s to %s', - epg, epg.static_paths) - self.aim.update(aim_ctx, epg, static_paths=epg.static_paths) + host = static_port.link.host_name + static_path = aim_resource.EPGStaticPath( + tenant_name=epg.tenant_name, + app_profile_name=epg.app_profile_name, + epg_name=epg.name, + path=static_port.link.path, + encap=static_port.encap, + mode=static_port.mode, + host=host) + LOG.debug('Adding static path %s for EPG %s', + static_path, epg) + self.aim.create(aim_ctx, static_path) def _get_static_ports(self, plugin_context, host, segment, port_context=None): @@ -7210,7 +7235,6 @@ class ApicMechanismDriver(api_plus.MechanismDriver, expected_epg = mgr.expected_aim_resource(epg) expected_epg.vmm_domains = actual_epg.vmm_domains expected_epg.physical_domains = actual_epg.physical_domains - expected_epg.static_paths = actual_epg.static_paths # REVISIT: Move to ValidationManager, just before # comparing actual and expected resources? expected_epg.openstack_vmm_domain_names = [ @@ -7550,7 +7574,6 @@ class ApicMechanismDriver(api_plus.MechanismDriver, epg.physical_domain_names = [] epg.vmm_domains = [] epg.physical_domains = [] - epg.static_paths = [] epg.epg_contract_masters = epg_contract_masters epg.monitored = False qos_policy_binding = net_db.get('qos_policy_binding') diff --git a/gbpservice/neutron/tests/unit/plugins/ml2plus/test_apic_aim.py b/gbpservice/neutron/tests/unit/plugins/ml2plus/test_apic_aim.py index 7eb38e13f..afccb3307 100644 --- a/gbpservice/neutron/tests/unit/plugins/ml2plus/test_apic_aim.py +++ b/gbpservice/neutron/tests/unit/plugins/ml2plus/test_apic_aim.py @@ -6741,7 +6741,6 @@ class TestPortBinding(ApicAimTestCase): parent_port_id = parent_port['id'] epg = self._net_2_epg(net1['network']) epg = self.aim_mgr.get(aim_ctx, epg) - self.assertEqual([], epg.static_paths) if with_subports: kwargs = {'provider:network_type': subport_net_type, 'provider:physical_network': subport_physnet} @@ -6753,7 +6752,6 @@ class TestPortBinding(ApicAimTestCase): sb_net1['network']['id'])['port'] epg = self._net_2_epg(sb_net1['network']) epg = self.aim_mgr.get(aim_ctx, epg) - self.assertEqual([], epg.static_paths) sb_net2 = self._make_network(self.fmt, 'subport_net2', True, arg_list=arg_list, **kwargs) @@ -6763,7 +6761,6 @@ class TestPortBinding(ApicAimTestCase): sb_net2['network']['id'])['port'] epg = self._net_2_epg(sb_net2['network']) epg = self.aim_mgr.get(aim_ctx, epg) - self.assertEqual([], epg.static_paths) # For now, trunk just has subport from sb_net1. subports = [{'port_id': subport_net1_port['id'], @@ -6800,18 +6797,28 @@ class TestPortBinding(ApicAimTestCase): net1['network']['provider:segmentation_id']) epg = self._net_2_epg(net1['network']) epg = self.aim_mgr.get(aim_ctx, epg) + path = 'topology/pod-1/paths-501/pathep-[eth1/1]' + static_path = self.aim_mgr.get(aim_ctx, aim_resource.EPGStaticPath( + tenant_name=epg.tenant_name, + app_profile_name=epg.app_profile_name, + epg_name=epg.name, + path=path)) vlan_name = 'vlan-%s' % access_vlan - self.assertEqual([{'path': 'topology/pod-1/paths-501/pathep-[eth1/1]', - 'mode': 'untagged', 'encap': vlan_name}], - epg.static_paths) + self.assertIsNotNone(static_path) + self.assertEqual('untagged', static_path.mode) + self.assertEqual(vlan_name, static_path.encap) if with_subports: epg = self._net_2_epg(sb_net1['network']) epg = self.aim_mgr.get(aim_ctx, epg) + static_path = self.aim_mgr.get(aim_ctx, aim_resource.EPGStaticPath( + tenant_name=epg.tenant_name, + app_profile_name=epg.app_profile_name, + epg_name=epg.name, + path=path)) vlan = 'vlan-%s' % (134 if not inherit else sb_net1['network']['provider:segmentation_id']) - self.assertEqual( - [{'path': 'topology/pod-1/paths-501/pathep-[eth1/1]', - 'encap': vlan}], epg.static_paths) + self.assertIsNotNone(static_path) + self.assertEqual(vlan, static_path.encap) trunk = self._show_trunk(net1['network']['tenant_id'], trunk['id'])['trunk'] # Trunk status is ACTIVE if parent and subports are bound. @@ -6867,9 +6874,13 @@ class TestPortBinding(ApicAimTestCase): epg = self.aim_mgr.get(aim_ctx, epg) vlan_name = 'vlan-%s' % (135 if not inherit else sb_net2['network']['provider:segmentation_id']) - self.assertEqual( - [{'path': 'topology/pod-1/paths-501/pathep-[eth1/1]', - 'encap': vlan_name}], epg.static_paths) + static_path = self.aim_mgr.get(aim_ctx, aim_resource.EPGStaticPath( + tenant_name=epg.tenant_name, + app_profile_name=epg.app_profile_name, + epg_name=epg.name, + path=path)) + self.assertIsNotNone(static_path) + self.assertEqual(vlan_name, static_path.encap) subports.extend(add_subports) self._update_trunk(net1['network']['tenant_id'], trunk['id'], subports, remove=True) @@ -6882,7 +6893,6 @@ class TestPortBinding(ApicAimTestCase): self.assertEqual('', subport['binding:host_id']) epg = self._net_2_epg(net['network']) epg = self.aim_mgr.get(aim_ctx, epg) - self.assertEqual([], epg.static_paths) # Trunk should still be active with only the bound parent port. trunk = self._show_trunk(net1['network']['tenant_id'], trunk['id'])['trunk'] @@ -10435,17 +10445,21 @@ class TestPortVlanNetwork(ApicAimTestCase): with self.port(subnet=sub1) as p1: # unbound port -> no static paths expected epg = self.aim_mgr.get(aim_ctx, epg) - self.assertEqual([], epg.static_paths) self._validate() # bind to host h1 p1 = self._bind_port_to_host(p1['port']['id'], 'h1') vlan_h1 = self._check_binding(p1['port']['id']) epg = self.aim_mgr.get(aim_ctx, epg) - self.assertEqual( - [{'path': self.hlink1.path, 'encap': 'vlan-%s' % vlan_h1, - 'host': 'h1'}], - epg.static_paths) + static_path = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg.tenant_name, + app_profile_name=epg.app_profile_name, + epg_name=epg.name, + path=self.hlink1.path)) + self.assertIsNotNone(static_path) + self.assertEqual('h1', static_path.host) + self.assertEqual('vlan-%s' % vlan_h1, static_path.encap) self._validate() p1 = self._show('ports', p1['port']['id']) @@ -10469,17 +10483,21 @@ class TestPortVlanNetwork(ApicAimTestCase): p1 = self._bind_port_to_host(p1['port']['id'], 'h2') vlan_h2 = self._check_binding(p1['port']['id']) epg = self.aim_mgr.get(aim_ctx, epg) - self.assertEqual( - [{'path': hlink2.path, 'encap': 'vlan-%s' % vlan_h2, - 'host': 'h2'}], - epg.static_paths) + static_path = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg.tenant_name, + app_profile_name=epg.app_profile_name, + epg_name=epg.name, + path=hlink2.path)) + self.assertIsNotNone(static_path) + self.assertEqual('h2', static_path.host) + self.assertEqual('vlan-%s' % vlan_h2, static_path.encap) self._validate() # delete port self._delete('ports', p1['port']['id']) self._check_no_dynamic_segment(net1['id']) epg = self.aim_mgr.get(aim_ctx, epg) - self.assertEqual([], epg.static_paths) self._validate() def test_port_lifecycle_internal_network(self): @@ -10680,10 +10698,15 @@ class TestPortVlanNetwork(ApicAimTestCase): vlan_p1 = self._check_binding(p1['port']['id']) if not is_svi: epg = self.aim_mgr.get(aim_ctx, epg) - self.assertEqual( - [{'path': self.hlink1.path, - 'encap': 'vlan-%s' % vlan_p1, 'host': 'h1'}], - epg.static_paths) + static_path = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg.tenant_name, + app_profile_name=epg.app_profile_name, + epg_name=epg.name, + path=self.hlink1.path)) + self.assertIsNotNone(static_path) + self.assertEqual('h1', static_path.host) + self.assertEqual('vlan-%s' % vlan_p1, static_path.encap) else: ext_net = aim_resource.ExternalNetwork.from_dn( net1[DN]['ExternalNetwork']) @@ -10753,10 +10776,16 @@ class TestPortVlanNetwork(ApicAimTestCase): self.assertEqual(vlan_p1, vlan_p2) if not is_svi: epg = self.aim_mgr.get(aim_ctx, epg) - self.assertEqual( - [{'path': self.hlink1.path, - 'encap': 'vlan-%s' % vlan_p2, 'host': 'h1'}], - epg.static_paths) + static_path = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg.tenant_name, + app_profile_name=epg.app_profile_name, + epg_name=epg.name, + path=self.hlink1.path)) + self.assertIsNotNone(static_path) + self.assertEqual('h1', static_path.host) + self.assertEqual('vlan-%s' % vlan_p2, + static_path.encap) else: l3out_node = self.aim_mgr.get(aim_ctx, l3out_node) self.assertEqual(l3out_node.router_id, apic_router_id) @@ -10783,10 +10812,16 @@ class TestPortVlanNetwork(ApicAimTestCase): self._check_binding(p1['port']['id']) if not is_svi: epg = self.aim_mgr.get(aim_ctx, epg) - self.assertEqual( - [{'path': self.hlink1.path, - 'encap': 'vlan-%s' % vlan_p1, 'host': 'h1'}], - epg.static_paths) + static_path = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg.tenant_name, + app_profile_name=epg.app_profile_name, + epg_name=epg.name, + path=self.hlink1.path)) + self.assertIsNotNone(static_path) + self.assertEqual('h1', static_path.host) + self.assertEqual('vlan-%s' % vlan_p1, + static_path.encap) else: for l3out_if in l3out_ifs: l3out_if = self.aim_mgr.get(aim_ctx, l3out_if) @@ -10810,7 +10845,6 @@ class TestPortVlanNetwork(ApicAimTestCase): self._check_no_dynamic_segment(net1['id']) if not is_svi: epg = self.aim_mgr.get(aim_ctx, epg) - self.assertEqual([], epg.static_paths) else: for l3out_if in l3out_ifs: l3out_if = self.aim_mgr.get(aim_ctx, l3out_if) @@ -10857,10 +10891,15 @@ class TestPortVlanNetwork(ApicAimTestCase): if not is_svi: epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual( - [{'path': self.hlink1.path, 'encap': 'vlan-%s' % vlan_p1, - 'host': 'h1'}], - epg1.static_paths) + static_path = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg1.tenant_name, + app_profile_name=epg1.app_profile_name, + epg_name=epg1.name, + path=self.hlink1.path)) + self.assertIsNotNone(static_path) + self.assertEqual('h1', static_path.host) + self.assertEqual('vlan-%s' % vlan_p1, static_path.encap) net2 = self._make_network(self.fmt, 'net2', True)['network'] epg2 = self._net_2_epg(net2) else: @@ -10932,10 +10971,15 @@ class TestPortVlanNetwork(ApicAimTestCase): if not is_svi: epg2 = self.aim_mgr.get(aim_ctx, epg2) - self.assertEqual( - [{'path': self.hlink1.path, 'encap': 'vlan-%s' % vlan_p2, - 'host': 'h1'}], - epg2.static_paths) + static_path = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg2.tenant_name, + app_profile_name=epg2.app_profile_name, + epg_name=epg2.name, + path=self.hlink1.path)) + self.assertIsNotNone(static_path) + self.assertEqual('h1', static_path.host) + self.assertEqual('vlan-%s' % vlan_p2, static_path.encap) else: ext_net = aim_resource.ExternalNetwork.from_dn( net2[DN]['ExternalNetwork']) @@ -11041,13 +11085,17 @@ class TestPortVlanNetwork(ApicAimTestCase): self._check_no_dynamic_segment(net2['id']) if not is_svi: epg2 = self.aim_mgr.get(aim_ctx, epg2) - self.assertEqual([], epg2.static_paths) epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual( - [{'path': self.hlink1.path, 'encap': 'vlan-%s' % vlan_p1, - 'host': 'h1'}], - epg1.static_paths) + static_path = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg1.tenant_name, + app_profile_name=epg1.app_profile_name, + epg_name=epg1.name, + path=self.hlink1.path)) + self.assertIsNotNone(static_path) + self.assertEqual('h1', static_path.host) + self.assertEqual('vlan-%s' % vlan_p1, static_path.encap) else: for l3out_if1 in l3out_if1s: l3out_if1 = self.aim_mgr.get(aim_ctx, l3out_if1) @@ -11150,12 +11198,24 @@ class TestPortVlanNetwork(ApicAimTestCase): if not is_svi: epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual( - [{'path': hlink_1a.path, 'encap': 'vlan-%s' % vlan_p1, - 'host': 'h1'}, - {'path': hlink_1b.path, 'encap': 'vlan-%s' % vlan_p1, - 'host': 'h1'}], - epg1.static_paths) + static_path1 = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg1.tenant_name, + app_profile_name=epg1.app_profile_name, + epg_name=epg1.name, + path=hlink_1a.path)) + self.assertIsNotNone(static_path1) + self.assertEqual('h1', static_path1.host) + self.assertEqual('vlan-%s' % vlan_p1, static_path1.encap) + static_path2 = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg1.tenant_name, + app_profile_name=epg1.app_profile_name, + epg_name=epg1.name, + path=hlink_1b.path)) + self.assertIsNotNone(static_path2) + self.assertEqual('h1', static_path2.host) + self.assertEqual('vlan-%s' % vlan_p1, static_path2.encap) else: ext_net = aim_resource.ExternalNetwork.from_dn( net1[DN]['ExternalNetwork']) @@ -11279,15 +11339,33 @@ class TestPortVlanNetwork(ApicAimTestCase): host_name='h1') if not is_svi: epg2 = self.aim_mgr.get(aim_ctx, epg2) - self.assertTrue( - g_utils.is_equal( - [{'path': host_links[0].path, 'encap': 'vlan-%s' % vlan_p2, - 'host': 'h1'}, - {'path': host_links[1].path, 'encap': 'vlan-%s' % vlan_p2, - 'host': 'h1'}, - {'path': host_links[2].path, 'encap': 'vlan-%s' % vlan_p2, - 'host': 'h1'}], - epg2.static_paths)) + static_path1 = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg2.tenant_name, + app_profile_name=epg2.app_profile_name, + epg_name=epg2.name, + path=host_links[0].path)) + self.assertIsNotNone(static_path1) + self.assertEqual('h1', static_path1.host) + self.assertEqual('vlan-%s' % vlan_p2, static_path1.encap) + static_path2 = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg2.tenant_name, + app_profile_name=epg2.app_profile_name, + epg_name=epg2.name, + path=host_links[1].path)) + self.assertIsNotNone(static_path2) + self.assertEqual('h1', static_path2.host) + self.assertEqual('vlan-%s' % vlan_p2, static_path2.encap) + static_path3 = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg2.tenant_name, + app_profile_name=epg2.app_profile_name, + epg_name=epg2.name, + path=host_links[2].path)) + self.assertIsNotNone(static_path3) + self.assertEqual('h1', static_path3.host) + self.assertEqual('vlan-%s' % vlan_p2, static_path3.encap) else: ext_net = aim_resource.ExternalNetwork.from_dn( net2[DN]['ExternalNetwork']) @@ -11331,14 +11409,25 @@ class TestPortVlanNetwork(ApicAimTestCase): if not is_svi: epg2 = self.aim_mgr.get(aim_ctx, epg2) - self.assertEqual([], epg2.static_paths) epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual( - [{'path': hlink_1a.path, 'encap': 'vlan-%s' % vlan_p1, - 'host': 'h1'}, - {'path': hlink_1b.path, 'encap': 'vlan-%s' % vlan_p1, - 'host': 'h1'}], - epg1.static_paths) + static_path1 = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg1.tenant_name, + app_profile_name=epg1.app_profile_name, + epg_name=epg1.name, + path=hlink_1a.path)) + self.assertIsNotNone(static_path1) + self.assertEqual('h1', static_path1.host) + self.assertEqual('vlan-%s' % vlan_p1, static_path1.encap) + static_path2 = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg1.tenant_name, + app_profile_name=epg1.app_profile_name, + epg_name=epg1.name, + path=hlink_1b.path)) + self.assertIsNotNone(static_path2) + self.assertEqual('h1', static_path2.host) + self.assertEqual('vlan-%s' % vlan_p1, static_path2.encap) else: for l3out_if2 in l3out_if2s: l3out_if2 = self.aim_mgr.get(aim_ctx, l3out_if2) @@ -11396,7 +11485,6 @@ class TestPortVlanNetwork(ApicAimTestCase): if not is_svi: epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual([], epg1.static_paths) else: for l3out_if1a in l3out_if1as: l3out_if1a = self.aim_mgr.get(aim_ctx, l3out_if1a) @@ -11468,12 +11556,24 @@ class TestPortVlanNetwork(ApicAimTestCase): if not is_svi: epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual( - [{'path': self.hlink1.path, 'encap': 'vlan-%s' % vlan_p1, - 'host': 'h1'}, - {'path': hlink2.path, 'encap': 'vlan-%s' % vlan_p2, - 'host': 'h2'}], - sorted(epg1.static_paths, key=lambda x: x['path'])) + static_path1 = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg1.tenant_name, + app_profile_name=epg1.app_profile_name, + epg_name=epg1.name, + path=self.hlink1.path)) + self.assertIsNotNone(static_path1) + self.assertEqual('h1', static_path1.host) + self.assertEqual('vlan-%s' % vlan_p1, static_path1.encap) + static_path2 = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg1.tenant_name, + app_profile_name=epg1.app_profile_name, + epg_name=epg1.name, + path=hlink2.path)) + self.assertIsNotNone(static_path2) + self.assertEqual('h2', static_path2.host) + self.assertEqual('vlan-%s' % vlan_p2, static_path2.encap) else: ext_net = aim_resource.ExternalNetwork.from_dn( net1[DN]['ExternalNetwork']) @@ -11564,10 +11664,15 @@ class TestPortVlanNetwork(ApicAimTestCase): self._delete('ports', p2['port']['id']) if not is_svi: epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual( - [{'path': self.hlink1.path, 'encap': 'vlan-%s' % vlan_p1, - 'host': 'h1'}], - epg1.static_paths) + static_path = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg1.tenant_name, + app_profile_name=epg1.app_profile_name, + epg_name=epg1.name, + path=self.hlink1.path)) + self.assertIsNotNone(static_path) + self.assertEqual('h1', static_path.host) + self.assertEqual('vlan-%s' % vlan_p1, static_path.encap) else: for l3out_if1b in l3out_if1bs: l3out_if1b = self.aim_mgr.get(aim_ctx, l3out_if1b) @@ -11598,7 +11703,6 @@ class TestPortVlanNetwork(ApicAimTestCase): if not is_svi: epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual([], epg1.static_paths) else: for l3out_if1a in l3out_if1as: l3out_if1a = self.aim_mgr.get(aim_ctx, l3out_if1a) @@ -11657,7 +11761,6 @@ class TestPortVlanNetwork(ApicAimTestCase): self._check_binding(p1['port']['id']) epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual([], epg1.static_paths) hlink42 = aim_infra.HostLink(host_name='h42', interface_name='eth0') @@ -11667,7 +11770,6 @@ class TestPortVlanNetwork(ApicAimTestCase): self._check_binding(p2['port']['id']) epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual([], epg1.static_paths) def _test_topology_rpc_no_ports(self, is_svi=False): nctx = n_context.get_admin_context() @@ -11702,7 +11804,6 @@ class TestPortVlanNetwork(ApicAimTestCase): self.assertIsNone(self.aim_mgr.get(aim_ctx, l3out_node1)) else: epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual([], epg1.static_paths) # remove hostlink for h10 self.driver.delete_link(nctx, 'h10', 'eth0', 'A:A', 0, 0, 0) self.assertIsNone(self.aim_mgr.get(aim_ctx, expected_hlink10)) @@ -11710,7 +11811,6 @@ class TestPortVlanNetwork(ApicAimTestCase): self.assertIsNone(self.aim_mgr.get(aim_ctx, l3out_node1)) else: epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual([], epg1.static_paths) def test_topology_rpc_no_ports(self): self._test_topology_rpc_no_ports() @@ -11754,7 +11854,6 @@ class TestPortVlanNetwork(ApicAimTestCase): self.assertIsNone(self.aim_mgr.get(aim_ctx, l3out_node)) else: epgs[x] = self.aim_mgr.get(aim_ctx, epgs[x]) - self.assertEqual([], epgs[x].static_paths) expected_hlink10 = aim_infra.HostLink(host_name='h10', interface_name='eth0', interface_mac='A:A', @@ -11764,11 +11863,18 @@ class TestPortVlanNetwork(ApicAimTestCase): def check_epg_static_paths(link_path): for x in range(0, len(epgs)): epgs[x] = self.aim_mgr.get(aim_ctx, epgs[x]) - expected_path = ([{'path': link_path, - 'encap': 'vlan-%s' % vlans[x], - 'host': 'h10'}] - if link_path else []) - self.assertEqual(expected_path, epgs[x].static_paths) + static_path = None + if link_path: + static_path = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epgs[x].tenant_name, + app_profile_name=epgs[x].app_profile_name, + epg_name=epgs[x].name, + path=link_path)) + self.assertIsNotNone(static_path) + self.assertEqual('h10', static_path.host) + self.assertEqual('vlan-%s' % vlans[x], + static_path.encap) def check_svi_paths(link_path): for x in range(0, len(nets)): @@ -11898,7 +12004,6 @@ class TestPortOnPhysicalNode(TestPortVlanNetwork): self._check_binding(p1['port']['id'], expected_binding_info=[('apic_aim', 'opflex')]) epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual([], epg1.static_paths) self._validate() # port on non-opflex host @@ -11906,10 +12011,15 @@ class TestPortOnPhysicalNode(TestPortVlanNetwork): p2 = self._bind_port_to_host(p2['port']['id'], 'h1') vlan_p2 = self._check_binding(p2['port']['id']) epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual( - [{'path': self.hlink1.path, 'encap': 'vlan-%s' % vlan_p2, - 'host': 'h1'}], - epg1.static_paths) + static_path = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg1.tenant_name, + app_profile_name=epg1.app_profile_name, + epg_name=epg1.name, + path=self.hlink1.path)) + self.assertIsNotNone(static_path) + self.assertEqual('h1', static_path.host) + self.assertEqual('vlan-%s' % vlan_p2, static_path.encap) self._validate() def test_mixed_ports_on_network_with_default_domains(self): @@ -12588,11 +12698,16 @@ class TestPortOnPhysicalNode(TestPortVlanNetwork): p1 = self._bind_port_to_host(p1['id'], 'h1', **kwargs)['port'] vlan_p1 = self._check_binding(p1['id'], expected_binding_info=expected_binding_info) - static_path_1 = {'path': bm_path1, 'encap': 'vlan-%s' % vlan_p1, - 'mode': 'untagged'} epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertEqual([static_path_1], - epg1.static_paths) + static_path1 = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg1.tenant_name, + app_profile_name=epg1.app_profile_name, + epg_name=epg1.name, + path=bm_path1)) + self.assertIsNotNone(static_path1) + self.assertEqual('untagged', static_path1.mode) + self.assertEqual('vlan-%s' % vlan_p1, static_path1.encap) self.assertEqual(set([]), set(self._doms(epg1.vmm_domains))) self.assertEqual(set(['ph1']), @@ -12615,11 +12730,16 @@ class TestPortOnPhysicalNode(TestPortVlanNetwork): expected_binding_info=expected_binding_info, top_bound_physnet='physnet3', bottom_bound_physnet='physnet2') - static_path_2 = {'path': bm_path2, 'encap': 'vlan-%s' % vlan_p2, - 'mode': 'untagged'} epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertIn(static_path_1, epg1.static_paths) - self.assertIn(static_path_2, epg1.static_paths) + static_path2 = self.aim_mgr.get(aim_ctx, + aim_resource.EPGStaticPath( + tenant_name=epg1.tenant_name, + app_profile_name=epg1.app_profile_name, + epg_name=epg1.name, + path=bm_path2)) + self.assertIsNotNone(static_path2) + self.assertEqual('untagged', static_path2.mode) + self.assertEqual('vlan-%s' % vlan_p2, static_path2.encap) self.assertEqual(set([]), set(self._doms(epg1.vmm_domains))) self.assertEqual(set(['ph1', 'ph2']), @@ -12629,8 +12749,6 @@ class TestPortOnPhysicalNode(TestPortVlanNetwork): kwargs = {portbindings.PROFILE: {}} self._bind_port_to_host(p1['id'], None, **kwargs)['port'] epg1 = self.aim_mgr.get(aim_ctx, epg1) - self.assertNotIn(static_path_1, epg1.static_paths) - self.assertIn(static_path_2, epg1.static_paths) def test_no_host_domain_mappings(self): with db_api.CONTEXT_READER.using(self.db_session): @@ -13076,11 +13194,9 @@ class TestPortOnPhysicalNodeSingleDriver(TestPortOnPhysicalNode): # VNICs). doms = [physical_domain] if delete: - static_path = [] - self.assertEqual(static_path, epg.static_paths) - self.assertEqual(set(doms), - set(self._doms(epg.physical_domains, - with_type=False))) + self.assertEqual(set(doms), + set(self._doms(epg.physical_domains, + with_type=False))) if net_type == 'vlan': expected_binding_info = [('apic_aim', 'vlan')]