Skip to content

Commit 8a4c62d

Browse files
ralonsohfelixhuettner
authored andcommitted
Since OVN 20.06, config is stored in "Chassis.other_config"
Since OVN 20.06 [1], the OVN configuration is stored in "Chassis.other_config". Since OVN 22.09, the "Chassis" configuration stored in "Chassis.other_config" will not be replicated to "Chassis.external_ids". The ML2/OVN plugin tries to retrieve the "Chassis" configuration from the "other_config" field first; if this field does not exist (in OVN versions before 20.06), the plugin will use "external_ids" field instead. Neutron will be compatible with the different OVN versions (with and without "other_config" field). [1]ovn-org/ovn@74d90c2 [2]ovn-org/ovn@5130942 NOTE: this patch is similar to [1], but in this case neutron keeps compatibility with the different OVN versions (with and without "other_config" field). Since [2], the Neutron CI has a new job that uses the OVN/OVS packages distributed by the operating system installed by the CI (in this case, Ubuntu 20.04 and OVN 20.03). [1]https://review.opendev.org/c/openstack/neutron/+/859642 [2]https://review.opendev.org/c/openstack/neutron/+/860636 conflicting files in cherry pick: - neutron/tests/functional/base.py - neutron/tests/functional/services/ovn_l3/test_plugin.py Closes-Bug: #1990229 Change-Id: I54c8fd4d065ae537f396408df16832b158ee8998 (cherry picked from commit 536498a)
1 parent 1183240 commit 8a4c62d

File tree

19 files changed

+150
-97
lines changed

19 files changed

+150
-97
lines changed

neutron/common/ovn/utils.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,8 +625,8 @@ def compute_address_pairs_diff(ovn_port, neutron_port):
625625

626626
def get_ovn_cms_options(chassis):
627627
"""Return the list of CMS options in a Chassis."""
628-
return [opt.strip() for opt in chassis.external_ids.get(
629-
constants.OVN_CMS_OPTIONS, '').split(',')]
628+
return [opt.strip() for opt in get_ovn_chassis_other_config(chassis).get(
629+
constants.OVN_CMS_OPTIONS, '').split(',')]
630630

631631

632632
def is_gateway_chassis(chassis):
@@ -815,3 +815,11 @@ def create_neutron_pg_drop():
815815
}]
816816

817817
OvsdbClientTransactCommand.run(command)
818+
819+
820+
def get_ovn_chassis_other_config(chassis):
821+
# NOTE(ralonsoh): LP#1990229 to be removed when min OVN version is 22.09
822+
try:
823+
return chassis.other_config
824+
except AttributeError:
825+
return chassis.external_ids

neutron/plugins/ml2/drivers/ovn/agent/neutron_agent.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ def as_dict(self):
8989
'configurations': {
9090
'chassis_name': self.chassis.name,
9191
'bridge-mappings':
92-
self.chassis.external_ids.get('ovn-bridge-mappings', '')},
92+
ovn_utils.get_ovn_chassis_other_config(self.chassis).get(
93+
'ovn-bridge-mappings', '')},
9394
'start_flag': True,
9495
'agent_type': self.agent_type,
9596
'id': self.agent_id,
@@ -141,9 +142,9 @@ class ControllerAgent(NeutronAgent):
141142

142143
@staticmethod # it is by default, but this makes pep8 happy
143144
def __new__(cls, chassis_private, driver):
144-
external_ids = cls.chassis_from_private(chassis_private).external_ids
145-
if ('enable-chassis-as-gw' in
146-
external_ids.get('ovn-cms-options', [])):
145+
_chassis = cls.chassis_from_private(chassis_private)
146+
other_config = ovn_utils.get_ovn_chassis_other_config(_chassis)
147+
if 'enable-chassis-as-gw' in other_config.get('ovn-cms-options', []):
147148
cls = ControllerGatewayAgent
148149
return super().__new__(cls)
149150

@@ -166,8 +167,9 @@ def description(self):
166167

167168
def update(self, chassis_private, clear_down=False):
168169
super().update(chassis_private, clear_down)
169-
external_ids = self.chassis_from_private(chassis_private).external_ids
170-
if 'enable-chassis-as-gw' in external_ids.get('ovn-cms-options', []):
170+
_chassis = self.chassis_from_private(chassis_private)
171+
other_config = ovn_utils.get_ovn_chassis_other_config(_chassis)
172+
if 'enable-chassis-as-gw' in other_config.get('ovn-cms-options', []):
171173
self.__class__ = ControllerGatewayAgent
172174

173175

@@ -176,9 +178,10 @@ class ControllerGatewayAgent(ControllerAgent):
176178

177179
def update(self, chassis_private, clear_down=False):
178180
super().update(chassis_private, clear_down)
179-
external_ids = self.chassis_from_private(chassis_private).external_ids
181+
_chassis = self.chassis_from_private(chassis_private)
182+
other_config = ovn_utils.get_ovn_chassis_other_config(_chassis)
180183
if ('enable-chassis-as-gw' not in
181-
external_ids.get('ovn-cms-options', [])):
184+
other_config.get('ovn-cms-options', [])):
182185
self.__class__ = ControllerAgent
183186

184187

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,8 @@ def sb_ovn(self, val):
179179
def get_supported_vif_types(self):
180180
vif_types = set()
181181
for ch in self.sb_ovn.chassis_list().execute(check_error=True):
182-
dp_type = ch.external_ids.get('datapath-type', '')
182+
other_config = ovn_utils.get_ovn_chassis_other_config(ch)
183+
dp_type = other_config.get('datapath-type', '')
183184
if dp_type == ovn_const.CHASSIS_DATAPATH_NETDEV:
184185
vif_types.add(portbindings.VIF_TYPE_VHOST_USER)
185186
else:
@@ -961,8 +962,9 @@ def bind_port(self, context):
961962
'agent': agent})
962963
return
963964
chassis = agent.chassis
964-
datapath_type = chassis.external_ids.get('datapath-type', '')
965-
iface_types = chassis.external_ids.get('iface-types', '')
965+
other_config = ovn_utils.get_ovn_chassis_other_config(chassis)
966+
datapath_type = other_config.get('datapath-type', '')
967+
iface_types = other_config.get('iface-types', '')
966968
iface_types = iface_types.split(',') if iface_types else []
967969
chassis_physnets = self.sb_ovn._get_chassis_physnets(chassis)
968970
for segment_to_bind in context.segments_to_bind:

neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/extensions/placement.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ def _parse_ovn_cms_options(chassis):
4242

4343

4444
def _parse_bridge_mappings(chassis):
45-
bridge_mappings = chassis.external_ids.get('ovn-bridge-mappings', '')
45+
other_config = ovn_utils.get_ovn_chassis_other_config(chassis)
46+
bridge_mappings = other_config.get('ovn-bridge-mappings', '')
4647
bridge_mappings = helpers.parse_mappings(bridge_mappings.split(','),
4748
unique_values=False)
4849
return {k: [v] for k, v in bridge_mappings.items()}

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,8 @@ def from_worker(cls, worker_class, driver=None):
830830
return cls(conn)
831831

832832
def _get_chassis_physnets(self, chassis):
833-
bridge_mappings = chassis.external_ids.get('ovn-bridge-mappings', '')
833+
other_config = utils.get_ovn_chassis_other_config(chassis)
834+
bridge_mappings = other_config.get('ovn-bridge-mappings', '')
834835
mapping_dict = helpers.parse_mappings(bridge_mappings.split(','))
835836
return list(mapping_dict.keys())
836837

@@ -848,7 +849,8 @@ def get_gateway_chassis_from_cms_options(self, name_only=True):
848849
return [ch.name if name_only else ch
849850
for ch in self.chassis_list().execute(check_error=True)
850851
if ovn_const.CMS_OPT_CHASSIS_AS_GW in
851-
ch.external_ids.get(ovn_const.OVN_CMS_OPTIONS, '').split(',')]
852+
utils.get_ovn_chassis_other_config(ch).get(
853+
ovn_const.OVN_CMS_OPTIONS, '').split(',')]
852854

853855
def get_chassis_and_physnets(self):
854856
chassis_info_dict = {}
@@ -867,7 +869,7 @@ def get_chassis_by_card_serial_from_cms_options(self,
867869
if ('{}={}'
868870
.format(ovn_const.CMS_OPT_CARD_SERIAL_NUMBER,
869871
card_serial_number)
870-
in ch.external_ids.get(
872+
in utils.get_ovn_chassis_other_config(ch).get(
871873
ovn_const.OVN_CMS_OPTIONS, '').split(',')):
872874
return ch
873875
msg = _('Chassis with %s %s %s does not exist'

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

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,21 @@ def handle_ha_chassis_group_changes(self, event, row, old):
172172
def match_fn(self, event, row, old):
173173
if event != self.ROW_UPDATE:
174174
return True
175-
# NOTE(lucasgomes): If the external_ids column wasn't updated
176-
# (meaning, Chassis "gateway" status didn't change) just returns
177-
if not hasattr(old, 'external_ids') and event == self.ROW_UPDATE:
175+
176+
# NOTE(ralonsoh): LP#1990229 to be removed when min OVN version is
177+
# 22.09
178+
other_config = ('other_config' if hasattr(row, 'other_config') else
179+
'external_ids')
180+
# NOTE(lucasgomes): If the other_config/external_ids column wasn't
181+
# updated (meaning, Chassis "gateway" status didn't change) just
182+
# returns
183+
if not hasattr(old, other_config) and event == self.ROW_UPDATE:
178184
return False
179-
if (old.external_ids.get('ovn-bridge-mappings') !=
180-
row.external_ids.get('ovn-bridge-mappings')):
185+
old_br_mappings = utils.get_ovn_chassis_other_config(old).get(
186+
'ovn-bridge-mappings')
187+
new_br_mappings = utils.get_ovn_chassis_other_config(row).get(
188+
'ovn-bridge-mappings')
189+
if old_br_mappings != new_br_mappings:
181190
return True
182191
# Check if either the Gateway status or Availability Zones has
183192
# changed in the Chassis
@@ -192,8 +201,9 @@ def match_fn(self, event, row, old):
192201
def run(self, event, row, old):
193202
host = row.hostname
194203
phy_nets = []
204+
new_other_config = utils.get_ovn_chassis_other_config(row)
195205
if event != self.ROW_DELETE:
196-
bridge_mappings = row.external_ids.get('ovn-bridge-mappings', '')
206+
bridge_mappings = new_other_config.get('ovn-bridge-mappings', '')
197207
mapping_dict = helpers.parse_mappings(bridge_mappings.split(','))
198208
phy_nets = list(mapping_dict)
199209

@@ -208,9 +218,10 @@ def run(self, event, row, old):
208218
if event == self.ROW_DELETE:
209219
kwargs['event_from_chassis'] = row.name
210220
elif event == self.ROW_UPDATE:
211-
old_mappings = old.external_ids.get('ovn-bridge-mappings',
221+
old_other_config = utils.get_ovn_chassis_other_config(old)
222+
old_mappings = old_other_config.get('ovn-bridge-mappings',
212223
set()) or set()
213-
new_mappings = row.external_ids.get('ovn-bridge-mappings',
224+
new_mappings = new_other_config.get('ovn-bridge-mappings',
214225
set()) or set()
215226
if old_mappings:
216227
old_mappings = set(old_mappings.split(','))
@@ -339,11 +350,17 @@ class ChassisAgentTypeChangeEvent(ChassisEvent):
339350
events = (BaseEvent.ROW_UPDATE,)
340351

341352
def match_fn(self, event, row, old=None):
342-
if not getattr(old, 'external_ids', False):
353+
# NOTE(ralonsoh): LP#1990229 to be removed when min OVN version is
354+
# 22.09
355+
other_config = ('other_config' if hasattr(row, 'other_config') else
356+
'external_ids')
357+
if not getattr(old, other_config, False):
343358
return False
344-
agent_type_change = n_agent.NeutronAgent.chassis_from_private(
345-
row).external_ids.get('ovn-cms-options', []) != (
346-
old.external_ids.get('ovn-cms-options', []))
359+
chassis = n_agent.NeutronAgent.chassis_from_private(row)
360+
new_other_config = utils.get_ovn_chassis_other_config(chassis)
361+
old_other_config = utils.get_ovn_chassis_other_config(old)
362+
agent_type_change = new_other_config.get('ovn-cms-options', []) != (
363+
old_other_config.get('ovn-cms-options', []))
347364
return agent_type_change
348365

349366
def run(self, event, row, old):

neutron/tests/functional/base.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,8 @@ def restart(self):
423423
self._start_ovn_northd()
424424

425425
def add_fake_chassis(self, host, physical_nets=None, external_ids=None,
426-
name=None, enable_chassis_as_gw=False):
426+
name=None, enable_chassis_as_gw=False,
427+
other_config=None):
427428
def append_cms_options(ext_ids, value):
428429
if 'ovn-cms-options' not in ext_ids:
429430
ext_ids['ovn-cms-options'] = value
@@ -432,14 +433,15 @@ def append_cms_options(ext_ids, value):
432433

433434
physical_nets = physical_nets or []
434435
external_ids = external_ids or {}
436+
other_config = other_config or {}
435437
if enable_chassis_as_gw:
436-
append_cms_options(external_ids, 'enable-chassis-as-gw')
438+
append_cms_options(other_config, 'enable-chassis-as-gw')
437439

438440
bridge_mapping = ",".join(["%s:br-provider%s" % (phys_net, i)
439441
for i, phys_net in enumerate(physical_nets)])
440442
if name is None:
441443
name = uuidutils.generate_uuid()
442-
external_ids['ovn-bridge-mappings'] = bridge_mapping
444+
other_config['ovn-bridge-mappings'] = bridge_mapping
443445
# We'll be using different IP addresses every time for the Encap of
444446
# the fake chassis as the SB schema doesn't allow to have two entries
445447
# with same (ip,type) pairs as of OVS 2.11. This shouldn't have any
@@ -450,7 +452,8 @@ def append_cms_options(ext_ids, value):
450452
self._counter += 1
451453
chassis = self.sb_api.chassis_add(
452454
name, ['geneve'], '172.24.4.%d' % self._counter,
453-
external_ids=external_ids, hostname=host).execute(check_error=True)
455+
external_ids=external_ids, hostname=host,
456+
other_config=other_config).execute(check_error=True)
454457
if self.sb_api.is_table_present('Chassis_Private'):
455458
nb_cfg_timestamp = timeutils.utcnow_ts() * 1000
456459
self.sb_api.db_create(

neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/extensions/test_placement.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def setUp(self, maintenance_worker=False, service_plugins=None):
7272
self.mock_send_batch = mock.patch.object(
7373
placement_extension, '_send_deferred_batch').start()
7474

75-
def _build_external_ids(self, bandwidths, inventory_defaults, hypervisors):
75+
def _build_other_config(self, bandwidths, inventory_defaults, hypervisors):
7676
options = []
7777
if bandwidths:
7878
options.append(n_const.RP_BANDWIDTHS + '=' + bandwidths)
@@ -85,17 +85,17 @@ def _build_external_ids(self, bandwidths, inventory_defaults, hypervisors):
8585

8686
def _create_chassis(self, host, name, physical_nets=None, bandwidths=None,
8787
inventory_defaults=None, hypervisors=None):
88-
external_ids = self._build_external_ids(bandwidths, inventory_defaults,
88+
other_config = self._build_other_config(bandwidths, inventory_defaults,
8989
hypervisors)
9090
self.add_fake_chassis(host, physical_nets=physical_nets,
91-
external_ids=external_ids, name=name)
91+
other_config=other_config, name=name)
9292

9393
def _update_chassis(self, name, bandwidths=None, inventory_defaults=None,
9494
hypervisors=None):
95-
external_ids = self._build_external_ids(bandwidths, inventory_defaults,
95+
other_config = self._build_other_config(bandwidths, inventory_defaults,
9696
hypervisors)
9797
self.sb_api.db_set(
98-
'Chassis', name, ('external_ids', external_ids)
98+
'Chassis', name, ('other_config', other_config)
9999
).execute(check_error=True)
100100

101101
def _check_placement_config(self, expected_chassis):

neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_impl_idl.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ def setUp(self):
5252
super(TestSbApi, self).setUp()
5353
self.data = {
5454
'chassis': [
55-
{'external_ids': {'ovn-bridge-mappings':
55+
{'other_config': {'ovn-bridge-mappings':
5656
'public:br-ex,private:br-0'}},
57-
{'external_ids': {'ovn-bridge-mappings':
57+
{'other_config': {'ovn-bridge-mappings':
5858
'public:br-ex,public2:br-ex2'}},
59-
{'external_ids': {'ovn-bridge-mappings':
59+
{'other_config': {'ovn-bridge-mappings':
6060
'public:br-ex'}},
6161
]
6262
}
@@ -70,7 +70,7 @@ def load_test_data(self):
7070
txn.add(self.api.chassis_add(
7171
chassis['name'], ['geneve'], chassis['hostname'],
7272
hostname=chassis['hostname'],
73-
external_ids=chassis['external_ids']))
73+
other_config=chassis['other_config']))
7474

7575
def test_get_chassis_hostname_and_physnets(self):
7676
mapping = self.api.get_chassis_hostname_and_physnets()
@@ -97,7 +97,7 @@ def test_get_chassis_and_physnets(self):
9797
def test_multiple_physnets_in_one_bridge(self):
9898
self.data = {
9999
'chassis': [
100-
{'external_ids': {'ovn-bridge-mappings': 'p1:br-ex,p2:br-ex'}}
100+
{'other_config': {'ovn-bridge-mappings': 'p1:br-ex,p2:br-ex'}}
101101
]
102102
}
103103
self.load_test_data()

neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -437,21 +437,20 @@ def setUp(self):
437437
chassis_name, self.mech_driver.agent_chassis_table)
438438
self.mech_driver.sb_ovn.idl.notify_handler.watch_event(row_event)
439439
self.chassis_name = self.add_fake_chassis(
440-
self.FAKE_CHASSIS_HOST,
441-
external_ids={'ovn-cms-options': 'enable-chassis-as-gw'},
442-
name=chassis_name)
440+
self.FAKE_CHASSIS_HOST, name=chassis_name,
441+
enable_chassis_as_gw=True)
443442
self.assertTrue(row_event.wait())
444443
n_utils.wait_until_true(
445444
lambda: len(list(neutron_agent.AgentCache())) == 1)
446445

447446
def test_agent_change_controller(self):
448447
self.assertEqual(neutron_agent.ControllerGatewayAgent,
449448
type(neutron_agent.AgentCache()[self.chassis_name]))
450-
self.sb_api.db_set('Chassis', self.chassis_name, ('external_ids',
449+
self.sb_api.db_set('Chassis', self.chassis_name, ('other_config',
451450
{'ovn-cms-options': ''})).execute(check_error=True)
452451
n_utils.wait_until_true(lambda:
453452
neutron_agent.AgentCache()[self.chassis_name].
454-
chassis.external_ids['ovn-cms-options'] == '')
453+
chassis.other_config['ovn-cms-options'] == '')
455454
self.assertEqual(neutron_agent.ControllerAgent,
456455
type(neutron_agent.AgentCache()[self.chassis_name]))
457456

0 commit comments

Comments
 (0)