Merge "[OVN][Placement] Read the initial config in the maintenance worker"
This commit is contained in:
commit
5c47957e89
@ -301,6 +301,25 @@ SR-IOV and OVS agents. This is how the values are registered:
|
||||
Each configuration option defined in "external_ids:ovn-cms-options" is divided
|
||||
by commas.
|
||||
|
||||
This information is retrieved from the OVN SB database during the Neutron
|
||||
server initialization and when the "Chassis" registers are updated.
|
||||
|
||||
During the Neutron server initialization, a ``MaintenanceWorker`` thread will
|
||||
call ``OvnSbSynchronizer.do_sync``, that will call
|
||||
``OVNClientPlacementExtension.read_initial_chassis_config``. This method lists
|
||||
all chassis and builds the resource provider information needed by Placement.
|
||||
This information is stored in the "Chassis" registers, in
|
||||
"external_ids:ovn-cms-options", with the same format as retrieved from the
|
||||
local "Open_vSwitch" registers from each chassis.
|
||||
|
||||
The second method to update the Placement information is when a "Chassis"
|
||||
registers is updated. The ``OVNClientPlacementExtension`` extension registers
|
||||
an event handler that attends the OVN SB "Chassis" bandwidth configuration
|
||||
changes. This event handler builds a ``PlacementState`` instance and sends it
|
||||
to the Placement API. If a new chassis is added or an existing one changes its
|
||||
resource provider configuration, this event updates it in the Placement
|
||||
database.
|
||||
|
||||
Propagation of resource information
|
||||
-----------------------------------
|
||||
|
||||
|
@ -100,7 +100,7 @@ def _send_deferred_batch(state):
|
||||
LOG.exception('Placement client call failed: %s', str(deferred))
|
||||
|
||||
|
||||
def _dict_chassis_config(state):
|
||||
def dict_chassis_config(state):
|
||||
if state:
|
||||
return {n_const.RP_BANDWIDTHS: state._rp_bandwidths,
|
||||
n_const.RP_INVENTORY_DEFAULTS: state._rp_inventory_defaults,
|
||||
@ -122,10 +122,11 @@ class ChassisBandwidthConfigEvent(row_event.RowEvent):
|
||||
def run(self, event, row, old):
|
||||
name2uuid = self._placement_extension.name2uuid()
|
||||
state = self._placement_extension.build_placement_state(row, name2uuid)
|
||||
if not state:
|
||||
return
|
||||
|
||||
_send_deferred_batch(state)
|
||||
self._placement_extension.add_chassis_config(
|
||||
row.name, _dict_chassis_config(state))
|
||||
ch_config = self._placement_extension.get_chassis_config(row.name)
|
||||
ch_config = dict_chassis_config(state)
|
||||
LOG.debug('OVN chassis %(chassis)s Placement configuration modified: '
|
||||
'%(config)s', {'chassis': row.name, 'config': ch_config})
|
||||
|
||||
@ -152,9 +153,7 @@ class OVNClientPlacementExtension(object):
|
||||
self._plugin = None
|
||||
self.uuid_ns = ovn_const.OVN_RP_UUID
|
||||
self.supported_vnic_types = ovn_const.OVN_SUPPORTED_VNIC_TYPES
|
||||
self._enabled = bool(self.placement_plugin)
|
||||
self._chassis = {} # Initial config read could take some time.
|
||||
if not self._enabled:
|
||||
if not self.enabled:
|
||||
return
|
||||
|
||||
if not self._config_event:
|
||||
@ -163,12 +162,9 @@ class OVNClientPlacementExtension(object):
|
||||
self._driver._sb_idl.idl.notify_handler.watch_events(
|
||||
[self._config_event])
|
||||
except AttributeError:
|
||||
self._enabled = False
|
||||
|
||||
if not self._enabled:
|
||||
return
|
||||
|
||||
self._chassis = self._read_initial_chassis_config()
|
||||
# "sb_idl.idl.notify_handler" is not present in the
|
||||
# MaintenanceWorker.
|
||||
pass
|
||||
|
||||
@property
|
||||
def placement_plugin(self):
|
||||
@ -177,6 +173,10 @@ class OVNClientPlacementExtension(object):
|
||||
plugins_constants.PLACEMENT_REPORT)
|
||||
return self._placement_plugin
|
||||
|
||||
@property
|
||||
def enabled(self):
|
||||
return bool(self.placement_plugin)
|
||||
|
||||
@property
|
||||
def plugin(self):
|
||||
if self._plugin is None:
|
||||
@ -190,24 +190,33 @@ class OVNClientPlacementExtension(object):
|
||||
self.plugin.mechanism_manager.mech_drivers['ovn'].obj)
|
||||
return self._ovn_mech_driver
|
||||
|
||||
@property
|
||||
def chassis(self):
|
||||
return self._chassis
|
||||
|
||||
def _read_initial_chassis_config(self):
|
||||
def get_chassis_config(self):
|
||||
"""Read all Chassis BW config and returns the Placement states"""
|
||||
chassis = {}
|
||||
name2uuid = self.name2uuid()
|
||||
for ch in self._driver._sb_idl.chassis_list().execute(
|
||||
check_error=True):
|
||||
state = self.build_placement_state(ch, name2uuid)
|
||||
_send_deferred_batch(state)
|
||||
config = _dict_chassis_config(state)
|
||||
if config:
|
||||
chassis[ch.name] = config
|
||||
if state:
|
||||
chassis[ch.name] = state
|
||||
|
||||
msg = '\n'.join(['Chassis %s: %s' % (name, config)
|
||||
for (name, config) in chassis.items()])
|
||||
LOG.debug('OVN chassis Placement initial configuration:\n%s', msg)
|
||||
return chassis
|
||||
|
||||
def read_initial_chassis_config(self):
|
||||
"""Read the Chassis BW configuration and update the Placement API
|
||||
|
||||
This method is called once from the MaintenanceWorker when the Neutron
|
||||
server starts.
|
||||
"""
|
||||
if not self.enabled:
|
||||
return
|
||||
|
||||
chassis = self.get_chassis_config()
|
||||
for state in chassis.values():
|
||||
_send_deferred_batch(state)
|
||||
msg = ', '.join(['Chassis %s: %s' % (name, dict_chassis_config(state))
|
||||
for (name, state) in chassis.items()]) or '(no info)'
|
||||
LOG.debug('OVN chassis Placement initial configuration: %s', msg)
|
||||
return chassis
|
||||
|
||||
def name2uuid(self, name=None):
|
||||
@ -248,7 +257,9 @@ class OVNClientPlacementExtension(object):
|
||||
device in hypervisor_rps and device in bridges}
|
||||
|
||||
# NOTE(ralonsoh): OVN only reports min BW RPs; packet processing RPs
|
||||
# will be added in a future implementation.
|
||||
# will be added in a future implementation. If no RP_BANDWIDTHS values
|
||||
# are present (that means there is no BW information for any interface
|
||||
# in this host), no "PlacementState" is returned.
|
||||
return placement_report.PlacementState(
|
||||
rp_bandwidths=cms_options[n_const.RP_BANDWIDTHS],
|
||||
rp_inventory_defaults=cms_options[n_const.RP_INVENTORY_DEFAULTS],
|
||||
@ -260,10 +271,3 @@ class OVNClientPlacementExtension(object):
|
||||
device_mappings=bridge_mappings,
|
||||
supported_vnic_types=self.supported_vnic_types,
|
||||
client=self.placement_plugin._placement_client)
|
||||
|
||||
def get_chassis_config(self, chassis_name):
|
||||
return self._chassis.get(chassis_name)
|
||||
|
||||
def add_chassis_config(self, chassis_name, config):
|
||||
if config:
|
||||
self._chassis[chassis_name] = config
|
||||
|
@ -80,7 +80,7 @@ class OVNClient(object):
|
||||
|
||||
# TODO(ralonsoh): handle the OVN client extensions with an ext. manager
|
||||
self._qos_driver = qos_extension.OVNClientQosExtension(driver=self)
|
||||
self._placement_extension = (
|
||||
self.placement_extension = (
|
||||
placement_extension.OVNClientPlacementExtension(self))
|
||||
self._ovn_scheduler = l3_ovn_scheduler.get_scheduler()
|
||||
|
||||
|
@ -1273,6 +1273,9 @@ class OvnSbSynchronizer(OvnDbSynchronizer):
|
||||
self.sync_hostname_and_physical_networks(ctx)
|
||||
if utils.is_ovn_l3(self.l3_plugin):
|
||||
self.l3_plugin.schedule_unhosted_gateways()
|
||||
# NOTE(ralonsoh): this could be called using a resource event.
|
||||
self.ovn_driver._ovn_client.placement_extension.\
|
||||
read_initial_chassis_config()
|
||||
|
||||
def sync_hostname_and_physical_networks(self, ctx):
|
||||
LOG.debug('OVN-SB Sync hostname and physical networks started')
|
||||
|
@ -66,7 +66,7 @@ class TestOVNClientQosExtension(base.TestOVNFunctionalBase):
|
||||
super().setUp(maintenance_worker=maintenance_worker,
|
||||
service_plugins=service_plugins)
|
||||
self.ovn_client = self.mech_driver._ovn_client
|
||||
self.placement_ext = self.ovn_client._placement_extension
|
||||
self.placement_ext = self.ovn_client.placement_extension
|
||||
self.mock_name2uuid = mock.patch.object(
|
||||
self.placement_ext, 'name2uuid').start()
|
||||
self.mock_send_batch = mock.patch.object(
|
||||
@ -98,12 +98,15 @@ class TestOVNClientQosExtension(base.TestOVNFunctionalBase):
|
||||
'Chassis', name, ('external_ids', external_ids)
|
||||
).execute(check_error=True)
|
||||
|
||||
def _check_placement_cache(self, expected_chassis):
|
||||
def _check_placement_config(self, expected_chassis):
|
||||
current_chassis = None
|
||||
|
||||
def check_chassis():
|
||||
nonlocal current_chassis
|
||||
current_chassis = self.placement_ext.chassis
|
||||
current_chassis = self.placement_ext.get_chassis_config()
|
||||
current_chassis = {
|
||||
chassis_name: placement_extension.dict_chassis_config(state)
|
||||
for chassis_name, state in current_chassis.items()}
|
||||
return current_chassis == expected_chassis
|
||||
|
||||
try:
|
||||
@ -126,37 +129,37 @@ class TestOVNClientQosExtension(base.TestOVNFunctionalBase):
|
||||
bandwidths='br-provider0:3000:4000',
|
||||
inventory_defaults='allocation_ratio:3.0;min_unit:1',
|
||||
hypervisors='br-provider0:host2')
|
||||
self._check_placement_cache({**self.CHASSIS1, **self.CHASSIS2})
|
||||
self._check_placement_config({**self.CHASSIS1, **self.CHASSIS2})
|
||||
|
||||
self._update_chassis(
|
||||
'chassis2',
|
||||
bandwidths='br-provider0:5000:6000',
|
||||
inventory_defaults='allocation_ratio:1.1;min_unit:1',
|
||||
hypervisors='br-provider0:host2')
|
||||
self._check_placement_cache({**self.CHASSIS1, **self.CHASSIS2_B})
|
||||
self._check_placement_config({**self.CHASSIS1, **self.CHASSIS2_B})
|
||||
|
||||
def test_read_initial_empty_config_and_update(self):
|
||||
self.mock_name2uuid.return_value = {'host1': 'uuid1',
|
||||
'host2': 'uuid2'}
|
||||
self._create_chassis('host1', 'chassis1', physical_nets=['phys1'])
|
||||
self._create_chassis('host2', 'chassis2', physical_nets=['phys2'])
|
||||
self._check_placement_cache({**{'chassis1': self.EMPTY_CHASSIS},
|
||||
**{'chassis2': self.EMPTY_CHASSIS}})
|
||||
self._check_placement_config({**{'chassis1': self.EMPTY_CHASSIS},
|
||||
**{'chassis2': self.EMPTY_CHASSIS}})
|
||||
|
||||
self._update_chassis(
|
||||
'chassis1',
|
||||
bandwidths='br-provider0:1000:2000',
|
||||
inventory_defaults='allocation_ratio:1.0;min_unit:2',
|
||||
hypervisors='br-provider0:host1')
|
||||
self._check_placement_cache({**self.CHASSIS1,
|
||||
**{'chassis2': self.EMPTY_CHASSIS}})
|
||||
self._check_placement_config({**self.CHASSIS1,
|
||||
**{'chassis2': self.EMPTY_CHASSIS}})
|
||||
|
||||
self._update_chassis(
|
||||
'chassis2',
|
||||
bandwidths='br-provider0:3000:4000',
|
||||
inventory_defaults='allocation_ratio:3.0;min_unit:1',
|
||||
hypervisors='br-provider0:host2')
|
||||
self._check_placement_cache({**self.CHASSIS1, **self.CHASSIS2})
|
||||
self._check_placement_config({**self.CHASSIS1, **self.CHASSIS2})
|
||||
|
||||
def test_update_twice(self):
|
||||
self.mock_name2uuid.return_value = {'host1': 'uuid1',
|
||||
@ -167,19 +170,19 @@ class TestOVNClientQosExtension(base.TestOVNFunctionalBase):
|
||||
inventory_defaults='allocation_ratio:1.0;min_unit:2',
|
||||
hypervisors='br-provider0:host1')
|
||||
self._create_chassis('host2', 'chassis2', physical_nets=['phys2'])
|
||||
self._check_placement_cache({**self.CHASSIS1,
|
||||
**{'chassis2': self.EMPTY_CHASSIS}})
|
||||
self._check_placement_config({**self.CHASSIS1,
|
||||
**{'chassis2': self.EMPTY_CHASSIS}})
|
||||
|
||||
self._update_chassis(
|
||||
'chassis2',
|
||||
bandwidths='br-provider0:3000:4000',
|
||||
inventory_defaults='allocation_ratio:3.0;min_unit:1',
|
||||
hypervisors='br-provider0:host2')
|
||||
self._check_placement_cache({**self.CHASSIS1, **self.CHASSIS2})
|
||||
self._check_placement_config({**self.CHASSIS1, **self.CHASSIS2})
|
||||
|
||||
self._update_chassis(
|
||||
'chassis2',
|
||||
bandwidths='br-provider0:5000:6000',
|
||||
inventory_defaults='allocation_ratio:1.1;min_unit:1',
|
||||
hypervisors='br-provider0:host2')
|
||||
self._check_placement_cache({**self.CHASSIS1, **self.CHASSIS2_B})
|
||||
self._check_placement_config({**self.CHASSIS1, **self.CHASSIS2_B})
|
||||
|
@ -48,9 +48,14 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
{'name': 'compute2', 'uuid': 'uuid2'}]
|
||||
}
|
||||
|
||||
def test__read_initial_chassis_config(self):
|
||||
def test_read_initial_chassis_config(self):
|
||||
# Add two public networks, a RP per bridge and the correlation between
|
||||
# the hypervisors and the bridges.
|
||||
def _check_expected_config(init_conf, expected):
|
||||
res = {chassis_name: p_extension.dict_chassis_config(state) for
|
||||
chassis_name, state in init_conf.items()}
|
||||
self.assertEqual(expected, res)
|
||||
|
||||
chassis = fakes.FakeChassis.create(
|
||||
bridge_mappings=['public1:br-ext1', 'public2:br-ext2'],
|
||||
rp_bandwidths=['br-ext1:1000:2000', 'br-ext2:3000:4000'],
|
||||
@ -58,7 +63,7 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
rp_hypervisors=['br-ext1:compute1', 'br-ext2:compute2'])
|
||||
self.plugin_driver._sb_idl.chassis_list.return_value.execute.\
|
||||
return_value = [chassis]
|
||||
init_conf = self.placement_driver._read_initial_chassis_config()
|
||||
init_conf = self.placement_driver.read_initial_chassis_config()
|
||||
expected = {chassis.name: {
|
||||
n_const.RP_BANDWIDTHS: {
|
||||
'br-ext1': {'egress': 1000, 'ingress': 2000},
|
||||
@ -69,7 +74,7 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
'br-ext1': {'name': 'compute1', 'uuid': 'uuid1'},
|
||||
'br-ext2': {'name': 'compute2', 'uuid': 'uuid2'}}
|
||||
}}
|
||||
self.assertEqual(expected, init_conf)
|
||||
_check_expected_config(init_conf, expected)
|
||||
|
||||
# Add an extra bridge mapping that is discarded because it is not in
|
||||
# the hypervisors list (wrong configuration).
|
||||
@ -81,7 +86,7 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
rp_hypervisors=['br-ext1:compute1', 'br-ext2:compute2'])
|
||||
self.plugin_driver._sb_idl.chassis_list.return_value.execute.\
|
||||
return_value = [chassis]
|
||||
init_conf = self.placement_driver._read_initial_chassis_config()
|
||||
init_conf = self.placement_driver.read_initial_chassis_config()
|
||||
expected = {chassis.name: {
|
||||
n_const.RP_BANDWIDTHS: {
|
||||
'br-ext1': {'egress': 1000, 'ingress': 2000},
|
||||
@ -92,7 +97,7 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
'br-ext1': {'name': 'compute1', 'uuid': 'uuid1'},
|
||||
'br-ext2': {'name': 'compute2', 'uuid': 'uuid2'}}
|
||||
}}
|
||||
self.assertEqual(expected, init_conf)
|
||||
_check_expected_config(init_conf, expected)
|
||||
|
||||
# Add an unknown bridge, not present in the bridge mappings, that is
|
||||
# discarded (wrong configuration).
|
||||
@ -103,7 +108,7 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
rp_hypervisors=['br-ext1:compute1', 'br-ext2:compute2'])
|
||||
self.plugin_driver._sb_idl.chassis_list.return_value.execute.\
|
||||
return_value = [chassis]
|
||||
init_conf = self.placement_driver._read_initial_chassis_config()
|
||||
init_conf = self.placement_driver.read_initial_chassis_config()
|
||||
expected = {chassis.name: {
|
||||
n_const.RP_BANDWIDTHS: {
|
||||
'br-ext1': {'egress': 1000, 'ingress': 2000}},
|
||||
@ -113,7 +118,7 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
'br-ext1': {'name': 'compute1', 'uuid': 'uuid1'},
|
||||
'br-ext2': {'name': 'compute2', 'uuid': 'uuid2'}}
|
||||
}}
|
||||
self.assertEqual(expected, init_conf)
|
||||
_check_expected_config(init_conf, expected)
|
||||
|
||||
# Add an unknown hypervisor, that is not present in the Placement list
|
||||
# of resource providers. This hypervisor is discarded (wrong
|
||||
@ -126,7 +131,7 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
rp_hypervisors=['br-ext1:compute1', 'br-ext2:compute3'])
|
||||
self.plugin_driver._sb_idl.chassis_list.return_value.execute.\
|
||||
return_value = [chassis]
|
||||
init_conf = self.placement_driver._read_initial_chassis_config()
|
||||
init_conf = self.placement_driver.read_initial_chassis_config()
|
||||
expected = {chassis.name: {
|
||||
n_const.RP_BANDWIDTHS: {
|
||||
'br-ext1': {'egress': 1000, 'ingress': 2000}},
|
||||
@ -135,7 +140,7 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
ovn_const.RP_HYPERVISORS: {
|
||||
'br-ext1': {'name': 'compute1', 'uuid': 'uuid1'}}
|
||||
}}
|
||||
self.assertEqual(expected, init_conf)
|
||||
_check_expected_config(init_conf, expected)
|
||||
|
||||
# Missing bridge mapping for br-ext2, the RP for this bridge will be
|
||||
# discarded.
|
||||
@ -146,7 +151,7 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
rp_hypervisors=['br-ext1:compute1', 'br-ext2:compute2'])
|
||||
self.plugin_driver._sb_idl.chassis_list.return_value.execute.\
|
||||
return_value = [chassis]
|
||||
init_conf = self.placement_driver._read_initial_chassis_config()
|
||||
init_conf = self.placement_driver.read_initial_chassis_config()
|
||||
expected = {chassis.name: {
|
||||
n_const.RP_BANDWIDTHS: {
|
||||
'br-ext1': {'egress': 1000, 'ingress': 2000}},
|
||||
@ -156,7 +161,7 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
'br-ext1': {'name': 'compute1', 'uuid': 'uuid1'},
|
||||
'br-ext2': {'name': 'compute2', 'uuid': 'uuid2'}}
|
||||
}}
|
||||
self.assertEqual(expected, init_conf)
|
||||
_check_expected_config(init_conf, expected)
|
||||
|
||||
# No bridge mappings, no RP BW inventories.
|
||||
chassis = fakes.FakeChassis.create(
|
||||
@ -166,7 +171,7 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
rp_hypervisors=['br-ext1:compute1', 'br-ext2:compute2'])
|
||||
self.plugin_driver._sb_idl.chassis_list.return_value.execute.\
|
||||
return_value = [chassis]
|
||||
init_conf = self.placement_driver._read_initial_chassis_config()
|
||||
init_conf = self.placement_driver.read_initial_chassis_config()
|
||||
expected = {chassis.name: {
|
||||
n_const.RP_BANDWIDTHS: {},
|
||||
n_const.RP_INVENTORY_DEFAULTS: {
|
||||
@ -175,7 +180,7 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
'br-ext1': {'name': 'compute1', 'uuid': 'uuid1'},
|
||||
'br-ext2': {'name': 'compute2', 'uuid': 'uuid2'}}
|
||||
}}
|
||||
self.assertEqual(expected, init_conf)
|
||||
_check_expected_config(init_conf, expected)
|
||||
|
||||
# No bridge mappings nor hypervisors, no RP BW inventories.
|
||||
chassis = fakes.FakeChassis.create(
|
||||
@ -185,14 +190,14 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
rp_hypervisors=None)
|
||||
self.plugin_driver._sb_idl.chassis_list.return_value.execute.\
|
||||
return_value = [chassis]
|
||||
init_conf = self.placement_driver._read_initial_chassis_config()
|
||||
init_conf = self.placement_driver.read_initial_chassis_config()
|
||||
expected = {chassis.name: {
|
||||
n_const.RP_BANDWIDTHS: {},
|
||||
n_const.RP_INVENTORY_DEFAULTS: {
|
||||
'allocation_ratio': 1.0, 'min_unit': 5},
|
||||
ovn_const.RP_HYPERVISORS: {}
|
||||
}}
|
||||
self.assertEqual(expected, init_conf)
|
||||
_check_expected_config(init_conf, expected)
|
||||
|
||||
# If no RP BW information (any deployment not using it), OVN Placement
|
||||
# extension won't break anything (sorry for LP#1936983, that was me).
|
||||
@ -203,13 +208,13 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
rp_hypervisors=None)
|
||||
self.plugin_driver._sb_idl.chassis_list.return_value.execute.\
|
||||
return_value = [chassis]
|
||||
init_conf = self.placement_driver._read_initial_chassis_config()
|
||||
init_conf = self.placement_driver.read_initial_chassis_config()
|
||||
expected = {chassis.name: {
|
||||
n_const.RP_BANDWIDTHS: {},
|
||||
n_const.RP_INVENTORY_DEFAULTS: {},
|
||||
ovn_const.RP_HYPERVISORS: {}
|
||||
}}
|
||||
self.assertEqual(expected, init_conf)
|
||||
_check_expected_config(init_conf, expected)
|
||||
|
||||
# Test wrongly defined parameters. E.g.:
|
||||
# external_ids: {ovn-cms-options={resource_provider_bandwidths=, ...}}
|
||||
@ -220,10 +225,10 @@ class TestOVNClientPlacementExtension(test_plugin.Ml2PluginV2TestCase):
|
||||
rp_hypervisors='')
|
||||
self.plugin_driver._sb_idl.chassis_list.return_value.execute.\
|
||||
return_value = [chassis]
|
||||
init_conf = self.placement_driver._read_initial_chassis_config()
|
||||
init_conf = self.placement_driver.read_initial_chassis_config()
|
||||
expected = {chassis.name: {
|
||||
n_const.RP_BANDWIDTHS: {},
|
||||
n_const.RP_INVENTORY_DEFAULTS: {},
|
||||
ovn_const.RP_HYPERVISORS: {}
|
||||
}}
|
||||
self.assertEqual(expected, init_conf)
|
||||
_check_expected_config(init_conf, expected)
|
||||
|
Loading…
Reference in New Issue
Block a user