diff options
author | Zuul <zuul@review.opendev.org> | 2023-02-20 14:14:30 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2023-02-20 14:14:30 +0000 |
commit | 76c9f44b25916e5d28843d3bd325ff3fe5100fbf (patch) | |
tree | 5ed25b39b259e220655b842d40334296b2c1a4d1 | |
parent | 6c5594aa44e6212b743e393110bb8e5be26ece93 (diff) | |
parent | f597154473281233f63b9bc32cb607e801c368a3 (diff) | |
download | neutron-76c9f44b25916e5d28843d3bd325ff3fe5100fbf.tar.gz |
Merge "[OVN] Add missing LSP device_owner info in trunk driver" into stable/xena
8 files changed, 69 insertions, 31 deletions
diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/api.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/api.py index 0d16d3f100..b04056313a 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/api.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/api.py @@ -40,16 +40,23 @@ class API(api.API, metaclass=abc.ABCMeta): """ @abc.abstractmethod - def set_lswitch_port(self, lport_name, if_exists=True, **columns): + def set_lswitch_port(self, lport_name, external_ids_update=None, + if_exists=True, **columns): """Create a command to set OVN logical switch port fields :param lport_name: The name of the lport :type lport_name: string + :param external_ids_update: Dictionary of keys to be updated + individually in the external IDs dictionary. + If "external_ids" is defined in "columns", + "external_ids" will override any + "external_ids_update" value. + :type external_ids_update: dictionary + :param if_exists: Do not fail if lport does not exist + :type if_exists: bool :param columns: Dictionary of port columns Supported columns: macs, external_ids, parent_name, tag, enabled - :param if_exists: Do not fail if lport does not exist - :type if_exists: bool :type columns: dictionary :returns: :class:`Command` with no result """ diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/commands.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/commands.py index 936b0cfdd0..a1e29e6e98 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/commands.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/commands.py @@ -148,9 +148,10 @@ class AddLSwitchPortCommand(command.BaseCommand): class SetLSwitchPortCommand(command.BaseCommand): - def __init__(self, api, lport, if_exists, **columns): + def __init__(self, api, lport, external_ids_update, if_exists, **columns): super(SetLSwitchPortCommand, self).__init__(api) self.lport = lport + self.external_ids_update = external_ids_update self.columns = columns self.if_exists = if_exists @@ -195,6 +196,12 @@ class SetLSwitchPortCommand(command.BaseCommand): for uuid in cur_port_dhcp_opts - new_port_dhcp_opts: self.api._tables['DHCP_Options'].rows[uuid].delete() + external_ids_update = self.external_ids_update or {} + external_ids = getattr(port, 'external_ids', {}) + for k, v in external_ids_update.items(): + external_ids[k] = v + port.external_ids = external_ids + for col, val in self.columns.items(): setattr(port, col, val) diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py index b628e82332..9fda9e5280 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py @@ -283,8 +283,9 @@ class OvsdbNbOvnIdl(nb_impl_idl.OvnNbApiIdlImpl, Backend): return cmd.AddLSwitchPortCommand(self, lport_name, lswitch_name, may_exist, **columns) - def set_lswitch_port(self, lport_name, if_exists=True, **columns): - return cmd.SetLSwitchPortCommand(self, lport_name, + def set_lswitch_port(self, lport_name, external_ids_update=None, + if_exists=True, **columns): + return cmd.SetLSwitchPortCommand(self, lport_name, external_ids_update, if_exists, **columns) def delete_lswitch_port(self, lport_name=None, lswitch_name=None, diff --git a/neutron/services/trunk/drivers/ovn/trunk_driver.py b/neutron/services/trunk/drivers/ovn/trunk_driver.py index a8a33223da..ea9186c2f6 100644 --- a/neutron/services/trunk/drivers/ovn/trunk_driver.py +++ b/neutron/services/trunk/drivers/ovn/trunk_driver.py @@ -21,7 +21,7 @@ from neutron_lib.services.trunk import constants as trunk_consts from oslo_config import cfg from oslo_log import log -from neutron.common.ovn.constants import OVN_ML2_MECH_DRIVER_NAME +from neutron.common.ovn import constants as ovn_const from neutron.objects import ports as port_obj from neutron.services.trunk.drivers import base as trunk_base @@ -94,10 +94,13 @@ class OVNTrunkHandler(object): LOG.debug("Port not found while trying to set " "binding_profile: %s", subport.port_id) return + ext_ids = {ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY: db_port.device_owner} ovn_txn.add(self.plugin_driver.nb_ovn.set_lswitch_port( lport_name=subport.port_id, parent_name=parent_port, - tag=subport.segmentation_id)) + tag=subport.segmentation_id, + external_ids_update=ext_ids, + )) LOG.debug("Done setting parent %s for subport %s", parent_port, subport.port_id) @@ -128,11 +131,14 @@ class OVNTrunkHandler(object): LOG.debug("Port not found while trying to unset " "binding_profile: %s", subport.port_id) return + ext_ids = {ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY: db_port.device_owner} ovn_txn.add(self.plugin_driver.nb_ovn.set_lswitch_port( lport_name=subport.port_id, parent_name=[], up=False, - tag=[])) + tag=[], + external_ids_update=ext_ids, + )) LOG.debug("Done unsetting parent for subport %s", subport.port_id) def trunk_created(self, trunk): @@ -185,7 +191,8 @@ class OVNTrunkDriver(trunk_base.DriverBase): @property def is_loaded(self): try: - return OVN_ML2_MECH_DRIVER_NAME in cfg.CONF.ml2.mechanism_drivers + return (ovn_const.OVN_ML2_MECH_DRIVER_NAME in + cfg.CONF.ml2.mechanism_drivers) except cfg.NoSuchOptError: return False @@ -205,7 +212,7 @@ class OVNTrunkDriver(trunk_base.DriverBase): @classmethod def create(cls, plugin_driver): cls.plugin_driver = plugin_driver - return cls(OVN_ML2_MECH_DRIVER_NAME, + return cls(ovn_const.OVN_ML2_MECH_DRIVER_NAME, SUPPORTED_INTERFACES, SUPPORTED_SEGMENTATION_TYPES, None, diff --git a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py index 408e60cf03..9246a89583 100644 --- a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py +++ b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py @@ -832,12 +832,12 @@ class TestOvnNbSync(base.TestOVNFunctionalBase): txn.add(self.nb_api.pg_del(pg)) for lport_name in self.reset_lport_dhcpv4_options: - txn.add(self.nb_api.set_lswitch_port(lport_name, True, - dhcpv4_options=[])) + txn.add(self.nb_api.set_lswitch_port( + lport_name, if_exists=True, dhcpv4_options=[])) for lport_name in self.reset_lport_dhcpv6_options: - txn.add(self.nb_api.set_lswitch_port(lport_name, True, - dhcpv6_options=[])) + txn.add(self.nb_api.set_lswitch_port( + lport_name, if_exists=True, dhcpv6_options=[])) for dhcp_opts in self.stale_lport_dhcpv4_options: dhcpv4_opts = txn.add(self.nb_api.add_dhcp_options( @@ -850,7 +850,7 @@ class TestOvnNbSync(base.TestOVNFunctionalBase): if dhcp_opts['port_id'] in self.orphaned_lport_dhcp_options: continue txn.add(self.nb_api.set_lswitch_port( - lport_name, True, dhcpv4_options=dhcpv4_opts)) + lport_name, if_exists=True, dhcpv4_options=dhcpv4_opts)) for dhcp_opts in self.stale_lport_dhcpv6_options: dhcpv6_opts = txn.add(self.nb_api.add_dhcp_options( @@ -863,7 +863,7 @@ class TestOvnNbSync(base.TestOVNFunctionalBase): if dhcp_opts['port_id'] in self.orphaned_lport_dhcp_options: continue txn.add(self.nb_api.set_lswitch_port( - lport_name, True, dhcpv6_options=dhcpv6_opts)) + lport_name, if_exists=True, dhcpv6_options=dhcpv6_opts)) for row_uuid in self.missed_dhcp_options: txn.add(self.nb_api.delete_dhcp_options(row_uuid)) @@ -880,12 +880,12 @@ class TestOvnNbSync(base.TestOVNFunctionalBase): for port_id in self.lport_dhcpv4_disabled: txn.add(self.nb_api.set_lswitch_port( - port_id, True, + port_id, if_exists=True, dhcpv4_options=[self.lport_dhcpv4_disabled[port_id]])) for port_id in self.lport_dhcpv6_disabled: txn.add(self.nb_api.set_lswitch_port( - port_id, True, + port_id, if_exists=True, dhcpv6_options=[self.lport_dhcpv6_disabled[port_id]])) # Delete the first DNS record and clear the second row records diff --git a/neutron/tests/functional/services/trunk/drivers/ovn/test_trunk_driver.py b/neutron/tests/functional/services/trunk/drivers/ovn/test_trunk_driver.py index 4927bbd5c6..0c42fbff3d 100644 --- a/neutron/tests/functional/services/trunk/drivers/ovn/test_trunk_driver.py +++ b/neutron/tests/functional/services/trunk/drivers/ovn/test_trunk_driver.py @@ -22,6 +22,8 @@ from neutron_lib.plugins import utils from neutron_lib.services.trunk import constants as trunk_consts from oslo_utils import uuidutils +from neutron.common.ovn import constants as ovn_const + class TestOVNTrunkDriver(base.TestOVNFunctionalBase): @@ -60,18 +62,25 @@ class TestOVNTrunkDriver(base.TestOVNFunctionalBase): for row in self.nb_api.tables[ 'Logical_Switch_Port'].rows.values(): if row.parent_name and row.tag: + device_owner = row.external_ids[ + ovn_const.OVN_DEVICE_OWNER_EXT_ID_KEY] ovn_trunk_info.append({'port_id': row.name, 'parent_port_id': row.parent_name, - 'tag': row.tag}) + 'tag': row.tag, + 'device_owner': device_owner, + }) return ovn_trunk_info def _verify_trunk_info(self, trunk, has_items): ovn_subports_info = self._get_ovn_trunk_info() neutron_subports_info = [] for subport in trunk.get('sub_ports', []): - neutron_subports_info.append({'port_id': subport['port_id'], - 'parent_port_id': [trunk['port_id']], - 'tag': [subport['segmentation_id']]}) + neutron_subports_info.append( + {'port_id': subport['port_id'], + 'parent_port_id': [trunk['port_id']], + 'tag': [subport['segmentation_id']], + 'device_owner': trunk_consts.TRUNK_SUBPORT_OWNER, + }) # Check that the subport has the binding is active. binding = obj_reg.load_class('PortBinding').get_object( self.context, port_id=subport['port_id'], host='') diff --git a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_commands.py b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_commands.py index 387ded939d..39bf2a2334 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_commands.py +++ b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_commands.py @@ -200,7 +200,8 @@ class TestSetLSwitchPortCommand(TestBaseCommand): with mock.patch.object(idlutils, 'row_by_value', side_effect=idlutils.RowNotFound): cmd = commands.SetLSwitchPortCommand( - self.ovn_api, 'fake-lsp', if_exists=if_exists) + self.ovn_api, 'fake-lsp', external_ids_update=None, + if_exists=if_exists) if if_exists: cmd.run_idl(self.transaction) else: @@ -220,8 +221,8 @@ class TestSetLSwitchPortCommand(TestBaseCommand): with mock.patch.object(idlutils, 'row_by_value', return_value=fake_lsp): cmd = commands.SetLSwitchPortCommand( - self.ovn_api, fake_lsp.name, if_exists=True, - external_ids=new_ext_ids) + self.ovn_api, fake_lsp.name, external_ids_update=new_ext_ids, + if_exists=True, external_ids=new_ext_ids) cmd.run_idl(self.transaction) self.assertEqual(new_ext_ids, fake_lsp.external_ids) @@ -255,7 +256,8 @@ class TestSetLSwitchPortCommand(TestBaseCommand): with mock.patch.object(idlutils, 'row_by_value', return_value=fake_lsp): cmd = commands.SetLSwitchPortCommand( - self.ovn_api, fake_lsp.name, if_exists=True, **columns) + self.ovn_api, fake_lsp.name, external_ids_update=None, + if_exists=True, **columns) cmd.run_idl(self.transaction) if clear_v4_opts and clear_v6_opts: @@ -307,7 +309,8 @@ class TestSetLSwitchPortCommand(TestBaseCommand): with mock.patch.object(idlutils, 'row_by_value', return_value=fake_lsp): cmd = commands.SetLSwitchPortCommand( - self.ovn_api, fake_lsp.name, if_exists=True, + self.ovn_api, fake_lsp.name, external_ids_update=ext_ids, + if_exists=True, external_ids=ext_ids, dhcpv4_options=dhcpv4_opts, dhcpv6_options=dhcpv6_opts) if not isinstance(dhcpv4_opts, list): diff --git a/neutron/tests/unit/services/trunk/drivers/ovn/test_trunk_driver.py b/neutron/tests/unit/services/trunk/drivers/ovn/test_trunk_driver.py index 621b815f44..986380e598 100644 --- a/neutron/tests/unit/services/trunk/drivers/ovn/test_trunk_driver.py +++ b/neutron/tests/unit/services/trunk/drivers/ovn/test_trunk_driver.py @@ -129,7 +129,9 @@ class TestTrunkHandler(base.BaseTestCase): calls = [mock.call(lport_name=s_port.port_id, parent_name=trunk.port_id, - tag=s_port.segmentation_id) + tag=s_port.segmentation_id, + external_ids_update={ + 'neutron:device_owner': 'trunk:subport'}) for trunk, s_port in [(self.trunk_1, self.sub_port_1), (self.trunk_1, self.sub_port_2)]] self._assert_calls(self.plugin_driver.nb_ovn.set_lswitch_port, calls) @@ -196,7 +198,8 @@ class TestTrunkHandler(base.BaseTestCase): calls = [mock.call(lport_name=s_port.port_id, parent_name=[], tag=[], - up=False) + up=False, + external_ids_update={'neutron:device_owner': ''}) for trunk, s_port in [(self.trunk_1, self.sub_port_1), (self.trunk_1, self.sub_port_2)]] self._assert_calls(self.plugin_driver.nb_ovn.set_lswitch_port, calls) @@ -225,7 +228,8 @@ class TestTrunkHandler(base.BaseTestCase): calls = [mock.call(lport_name=s_port.port_id, parent_name=[], tag=[], - up=False) + up=False, + external_ids_update={'neutron:device_owner': ''}) for trunk, s_port in [(self.trunk_1, self.sub_port_1)]] self._assert_calls(self.plugin_driver.nb_ovn.set_lswitch_port, calls) |