Merge "Allow shared resources between physical and tunnelled networks"

This commit is contained in:
Zuul 2023-01-18 18:11:18 +00:00 committed by Gerrit Code Review
commit f50dbac487
2 changed files with 64 additions and 4 deletions

View File

@ -205,14 +205,30 @@ class PlacementState(object):
return agent_rp_traits return agent_rp_traits
def deferred_update_resource_provider_traits(self): def deferred_update_resource_provider_traits(self):
def _get_traits(device, physical_bridges, physnet_trait_mappings):
if device == self._rp_tun_name and device not in physical_bridges:
# That means the RP for tunnelled networks is not associated
# to a physical bridge interface.
return [n_const.TRAIT_NETWORK_TUNNEL]
elif device == self._rp_tun_name and device in physical_bridges:
# The physical network and the tunnelled networks share the
# same physical interface.
return [n_const.TRAIT_NETWORK_TUNNEL,
physnet_trait_mappings[device]]
else:
# Just the physical interface.
return [physnet_trait_mappings.get(device)]
rp_traits = [] rp_traits = []
tunnelled_trait_mappings = { physical_bridges = {br for brs in self._device_mappings.values() for
self._rp_tun_name: n_const.TRAIT_NETWORK_TUNNEL} br in brs}
physnet_trait_mappings = {} physnet_trait_mappings = {}
for physnet, devices in self._device_mappings.items(): for physnet, devices in self._device_mappings.items():
for device in devices: for device in devices:
physnet_trait_mappings[device] = place_utils.physnet_trait( physnet_trait_mappings[device] = place_utils.physnet_trait(
physnet) physnet)
vnic_type_traits = [place_utils.vnic_type_trait(vnic_type) vnic_type_traits = [place_utils.vnic_type_trait(vnic_type)
for vnic_type for vnic_type
in self._supported_vnic_types] in self._supported_vnic_types]
@ -221,8 +237,8 @@ class PlacementState(object):
self._driver_uuid_namespace, self._driver_uuid_namespace,
self._hypervisor_rps[device]['name'], self._hypervisor_rps[device]['name'],
device) device)
traits = [physnet_trait_mappings.get(device) or traits = _get_traits(device, physical_bridges,
tunnelled_trait_mappings[device]] physnet_trait_mappings)
traits.extend(vnic_type_traits) traits.extend(vnic_type_traits)
rp_traits.append( rp_traits.append(
DeferredCall( DeferredCall(

View File

@ -15,6 +15,8 @@
from unittest import mock from unittest import mock
import uuid import uuid
from oslo_config import cfg
from neutron.agent.common import placement_report from neutron.agent.common import placement_report
from neutron.common import _constants as n_const from neutron.common import _constants as n_const
from neutron.conf.plugins.ml2 import config as ml2_config from neutron.conf.plugins.ml2 import config as ml2_config
@ -243,6 +245,48 @@ class PlacementStateTestCase(base.BaseTestCase):
{'CUSTOM_VNIC_TYPE_NORMAL'}], {'CUSTOM_VNIC_TYPE_NORMAL'}],
actual_traits) actual_traits)
def test_deferred_update_resource_provider_traits_shared_rp(self):
import uuid
self.kwargs.update({
'device_mappings': {
'physnet0': ['eth0'],
},
'rp_bandwidths': {
'eth0': {'egress': 1, 'ingress': 1},
},
'supported_vnic_types': ['normal'],
})
cfg.CONF.set_override('tunnelled_network_rp_name', 'eth0', group='ml2')
state = placement_report.PlacementState(**self.kwargs)
for deferred in state.deferred_update_resource_provider_traits():
deferred.execute()
expected_calls = [
# uuid below generated by the following command:
# uuid -v5 '00000000-0000-0000-0000-000000000001' 'fakehost:eth0'
mock.call(
resource_provider_uuid=uuid.UUID(
'1ea6f823-bcf2-5dc5-9bee-4ee6177a6451'),
traits=mock.ANY),
# uuid -v5 '00000000-0000-0000-0000-000000000001' 'fakehost'
mock.call(
resource_provider_uuid=uuid.UUID(
'c0b4abe5-516f-54b8-b965-ff94060dcbcc'),
traits=mock.ANY)]
self.client_mock.update_resource_provider_traits.assert_has_calls(
expected_calls)
# NOTE(bence romsics): To avoid testing the _order_ of traits.
actual_traits = [set(args[1]['traits']) for args in
self.client_mock.update_resource_provider_traits.call_args_list]
self.assertEqual(
[{n_const.TRAIT_NETWORK_TUNNEL, 'CUSTOM_PHYSNET_PHYSNET0',
'CUSTOM_VNIC_TYPE_NORMAL'},
{'CUSTOM_VNIC_TYPE_NORMAL'}],
actual_traits)
def test_deferred_update_resource_provider_inventories_bw(self): def test_deferred_update_resource_provider_inventories_bw(self):
self.kwargs.update({ self.kwargs.update({
'device_mappings': { 'device_mappings': {