diff --git a/neutron/common/ovn/utils.py b/neutron/common/ovn/utils.py index 5b2890dd7ac..e88a3d89149 100644 --- a/neutron/common/ovn/utils.py +++ b/neutron/common/ovn/utils.py @@ -68,8 +68,6 @@ 'HAChassisGroupInfo', ['group_name', 'chassis_list', 'az_hints', 'ignore_chassis', 'external_ids']) -_OVS_PERSIST_UUID = _SENTINEL = object() - class OvsdbClientCommand: _CONNECTION = 0 @@ -905,16 +903,6 @@ def get_chassis_without_azs(chassis_list): get_chassis_availability_zones(ch)} -def get_chassis_priority(chassis_list): - """Given a chassis list, returns a dictionary with chassis name and prio - - The chassis list is ordered according to the priority: the first one is the - highest priority chassis, the last one is the least priority chassis. - """ - return {chassis: prio + 1 for prio, chassis - in enumerate(reversed(chassis_list))} - - def parse_ovn_lb_port_forwarding(ovn_rtr_lb_pfs): """Return a dictionary compatible with port forwarding from OVN lb.""" result = {} @@ -1389,41 +1377,3 @@ def validate_port_forwarding_configuration(): if any(net_type in provider_network_types for net_type in cfg.CONF.ml2.tenant_network_types): raise ovn_exc.InvalidPortForwardingConfiguration() - - -def ovs_persist_uuid_supported(nb_idl): - # OVS 3.1+ contain the persist_uuid feature that allows choosing the UUID - # that will be stored in the DB. It was broken prior to 3.1.5/3.2.3/3.3.1 - # so this will return True only for the fixed version. As actually testing - # the fix requires committing a transaction, an implementation detail is - # tested. This can be removed once a fixed version is required. - global _OVS_PERSIST_UUID - if _OVS_PERSIST_UUID is _SENTINEL: - _OVS_PERSIST_UUID = isinstance( - next(iter(nb_idl.tables["NB_Global"].rows.data.values())), list) - LOG.debug(f"OVS persist_uuid supported={_OVS_PERSIST_UUID}") - return _OVS_PERSIST_UUID - - -def get_logical_router_port_ha_chassis(nb_idl, lrp, priorities=None): - """Get the list of chassis hosting this Logical_Router_Port. - - :param nb_idl: (``OvsdbNbOvnIdl``) OVN Northbound IDL - :param lrp: Logical_Router_Port - :param priorities: (list of int) a list of HA_Chassis chassis priorities - to search for - :return: List of tuples (chassis_name, priority) sorted by priority. If - ``priorities`` is set then only chassis matching of these - priorities are returned. - """ - chassis = [] - lrp = nb_idl.lookup('Logical_Router_Port', lrp.name, default=None) - if not lrp or not lrp.ha_chassis_group: - return chassis - - for hc in lrp.ha_chassis_group[0].ha_chassis: - if priorities and hc.priority not in priorities: - continue - chassis.append((hc.chassis_name, hc.priority)) - - return chassis diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py index af1dfcff3ee..ec87494a1bc 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py @@ -70,7 +70,6 @@ from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import maintenance from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovn_client from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovn_db_sync -from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovs_fixes from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import worker from neutron import service from neutron.services.logapi.drivers.ovn import driver as log_driver @@ -420,9 +419,6 @@ def post_fork_initialize(self, resource, event, trigger, payload=None): self._post_fork_event.clear() self._ovn_client_inst = None - # Patch python-ovs for fixes not yet released - ovs_fixes.apply_ovs_fixes() - if worker_class == wsgi.WorkerService: self._setup_hash_ring() 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 b1ee143aa18..687db6bd4c1 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/commands.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/commands.py @@ -13,14 +13,10 @@ # under the License. import abc -import copy -import uuid from oslo_utils import timeutils -from ovs.db import idl as ovs_idl from ovsdbapp.backend.ovs_idl import command from ovsdbapp.backend.ovs_idl import idlutils -from ovsdbapp.backend.ovs_idl import rowview from ovsdbapp.schema.ovn_northbound import commands as ovn_nb_commands from ovsdbapp import utils as ovsdbapp_utils @@ -104,49 +100,6 @@ def _add_gateway_chassis(api, txn, lrp_name, val): return 'gateway_chassis', uuid_list -def _sync_ha_chassis_group(txn, nb_api, name, chassis_priority, - may_exist=False, table_name='HA_Chassis_Group', - **columns): - result = None - hcg = nb_api.lookup(table_name, name, default=None) - if hcg: - if not may_exist: - raise RuntimeError(_('HA_Chassis_Group %s exists' % name)) - else: - hcg = txn.insert(nb_api._tables[table_name]) - hcg.name = name - command.BaseCommand.set_columns(hcg, **columns) - result = hcg.uuid - - # HA_Chassis registers handling. - # Remove the non-existing chassis in ``self.chassis_priority`` - hc_to_remove = [] - for hc in getattr(hcg, 'ha_chassis', []): - if hc.chassis_name not in chassis_priority: - hc_to_remove.append(hc) - - for hc in hc_to_remove: - hcg.delvalue('ha_chassis', hc) - hc.delete() - - # Update the priority of the existing chassis. - for hc in getattr(hcg, 'ha_chassis', []): - hc_priority = chassis_priority.pop(hc.chassis_name) - hc.priority = hc_priority - - # Add the non-existing HA_Chassis registers. - for hc_name, priority in chassis_priority.items(): - hc = txn.insert(nb_api.tables['HA_Chassis']) - hc.chassis_name = hc_name - hc.priority = priority - hcg.addvalue('ha_chassis', hc) - - if not result: - result = rowview.RowView(hcg) - - return result - - class CheckLivenessCommand(command.BaseCommand): def run_idl(self, txn): # txn.pre_commit responsible for updating nb_global.nb_cfg, but @@ -157,64 +110,21 @@ def run_idl(self, txn): self.result = self.api.nb_global.nb_cfg -class AddNetworkCommand(command.AddCommand): - table_name = 'Logical_Switch' - - def __init__(self, api, network_id, may_exist=False, **columns): - super().__init__(api) - self.network_uuid = uuid.UUID(str(network_id)) - self.may_exist = may_exist - self.columns = columns - - def run_idl(self, txn): - table = self.api.tables[self.table_name] - try: - ls = table.rows[self.network_uuid] - if self.may_exist: - self.result = rowview.RowView(ls) - return - msg = _("Switch %s already exists") % self.network_uuid - raise RuntimeError(msg) - except KeyError: - # Adding a new LS - if utils.ovs_persist_uuid_supported(txn.idl): - ls = txn.insert(table, new_uuid=self.network_uuid, - persist_uuid=True) - else: - ls = txn.insert(table) - self.set_columns(ls, **self.columns) - ls.name = utils.ovn_name(self.network_uuid) - self.result = ls.uuid - - class AddLSwitchPortCommand(command.BaseCommand): - def __init__(self, api, lport, lswitch, may_exist, network_id=None, - **columns): + def __init__(self, api, lport, lswitch, may_exist, **columns): super().__init__(api) self.lport = lport self.lswitch = lswitch self.may_exist = may_exist - self.network_uuid = uuid.UUID(str(network_id)) if network_id else None self.columns = columns def run_idl(self, txn): try: - # We must look in the local cache first, because the LS may have - # been created as part of the current transaction. or in the case - # of adding an LSP to a LS that was created before persist_uuid lswitch = idlutils.row_by_value(self.api.idl, 'Logical_Switch', 'name', self.lswitch) except idlutils.RowNotFound: - if self.network_uuid and utils.ovs_persist_uuid_supported(txn.idl): - # Create a "fake" row with the right UUID so python-ovs creates - # a transaction referencing the Row, even though we might not - # have received the update for the row ourselves. - lswitch = ovs_idl.Row(self.api.idl, - self.api.tables['Logical_Switch'], - uuid=self.network_uuid, data={}) - else: - msg = _("Logical Switch %s does not exist") % self.lswitch - raise RuntimeError(msg) + msg = _("Logical Switch %s does not exist") % self.lswitch + raise RuntimeError(msg) if self.may_exist: port = idlutils.row_by_value(self.api.idl, 'Logical_Switch_Port', 'name', @@ -300,8 +210,8 @@ def run_idl(self, txn): else: new_port_dhcp_opts.add(dhcpv6_options.result) port.dhcpv6_options = [dhcpv6_options.result] - for uuid_ in cur_port_dhcp_opts - new_port_dhcp_opts: - self.api._tables['DHCP_Options'].rows[uuid_].delete() + 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', {}) @@ -383,8 +293,8 @@ def run_idl(self, txn): # Delete DHCP_Options records no longer referred by this port. cur_port_dhcp_opts = get_lsp_dhcp_options_uuids( lport, self.lport) - for uuid_ in cur_port_dhcp_opts: - self.api._tables['DHCP_Options'].rows[uuid_].delete() + for uuid in cur_port_dhcp_opts: + self.api._tables['DHCP_Options'].rows[uuid].delete() _delvalue_from_list(lswitch, 'ports', lport) self.api._tables['Logical_Switch_Port'].rows[lport.uuid].delete() @@ -437,7 +347,8 @@ def run_idl(self, txn): az_hints = self.api.get_gateway_chassis_az_hints(self.g_name) filtered_existing_chassis = ( self.scheduler.filter_existing_chassis( - gw_chassis=self.all_gw_chassis, physnet=physnet, + nb_idl=self.api, gw_chassis=self.all_gw_chassis, + physnet=physnet, chassis_physnets=self.chassis_with_physnets, existing_chassis=existing_chassis, az_hints=az_hints, chassis_with_azs=self.chassis_with_azs)) @@ -477,12 +388,9 @@ def run_idl(self, txn): # the top. index = chassis.index(primary) chassis[0], chassis[index] = chassis[index], chassis[0] - chassis_priority = utils.get_chassis_priority(chassis) - lrouter_name = lrouter_port.external_ids[ - ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY] - hcg = _sync_ha_chassis_group(txn, self.api, lrouter_name, - chassis_priority, may_exist=True) - setattr(lrouter_port, 'ha_chassis_group', ovsdbapp_utils.get_uuid(hcg)) + setattr( + lrouter_port, + *_add_gateway_chassis(self.api, txn, self.g_name, chassis)) class ScheduleNewGatewayCommand(command.BaseCommand): @@ -507,11 +415,8 @@ def run_idl(self, txn): self.api, self.sb_api, self.g_name, candidates=candidates, target_lrouter=lrouter) if chassis: - chassis_priority = utils.get_chassis_priority(chassis) - hcg = _sync_ha_chassis_group(txn, self.api, self.lrouter_name, - chassis_priority, may_exist=True) - setattr(lrouter_port, 'ha_chassis_group', - ovsdbapp_utils.get_uuid(hcg)) + setattr(lrouter_port, + *_add_gateway_chassis(self.api, txn, self.g_name, chassis)) class LrDelCommand(ovn_nb_commands.LrDelCommand): @@ -560,9 +465,8 @@ def run_idl(self, txn): if col == 'gateway_chassis': col, val = _add_gateway_chassis(self.api, txn, self.name, val) - self.set_column(lrouter_port, col, val) + setattr(lrouter_port, col, val) _addvalue_to_list(lrouter, 'ports', lrouter_port) - self.result = lrouter_port.uuid class UpdateLRouterPortCommand(command.BaseCommand): @@ -587,7 +491,7 @@ def run_idl(self, txn): if col == 'gateway_chassis': col, val = _add_gateway_chassis(self.api, txn, self.name, val) - self.set_column(lrouter_port, col, val) + setattr(lrouter_port, col, val) class DelLRouterPortCommand(command.BaseCommand): @@ -1104,17 +1008,15 @@ def run_idl(self, txn): # Remove the router pinning to a chassis (if any). lrouter.delkey('options', 'chassis') - for gw_port in self.api.get_lrouter_gw_ports(lrouter.name): - gw_port.ha_chassis_group = [] - lrouter.delvalue('ports', gw_port) - - # Remove the HA_Chassis_Group of the router (if any), after - # removing it from the gateway Logical_Router_Ports. + # Remove the HA_Chassis_Group of the router (if any). hcg = self.api.lookup('HA_Chassis_Group', lrouter.name, default=None) if hcg: hcg.delete() + for gw_port in self.api.get_lrouter_gw_ports(lrouter.name): + lrouter.delvalue('ports', gw_port) + class SetLSwitchPortToVirtualTypeCommand(command.BaseCommand): def __init__(self, api, lport, vip, parent, if_exists): @@ -1187,22 +1089,3 @@ def run_idl(self, txn): virtual_parents) setattr(lsp, 'options', options) - - -class HAChassisGroupWithHCAddCommand(command.AddCommand): - table_name = 'HA_Chassis_Group' - - def __init__(self, api, name, chassis_priority, may_exist=False, - **columns): - super().__init__(api) - self.name = name - self.chassis_priority = copy.deepcopy(chassis_priority) - self.may_exist = may_exist - self.columns = columns - - def run_idl(self, txn): - # HA_Chassis_Group register creation. - self.result = _sync_ha_chassis_group( - txn, self.api, self.name, self.chassis_priority, - may_exist=self.may_exist, table_name=self.table_name, - **self.columns) 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 f21bf79db01..7c25b69049e 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 @@ -275,17 +275,10 @@ def transaction(self, *args, **kwargs): if revision_mismatch_raise: raise e - def ls_add(self, switch=None, may_exist=False, network_id=None, **columns): - if network_id is None: - return super().ls_add(switch, may_exist, **columns) - return cmd.AddNetworkCommand(self, network_id, may_exist=may_exist, - **columns) - def create_lswitch_port(self, lport_name, lswitch_name, may_exist=True, - network_id=None, **columns): + **columns): return cmd.AddLSwitchPortCommand(self, lport_name, lswitch_name, - may_exist, network_id=network_id, - **columns) + may_exist, **columns) def set_lswitch_port(self, lport_name, external_ids_update=None, if_exists=True, **columns): @@ -527,30 +520,6 @@ def _get_logical_router_port_gateway_chassis(self, lrp, priorities=None): # make sure that chassis are sorted by priority return sorted(chassis, reverse=True, key=lambda x: x[1]) - @staticmethod - def _get_logical_router_port_ha_chassis_group(lrp, priorities=None): - """Get the list of chassis hosting this gateway port. - - @param lrp: logical router port - @type lrp: Logical_Router_Port row - @param priorities: a list of gateway chassis priorities to search for - @type priorities: list of int - @return: List of tuples (chassis_name, priority) sorted by priority. If - ``priorities`` is set then only chassis matching of these - priorities are returned. - """ - chassis = [] - hcg = getattr(lrp, 'ha_chassis_group', None) - if not hcg: - return chassis - - for hc in hcg[0].ha_chassis: - if priorities is not None and hc.priority not in priorities: - continue - chassis.append((hc.chassis_name, hc.priority)) - # Make sure that chassis are sorted by priority (highest prio first) - return sorted(chassis, reverse=True, key=lambda x: x[1]) - def get_all_chassis_gateway_bindings(self, chassis_candidate_list=None, priorities=None): @@ -937,12 +906,6 @@ def set_router_mac_age_limit(self, router=None): return cmd.SetLRouterMacAgeLimitCommand( self, router, cfg.get_ovn_mac_binding_age_threshold()) - def ha_chassis_group_with_hc_add(self, name, chassis_priority, - may_exist=False, **columns): - return cmd.HAChassisGroupWithHCAddCommand( - self, name, chassis_priority, may_exist=may_exist, - **columns) - class OvsdbSbOvnIdl(sb_impl_idl.OvnSbApiIdlImpl, Backend): @n_utils.classproperty diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/maintenance.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/maintenance.py index 036d5f536aa..2783ec84102 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/maintenance.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/maintenance.py @@ -1160,41 +1160,6 @@ def update_qos_fip_rule_priority(self): raise periodics.NeverAgain() - # TODO(ralonsoh): Remove this method in F+3 cycle (2nd next SLURP release) - @has_lock_periodic( - periodic_run_limit=ovn_const.MAINTENANCE_TASK_RETRY_LIMIT, - spacing=ovn_const.MAINTENANCE_ONE_RUN_TASK_SPACING, - run_immediately=True) - def migrate_lrp_gateway_chassis_to_ha_chassis_group(self): - """Migrate the LRP Gateway_Chassis to HA_Chassis_Group""" - with self._nb_idl.transaction(check_error=True) as txn: - for lrp in self._nb_idl.db_list_rows( - 'Logical_Router_Port').execute(check_error=True): - if not lrp.gateway_chassis: - continue - - chassis_prio = {} - for gc in lrp.gateway_chassis: - chassis_prio[gc.chassis_name] = gc.priority - r_name = lrp.external_ids.get( - ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY) - if not r_name: - LOG.warning(f'Logical_Router_Port {lrp.name} does not ' - 'have the router name in external_ids.') - continue - - # Add the new HA_Chassis_Group and assign to the LRP. - hcg_cmd = txn.add(self._nb_idl.ha_chassis_group_with_hc_add( - r_name, chassis_prio, may_exist=True)) - txn.add(self._nb_idl.db_set( - 'Logical_Router_Port', lrp.uuid, - ('ha_chassis_group', hcg_cmd))) - # Unset the Gateway_Chassis in the LRP. - txn.add(self._nb_idl.db_clear( - 'Logical_Router_Port', lrp.uuid, 'gateway_chassis')) - - raise periodics.NeverAgain() - class HashRingHealthCheckPeriodics: diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py index 1f74621e35e..0fe4b285115 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py @@ -590,11 +590,9 @@ def create_port(self, context, port): # controller does not yet see that network in its local cache of the # OVN northbound database. Check if the logical switch is present # or not in the idl's local copy of the database before creating - # the lswitch port. Once we require an ovs version with working - # persist_uuid support, this can be removed. - if not utils.ovs_persist_uuid_supported(self._nb_idl): - self._nb_idl.check_for_row_by_value_and_retry( - 'Logical_Switch', 'name', lswitch_name) + # the lswitch port. + self._nb_idl.check_for_row_by_value_and_retry( + 'Logical_Switch', 'name', lswitch_name) with self._nb_idl.transaction(check_error=True) as txn: dhcpv4_options, dhcpv6_options = self.update_port_dhcp_options( @@ -606,7 +604,6 @@ def create_port(self, context, port): kwargs = { 'lport_name': port['id'], 'lswitch_name': lswitch_name, - 'network_id': port['network_id'], 'addresses': port_info.addresses, 'external_ids': external_ids, 'parent_name': port_info.parent_name, @@ -2077,7 +2074,6 @@ def create_provnet_port(self, network_id, segment, txn=None, cmd = self._nb_idl.create_lswitch_port( lport_name=utils.ovn_provnet_port_name(segment['id']), lswitch_name=utils.ovn_name(network_id), - network_id=network_id, addresses=[ovn_const.UNKNOWN_ADDR], external_ids={}, type=ovn_const.LSP_TYPE_LOCALNET, @@ -2140,13 +2136,14 @@ def create_network(self, context, network): # UUID. This provides an easy way to refer to the logical switch # without having to track what UUID OVN assigned to it. lswitch_params = self._gen_network_parameters(network) + lswitch_name = utils.ovn_name(network['id']) # NOTE(mjozefcz): Remove this workaround when bug # 1869877 will be fixed. segments = segments_db.get_network_segments( context, network['id']) with self._nb_idl.transaction(check_error=True) as txn: - txn.add(self._nb_idl.ls_add(network_id=network['id'], - **lswitch_params, may_exist=True)) + txn.add(self._nb_idl.ls_add(lswitch_name, **lswitch_params, + may_exist=True)) for segment in segments: if segment.get(segment_def.PHYSICAL_NETWORK): self.create_provnet_port(network['id'], segment, txn=txn, diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovs_fixes.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovs_fixes.py deleted file mode 100644 index e8d2d81bd57..00000000000 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovs_fixes.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (c) 2024 -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from ovs.db import idl -import ovs.ovsuuid - - -# Temporarily fix ovs.db.idl.Transaction._substitute_uuids to support handling -# the persist_uuid feature -def _substitute_uuids(self, json): - if isinstance(json, (list, tuple)): - if (len(json) == 2 and - json[0] == 'uuid' and - ovs.ovsuuid.is_valid_string(json[1])): - uuid = ovs.ovsuuid.from_string(json[1]) - row = self._txn_rows.get(uuid, None) - if row and row._data is None and not row._persist_uuid: - return ["named-uuid", idl._uuid_name_from_uuid(uuid)] - else: - return [self._substitute_uuids(elem) for elem in json] - return json - - -def apply_ovs_fixes(): - idl.Transaction._substitute_uuids = _substitute_uuids diff --git a/neutron/scheduler/l3_ovn_scheduler.py b/neutron/scheduler/l3_ovn_scheduler.py index 1c21ed9e18a..f18a627980d 100644 --- a/neutron/scheduler/l3_ovn_scheduler.py +++ b/neutron/scheduler/l3_ovn_scheduler.py @@ -40,8 +40,8 @@ def select(self, nb_idl, sb_idl, gateway_name, candidates=None, scheduled. """ - @staticmethod - def filter_existing_chassis(gw_chassis, physnet, chassis_physnets, + def filter_existing_chassis(self, nb_idl, gw_chassis, + physnet, chassis_physnets, existing_chassis, az_hints, chassis_with_azs): chassis_list = copy.copy(existing_chassis) for chassis_name in existing_chassis or []: diff --git a/neutron/tests/functional/common/ovn/test_utils.py b/neutron/tests/functional/common/ovn/test_utils.py index 7f371ed882e..ffdd7816e3d 100644 --- a/neutron/tests/functional/common/ovn/test_utils.py +++ b/neutron/tests/functional/common/ovn/test_utils.py @@ -13,7 +13,6 @@ # under the License. import ddt -from neutron_lib.api.definitions import external_net from neutron_lib.api.definitions import portbindings from oslo_utils import uuidutils from ovsdbapp.backend.ovs_idl import event @@ -322,76 +321,3 @@ def test_without_transaction(self, method, _args, _kwargs): def test_needed_parameters(self, method): self.assertRaises(RuntimeError, method, uuidutils.generate_uuid(), None, None) - - -class TestGetLogicalRouterPortHAChassis(base.TestOVNFunctionalBase): - def _create_network_and_port(self): - kwargs = {external_net.EXTERNAL: True, 'as_admin': True} - net = self._make_network(self.fmt, 'n1', True, **kwargs)['network'] - port_data = {'port': {'network_id': net['id'], - 'tenant_id': self._tenant_id,}} - port_req = self.new_create_request('ports', port_data, self.fmt) - port_res = port_req.get_response(self.api) - return self.deserialize(self.fmt, port_res)['port'] - - def _create_gw_chassis(self, num_chassis): - chassis = [] - for _ in range(num_chassis): - chassis.append(self.add_fake_chassis( - uuidutils.generate_uuid(), azs=[], - enable_chassis_as_gw=True)) - return chassis - - def _create_router(self, network_id): - gw_info = {'network_id': network_id} - router = {'router': {'name': uuidutils.generate_uuid(), - 'admin_state_up': True, - 'tenant_id': self._tenant_id, - 'external_gateway_info': gw_info}} - return self.l3_plugin.create_router(self.context, router) - - def _set_lrp_hcg(self, gw_port_id, hcg): - lrp_name = utils.ovn_lrouter_port_name(gw_port_id) - self.nb_api.db_set( - 'Logical_Router_Port', lrp_name, - ('ha_chassis_group', hcg.uuid)).execute() - return self.nb_api.lookup('Logical_Router_Port', lrp_name) - - def _get_router_hcg(self, router_id): - hcg_name = utils.ovn_name(router_id) - return self.nb_api.lookup('HA_Chassis_Group', hcg_name) - - def _check_chassis(self, ha_chassis, expected_chassis, priorities=None): - length = len(priorities) if priorities else len(expected_chassis) - self.assertEqual(length, len(ha_chassis)) - ch_priorities = set([]) - for hc in ha_chassis: - self.assertIn(hc[0], expected_chassis) - ch_priorities.add(hc[1]) - self.assertEqual(length, len(ch_priorities)) - if priorities: - for ch_priority in ch_priorities: - self.assertIn(ch_priority, priorities) - - def test_get_ha_chassis(self): - port = self._create_network_and_port() - ch_list = self._create_gw_chassis(5) - router = self._create_router(port['network_id']) - hcg = self._get_router_hcg(router['id']) - lrp = self._set_lrp_hcg(router['gw_port_id'], hcg) - - ha_chassis = utils.get_logical_router_port_ha_chassis(self.nb_api, lrp) - self._check_chassis(ha_chassis, ch_list) - - def test_get_ha_chassis_priorities(self): - port = self._create_network_and_port() - ch_list = self._create_gw_chassis(5) - router = self._create_router(port['network_id']) - hcg = self._get_router_hcg(router['id']) - lrp = self._set_lrp_hcg(router['gw_port_id'], hcg) - - prio = [ovn_const.HA_CHASSIS_GROUP_HIGHEST_PRIORITY, - ovn_const.HA_CHASSIS_GROUP_HIGHEST_PRIORITY - 1] - ha_chassis = utils.get_logical_router_port_ha_chassis( - self.nb_api, lrp, priorities=prio) - self._check_chassis(ha_chassis, ch_list, priorities=prio) diff --git a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_impl_idl.py b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_impl_idl.py index 40fb6049d66..f5adcbea58a 100644 --- a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_impl_idl.py +++ b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_impl_idl.py @@ -12,14 +12,12 @@ # under the License. # -from collections import abc import copy from unittest import mock import uuid import netaddr from neutron_lib import constants -from neutron_lib.utils import net as net_utils from oslo_utils import netutils from oslo_utils import uuidutils from ovsdbapp.backend.ovs_idl import connection @@ -697,204 +695,6 @@ def test_modify_static_route_external_ids(self): self.assertEqual(external_ids, lr.static_routes[0].external_ids) - def _cleanup_delete_hcg(self, hcg_name): - if isinstance(hcg_name, str): - self.nbapi.db_destroy('HA_Chassis_Group', hcg_name).execute( - check_error=True) - elif isinstance(hcg_name, abc.Iterable): - for _hcg_name in hcg_name: - self.nbapi.db_destroy('HA_Chassis_Group', _hcg_name).execute( - check_error=True) - - def _check_hcg(self, hcg, hcg_name, chassis_priority, - chassis_priority_deleted=None): - self.assertEqual(hcg_name, hcg.name) - self.assertEqual(len(chassis_priority), len(hcg.ha_chassis)) - for hc in hcg.ha_chassis: - self.assertEqual(chassis_priority[hc.chassis_name], hc.priority) - - if chassis_priority_deleted: - for hc_name in chassis_priority_deleted: - self.assertIsNone( - self.nbapi.lookup('HA_Chassis', hc_name, default=None)) - - def test_ha_chassis_group_with_hc_add_no_existing_hcg(self): - chassis_priority = {'ch1': 1, 'ch2': 2, 'ch3': 3, 'ch4': 4} - hcg_name = uuidutils.generate_uuid() - self.addCleanup(self._cleanup_delete_hcg, hcg_name) - hcg = self.nbapi.ha_chassis_group_with_hc_add( - hcg_name, chassis_priority).execute(check_error=True) - self._check_hcg(hcg, hcg_name, chassis_priority) - - def test_ha_chassis_group_with_hc_add_existing_hcg(self): - chassis_priority = {'ch1': 1, 'ch2': 2, 'ch3': 3, 'ch4': 4} - hcg_name = uuidutils.generate_uuid() - self.addCleanup(self._cleanup_delete_hcg, hcg_name) - self.nbapi.ha_chassis_group_with_hc_add( - hcg_name, chassis_priority).execute(check_error=True) - cmd = self.nbapi.ha_chassis_group_with_hc_add( - hcg_name, chassis_priority) - self.assertRaises(RuntimeError, cmd.execute, check_error=True) - - def test_ha_chassis_group_with_hc_add_existing_hcg_may_exist(self): - chassis_priority = {'ch1': 1, 'ch2': 2, 'ch3': 3, 'ch4': 4} - hcg_name = uuidutils.generate_uuid() - self.addCleanup(self._cleanup_delete_hcg, hcg_name) - hcg = None - for _ in range(2): - hcg = self.nbapi.ha_chassis_group_with_hc_add( - hcg_name, chassis_priority, may_exist=True).execute( - check_error=True) - self._check_hcg(hcg, hcg_name, chassis_priority) - - def test_ha_chassis_group_with_hc_add_existing_hcg_update_chassis(self): - # This test: - # - adds new chassis: ch5, ch6 - # - removes others: ch3, ch4 - # - changes the priority of the existing ones ch1, ch2 - chassis_priority = {'ch1': 1, 'ch2': 2, 'ch3': 3, 'ch4': 4} - hcg_name = uuidutils.generate_uuid() - self.addCleanup(self._cleanup_delete_hcg, hcg_name) - self.nbapi.ha_chassis_group_with_hc_add( - hcg_name, chassis_priority).execute(check_error=True) - - chassis_priority = {'ch1': 2, 'ch2': 1, 'ch5': 3, 'ch6': 4} - hcg = self.nbapi.ha_chassis_group_with_hc_add( - hcg_name, chassis_priority, may_exist=True).execute( - check_error=True) - self._check_hcg(hcg, hcg_name, chassis_priority, - chassis_priority_deleted=['ch3', 'ch4']) - - def test_ha_chassis_group_with_hc_add_two_hcg(self): - # Both HCG will have the same chassis priority (the same chassis - # names, that is something very common. - chassis_priority1 = {'ch1': 1, 'ch2': 2, 'ch3': 3, 'ch4': 4} - chassis_priority2 = {'ch1': 11, 'ch2': 12, 'ch3': 13, 'ch4': 14} - hcg_name1 = uuidutils.generate_uuid() - hcg_name2 = uuidutils.generate_uuid() - self.addCleanup(self._cleanup_delete_hcg, [hcg_name1, hcg_name2]) - hcg1 = self.nbapi.ha_chassis_group_with_hc_add( - hcg_name1, chassis_priority1).execute(check_error=True) - hcg2 = self.nbapi.ha_chassis_group_with_hc_add( - hcg_name2, chassis_priority2).execute(check_error=True) - self._check_hcg(hcg1, hcg_name1, chassis_priority1) - self._check_hcg(hcg2, hcg_name2, chassis_priority2) - - def _add_lrp_with_gw(self, chassis_priority=None, is_gw=True): - if is_gw: - hcg_name = uuidutils.generate_uuid() - hcg = self.nbapi.ha_chassis_group_with_hc_add( - hcg_name, chassis_priority).execute(check_error=True) - kwargs = {'ha_chassis_group': hcg.uuid} - else: - hcg = None - kwargs = {} - - mac = next(net_utils.random_mac_generator(['ca', 'fe', 'ca', 'fe'])) - networks = ['192.0.2.0/24'] - lr = self.nbapi.lr_add(uuidutils.generate_uuid()).execute( - check_error=True) - - lrp = self.nbapi.lrp_add( - lr.uuid, uuidutils.generate_uuid(), mac, networks, - **kwargs).execute(check_error=True) - return lr, lrp, hcg - - def test__get_logical_router_port_ha_chassis_group(self): - chassis_priority = {'ch1': 1, 'ch2': 2, 'ch3': 3, 'ch4': 4} - lr, lrp, hcg = self._add_lrp_with_gw(chassis_priority) - cprio_res = self.nbapi._get_logical_router_port_ha_chassis_group(lrp) - self.assertEqual([('ch4', 4), ('ch3', 3), ('ch2', 2), ('ch1', 1)], - cprio_res) - - def test__get_logical_router_port_ha_chassis_group_with_priorities(self): - chassis_priority = {'ch1': 1, 'ch2': 2, 'ch3': 3, 'ch4': 4} - lr, lrp, hcg = self._add_lrp_with_gw(chassis_priority) - cprio_res = self.nbapi._get_logical_router_port_ha_chassis_group( - lrp, priorities=(1, 3, 4)) - self.assertEqual([('ch4', 4), ('ch3', 3), ('ch1', 1)], cprio_res) - - def test__get_logical_router_port_ha_chassis_group_no_hcg(self): - lr, lrp, hcg = self._add_lrp_with_gw(is_gw=False) - cprio_res = self.nbapi._get_logical_router_port_ha_chassis_group(lrp) - self.assertEqual([], cprio_res) - - def test_create_lrp_with_ha_chassis_group_same_txn(self): - mac = next(net_utils.random_mac_generator(['ca', 'fe', 'ca', 'fe'])) - networks = ['192.0.2.0/24'] - lr_name = uuidutils.generate_uuid() - lrp_name = uuidutils.generate_uuid() - self.nbapi.lr_add(lr_name).execute(check_error=True) - - # Create the HCG and the LRP in the same transaction. - with self.nbapi.transaction(check_error=True) as txn: - hcg_cmd = txn.add(self.nbapi.ha_chassis_group_with_hc_add( - uuidutils.generate_uuid(), {'ch1': 1, 'ch2': 2})) - txn.add(self.nbapi.add_lrouter_port( - lrp_name, lr_name, mac=mac, networks=networks, - ha_chassis_group=hcg_cmd)) - - lrp = self.nbapi.lrp_get(lrp_name).execute(check_error=True) - self.assertEqual(hcg_cmd.result.uuid, lrp.ha_chassis_group[0].uuid) - - def test_create_lrp_with_ha_chassis_group_different_txn(self): - mac = next(net_utils.random_mac_generator(['ca', 'fe', 'ca', 'fe'])) - networks = ['192.0.2.0/24'] - lr_name = uuidutils.generate_uuid() - lrp_name = uuidutils.generate_uuid() - self.nbapi.lr_add(lr_name).execute(check_error=True) - - # Create the HCG and the LRP in two consecutive transactions. - hcg = self.nbapi.ha_chassis_group_with_hc_add( - uuidutils.generate_uuid(), {'ch1': 1, 'ch2': 2}).execute( - check_error=True) - self.nbapi.add_lrouter_port( - lrp_name, lr_name, mac=mac, networks=networks, - ha_chassis_group=hcg.uuid).execute(check_error=True) - - lrp = self.nbapi.lrp_get(lrp_name).execute(check_error=True) - self.assertEqual(hcg.uuid, lrp.ha_chassis_group[0].uuid) - - def test_update_lrp_with_ha_chassis_group_same_txn(self): - mac = next(net_utils.random_mac_generator(['ca', 'fe', 'ca', 'fe'])) - networks = ['192.0.2.0/24'] - lr_name = uuidutils.generate_uuid() - lrp_name = uuidutils.generate_uuid() - self.nbapi.lr_add(lr_name).execute(check_error=True) - self.nbapi.add_lrouter_port( - lrp_name, lr_name, mac=mac, - networks=networks).execute(check_error=True) - - # Create the HCG and update the LRP in the same transaction. - with self.nbapi.transaction(check_error=True) as txn: - hcg_cmd = txn.add(self.nbapi.ha_chassis_group_with_hc_add( - uuidutils.generate_uuid(), {'ch1': 1, 'ch2': 2})) - txn.add(self.nbapi.update_lrouter_port( - lrp_name, ha_chassis_group=hcg_cmd)) - - lrp = self.nbapi.lrp_get(lrp_name).execute(check_error=True) - self.assertEqual(hcg_cmd.result.uuid, lrp.ha_chassis_group[0].uuid) - - def test_update_lrp_with_ha_chassis_group_different_txn(self): - mac = next(net_utils.random_mac_generator(['ca', 'fe', 'ca', 'fe'])) - networks = ['192.0.2.0/24'] - lr_name = uuidutils.generate_uuid() - lrp_name = uuidutils.generate_uuid() - self.nbapi.lr_add(lr_name).execute(check_error=True) - self.nbapi.add_lrouter_port( - lrp_name, lr_name, mac=mac, - networks=networks).execute(check_error=True) - - # Create the HCG and update the LRP in two consecutive transactions. - hcg = self.nbapi.ha_chassis_group_with_hc_add( - uuidutils.generate_uuid(), {'ch1': 1, 'ch2': 2}).execute( - check_error=True) - self.nbapi.update_lrouter_port( - lrp_name, ha_chassis_group=hcg.uuid).execute(check_error=True) - - lrp = self.nbapi.lrp_get(lrp_name).execute(check_error=True) - self.assertEqual(hcg.uuid, lrp.ha_chassis_group[0].uuid) - class TestIgnoreConnectionTimeout(BaseOvnIdlTest): @classmethod diff --git a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_maintenance.py b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_maintenance.py index f241494cc95..5a7ea7a6158 100644 --- a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_maintenance.py +++ b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_maintenance.py @@ -27,7 +27,6 @@ from neutron_lib import constants as n_const from neutron_lib import context as n_context from neutron_lib.exceptions import l3 as lib_l3_exc -from neutron_lib.utils import net as net_utils from oslo_utils import uuidutils from sqlalchemy.dialects.mysql import dialect as mysql_dialect @@ -1481,44 +1480,6 @@ def test_update_qos_fip_rule_priority(self): else: self.assertEqual(def_prio, qos_rule.priority) - def test_migrate_lrp_gateway_chassis_to_ha_chassis_group(self): - mac = next(net_utils.random_mac_generator(['ca', 'fe', 'ca', 'fe'])) - networks = ['192.0.2.0/24'] - lr_name = uuidutils.generate_uuid() - lrp_name = uuidutils.generate_uuid() - gateway_chassis = ['gw_ch1', 'gw_ch2', 'gw_ch3'] - - self.nb_api.lr_add(lr_name).execute(check_error=True) - ext_ids = {ovn_const.OVN_ROUTER_NAME_EXT_ID_KEY: lr_name} - self.nb_api.add_lrouter_port( - lrp_name, lr_name, mac=mac, - networks=networks, gateway_chassis=gateway_chassis, - external_ids=ext_ids).execute(check_error=True) - - hcg = self.nb_api.lookup('HA_Chassis_Group', lr_name, default=None) - self.assertIsNone(hcg) - lr = self.nb_api.lookup('Logical_Router_Port', lrp_name) - chassis_prio = {} - for gc in lr.gateway_chassis: - chassis_prio[gc.chassis_name] = gc.priority - - self.assertRaises( - periodics.NeverAgain, - self.maint.migrate_lrp_gateway_chassis_to_ha_chassis_group) - - hcg = self.nb_api.lookup('HA_Chassis_Group', lr_name, default=None) - self.assertEqual(len(chassis_prio), len(hcg.ha_chassis)) - for ha_chassis in hcg.ha_chassis: - try: - # The priority and the chassis_name of the former - # Gateway_Chassis registers must match the new HA_Chassis ones. - self.assertEqual(ha_chassis.priority, - chassis_prio.pop(ha_chassis.chassis_name)) - except KeyError: - self.fail(f'HA_Chassis with chassis name ' - f'{ha_chassis.chassis_name} not present in the ' - f'chassis list') - class TestLogMaintenance(_TestMaintenanceHelper, test_log_driver.LogApiTestCaseBase): diff --git a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py index 5831b13bd1b..7bd6e1bc386 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py +++ b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py @@ -106,8 +106,6 @@ def setUp(self): neutron_agent.AgentCache().get_agents.return_value = [agent1] self.mock_vp_parents = mock.patch.object( ovn_utils, 'get_virtual_port_parents', return_value=None).start() - mock.patch.object(ovn_utils, 'ovs_persist_uuid_supported', - return_value=True).start() def _add_chassis_private(self, nb_cfg, name=None): chassis_private = mock.Mock() @@ -883,19 +881,15 @@ def test_network_precommit(self): self.mech_driver.update_network_precommit, fake_network_context) - def _verify_ls_add(self, net_id, may_exist=True, **kwargs): - ls_add = self.mech_driver._ovn_client._nb_idl.ls_add - ls_add.assert_called_once_with( - external_ids=mock.ANY, - may_exist=may_exist, network_id=net_id, **kwargs) - def _create_network_igmp_snoop(self, enabled): cfg.CONF.set_override('igmp_snooping_enable', enabled, group='OVS') + nb_idl = self.mech_driver._ovn_client._nb_idl net = self._make_network(self.fmt, name='net1', admin_state_up=True)['network'] value = 'true' if enabled else 'false' - self._verify_ls_add( - net_id=net['id'], + nb_idl.ls_add.assert_called_once_with( + ovn_utils.ovn_name(net['id']), external_ids=mock.ANY, + may_exist=True, other_config={ovn_const.MCAST_SNOOP: value, ovn_const.MCAST_FLOOD_UNREGISTERED: 'false', ovn_const.VLAN_PASSTHRU: 'false'}) @@ -907,6 +901,7 @@ def test_create_network_igmp_snoop_disabled(self): self._create_network_igmp_snoop(enabled=False) def _create_network_vlan_passthru(self, vlan_transparent, qinq): + nb_idl = self.mech_driver._ovn_client._nb_idl net = self._make_network( self.fmt, name='net1', as_admin=True, @@ -922,8 +917,9 @@ def _create_network_vlan_passthru(self, vlan_transparent, qinq): 'provider:physical_network': 'physnet1'})['network'] value = 'true' if vlan_transparent or qinq else 'false' expected_fdb_age_treshold = ovn_conf.get_fdb_age_threshold() - self._verify_ls_add( - net_id=net['id'], + nb_idl.ls_add.assert_called_once_with( + ovn_utils.ovn_name(net['id']), external_ids=mock.ANY, + may_exist=True, other_config={ ovn_const.MCAST_SNOOP: 'false', ovn_const.MCAST_FLOOD_UNREGISTERED: 'false', @@ -962,7 +958,6 @@ def test_create_network_create_localnet_port_physical_network_type(self): self.context, net['id']) nb_idl.create_lswitch_port.assert_called_once_with( addresses=[ovn_const.UNKNOWN_ADDR], - network_id=net['id'], external_ids={}, lport_name=ovn_utils.ovn_provnet_port_name(segments[0]['id']), lswitch_name=ovn_utils.ovn_name(net['id']), @@ -3482,7 +3477,6 @@ def test_create_segment_create_localnet_port(self): segmentation_id=200, network_type='vlan')['segment'] ovn_nb_api.create_lswitch_port.assert_called_once_with( addresses=[ovn_const.UNKNOWN_ADDR], - network_id=net['id'], external_ids={}, lport_name=ovn_utils.ovn_provnet_port_name(new_segment['id']), lswitch_name=ovn_utils.ovn_name(net['id']), @@ -3501,7 +3495,6 @@ def test_create_segment_create_localnet_port(self): segmentation_id=300, network_type='vlan')['segment'] ovn_nb_api.create_lswitch_port.assert_called_once_with( addresses=[ovn_const.UNKNOWN_ADDR], - network_id=net['id'], external_ids={}, lport_name=ovn_utils.ovn_provnet_port_name(new_segment['id']), lswitch_name=ovn_utils.ovn_name(net['id']), diff --git a/neutron/tests/unit/scheduler/test_l3_ovn_scheduler.py b/neutron/tests/unit/scheduler/test_l3_ovn_scheduler.py index e4d64df7567..a7aff4086d8 100644 --- a/neutron/tests/unit/scheduler/test_l3_ovn_scheduler.py +++ b/neutron/tests/unit/scheduler/test_l3_ovn_scheduler.py @@ -118,7 +118,8 @@ def select(self, chassis_gateway_mapping, gateway_name, def filter_existing_chassis(self, *args, **kwargs): return self.l3_scheduler.filter_existing_chassis( - gw_chassis=kwargs.pop('gw_chassis'), physnet=kwargs.pop('physnet'), + nb_idl=kwargs.pop('nb_idl'), gw_chassis=kwargs.pop('gw_chassis'), + physnet=kwargs.pop('physnet'), chassis_physnets=kwargs.pop('chassis_physnets'), existing_chassis=kwargs.pop('existing_chassis'), az_hints=kwargs.pop('az_hints', []), @@ -170,24 +171,26 @@ def test_filter_existing_chassis(self): # it from Base class didnt seem right. Also, there is no need to have # another test in LeastLoadedScheduler. chassis_physnets = {'temp': ['phys-network-0', 'phys-network-1']} + nb_idl = FakeOVNGatewaySchedulerNbOvnIdl( + self.fake_chassis_gateway_mappings['None'], 'g1') # Check if invalid chassis is removed self.assertEqual( ['temp'], self.filter_existing_chassis( - gw_chassis=["temp"], + nb_idl=nb_idl, gw_chassis=["temp"], physnet='phys-network-1', chassis_physnets=chassis_physnets, existing_chassis=['temp', None])) # Check if invalid is removed -II self.assertFalse( self.filter_existing_chassis( - gw_chassis=["temp"], + nb_idl=nb_idl, gw_chassis=["temp"], physnet='phys-network-1', chassis_physnets=chassis_physnets, existing_chassis=None)) # Check if chassis removed when physnet doesnt exist self.assertFalse( self.filter_existing_chassis( - gw_chassis=["temp"], + nb_idl=nb_idl, gw_chassis=["temp"], physnet='phys-network-2', chassis_physnets=chassis_physnets, existing_chassis=['temp'])) @@ -195,7 +198,7 @@ def test_filter_existing_chassis(self): # or in chassis_physnets self.assertFalse( self.filter_existing_chassis( - gw_chassis=["temp1"], + nb_idl=nb_idl, gw_chassis=["temp1"], physnet='phys-network-2', chassis_physnets=chassis_physnets, existing_chassis=['temp'])) diff --git a/requirements.txt b/requirements.txt index afd39c66ae8..161c7b69832 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,7 +44,7 @@ oslo.versionedobjects>=1.35.1 # Apache-2.0 osprofiler>=2.3.0 # Apache-2.0 os-ken>=3.0.0 # Apache-2.0 os-resource-classes>=1.1.0 # Apache-2.0 -ovs>3.3.0 # Apache-2.0 +ovs>=2.12.0 # Apache-2.0 ovsdbapp>=2.11.0 # Apache-2.0 psutil>=6.1.0 # BSD pyroute2>=0.7.3;sys_platform!='win32' # Apache-2.0 (+ dual licensed GPL2)