Skip to content

Commit c162ea2

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "[OVN] A LRP in an external tunnelled network has no chassis" into stable/2023.1
2 parents c48f36d + b34911a commit c162ea2

File tree

3 files changed

+54
-50
lines changed

3 files changed

+54
-50
lines changed

neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,11 +1486,13 @@ def get_candidates_for_scheduling(self, physnet, cms=None,
14861486
"""Return chassis for scheduling gateway router.
14871487
14881488
Criteria for selecting chassis as candidates
1489-
1) chassis from cms with proper bridge mappings
1490-
2) if no chassis is available from 1) then,
1491-
select chassis with proper bridge mappings
1492-
3) Filter the available chassis accordingly to the routers
1489+
1) Chassis from cms with proper bridge mappings only (that means these
1490+
gateway chassis with the requested physical network).
1491+
2) Filter the available chassis accordingly to the routers
14931492
availability zone hints (if present)
1493+
1494+
If the logical router port belongs to a tunnelled network, there won't
1495+
be any candidate.
14941496
"""
14951497
# TODO(lucasagomes): Simplify the logic here, the CMS option has
14961498
# been introduced long ago and by now all gateway chassis should
@@ -1499,15 +1501,13 @@ def get_candidates_for_scheduling(self, physnet, cms=None,
14991501
cms = cms or self._sb_idl.get_gateway_chassis_from_cms_options()
15001502
chassis_physnets = (chassis_physnets or
15011503
self._sb_idl.get_chassis_and_physnets())
1502-
cms_bmaps = []
1503-
bmaps = []
1504+
candidates = set()
15041505
for chassis, physnets in chassis_physnets.items():
1505-
if physnet and physnet in physnets:
1506-
if chassis in cms:
1507-
cms_bmaps.append(chassis)
1508-
else:
1509-
bmaps.append(chassis)
1510-
candidates = cms_bmaps or bmaps or cms
1506+
if (physnet and
1507+
physnet in physnets and
1508+
chassis in cms):
1509+
candidates.add(chassis)
1510+
candidates = list(candidates)
15111511

15121512
# Filter for availability zones
15131513
if availability_zone_hints:
@@ -1518,11 +1518,8 @@ def get_candidates_for_scheduling(self, physnet, cms=None,
15181518
if az in utils.get_chassis_availability_zones(
15191519
self._sb_idl.lookup('Chassis', ch, None))]
15201520

1521-
if not cms_bmaps:
1522-
LOG.debug("No eligible chassis with external connectivity"
1523-
" through ovn-cms-options for %s", physnet)
1524-
LOG.debug("Chassis candidates for scheduling gateway router ports: %s",
1525-
candidates)
1521+
LOG.debug('Chassis candidates for scheduling gateway router ports '
1522+
'for "%s" physical network: %s', physnet, candidates)
15261523
return candidates
15271524

15281525
def _get_physnet(self, network):

neutron/tests/functional/services/ovn_l3/test_plugin.py

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,14 @@
3232

3333

3434
class TestRouter(base.TestOVNFunctionalBase):
35-
def setUp(self):
36-
super(TestRouter, self).setUp()
35+
def setUp(self, **kwargs):
36+
super().setUp(**kwargs)
3737
self.chassis1 = self.add_fake_chassis(
38-
'ovs-host1', physical_nets=['physnet1', 'physnet3'])
38+
'ovs-host1', physical_nets=['physnet1', 'physnet3'],
39+
enable_chassis_as_gw=True, azs=[])
3940
self.chassis2 = self.add_fake_chassis(
40-
'ovs-host2', physical_nets=['physnet2', 'physnet3'])
41+
'ovs-host2', physical_nets=['physnet2', 'physnet3'],
42+
enable_chassis_as_gw=True, azs=[])
4143
self.cr_lrp_pb_event = events.WaitForCrLrpPortBindingEvent()
4244
self.sb_api.idl.notify_handler.watch_event(self.cr_lrp_pb_event)
4345

@@ -95,12 +97,14 @@ def test_gateway_chassis_on_router_gateway_port(self):
9597
self.assertIn(rc, expected)
9698

9799
def _check_gateway_chassis_candidates(self, candidates,
98-
router_az_hints=None):
100+
router_az_hints=None,
101+
physnet='physnet1'):
99102
# In this test, fake_select() is called once from _create_router()
100103
# and later from schedule_unhosted_gateways()
101104
ovn_client = self.l3_plugin._ovn_client
105+
net_type = 'vlan' if physnet else 'geneve'
102106
ext1 = self._create_ext_network(
103-
'ext1', 'vlan', 'physnet1', 1, "10.0.0.1", "10.0.0.0/24")
107+
'ext1', net_type, physnet, 1, "10.0.0.1", "10.0.0.0/24")
104108
# mock select function and check if it is called with expected
105109
# candidates.
106110

@@ -131,12 +135,11 @@ def fake_select(*args, **kwargs):
131135

132136
def test_gateway_chassis_with_cms_and_bridge_mappings(self):
133137
# Both chassis1 and chassis3 are having proper bridge mappings,
134-
# but only chassis3 is having enable-chassis-as-gw.
135-
# Test if chassis3 is selected as candidate or not.
138+
# but only chassis1 is having enable-chassis-as-gw.
139+
# Test if chassis1 is selected as candidate or not.
136140
self.chassis3 = self.add_fake_chassis(
137-
'ovs-host3', physical_nets=['physnet1'],
138-
other_config={'ovn-cms-options': 'enable-chassis-as-gw'})
139-
self._check_gateway_chassis_candidates([self.chassis3])
141+
'ovs-host3', physical_nets=['physnet1'], azs=[])
142+
self._check_gateway_chassis_candidates([self.chassis1])
140143

141144
def test_gateway_chassis_with_cms_and_no_bridge_mappings(self):
142145
# chassis1 is having proper bridge mappings.
@@ -170,12 +173,10 @@ def test_gateway_chassis_with_cms_and_azs(self):
170173
# Test if chassis3 is selected as candidate or not.
171174
self.chassis3 = self.add_fake_chassis(
172175
'ovs-host3', physical_nets=['physnet1'],
173-
other_config={'ovn-cms-options': 'enable-chassis-as-gw'},
174-
azs=['ovn'])
176+
azs=['ovn'], enable_chassis_as_gw=True)
175177
self.chassis4 = self.add_fake_chassis(
176178
'ovs-host4', physical_nets=['physnet1'],
177-
other_config={'ovn-cms-options': 'enable-chassis-as-gw'},
178-
azs=['ovn2'])
179+
azs=['ovn2'], enable_chassis_as_gw=True)
179180
self._check_gateway_chassis_candidates([self.chassis3],
180181
router_az_hints=['ovn'])
181182

@@ -185,11 +186,9 @@ def test_gateway_chassis_with_cms_and_not_match_azs(self):
185186
# AvailabilityZoneNotFound. after create will delete if.
186187
# add chassis4 is having azs [ovn2], not match routers az_hints [ovn]
187188
self.chassis3 = self.add_fake_chassis(
188-
'ovs-host3', physical_nets=['physnet1'],
189-
other_config={'ovn-cms-options': 'enable-chassis-as-gw'})
189+
'ovs-host3', physical_nets=['physnet1'], enable_chassis_as_gw=True)
190190
self.chassis4 = self.add_fake_chassis(
191-
'ovs-host4', physical_nets=['physnet1'],
192-
other_config={'ovn-cms-options': 'enable-chassis-as-gw'},
191+
'ovs-host4', physical_nets=['physnet1'], enable_chassis_as_gw=True,
193192
azs=['ovn2'])
194193
ovn_client = self.l3_plugin._ovn_client
195194
ext1 = self._create_ext_network(
@@ -217,6 +216,11 @@ def test_gateway_chassis_with_bridge_mappings_and_no_cms(self):
217216
# Test if chassis1 is selected as candidate or not.
218217
self._check_gateway_chassis_candidates([self.chassis1])
219218

219+
def test_gateway_chassis_no_physnet_tunnelled_network(self):
220+
# The GW network is tunnelled, no physnet defined --> no possible
221+
# candidates.
222+
self._check_gateway_chassis_candidates([], physnet=None)
223+
220224
def _l3_ha_supported(self):
221225
# If the Gateway_Chassis table exists in SB database, then it
222226
# means that L3 HA is supported.

neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2554,24 +2554,27 @@ def fake_lookup(table, chassis_name, default):
25542554
return ch
25552555
ovn_client._sb_idl.lookup = fake_lookup
25562556

2557-
# The target physnet and availability zones
2558-
physnet = 'public'
2559-
az_hints = ['az0', 'az2']
2560-
2557+
# List of chassis and chassis:physnet mappings.
2558+
physnet_name = 'public'
25612559
cms = [ch0.name, ch1.name, ch2.name, ch3.name, ch4.name, ch5.name]
2562-
ch_physnet = {ch0.name: [physnet], ch1.name: [physnet],
2563-
ch2.name: [physnet], ch3.name: [physnet],
2560+
ch_physnet = {ch0.name: [physnet_name], ch1.name: [physnet_name],
2561+
ch2.name: [physnet_name], ch3.name: [physnet_name],
25642562
ch4.name: ['another-physnet'],
25652563
ch5.name: ['yet-another-physnet']}
25662564

2567-
candidates = ovn_client.get_candidates_for_scheduling(
2568-
physnet, cms=cms, chassis_physnets=ch_physnet,
2569-
availability_zone_hints=az_hints)
2570-
2571-
# Only chassis ch0 and ch2 should match the availability zones
2572-
# hints and physnet we passed to get_candidates_for_scheduling()
2573-
expected_candidates = [ch0.name, ch2.name]
2574-
self.assertEqual(sorted(expected_candidates), sorted(candidates))
2565+
# The target physnets, the availability zones and the expected
2566+
# candidates.
2567+
results = [{'physnet': physnet_name, 'az_hints': ['az0', 'az2'],
2568+
'expected_candidates': [ch0.name, ch2.name]},
2569+
{'physnet': None, 'az_hints': ['az0', 'az2'],
2570+
'expected_candidates': []},
2571+
]
2572+
for result in results:
2573+
candidates = ovn_client.get_candidates_for_scheduling(
2574+
result['physnet'], cms=cms, chassis_physnets=ch_physnet,
2575+
availability_zone_hints=result['az_hints'])
2576+
self.assertEqual(sorted(result['expected_candidates']),
2577+
sorted(candidates))
25752578

25762579
def test__get_info_for_ha_chassis_group_as_extport(self):
25772580
net_attrs = {az_def.AZ_HINTS: ['az0', 'az1', 'az2']}

0 commit comments

Comments
 (0)