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]74d90c2223
[2]51309429cc
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 Closes-Bug: #1990229 Change-Id: I54c8fd4d065ae537f396408df16832b158ee8998
This commit is contained in:
parent
98d76ec6b4
commit
536498a29a
@ -641,8 +641,8 @@ def compute_address_pairs_diff(ovn_port, neutron_port):
|
|||||||
|
|
||||||
def get_ovn_cms_options(chassis):
|
def get_ovn_cms_options(chassis):
|
||||||
"""Return the list of CMS options in a Chassis."""
|
"""Return the list of CMS options in a Chassis."""
|
||||||
return [opt.strip() for opt in chassis.external_ids.get(
|
return [opt.strip() for opt in get_ovn_chassis_other_config(chassis).get(
|
||||||
constants.OVN_CMS_OPTIONS, '').split(',')]
|
constants.OVN_CMS_OPTIONS, '').split(',')]
|
||||||
|
|
||||||
|
|
||||||
def is_gateway_chassis(chassis):
|
def is_gateway_chassis(chassis):
|
||||||
@ -831,3 +831,11 @@ def create_neutron_pg_drop():
|
|||||||
}]
|
}]
|
||||||
|
|
||||||
OvsdbClientTransactCommand.run(command)
|
OvsdbClientTransactCommand.run(command)
|
||||||
|
|
||||||
|
|
||||||
|
def get_ovn_chassis_other_config(chassis):
|
||||||
|
# NOTE(ralonsoh): LP#1990229 to be removed when min OVN version is 22.09
|
||||||
|
try:
|
||||||
|
return chassis.other_config
|
||||||
|
except AttributeError:
|
||||||
|
return chassis.external_ids
|
||||||
|
@ -89,7 +89,8 @@ class NeutronAgent(abc.ABC):
|
|||||||
'configurations': {
|
'configurations': {
|
||||||
'chassis_name': self.chassis.name,
|
'chassis_name': self.chassis.name,
|
||||||
'bridge-mappings':
|
'bridge-mappings':
|
||||||
self.chassis.external_ids.get('ovn-bridge-mappings', '')},
|
ovn_utils.get_ovn_chassis_other_config(self.chassis).get(
|
||||||
|
'ovn-bridge-mappings', '')},
|
||||||
'start_flag': True,
|
'start_flag': True,
|
||||||
'agent_type': self.agent_type,
|
'agent_type': self.agent_type,
|
||||||
'id': self.agent_id,
|
'id': self.agent_id,
|
||||||
@ -141,9 +142,9 @@ class ControllerAgent(NeutronAgent):
|
|||||||
|
|
||||||
@staticmethod # it is by default, but this makes pep8 happy
|
@staticmethod # it is by default, but this makes pep8 happy
|
||||||
def __new__(cls, chassis_private, driver):
|
def __new__(cls, chassis_private, driver):
|
||||||
external_ids = cls.chassis_from_private(chassis_private).external_ids
|
_chassis = cls.chassis_from_private(chassis_private)
|
||||||
if ('enable-chassis-as-gw' in
|
other_config = ovn_utils.get_ovn_chassis_other_config(_chassis)
|
||||||
external_ids.get('ovn-cms-options', [])):
|
if 'enable-chassis-as-gw' in other_config.get('ovn-cms-options', []):
|
||||||
cls = ControllerGatewayAgent
|
cls = ControllerGatewayAgent
|
||||||
return super().__new__(cls)
|
return super().__new__(cls)
|
||||||
|
|
||||||
@ -166,8 +167,9 @@ class ControllerAgent(NeutronAgent):
|
|||||||
|
|
||||||
def update(self, chassis_private, clear_down=False):
|
def update(self, chassis_private, clear_down=False):
|
||||||
super().update(chassis_private, clear_down)
|
super().update(chassis_private, clear_down)
|
||||||
external_ids = self.chassis_from_private(chassis_private).external_ids
|
_chassis = self.chassis_from_private(chassis_private)
|
||||||
if 'enable-chassis-as-gw' in external_ids.get('ovn-cms-options', []):
|
other_config = ovn_utils.get_ovn_chassis_other_config(_chassis)
|
||||||
|
if 'enable-chassis-as-gw' in other_config.get('ovn-cms-options', []):
|
||||||
self.__class__ = ControllerGatewayAgent
|
self.__class__ = ControllerGatewayAgent
|
||||||
|
|
||||||
|
|
||||||
@ -176,9 +178,10 @@ class ControllerGatewayAgent(ControllerAgent):
|
|||||||
|
|
||||||
def update(self, chassis_private, clear_down=False):
|
def update(self, chassis_private, clear_down=False):
|
||||||
super().update(chassis_private, clear_down)
|
super().update(chassis_private, clear_down)
|
||||||
external_ids = self.chassis_from_private(chassis_private).external_ids
|
_chassis = self.chassis_from_private(chassis_private)
|
||||||
|
other_config = ovn_utils.get_ovn_chassis_other_config(_chassis)
|
||||||
if ('enable-chassis-as-gw' not in
|
if ('enable-chassis-as-gw' not in
|
||||||
external_ids.get('ovn-cms-options', [])):
|
other_config.get('ovn-cms-options', [])):
|
||||||
self.__class__ = ControllerAgent
|
self.__class__ = ControllerAgent
|
||||||
|
|
||||||
|
|
||||||
|
@ -191,7 +191,8 @@ class OVNMechanismDriver(api.MechanismDriver):
|
|||||||
def get_supported_vif_types(self):
|
def get_supported_vif_types(self):
|
||||||
vif_types = set()
|
vif_types = set()
|
||||||
for ch in self.sb_ovn.chassis_list().execute(check_error=True):
|
for ch in self.sb_ovn.chassis_list().execute(check_error=True):
|
||||||
dp_type = ch.external_ids.get('datapath-type', '')
|
other_config = ovn_utils.get_ovn_chassis_other_config(ch)
|
||||||
|
dp_type = other_config.get('datapath-type', '')
|
||||||
if dp_type == ovn_const.CHASSIS_DATAPATH_NETDEV:
|
if dp_type == ovn_const.CHASSIS_DATAPATH_NETDEV:
|
||||||
vif_types.add(portbindings.VIF_TYPE_VHOST_USER)
|
vif_types.add(portbindings.VIF_TYPE_VHOST_USER)
|
||||||
else:
|
else:
|
||||||
@ -962,8 +963,9 @@ class OVNMechanismDriver(api.MechanismDriver):
|
|||||||
'agent': agent})
|
'agent': agent})
|
||||||
return
|
return
|
||||||
chassis = agent.chassis
|
chassis = agent.chassis
|
||||||
datapath_type = chassis.external_ids.get('datapath-type', '')
|
other_config = ovn_utils.get_ovn_chassis_other_config(chassis)
|
||||||
iface_types = chassis.external_ids.get('iface-types', '')
|
datapath_type = other_config.get('datapath-type', '')
|
||||||
|
iface_types = other_config.get('iface-types', '')
|
||||||
iface_types = iface_types.split(',') if iface_types else []
|
iface_types = iface_types.split(',') if iface_types else []
|
||||||
chassis_physnets = self.sb_ovn._get_chassis_physnets(chassis)
|
chassis_physnets = self.sb_ovn._get_chassis_physnets(chassis)
|
||||||
for segment_to_bind in context.segments_to_bind:
|
for segment_to_bind in context.segments_to_bind:
|
||||||
|
@ -42,7 +42,8 @@ def _parse_ovn_cms_options(chassis):
|
|||||||
|
|
||||||
|
|
||||||
def _parse_bridge_mappings(chassis):
|
def _parse_bridge_mappings(chassis):
|
||||||
bridge_mappings = chassis.external_ids.get('ovn-bridge-mappings', '')
|
other_config = ovn_utils.get_ovn_chassis_other_config(chassis)
|
||||||
|
bridge_mappings = other_config.get('ovn-bridge-mappings', '')
|
||||||
bridge_mappings = helpers.parse_mappings(bridge_mappings.split(','),
|
bridge_mappings = helpers.parse_mappings(bridge_mappings.split(','),
|
||||||
unique_values=False)
|
unique_values=False)
|
||||||
return {k: [v] for k, v in bridge_mappings.items()}
|
return {k: [v] for k, v in bridge_mappings.items()}
|
||||||
|
@ -847,7 +847,8 @@ class OvsdbSbOvnIdl(sb_impl_idl.OvnSbApiIdlImpl, Backend):
|
|||||||
return cls(conn)
|
return cls(conn)
|
||||||
|
|
||||||
def _get_chassis_physnets(self, chassis):
|
def _get_chassis_physnets(self, chassis):
|
||||||
bridge_mappings = chassis.external_ids.get('ovn-bridge-mappings', '')
|
other_config = utils.get_ovn_chassis_other_config(chassis)
|
||||||
|
bridge_mappings = other_config.get('ovn-bridge-mappings', '')
|
||||||
mapping_dict = helpers.parse_mappings(bridge_mappings.split(','))
|
mapping_dict = helpers.parse_mappings(bridge_mappings.split(','))
|
||||||
return list(mapping_dict.keys())
|
return list(mapping_dict.keys())
|
||||||
|
|
||||||
@ -865,7 +866,8 @@ class OvsdbSbOvnIdl(sb_impl_idl.OvnSbApiIdlImpl, Backend):
|
|||||||
return [ch.name if name_only else ch
|
return [ch.name if name_only else ch
|
||||||
for ch in self.chassis_list().execute(check_error=True)
|
for ch in self.chassis_list().execute(check_error=True)
|
||||||
if ovn_const.CMS_OPT_CHASSIS_AS_GW in
|
if ovn_const.CMS_OPT_CHASSIS_AS_GW in
|
||||||
ch.external_ids.get(ovn_const.OVN_CMS_OPTIONS, '').split(',')]
|
utils.get_ovn_chassis_other_config(ch).get(
|
||||||
|
ovn_const.OVN_CMS_OPTIONS, '').split(',')]
|
||||||
|
|
||||||
def get_chassis_and_physnets(self):
|
def get_chassis_and_physnets(self):
|
||||||
chassis_info_dict = {}
|
chassis_info_dict = {}
|
||||||
@ -890,7 +892,7 @@ class OvsdbSbOvnIdl(sb_impl_idl.OvnSbApiIdlImpl, Backend):
|
|||||||
if ('{}={}'
|
if ('{}={}'
|
||||||
.format(ovn_const.CMS_OPT_CARD_SERIAL_NUMBER,
|
.format(ovn_const.CMS_OPT_CARD_SERIAL_NUMBER,
|
||||||
card_serial_number)
|
card_serial_number)
|
||||||
in ch.external_ids.get(
|
in utils.get_ovn_chassis_other_config(ch).get(
|
||||||
ovn_const.OVN_CMS_OPTIONS, '').split(',')):
|
ovn_const.OVN_CMS_OPTIONS, '').split(',')):
|
||||||
return ch
|
return ch
|
||||||
msg = _('Chassis with %s %s %s does not exist'
|
msg = _('Chassis with %s %s %s does not exist'
|
||||||
|
@ -172,12 +172,21 @@ class ChassisEvent(row_event.RowEvent):
|
|||||||
def match_fn(self, event, row, old):
|
def match_fn(self, event, row, old):
|
||||||
if event != self.ROW_UPDATE:
|
if event != self.ROW_UPDATE:
|
||||||
return True
|
return True
|
||||||
# NOTE(lucasgomes): If the external_ids column wasn't updated
|
|
||||||
# (meaning, Chassis "gateway" status didn't change) just returns
|
# NOTE(ralonsoh): LP#1990229 to be removed when min OVN version is
|
||||||
if not hasattr(old, 'external_ids') and event == self.ROW_UPDATE:
|
# 22.09
|
||||||
|
other_config = ('other_config' if hasattr(row, 'other_config') else
|
||||||
|
'external_ids')
|
||||||
|
# NOTE(lucasgomes): If the other_config/external_ids column wasn't
|
||||||
|
# updated (meaning, Chassis "gateway" status didn't change) just
|
||||||
|
# returns
|
||||||
|
if not hasattr(old, other_config) and event == self.ROW_UPDATE:
|
||||||
return False
|
return False
|
||||||
if (old.external_ids.get('ovn-bridge-mappings') !=
|
old_br_mappings = utils.get_ovn_chassis_other_config(old).get(
|
||||||
row.external_ids.get('ovn-bridge-mappings')):
|
'ovn-bridge-mappings')
|
||||||
|
new_br_mappings = utils.get_ovn_chassis_other_config(row).get(
|
||||||
|
'ovn-bridge-mappings')
|
||||||
|
if old_br_mappings != new_br_mappings:
|
||||||
return True
|
return True
|
||||||
# Check if either the Gateway status or Availability Zones has
|
# Check if either the Gateway status or Availability Zones has
|
||||||
# changed in the Chassis
|
# changed in the Chassis
|
||||||
@ -192,8 +201,9 @@ class ChassisEvent(row_event.RowEvent):
|
|||||||
def run(self, event, row, old):
|
def run(self, event, row, old):
|
||||||
host = row.hostname
|
host = row.hostname
|
||||||
phy_nets = []
|
phy_nets = []
|
||||||
|
new_other_config = utils.get_ovn_chassis_other_config(row)
|
||||||
if event != self.ROW_DELETE:
|
if event != self.ROW_DELETE:
|
||||||
bridge_mappings = row.external_ids.get('ovn-bridge-mappings', '')
|
bridge_mappings = new_other_config.get('ovn-bridge-mappings', '')
|
||||||
mapping_dict = helpers.parse_mappings(bridge_mappings.split(','))
|
mapping_dict = helpers.parse_mappings(bridge_mappings.split(','))
|
||||||
phy_nets = list(mapping_dict)
|
phy_nets = list(mapping_dict)
|
||||||
|
|
||||||
@ -208,9 +218,10 @@ class ChassisEvent(row_event.RowEvent):
|
|||||||
if event == self.ROW_DELETE:
|
if event == self.ROW_DELETE:
|
||||||
kwargs['event_from_chassis'] = row.name
|
kwargs['event_from_chassis'] = row.name
|
||||||
elif event == self.ROW_UPDATE:
|
elif event == self.ROW_UPDATE:
|
||||||
old_mappings = old.external_ids.get('ovn-bridge-mappings',
|
old_other_config = utils.get_ovn_chassis_other_config(old)
|
||||||
|
old_mappings = old_other_config.get('ovn-bridge-mappings',
|
||||||
set()) or set()
|
set()) or set()
|
||||||
new_mappings = row.external_ids.get('ovn-bridge-mappings',
|
new_mappings = new_other_config.get('ovn-bridge-mappings',
|
||||||
set()) or set()
|
set()) or set()
|
||||||
if old_mappings:
|
if old_mappings:
|
||||||
old_mappings = set(old_mappings.split(','))
|
old_mappings = set(old_mappings.split(','))
|
||||||
@ -339,11 +350,17 @@ class ChassisAgentTypeChangeEvent(ChassisEvent):
|
|||||||
events = (BaseEvent.ROW_UPDATE,)
|
events = (BaseEvent.ROW_UPDATE,)
|
||||||
|
|
||||||
def match_fn(self, event, row, old=None):
|
def match_fn(self, event, row, old=None):
|
||||||
if not getattr(old, 'external_ids', False):
|
# NOTE(ralonsoh): LP#1990229 to be removed when min OVN version is
|
||||||
|
# 22.09
|
||||||
|
other_config = ('other_config' if hasattr(row, 'other_config') else
|
||||||
|
'external_ids')
|
||||||
|
if not getattr(old, other_config, False):
|
||||||
return False
|
return False
|
||||||
agent_type_change = n_agent.NeutronAgent.chassis_from_private(
|
chassis = n_agent.NeutronAgent.chassis_from_private(row)
|
||||||
row).external_ids.get('ovn-cms-options', []) != (
|
new_other_config = utils.get_ovn_chassis_other_config(chassis)
|
||||||
old.external_ids.get('ovn-cms-options', []))
|
old_other_config = utils.get_ovn_chassis_other_config(old)
|
||||||
|
agent_type_change = new_other_config.get('ovn-cms-options', []) != (
|
||||||
|
old_other_config.get('ovn-cms-options', []))
|
||||||
return agent_type_change
|
return agent_type_change
|
||||||
|
|
||||||
def run(self, event, row, old):
|
def run(self, event, row, old):
|
||||||
|
@ -423,7 +423,8 @@ class TestOVNFunctionalBase(test_plugin.Ml2PluginV2TestCase,
|
|||||||
self._start_ovn_northd()
|
self._start_ovn_northd()
|
||||||
|
|
||||||
def add_fake_chassis(self, host, physical_nets=None, external_ids=None,
|
def add_fake_chassis(self, host, physical_nets=None, external_ids=None,
|
||||||
name=None, azs=None, enable_chassis_as_gw=False):
|
name=None, azs=None, enable_chassis_as_gw=False,
|
||||||
|
other_config=None):
|
||||||
def append_cms_options(ext_ids, value):
|
def append_cms_options(ext_ids, value):
|
||||||
if 'ovn-cms-options' not in ext_ids:
|
if 'ovn-cms-options' not in ext_ids:
|
||||||
ext_ids['ovn-cms-options'] = value
|
ext_ids['ovn-cms-options'] = value
|
||||||
@ -432,19 +433,20 @@ class TestOVNFunctionalBase(test_plugin.Ml2PluginV2TestCase,
|
|||||||
|
|
||||||
physical_nets = physical_nets or []
|
physical_nets = physical_nets or []
|
||||||
external_ids = external_ids or {}
|
external_ids = external_ids or {}
|
||||||
|
other_config = other_config or {}
|
||||||
if azs is None:
|
if azs is None:
|
||||||
azs = ['ovn']
|
azs = ['ovn']
|
||||||
if azs:
|
if azs:
|
||||||
append_cms_options(external_ids, 'availability-zones=')
|
append_cms_options(other_config, 'availability-zones=')
|
||||||
external_ids['ovn-cms-options'] += ':'.join(azs)
|
other_config['ovn-cms-options'] += ':'.join(azs)
|
||||||
if enable_chassis_as_gw:
|
if enable_chassis_as_gw:
|
||||||
append_cms_options(external_ids, 'enable-chassis-as-gw')
|
append_cms_options(other_config, 'enable-chassis-as-gw')
|
||||||
|
|
||||||
bridge_mapping = ",".join(["%s:br-provider%s" % (phys_net, i)
|
bridge_mapping = ",".join(["%s:br-provider%s" % (phys_net, i)
|
||||||
for i, phys_net in enumerate(physical_nets)])
|
for i, phys_net in enumerate(physical_nets)])
|
||||||
if name is None:
|
if name is None:
|
||||||
name = uuidutils.generate_uuid()
|
name = uuidutils.generate_uuid()
|
||||||
external_ids['ovn-bridge-mappings'] = bridge_mapping
|
other_config['ovn-bridge-mappings'] = bridge_mapping
|
||||||
# We'll be using different IP addresses every time for the Encap of
|
# We'll be using different IP addresses every time for the Encap of
|
||||||
# the fake chassis as the SB schema doesn't allow to have two entries
|
# the fake chassis as the SB schema doesn't allow to have two entries
|
||||||
# with same (ip,type) pairs as of OVS 2.11. This shouldn't have any
|
# with same (ip,type) pairs as of OVS 2.11. This shouldn't have any
|
||||||
@ -455,7 +457,8 @@ class TestOVNFunctionalBase(test_plugin.Ml2PluginV2TestCase,
|
|||||||
self._counter += 1
|
self._counter += 1
|
||||||
chassis = self.sb_api.chassis_add(
|
chassis = self.sb_api.chassis_add(
|
||||||
name, ['geneve'], '172.24.4.%d' % self._counter,
|
name, ['geneve'], '172.24.4.%d' % self._counter,
|
||||||
external_ids=external_ids, hostname=host).execute(check_error=True)
|
external_ids=external_ids, hostname=host,
|
||||||
|
other_config=other_config).execute(check_error=True)
|
||||||
if self.sb_api.is_table_present('Chassis_Private'):
|
if self.sb_api.is_table_present('Chassis_Private'):
|
||||||
nb_cfg_timestamp = timeutils.utcnow_ts() * 1000
|
nb_cfg_timestamp = timeutils.utcnow_ts() * 1000
|
||||||
self.sb_api.db_create(
|
self.sb_api.db_create(
|
||||||
|
@ -72,7 +72,7 @@ class TestOVNClientQosExtension(base.TestOVNFunctionalBase):
|
|||||||
self.mock_send_batch = mock.patch.object(
|
self.mock_send_batch = mock.patch.object(
|
||||||
placement_extension, '_send_deferred_batch').start()
|
placement_extension, '_send_deferred_batch').start()
|
||||||
|
|
||||||
def _build_external_ids(self, bandwidths, inventory_defaults, hypervisors):
|
def _build_other_config(self, bandwidths, inventory_defaults, hypervisors):
|
||||||
options = []
|
options = []
|
||||||
if bandwidths:
|
if bandwidths:
|
||||||
options.append(n_const.RP_BANDWIDTHS + '=' + bandwidths)
|
options.append(n_const.RP_BANDWIDTHS + '=' + bandwidths)
|
||||||
@ -85,17 +85,17 @@ class TestOVNClientQosExtension(base.TestOVNFunctionalBase):
|
|||||||
|
|
||||||
def _create_chassis(self, host, name, physical_nets=None, bandwidths=None,
|
def _create_chassis(self, host, name, physical_nets=None, bandwidths=None,
|
||||||
inventory_defaults=None, hypervisors=None):
|
inventory_defaults=None, hypervisors=None):
|
||||||
external_ids = self._build_external_ids(bandwidths, inventory_defaults,
|
other_config = self._build_other_config(bandwidths, inventory_defaults,
|
||||||
hypervisors)
|
hypervisors)
|
||||||
self.add_fake_chassis(host, physical_nets=physical_nets,
|
self.add_fake_chassis(host, physical_nets=physical_nets,
|
||||||
external_ids=external_ids, name=name)
|
other_config=other_config, name=name)
|
||||||
|
|
||||||
def _update_chassis(self, name, bandwidths=None, inventory_defaults=None,
|
def _update_chassis(self, name, bandwidths=None, inventory_defaults=None,
|
||||||
hypervisors=None):
|
hypervisors=None):
|
||||||
external_ids = self._build_external_ids(bandwidths, inventory_defaults,
|
other_config = self._build_other_config(bandwidths, inventory_defaults,
|
||||||
hypervisors)
|
hypervisors)
|
||||||
self.sb_api.db_set(
|
self.sb_api.db_set(
|
||||||
'Chassis', name, ('external_ids', external_ids)
|
'Chassis', name, ('other_config', other_config)
|
||||||
).execute(check_error=True)
|
).execute(check_error=True)
|
||||||
|
|
||||||
def _check_placement_config(self, expected_chassis):
|
def _check_placement_config(self, expected_chassis):
|
||||||
|
@ -52,11 +52,11 @@ class TestSbApi(BaseOvnIdlTest):
|
|||||||
super(TestSbApi, self).setUp()
|
super(TestSbApi, self).setUp()
|
||||||
self.data = {
|
self.data = {
|
||||||
'chassis': [
|
'chassis': [
|
||||||
{'external_ids': {'ovn-bridge-mappings':
|
{'other_config': {'ovn-bridge-mappings':
|
||||||
'public:br-ex,private:br-0'}},
|
'public:br-ex,private:br-0'}},
|
||||||
{'external_ids': {'ovn-bridge-mappings':
|
{'other_config': {'ovn-bridge-mappings':
|
||||||
'public:br-ex,public2:br-ex2'}},
|
'public:br-ex,public2:br-ex2'}},
|
||||||
{'external_ids': {'ovn-bridge-mappings':
|
{'other_config': {'ovn-bridge-mappings':
|
||||||
'public:br-ex'}},
|
'public:br-ex'}},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ class TestSbApi(BaseOvnIdlTest):
|
|||||||
txn.add(self.api.chassis_add(
|
txn.add(self.api.chassis_add(
|
||||||
chassis['name'], ['geneve'], chassis['hostname'],
|
chassis['name'], ['geneve'], chassis['hostname'],
|
||||||
hostname=chassis['hostname'],
|
hostname=chassis['hostname'],
|
||||||
external_ids=chassis['external_ids']))
|
other_config=chassis['other_config']))
|
||||||
|
|
||||||
def test_get_chassis_hostname_and_physnets(self):
|
def test_get_chassis_hostname_and_physnets(self):
|
||||||
mapping = self.api.get_chassis_hostname_and_physnets()
|
mapping = self.api.get_chassis_hostname_and_physnets()
|
||||||
@ -97,7 +97,7 @@ class TestSbApi(BaseOvnIdlTest):
|
|||||||
def test_multiple_physnets_in_one_bridge(self):
|
def test_multiple_physnets_in_one_bridge(self):
|
||||||
self.data = {
|
self.data = {
|
||||||
'chassis': [
|
'chassis': [
|
||||||
{'external_ids': {'ovn-bridge-mappings': 'p1:br-ex,p2:br-ex'}}
|
{'other_config': {'ovn-bridge-mappings': 'p1:br-ex,p2:br-ex'}}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
self.load_test_data()
|
self.load_test_data()
|
||||||
|
@ -441,9 +441,8 @@ class TestAgentMonitor(base.TestOVNFunctionalBase):
|
|||||||
chassis_name, self.mech_driver.agent_chassis_table)
|
chassis_name, self.mech_driver.agent_chassis_table)
|
||||||
self.mech_driver.sb_ovn.idl.notify_handler.watch_event(row_event)
|
self.mech_driver.sb_ovn.idl.notify_handler.watch_event(row_event)
|
||||||
self.chassis_name = self.add_fake_chassis(
|
self.chassis_name = self.add_fake_chassis(
|
||||||
self.FAKE_CHASSIS_HOST,
|
self.FAKE_CHASSIS_HOST, name=chassis_name,
|
||||||
external_ids={'ovn-cms-options': 'enable-chassis-as-gw'},
|
enable_chassis_as_gw=True)
|
||||||
name=chassis_name)
|
|
||||||
self.assertTrue(row_event.wait())
|
self.assertTrue(row_event.wait())
|
||||||
n_utils.wait_until_true(
|
n_utils.wait_until_true(
|
||||||
lambda: len(list(neutron_agent.AgentCache())) == 1)
|
lambda: len(list(neutron_agent.AgentCache())) == 1)
|
||||||
@ -451,11 +450,11 @@ class TestAgentMonitor(base.TestOVNFunctionalBase):
|
|||||||
def test_agent_change_controller(self):
|
def test_agent_change_controller(self):
|
||||||
self.assertEqual(neutron_agent.ControllerGatewayAgent,
|
self.assertEqual(neutron_agent.ControllerGatewayAgent,
|
||||||
type(neutron_agent.AgentCache()[self.chassis_name]))
|
type(neutron_agent.AgentCache()[self.chassis_name]))
|
||||||
self.sb_api.db_set('Chassis', self.chassis_name, ('external_ids',
|
self.sb_api.db_set('Chassis', self.chassis_name, ('other_config',
|
||||||
{'ovn-cms-options': ''})).execute(check_error=True)
|
{'ovn-cms-options': ''})).execute(check_error=True)
|
||||||
n_utils.wait_until_true(lambda:
|
n_utils.wait_until_true(lambda:
|
||||||
neutron_agent.AgentCache()[self.chassis_name].
|
neutron_agent.AgentCache()[self.chassis_name].
|
||||||
chassis.external_ids['ovn-cms-options'] == '')
|
chassis.other_config['ovn-cms-options'] == '')
|
||||||
self.assertEqual(neutron_agent.ControllerAgent,
|
self.assertEqual(neutron_agent.ControllerAgent,
|
||||||
type(neutron_agent.AgentCache()[self.chassis_name]))
|
type(neutron_agent.AgentCache()[self.chassis_name]))
|
||||||
|
|
||||||
|
@ -66,16 +66,16 @@ class TestPortBinding(base.TestOVNFunctionalBase):
|
|||||||
self.add_fake_chassis(self.ovs_host)
|
self.add_fake_chassis(self.ovs_host)
|
||||||
self.add_fake_chassis(
|
self.add_fake_chassis(
|
||||||
self.dpdk_host,
|
self.dpdk_host,
|
||||||
external_ids={'datapath-type': 'netdev',
|
other_config={'datapath-type': 'netdev',
|
||||||
'iface-types': 'dummy,dummy-internal,dpdkvhostuser'})
|
'iface-types': 'dummy,dummy-internal,dpdkvhostuser'})
|
||||||
|
|
||||||
self.add_fake_chassis(
|
self.add_fake_chassis(
|
||||||
self.invalid_dpdk_host,
|
self.invalid_dpdk_host,
|
||||||
external_ids={'datapath-type': 'netdev',
|
other_config={'datapath-type': 'netdev',
|
||||||
'iface-types': 'dummy,dummy-internal,geneve,vxlan'})
|
'iface-types': 'dummy,dummy-internal,geneve,vxlan'})
|
||||||
self.add_fake_chassis(
|
self.add_fake_chassis(
|
||||||
self.smartnic_dpu_host,
|
self.smartnic_dpu_host,
|
||||||
external_ids={ovn_const.OVN_CMS_OPTIONS: '{}={}'.format(
|
other_config={ovn_const.OVN_CMS_OPTIONS: '{}={}'.format(
|
||||||
ovn_const.CMS_OPT_CARD_SERIAL_NUMBER,
|
ovn_const.CMS_OPT_CARD_SERIAL_NUMBER,
|
||||||
self.smartnic_dpu_serial)})
|
self.smartnic_dpu_serial)})
|
||||||
self.n1 = self._make_network(self.fmt, 'n1', True)
|
self.n1 = self._make_network(self.fmt, 'n1', True)
|
||||||
|
@ -135,7 +135,7 @@ class TestRouter(base.TestOVNFunctionalBase):
|
|||||||
# Test if chassis3 is selected as candidate or not.
|
# Test if chassis3 is selected as candidate or not.
|
||||||
self.chassis3 = self.add_fake_chassis(
|
self.chassis3 = self.add_fake_chassis(
|
||||||
'ovs-host3', physical_nets=['physnet1'],
|
'ovs-host3', physical_nets=['physnet1'],
|
||||||
external_ids={'ovn-cms-options': 'enable-chassis-as-gw'})
|
other_config={'ovn-cms-options': 'enable-chassis-as-gw'})
|
||||||
self._check_gateway_chassis_candidates([self.chassis3])
|
self._check_gateway_chassis_candidates([self.chassis3])
|
||||||
|
|
||||||
def test_gateway_chassis_with_cms_and_no_bridge_mappings(self):
|
def test_gateway_chassis_with_cms_and_no_bridge_mappings(self):
|
||||||
@ -143,7 +143,7 @@ class TestRouter(base.TestOVNFunctionalBase):
|
|||||||
# chassis3 is having enable-chassis-as-gw, but no bridge mappings.
|
# chassis3 is having enable-chassis-as-gw, but no bridge mappings.
|
||||||
self.chassis3 = self.add_fake_chassis(
|
self.chassis3 = self.add_fake_chassis(
|
||||||
'ovs-host3',
|
'ovs-host3',
|
||||||
external_ids={'ovn-cms-options': 'enable-chassis-as-gw'})
|
other_config={'ovn-cms-options': 'enable-chassis-as-gw'})
|
||||||
ovn_client = self.l3_plugin._ovn_client
|
ovn_client = self.l3_plugin._ovn_client
|
||||||
ext1 = self._create_ext_network(
|
ext1 = self._create_ext_network(
|
||||||
'ext1', 'vlan', 'physnet1', 1, "10.0.0.1", "10.0.0.0/24")
|
'ext1', 'vlan', 'physnet1', 1, "10.0.0.1", "10.0.0.0/24")
|
||||||
@ -170,11 +170,11 @@ class TestRouter(base.TestOVNFunctionalBase):
|
|||||||
# Test if chassis3 is selected as candidate or not.
|
# Test if chassis3 is selected as candidate or not.
|
||||||
self.chassis3 = self.add_fake_chassis(
|
self.chassis3 = self.add_fake_chassis(
|
||||||
'ovs-host3', physical_nets=['physnet1'],
|
'ovs-host3', physical_nets=['physnet1'],
|
||||||
external_ids={'ovn-cms-options': 'enable-chassis-as-gw'},
|
other_config={'ovn-cms-options': 'enable-chassis-as-gw'},
|
||||||
azs=['ovn'])
|
azs=['ovn'])
|
||||||
self.chassis4 = self.add_fake_chassis(
|
self.chassis4 = self.add_fake_chassis(
|
||||||
'ovs-host4', physical_nets=['physnet1'],
|
'ovs-host4', physical_nets=['physnet1'],
|
||||||
external_ids={'ovn-cms-options': 'enable-chassis-as-gw'},
|
other_config={'ovn-cms-options': 'enable-chassis-as-gw'},
|
||||||
azs=['ovn2'])
|
azs=['ovn2'])
|
||||||
self._check_gateway_chassis_candidates([self.chassis3],
|
self._check_gateway_chassis_candidates([self.chassis3],
|
||||||
router_az_hints=['ovn'])
|
router_az_hints=['ovn'])
|
||||||
@ -186,10 +186,10 @@ class TestRouter(base.TestOVNFunctionalBase):
|
|||||||
# add chassis4 is having azs [ovn2], not match routers az_hints [ovn]
|
# add chassis4 is having azs [ovn2], not match routers az_hints [ovn]
|
||||||
self.chassis3 = self.add_fake_chassis(
|
self.chassis3 = self.add_fake_chassis(
|
||||||
'ovs-host3', physical_nets=['physnet1'],
|
'ovs-host3', physical_nets=['physnet1'],
|
||||||
external_ids={'ovn-cms-options': 'enable-chassis-as-gw'})
|
other_config={'ovn-cms-options': 'enable-chassis-as-gw'})
|
||||||
self.chassis4 = self.add_fake_chassis(
|
self.chassis4 = self.add_fake_chassis(
|
||||||
'ovs-host4', physical_nets=['physnet1'],
|
'ovs-host4', physical_nets=['physnet1'],
|
||||||
external_ids={'ovn-cms-options': 'enable-chassis-as-gw'},
|
other_config={'ovn-cms-options': 'enable-chassis-as-gw'},
|
||||||
azs=['ovn2'])
|
azs=['ovn2'])
|
||||||
ovn_client = self.l3_plugin._ovn_client
|
ovn_client = self.l3_plugin._ovn_client
|
||||||
ext1 = self._create_ext_network(
|
ext1 = self._create_ext_network(
|
||||||
@ -535,7 +535,7 @@ class TestRouter(base.TestOVNFunctionalBase):
|
|||||||
self.skipTest('L3 HA not supported')
|
self.skipTest('L3 HA not supported')
|
||||||
ovn_client = self.l3_plugin._ovn_client
|
ovn_client = self.l3_plugin._ovn_client
|
||||||
chassis4 = self.add_fake_chassis(
|
chassis4 = self.add_fake_chassis(
|
||||||
'ovs-host4', physical_nets=['physnet4'], external_ids={
|
'ovs-host4', physical_nets=['physnet4'], other_config={
|
||||||
'ovn-cms-options': 'enable-chassis-as-gw'})
|
'ovn-cms-options': 'enable-chassis-as-gw'})
|
||||||
ovn_client._ovn_scheduler = l3_sched.OVNGatewayLeastLoadedScheduler()
|
ovn_client._ovn_scheduler = l3_sched.OVNGatewayLeastLoadedScheduler()
|
||||||
ext1 = self._create_ext_network(
|
ext1 = self._create_ext_network(
|
||||||
@ -567,7 +567,7 @@ class TestRouter(base.TestOVNFunctionalBase):
|
|||||||
|
|
||||||
# Add another chassis as a gateway chassis
|
# Add another chassis as a gateway chassis
|
||||||
chassis5 = self.add_fake_chassis(
|
chassis5 = self.add_fake_chassis(
|
||||||
'ovs-host5', physical_nets=['physnet4'], external_ids={
|
'ovs-host5', physical_nets=['physnet4'], other_config={
|
||||||
'ovn-cms-options': 'enable-chassis-as-gw'})
|
'ovn-cms-options': 'enable-chassis-as-gw'})
|
||||||
# Add a node as compute node. Compute node wont be
|
# Add a node as compute node. Compute node wont be
|
||||||
# used to schedule the router gateway ports therefore
|
# used to schedule the router gateway ports therefore
|
||||||
@ -597,8 +597,7 @@ class TestRouter(base.TestOVNFunctionalBase):
|
|||||||
chassis_list.append(
|
chassis_list.append(
|
||||||
self.add_fake_chassis(
|
self.add_fake_chassis(
|
||||||
'ovs-host%s' % i, physical_nets=['physnet1'],
|
'ovs-host%s' % i, physical_nets=['physnet1'],
|
||||||
external_ids={
|
other_config={'ovn-cms-options': 'enable-chassis-as-gw'}))
|
||||||
'ovn-cms-options': 'enable-chassis-as-gw'}))
|
|
||||||
|
|
||||||
ext1 = self._create_ext_network(
|
ext1 = self._create_ext_network(
|
||||||
'ext1', 'vlan', 'physnet1', 1, "10.0.0.1", "10.0.0.0/24")
|
'ext1', 'vlan', 'physnet1', 1, "10.0.0.1", "10.0.0.0/24")
|
||||||
|
@ -62,33 +62,31 @@ class TestUtils(base.BaseTestCase):
|
|||||||
|
|
||||||
def test_is_gateway_chassis(self):
|
def test_is_gateway_chassis(self):
|
||||||
chassis = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
chassis = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
||||||
'external_ids': {'ovn-cms-options': 'enable-chassis-as-gw'}})
|
'other_config': {'ovn-cms-options': 'enable-chassis-as-gw'}})
|
||||||
non_gw_chassis_0 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
non_gw_chassis_0 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
||||||
'external_ids': {'ovn-cms-options': ''}})
|
'other_config': {'ovn-cms-options': ''}})
|
||||||
non_gw_chassis_1 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={})
|
non_gw_chassis_1 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
||||||
non_gw_chassis_2 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
'other_config': {}})
|
||||||
'external_ids': {}})
|
|
||||||
|
|
||||||
self.assertTrue(utils.is_gateway_chassis(chassis))
|
self.assertTrue(utils.is_gateway_chassis(chassis))
|
||||||
self.assertFalse(utils.is_gateway_chassis(non_gw_chassis_0))
|
self.assertFalse(utils.is_gateway_chassis(non_gw_chassis_0))
|
||||||
self.assertFalse(utils.is_gateway_chassis(non_gw_chassis_1))
|
self.assertFalse(utils.is_gateway_chassis(non_gw_chassis_1))
|
||||||
self.assertFalse(utils.is_gateway_chassis(non_gw_chassis_2))
|
|
||||||
|
|
||||||
def test_get_chassis_availability_zones_no_azs(self):
|
def test_get_chassis_availability_zones_no_azs(self):
|
||||||
chassis = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
chassis = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
||||||
'external_ids': {'ovn-cms-options': 'enable-chassis-as-gw'}})
|
'other_config': {'ovn-cms-options': 'enable-chassis-as-gw'}})
|
||||||
self.assertEqual(set(), utils.get_chassis_availability_zones(chassis))
|
self.assertEqual(set(), utils.get_chassis_availability_zones(chassis))
|
||||||
|
|
||||||
def test_get_chassis_availability_zones_one_az(self):
|
def test_get_chassis_availability_zones_one_az(self):
|
||||||
chassis = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
chassis = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
||||||
'external_ids': {'ovn-cms-options':
|
'other_config': {'ovn-cms-options':
|
||||||
'enable-chassis-as-gw,availability-zones=az0'}})
|
'enable-chassis-as-gw,availability-zones=az0'}})
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
{'az0'}, utils.get_chassis_availability_zones(chassis))
|
{'az0'}, utils.get_chassis_availability_zones(chassis))
|
||||||
|
|
||||||
def test_get_chassis_availability_zones_multiple_az(self):
|
def test_get_chassis_availability_zones_multiple_az(self):
|
||||||
chassis = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
chassis = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
||||||
'external_ids': {
|
'other_config': {
|
||||||
'ovn-cms-options':
|
'ovn-cms-options':
|
||||||
'enable-chassis-as-gw,availability-zones=az0:az1 :az2:: :'}})
|
'enable-chassis-as-gw,availability-zones=az0:az1 :az2:: :'}})
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -97,7 +95,7 @@ class TestUtils(base.BaseTestCase):
|
|||||||
|
|
||||||
def test_get_chassis_availability_zones_malformed(self):
|
def test_get_chassis_availability_zones_malformed(self):
|
||||||
chassis = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
chassis = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
||||||
'external_ids': {'ovn-cms-options':
|
'other_config': {'ovn-cms-options':
|
||||||
'enable-chassis-as-gw,availability-zones:az0'}})
|
'enable-chassis-as-gw,availability-zones:az0'}})
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
set(), utils.get_chassis_availability_zones(chassis))
|
set(), utils.get_chassis_availability_zones(chassis))
|
||||||
@ -156,16 +154,16 @@ class TestUtils(base.BaseTestCase):
|
|||||||
def test_get_chassis_in_azs(self):
|
def test_get_chassis_in_azs(self):
|
||||||
ch0 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
ch0 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
||||||
'name': 'ch0',
|
'name': 'ch0',
|
||||||
'external_ids': {
|
'other_config': {
|
||||||
'ovn-cms-options':
|
'ovn-cms-options':
|
||||||
'enable-chassis-as-gw,availability-zones=az0:az1:az2'}})
|
'enable-chassis-as-gw,availability-zones=az0:az1:az2'}})
|
||||||
ch1 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
ch1 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
||||||
'name': 'ch1',
|
'name': 'ch1',
|
||||||
'external_ids': {
|
'other_config': {
|
||||||
'ovn-cms-options': 'enable-chassis-as-gw'}})
|
'ovn-cms-options': 'enable-chassis-as-gw'}})
|
||||||
ch2 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
ch2 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
||||||
'name': 'ch2',
|
'name': 'ch2',
|
||||||
'external_ids': {
|
'other_config': {
|
||||||
'ovn-cms-options':
|
'ovn-cms-options':
|
||||||
'enable-chassis-as-gw,availability-zones=az1:az5'}})
|
'enable-chassis-as-gw,availability-zones=az1:az5'}})
|
||||||
|
|
||||||
@ -183,21 +181,21 @@ class TestUtils(base.BaseTestCase):
|
|||||||
def test_get_gateway_chassis_without_azs(self):
|
def test_get_gateway_chassis_without_azs(self):
|
||||||
ch0 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
ch0 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
||||||
'name': 'ch0',
|
'name': 'ch0',
|
||||||
'external_ids': {
|
'other_config': {
|
||||||
'ovn-cms-options':
|
'ovn-cms-options':
|
||||||
'enable-chassis-as-gw,availability-zones=az0:az1:az2'}})
|
'enable-chassis-as-gw,availability-zones=az0:az1:az2'}})
|
||||||
ch1 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
ch1 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
||||||
'name': 'ch1',
|
'name': 'ch1',
|
||||||
'external_ids': {
|
'other_config': {
|
||||||
'ovn-cms-options': 'enable-chassis-as-gw'}})
|
'ovn-cms-options': 'enable-chassis-as-gw'}})
|
||||||
ch2 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
ch2 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
||||||
'name': 'ch2',
|
'name': 'ch2',
|
||||||
'external_ids': {
|
'other_config': {
|
||||||
'ovn-cms-options':
|
'ovn-cms-options':
|
||||||
'enable-chassis-as-gw,availability-zones=az1:az5'}})
|
'enable-chassis-as-gw,availability-zones=az1:az5'}})
|
||||||
ch3 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
ch3 = fakes.FakeOvsdbRow.create_one_ovsdb_row(attrs={
|
||||||
'name': 'ch3',
|
'name': 'ch3',
|
||||||
'external_ids': {}})
|
'other_config': {}})
|
||||||
|
|
||||||
chassis_list = [ch0, ch1, ch2, ch3]
|
chassis_list = [ch0, ch1, ch2, ch3]
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
@ -877,20 +877,23 @@ class FakeChassis(object):
|
|||||||
cms_opts.append('%s=%s' % (ovn_const.CMS_OPT_CARD_SERIAL_NUMBER,
|
cms_opts.append('%s=%s' % (ovn_const.CMS_OPT_CARD_SERIAL_NUMBER,
|
||||||
card_serial_number))
|
card_serial_number))
|
||||||
|
|
||||||
external_ids = {}
|
# NOTE(ralonsoh): LP#1990229, once min OVN version >= 20.06, the CMS
|
||||||
|
# options and the bridge mappings should be stored only in
|
||||||
|
# "other_config".
|
||||||
|
other_config = {}
|
||||||
if cms_opts:
|
if cms_opts:
|
||||||
external_ids[ovn_const.OVN_CMS_OPTIONS] = ','.join(cms_opts)
|
other_config[ovn_const.OVN_CMS_OPTIONS] = ','.join(cms_opts)
|
||||||
|
|
||||||
if bridge_mappings:
|
if bridge_mappings:
|
||||||
external_ids['ovn-bridge-mappings'] = ','.join(bridge_mappings)
|
other_config['ovn-bridge-mappings'] = ','.join(bridge_mappings)
|
||||||
|
|
||||||
chassis_attrs = {
|
chassis_attrs = {
|
||||||
'encaps': [],
|
'encaps': [],
|
||||||
'external_ids': external_ids,
|
'external_ids': '',
|
||||||
'hostname': '',
|
'hostname': '',
|
||||||
'name': uuidutils.generate_uuid(),
|
'name': uuidutils.generate_uuid(),
|
||||||
'nb_cfg': 0,
|
'nb_cfg': 0,
|
||||||
'other_config': {},
|
'other_config': other_config,
|
||||||
'transport_zones': [],
|
'transport_zones': [],
|
||||||
'vtep_logical_switches': []}
|
'vtep_logical_switches': []}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class AgentCacheTestCase(base.BaseTestCase):
|
|||||||
self.names_ref = []
|
self.names_ref = []
|
||||||
for i in range(10): # Add 10 agents.
|
for i in range(10): # Add 10 agents.
|
||||||
chassis_private = fakes.FakeOvsdbRow.create_one_ovsdb_row(
|
chassis_private = fakes.FakeOvsdbRow.create_one_ovsdb_row(
|
||||||
attrs={'name': 'chassis' + str(i)})
|
attrs={'name': 'chassis' + str(i), 'other_config': {}})
|
||||||
self.agent_cache.update(ovn_const.OVN_CONTROLLER_AGENT,
|
self.agent_cache.update(ovn_const.OVN_CONTROLLER_AGENT,
|
||||||
chassis_private)
|
chassis_private)
|
||||||
self.names_ref.append('chassis' + str(i))
|
self.names_ref.append('chassis' + str(i))
|
||||||
|
@ -820,7 +820,7 @@ class TestSBImplIdlOvnBase(TestDBImplIdlOvn):
|
|||||||
'chassis': [
|
'chassis': [
|
||||||
{
|
{
|
||||||
'hostname': 'fake-smartnic-dpu-chassis.fqdn',
|
'hostname': 'fake-smartnic-dpu-chassis.fqdn',
|
||||||
'external_ids': {
|
'other_config': {
|
||||||
ovn_const.OVN_CMS_OPTIONS: (
|
ovn_const.OVN_CMS_OPTIONS: (
|
||||||
'firstoption,'
|
'firstoption,'
|
||||||
'card-serial-number=fake-serial,'
|
'card-serial-number=fake-serial,'
|
||||||
|
@ -81,6 +81,9 @@ OVN_SB_SCHEMA = {
|
|||||||
"name": {"type": "string"},
|
"name": {"type": "string"},
|
||||||
"hostname": {"type": "string"},
|
"hostname": {"type": "string"},
|
||||||
"external_ids": {
|
"external_ids": {
|
||||||
|
"type": {"key": "string", "value": "string",
|
||||||
|
"min": 0, "max": "unlimited"}},
|
||||||
|
"other_config": {
|
||||||
"type": {"key": "string", "value": "string",
|
"type": {"key": "string", "value": "string",
|
||||||
"min": 0, "max": "unlimited"}}},
|
"min": 0, "max": "unlimited"}}},
|
||||||
"isRoot": True,
|
"isRoot": True,
|
||||||
@ -521,7 +524,7 @@ class TestOvnSbIdlNotifyHandler(test_mech_driver.OVNMechanismDriverTestCase):
|
|||||||
self.row_json = {
|
self.row_json = {
|
||||||
"name": "fake-name",
|
"name": "fake-name",
|
||||||
"hostname": "fake-hostname",
|
"hostname": "fake-hostname",
|
||||||
"external_ids": ['map', [["ovn-bridge-mappings",
|
"other_config": ['map', [["ovn-bridge-mappings",
|
||||||
"fake-phynet1:fake-br1"]]]
|
"fake-phynet1:fake-br1"]]]
|
||||||
}
|
}
|
||||||
self._mock_hash_ring = mock.patch.object(
|
self._mock_hash_ring = mock.patch.object(
|
||||||
@ -545,14 +548,18 @@ class TestOvnSbIdlNotifyHandler(test_mech_driver.OVNMechanismDriverTestCase):
|
|||||||
self.sb_idl.notify_handler.notify_loop()
|
self.sb_idl.notify_handler.notify_loop()
|
||||||
|
|
||||||
def test_chassis_create_event(self):
|
def test_chassis_create_event(self):
|
||||||
self._test_chassis_helper('create', self.row_json)
|
old_row_json = {'other_config': ['map', []]}
|
||||||
|
self._test_chassis_helper('create', self.row_json,
|
||||||
|
old_row_json=old_row_json)
|
||||||
self.mech_driver.update_segment_host_mapping.assert_called_once_with(
|
self.mech_driver.update_segment_host_mapping.assert_called_once_with(
|
||||||
'fake-hostname', ['fake-phynet1'])
|
'fake-hostname', ['fake-phynet1'])
|
||||||
self.l3_plugin.schedule_unhosted_gateways.assert_called_once_with(
|
self.l3_plugin.schedule_unhosted_gateways.assert_called_once_with(
|
||||||
event_from_chassis=None)
|
event_from_chassis=None)
|
||||||
|
|
||||||
def test_chassis_delete_event(self):
|
def test_chassis_delete_event(self):
|
||||||
self._test_chassis_helper('delete', self.row_json)
|
old_row_json = {'other_config': ['map', []]}
|
||||||
|
self._test_chassis_helper('delete', self.row_json,
|
||||||
|
old_row_json=old_row_json)
|
||||||
self.mech_driver.update_segment_host_mapping.assert_called_once_with(
|
self.mech_driver.update_segment_host_mapping.assert_called_once_with(
|
||||||
'fake-hostname', [])
|
'fake-hostname', [])
|
||||||
self.l3_plugin.schedule_unhosted_gateways.assert_called_once_with(
|
self.l3_plugin.schedule_unhosted_gateways.assert_called_once_with(
|
||||||
@ -560,7 +567,7 @@ class TestOvnSbIdlNotifyHandler(test_mech_driver.OVNMechanismDriverTestCase):
|
|||||||
|
|
||||||
def test_chassis_update_event(self):
|
def test_chassis_update_event(self):
|
||||||
old_row_json = copy.deepcopy(self.row_json)
|
old_row_json = copy.deepcopy(self.row_json)
|
||||||
old_row_json['external_ids'][1][0][1] = (
|
old_row_json['other_config'][1][0][1] = (
|
||||||
"fake-phynet2:fake-br2")
|
"fake-phynet2:fake-br2")
|
||||||
self._test_chassis_helper('update', self.row_json, old_row_json)
|
self._test_chassis_helper('update', self.row_json, old_row_json)
|
||||||
self.mech_driver.update_segment_host_mapping.assert_called_once_with(
|
self.mech_driver.update_segment_host_mapping.assert_called_once_with(
|
||||||
@ -569,9 +576,9 @@ class TestOvnSbIdlNotifyHandler(test_mech_driver.OVNMechanismDriverTestCase):
|
|||||||
event_from_chassis=None)
|
event_from_chassis=None)
|
||||||
|
|
||||||
def test_chassis_update_event_reschedule_not_needed(self):
|
def test_chassis_update_event_reschedule_not_needed(self):
|
||||||
self.row_json['external_ids'][1].append(['foo_field', 'foo_value_new'])
|
self.row_json['other_config'][1].append(['foo_field', 'foo_value_new'])
|
||||||
old_row_json = copy.deepcopy(self.row_json)
|
old_row_json = copy.deepcopy(self.row_json)
|
||||||
old_row_json['external_ids'][1][1][1] = (
|
old_row_json['other_config'][1][1][1] = (
|
||||||
"foo_value")
|
"foo_value")
|
||||||
self._test_chassis_helper('update', self.row_json, old_row_json)
|
self._test_chassis_helper('update', self.row_json, old_row_json)
|
||||||
self.mech_driver.update_segment_host_mapping.assert_not_called()
|
self.mech_driver.update_segment_host_mapping.assert_not_called()
|
||||||
@ -579,14 +586,14 @@ class TestOvnSbIdlNotifyHandler(test_mech_driver.OVNMechanismDriverTestCase):
|
|||||||
|
|
||||||
def test_chassis_update_event_reschedule_lost_physnet(self):
|
def test_chassis_update_event_reschedule_lost_physnet(self):
|
||||||
old_row_json = copy.deepcopy(self.row_json)
|
old_row_json = copy.deepcopy(self.row_json)
|
||||||
self.row_json['external_ids'][1][0][1] = ''
|
self.row_json['other_config'][1][0][1] = ''
|
||||||
self._test_chassis_helper('update', self.row_json, old_row_json)
|
self._test_chassis_helper('update', self.row_json, old_row_json)
|
||||||
self.l3_plugin.schedule_unhosted_gateways.assert_called_once_with(
|
self.l3_plugin.schedule_unhosted_gateways.assert_called_once_with(
|
||||||
event_from_chassis='fake-name')
|
event_from_chassis='fake-name')
|
||||||
|
|
||||||
def test_chassis_update_event_reschedule_add_physnet(self):
|
def test_chassis_update_event_reschedule_add_physnet(self):
|
||||||
old_row_json = copy.deepcopy(self.row_json)
|
old_row_json = copy.deepcopy(self.row_json)
|
||||||
self.row_json['external_ids'][1][0][1] += ',foo_physnet:foo_br'
|
self.row_json['other_config'][1][0][1] += ',foo_physnet:foo_br'
|
||||||
self._test_chassis_helper('update', self.row_json, old_row_json)
|
self._test_chassis_helper('update', self.row_json, old_row_json)
|
||||||
self.mech_driver.update_segment_host_mapping.assert_called_once_with(
|
self.mech_driver.update_segment_host_mapping.assert_called_once_with(
|
||||||
'fake-hostname', ['fake-phynet1', 'foo_physnet'])
|
'fake-hostname', ['fake-phynet1', 'foo_physnet'])
|
||||||
@ -595,7 +602,7 @@ class TestOvnSbIdlNotifyHandler(test_mech_driver.OVNMechanismDriverTestCase):
|
|||||||
|
|
||||||
def test_chassis_update_event_reschedule_add_and_remove_physnet(self):
|
def test_chassis_update_event_reschedule_add_and_remove_physnet(self):
|
||||||
old_row_json = copy.deepcopy(self.row_json)
|
old_row_json = copy.deepcopy(self.row_json)
|
||||||
self.row_json['external_ids'][1][0][1] = 'foo_physnet:foo_br'
|
self.row_json['other_config'][1][0][1] = 'foo_physnet:foo_br'
|
||||||
self._test_chassis_helper('update', self.row_json, old_row_json)
|
self._test_chassis_helper('update', self.row_json, old_row_json)
|
||||||
self.mech_driver.update_segment_host_mapping.assert_called_once_with(
|
self.mech_driver.update_segment_host_mapping.assert_called_once_with(
|
||||||
'fake-hostname', ['foo_physnet'])
|
'fake-hostname', ['foo_physnet'])
|
||||||
@ -604,7 +611,7 @@ class TestOvnSbIdlNotifyHandler(test_mech_driver.OVNMechanismDriverTestCase):
|
|||||||
|
|
||||||
def test_chassis_update_empty_no_external_ids(self):
|
def test_chassis_update_empty_no_external_ids(self):
|
||||||
old_row_json = copy.deepcopy(self.row_json)
|
old_row_json = copy.deepcopy(self.row_json)
|
||||||
old_row_json.pop('external_ids')
|
old_row_json.pop('other_config')
|
||||||
with mock.patch(
|
with mock.patch(
|
||||||
'neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb.'
|
'neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb.'
|
||||||
'ovsdb_monitor.ChassisEvent.'
|
'ovsdb_monitor.ChassisEvent.'
|
||||||
@ -637,10 +644,10 @@ class TestChassisEvent(base.BaseTestCase):
|
|||||||
|
|
||||||
def _test_handle_ha_chassis_group_changes_create(self, event):
|
def _test_handle_ha_chassis_group_changes_create(self, event):
|
||||||
# Chassis
|
# Chassis
|
||||||
ext_ids = {
|
other_config = {
|
||||||
'ovn-cms-options': 'enable-chassis-as-gw,availability-zones=az-0'}
|
'ovn-cms-options': 'enable-chassis-as-gw,availability-zones=az-0'}
|
||||||
row = fakes.FakeOvsdbTable.create_one_ovsdb_table(
|
row = fakes.FakeOvsdbTable.create_one_ovsdb_table(
|
||||||
attrs={'name': 'SpongeBob', 'external_ids': ext_ids})
|
attrs={'name': 'SpongeBob', 'other_config': other_config})
|
||||||
# HA Chassis
|
# HA Chassis
|
||||||
ch0 = fakes.FakeOvsdbTable.create_one_ovsdb_table(
|
ch0 = fakes.FakeOvsdbTable.create_one_ovsdb_table(
|
||||||
attrs={'priority': 10})
|
attrs={'priority': 10})
|
||||||
@ -672,10 +679,10 @@ class TestChassisEvent(base.BaseTestCase):
|
|||||||
|
|
||||||
def _test_handle_ha_chassis_group_changes_delete(self, event):
|
def _test_handle_ha_chassis_group_changes_delete(self, event):
|
||||||
# Chassis
|
# Chassis
|
||||||
ext_ids = {
|
other_config = {
|
||||||
'ovn-cms-options': 'enable-chassis-as-gw,availability-zones=az-0'}
|
'ovn-cms-options': 'enable-chassis-as-gw,availability-zones=az-0'}
|
||||||
row = fakes.FakeOvsdbTable.create_one_ovsdb_table(
|
row = fakes.FakeOvsdbTable.create_one_ovsdb_table(
|
||||||
attrs={'name': 'SpongeBob', 'external_ids': ext_ids})
|
attrs={'name': 'SpongeBob', 'other_config': other_config})
|
||||||
# HA Chassis
|
# HA Chassis
|
||||||
ha_ch = fakes.FakeOvsdbTable.create_one_ovsdb_table(
|
ha_ch = fakes.FakeOvsdbTable.create_one_ovsdb_table(
|
||||||
attrs={'priority': 10})
|
attrs={'priority': 10})
|
||||||
@ -699,10 +706,10 @@ class TestChassisEvent(base.BaseTestCase):
|
|||||||
def test_handle_ha_chassis_group_changes_update_no_changes(self):
|
def test_handle_ha_chassis_group_changes_update_no_changes(self):
|
||||||
# Assert nothing was done because the update didn't
|
# Assert nothing was done because the update didn't
|
||||||
# change the gateway chassis status or the availability zones
|
# change the gateway chassis status or the availability zones
|
||||||
ext_ids = {
|
other_config = {
|
||||||
'ovn-cms-options': 'enable-chassis-as-gw,availability-zones=az-0'}
|
'ovn-cms-options': 'enable-chassis-as-gw,availability-zones=az-0'}
|
||||||
new = fakes.FakeOvsdbTable.create_one_ovsdb_table(
|
new = fakes.FakeOvsdbTable.create_one_ovsdb_table(
|
||||||
attrs={'name': 'SpongeBob', 'external_ids': ext_ids})
|
attrs={'name': 'SpongeBob', 'other_config': other_config})
|
||||||
old = new
|
old = new
|
||||||
self.assertIsNone(self.event.handle_ha_chassis_group_changes(
|
self.assertIsNone(self.event.handle_ha_chassis_group_changes(
|
||||||
self.event.ROW_UPDATE, new, old))
|
self.event.ROW_UPDATE, new, old))
|
||||||
|
@ -112,6 +112,7 @@ class MechDriverSetupBase(abc.ABC):
|
|||||||
chassis_private.nb_cfg_timestamp, mock.Mock):
|
chassis_private.nb_cfg_timestamp, mock.Mock):
|
||||||
del chassis_private.nb_cfg_timestamp
|
del chassis_private.nb_cfg_timestamp
|
||||||
chassis_private.external_ids = {}
|
chassis_private.external_ids = {}
|
||||||
|
chassis_private.other_config = {}
|
||||||
if agent_type == ovn_const.OVN_METADATA_AGENT:
|
if agent_type == ovn_const.OVN_METADATA_AGENT:
|
||||||
chassis_private.external_ids.update({
|
chassis_private.external_ids.update({
|
||||||
ovn_const.OVN_AGENT_METADATA_SB_CFG_KEY: nb_cfg,
|
ovn_const.OVN_AGENT_METADATA_SB_CFG_KEY: nb_cfg,
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
other:
|
||||||
|
- |
|
||||||
|
Since OVN 20.06, the "Chassis" register configuration is stored in the
|
||||||
|
"other_config" field and replicated into "external_ids". This replication
|
||||||
|
is stopped in OVN 22.09. 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).
|
Loading…
Reference in New Issue
Block a user