Merge "Allow shared resources between physical and tunnelled networks"
This commit is contained in:
commit
f50dbac487
|
@ -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(
|
||||||
|
|
|
@ -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': {
|
||||||
|
|
Loading…
Reference in New Issue