Skip to content

Commit 9b1b61c

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "[OVN] Add missing LSP device_owner info in trunk driver" into stable/yoga
2 parents a6253c0 + 86e2aa8 commit 9b1b61c

File tree

8 files changed

+69
-31
lines changed

8 files changed

+69
-31
lines changed

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,23 @@ def create_lswitch_port(self, lport_name, lswitch_name, may_exist=True,
4040
"""
4141

4242
@abc.abstractmethod
43-
def set_lswitch_port(self, lport_name, if_exists=True, **columns):
43+
def set_lswitch_port(self, lport_name, external_ids_update=None,
44+
if_exists=True, **columns):
4445
"""Create a command to set OVN logical switch port fields
4546
4647
:param lport_name: The name of the lport
4748
:type lport_name: string
49+
:param external_ids_update: Dictionary of keys to be updated
50+
individually in the external IDs dictionary.
51+
If "external_ids" is defined in "columns",
52+
"external_ids" will override any
53+
"external_ids_update" value.
54+
:type external_ids_update: dictionary
55+
:param if_exists: Do not fail if lport does not exist
56+
:type if_exists: bool
4857
:param columns: Dictionary of port columns
4958
Supported columns: macs, external_ids,
5059
parent_name, tag, enabled
51-
:param if_exists: Do not fail if lport does not exist
52-
:type if_exists: bool
5360
:type columns: dictionary
5461
:returns: :class:`Command` with no result
5562
"""

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,10 @@ def post_commit(self, txn):
148148

149149

150150
class SetLSwitchPortCommand(command.BaseCommand):
151-
def __init__(self, api, lport, if_exists, **columns):
151+
def __init__(self, api, lport, external_ids_update, if_exists, **columns):
152152
super(SetLSwitchPortCommand, self).__init__(api)
153153
self.lport = lport
154+
self.external_ids_update = external_ids_update
154155
self.columns = columns
155156
self.if_exists = if_exists
156157

@@ -195,6 +196,12 @@ def run_idl(self, txn):
195196
for uuid in cur_port_dhcp_opts - new_port_dhcp_opts:
196197
self.api._tables['DHCP_Options'].rows[uuid].delete()
197198

199+
external_ids_update = self.external_ids_update or {}
200+
external_ids = getattr(port, 'external_ids', {})
201+
for k, v in external_ids_update.items():
202+
external_ids[k] = v
203+
port.external_ids = external_ids
204+
198205
for col, val in self.columns.items():
199206
setattr(port, col, val)
200207

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,9 @@ def create_lswitch_port(self, lport_name, lswitch_name, may_exist=True,
283283
return cmd.AddLSwitchPortCommand(self, lport_name, lswitch_name,
284284
may_exist, **columns)
285285

286-
def set_lswitch_port(self, lport_name, if_exists=True, **columns):
287-
return cmd.SetLSwitchPortCommand(self, lport_name,
286+
def set_lswitch_port(self, lport_name, external_ids_update=None,
287+
if_exists=True, **columns):
288+
return cmd.SetLSwitchPortCommand(self, lport_name, external_ids_update,
288289
if_exists, **columns)
289290

290291
def delete_lswitch_port(self, lport_name=None, lswitch_name=None,

neutron/services/trunk/drivers/ovn/trunk_driver.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from oslo_config import cfg
2222
from oslo_log import log
2323

24-
from neutron.common.ovn.constants import OVN_ML2_MECH_DRIVER_NAME
24+
from neutron.common.ovn import constants as ovn_const
2525
from neutron.objects import ports as port_obj
2626
from neutron.services.trunk.drivers import base as trunk_base
2727

@@ -94,10 +94,13 @@ def _set_binding_profile(self, context, subport, parent_port,
9494
LOG.debug("Port not found while trying to set "
9595
"binding_profile: %s", subport.port_id)
9696
return
97+
ext_ids = {ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY: db_port.device_owner}
9798
ovn_txn.add(self.plugin_driver.nb_ovn.set_lswitch_port(
9899
lport_name=subport.port_id,
99100
parent_name=parent_port,
100-
tag=subport.segmentation_id))
101+
tag=subport.segmentation_id,
102+
external_ids_update=ext_ids,
103+
))
101104
LOG.debug("Done setting parent %s for subport %s",
102105
parent_port, subport.port_id)
103106

@@ -128,11 +131,14 @@ def _unset_binding_profile(self, context, subport, ovn_txn):
128131
LOG.debug("Port not found while trying to unset "
129132
"binding_profile: %s", subport.port_id)
130133
return
134+
ext_ids = {ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY: db_port.device_owner}
131135
ovn_txn.add(self.plugin_driver.nb_ovn.set_lswitch_port(
132136
lport_name=subport.port_id,
133137
parent_name=[],
134138
up=False,
135-
tag=[]))
139+
tag=[],
140+
external_ids_update=ext_ids,
141+
))
136142
LOG.debug("Done unsetting parent for subport %s", subport.port_id)
137143

138144
def trunk_created(self, trunk):
@@ -185,7 +191,8 @@ class OVNTrunkDriver(trunk_base.DriverBase):
185191
@property
186192
def is_loaded(self):
187193
try:
188-
return OVN_ML2_MECH_DRIVER_NAME in cfg.CONF.ml2.mechanism_drivers
194+
return (ovn_const.OVN_ML2_MECH_DRIVER_NAME in
195+
cfg.CONF.ml2.mechanism_drivers)
189196
except cfg.NoSuchOptError:
190197
return False
191198

@@ -205,7 +212,7 @@ def register(self, resource, event, trigger, payload=None):
205212
@classmethod
206213
def create(cls, plugin_driver):
207214
cls.plugin_driver = plugin_driver
208-
return cls(OVN_ML2_MECH_DRIVER_NAME,
215+
return cls(ovn_const.OVN_ML2_MECH_DRIVER_NAME,
209216
SUPPORTED_INTERFACES,
210217
SUPPORTED_SEGMENTATION_TYPES,
211218
None,

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -832,12 +832,12 @@ def _modify_resources_in_nb_db(self):
832832
txn.add(self.nb_api.pg_del(pg))
833833

834834
for lport_name in self.reset_lport_dhcpv4_options:
835-
txn.add(self.nb_api.set_lswitch_port(lport_name, True,
836-
dhcpv4_options=[]))
835+
txn.add(self.nb_api.set_lswitch_port(
836+
lport_name, if_exists=True, dhcpv4_options=[]))
837837

838838
for lport_name in self.reset_lport_dhcpv6_options:
839-
txn.add(self.nb_api.set_lswitch_port(lport_name, True,
840-
dhcpv6_options=[]))
839+
txn.add(self.nb_api.set_lswitch_port(
840+
lport_name, if_exists=True, dhcpv6_options=[]))
841841

842842
for dhcp_opts in self.stale_lport_dhcpv4_options:
843843
dhcpv4_opts = txn.add(self.nb_api.add_dhcp_options(
@@ -850,7 +850,7 @@ def _modify_resources_in_nb_db(self):
850850
if dhcp_opts['port_id'] in self.orphaned_lport_dhcp_options:
851851
continue
852852
txn.add(self.nb_api.set_lswitch_port(
853-
lport_name, True, dhcpv4_options=dhcpv4_opts))
853+
lport_name, if_exists=True, dhcpv4_options=dhcpv4_opts))
854854

855855
for dhcp_opts in self.stale_lport_dhcpv6_options:
856856
dhcpv6_opts = txn.add(self.nb_api.add_dhcp_options(
@@ -863,7 +863,7 @@ def _modify_resources_in_nb_db(self):
863863
if dhcp_opts['port_id'] in self.orphaned_lport_dhcp_options:
864864
continue
865865
txn.add(self.nb_api.set_lswitch_port(
866-
lport_name, True, dhcpv6_options=dhcpv6_opts))
866+
lport_name, if_exists=True, dhcpv6_options=dhcpv6_opts))
867867

868868
for row_uuid in self.missed_dhcp_options:
869869
txn.add(self.nb_api.delete_dhcp_options(row_uuid))
@@ -880,12 +880,12 @@ def _modify_resources_in_nb_db(self):
880880

881881
for port_id in self.lport_dhcpv4_disabled:
882882
txn.add(self.nb_api.set_lswitch_port(
883-
port_id, True,
883+
port_id, if_exists=True,
884884
dhcpv4_options=[self.lport_dhcpv4_disabled[port_id]]))
885885

886886
for port_id in self.lport_dhcpv6_disabled:
887887
txn.add(self.nb_api.set_lswitch_port(
888-
port_id, True,
888+
port_id, if_exists=True,
889889
dhcpv6_options=[self.lport_dhcpv6_disabled[port_id]]))
890890

891891
# Delete the first DNS record and clear the second row records

neutron/tests/functional/services/trunk/drivers/ovn/test_trunk_driver.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
from neutron_lib.services.trunk import constants as trunk_consts
2323
from oslo_utils import uuidutils
2424

25+
from neutron.common.ovn import constants as ovn_const
26+
2527

2628
class TestOVNTrunkDriver(base.TestOVNFunctionalBase):
2729

@@ -60,18 +62,25 @@ def _get_ovn_trunk_info(self):
6062
for row in self.nb_api.tables[
6163
'Logical_Switch_Port'].rows.values():
6264
if row.parent_name and row.tag:
65+
device_owner = row.external_ids[
66+
ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY]
6367
ovn_trunk_info.append({'port_id': row.name,
6468
'parent_port_id': row.parent_name,
65-
'tag': row.tag})
69+
'tag': row.tag,
70+
'device_owner': device_owner,
71+
})
6672
return ovn_trunk_info
6773

6874
def _verify_trunk_info(self, trunk, has_items):
6975
ovn_subports_info = self._get_ovn_trunk_info()
7076
neutron_subports_info = []
7177
for subport in trunk.get('sub_ports', []):
72-
neutron_subports_info.append({'port_id': subport['port_id'],
73-
'parent_port_id': [trunk['port_id']],
74-
'tag': [subport['segmentation_id']]})
78+
neutron_subports_info.append(
79+
{'port_id': subport['port_id'],
80+
'parent_port_id': [trunk['port_id']],
81+
'tag': [subport['segmentation_id']],
82+
'device_owner': trunk_consts.TRUNK_SUBPORT_OWNER,
83+
})
7584
# Check that the subport has the binding is active.
7685
binding = obj_reg.load_class('PortBinding').get_object(
7786
self.context, port_id=subport['port_id'], host='')

neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_commands.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ def _test_lswitch_port_update_no_exist(self, if_exists=True):
200200
with mock.patch.object(idlutils, 'row_by_value',
201201
side_effect=idlutils.RowNotFound):
202202
cmd = commands.SetLSwitchPortCommand(
203-
self.ovn_api, 'fake-lsp', if_exists=if_exists)
203+
self.ovn_api, 'fake-lsp', external_ids_update=None,
204+
if_exists=if_exists)
204205
if if_exists:
205206
cmd.run_idl(self.transaction)
206207
else:
@@ -220,8 +221,8 @@ def test_lswitch_port_update(self):
220221
with mock.patch.object(idlutils, 'row_by_value',
221222
return_value=fake_lsp):
222223
cmd = commands.SetLSwitchPortCommand(
223-
self.ovn_api, fake_lsp.name, if_exists=True,
224-
external_ids=new_ext_ids)
224+
self.ovn_api, fake_lsp.name, external_ids_update=new_ext_ids,
225+
if_exists=True, external_ids=new_ext_ids)
225226
cmd.run_idl(self.transaction)
226227
self.assertEqual(new_ext_ids, fake_lsp.external_ids)
227228

@@ -255,7 +256,8 @@ def _test_lswitch_port_update_del_dhcp(self, clear_v4_opts,
255256
with mock.patch.object(idlutils, 'row_by_value',
256257
return_value=fake_lsp):
257258
cmd = commands.SetLSwitchPortCommand(
258-
self.ovn_api, fake_lsp.name, if_exists=True, **columns)
259+
self.ovn_api, fake_lsp.name, external_ids_update=None,
260+
if_exists=True, **columns)
259261
cmd.run_idl(self.transaction)
260262

261263
if clear_v4_opts and clear_v6_opts:
@@ -307,7 +309,8 @@ def _test_lswitch_port_update_with_dhcp(self, dhcpv4_opts, dhcpv6_opts):
307309
with mock.patch.object(idlutils, 'row_by_value',
308310
return_value=fake_lsp):
309311
cmd = commands.SetLSwitchPortCommand(
310-
self.ovn_api, fake_lsp.name, if_exists=True,
312+
self.ovn_api, fake_lsp.name, external_ids_update=ext_ids,
313+
if_exists=True,
311314
external_ids=ext_ids, dhcpv4_options=dhcpv4_opts,
312315
dhcpv6_options=dhcpv6_opts)
313316
if not isinstance(dhcpv4_opts, list):

neutron/tests/unit/services/trunk/drivers/ovn/test_trunk_driver.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ def test_create_trunk(self):
129129

130130
calls = [mock.call(lport_name=s_port.port_id,
131131
parent_name=trunk.port_id,
132-
tag=s_port.segmentation_id)
132+
tag=s_port.segmentation_id,
133+
external_ids_update={
134+
'neutron:device_owner': 'trunk:subport'})
133135
for trunk, s_port in [(self.trunk_1, self.sub_port_1),
134136
(self.trunk_1, self.sub_port_2)]]
135137
self._assert_calls(self.plugin_driver.nb_ovn.set_lswitch_port, calls)
@@ -196,7 +198,8 @@ def test_delete_trunk(self):
196198
calls = [mock.call(lport_name=s_port.port_id,
197199
parent_name=[],
198200
tag=[],
199-
up=False)
201+
up=False,
202+
external_ids_update={'neutron:device_owner': ''})
200203
for trunk, s_port in [(self.trunk_1, self.sub_port_1),
201204
(self.trunk_1, self.sub_port_2)]]
202205
self._assert_calls(self.plugin_driver.nb_ovn.set_lswitch_port, calls)
@@ -225,7 +228,8 @@ def test_delete_trunk_key_not_found(self):
225228
calls = [mock.call(lport_name=s_port.port_id,
226229
parent_name=[],
227230
tag=[],
228-
up=False)
231+
up=False,
232+
external_ids_update={'neutron:device_owner': ''})
229233
for trunk, s_port in [(self.trunk_1, self.sub_port_1)]]
230234
self._assert_calls(self.plugin_driver.nb_ovn.set_lswitch_port, calls)
231235

0 commit comments

Comments
 (0)