scheduler: AggregateMultitenancyIsolation to support unlimited tenant

This commit removes the previous limitation on the number of tenants
that can be filtered using the `filter_tenant_id` aggregate property
in the AggregateMultitenancyIsolation scheduler filter.

The `filter_tenant_id` can now be used as a suffix, allowing for an
unlimited number of tenant ID properties to be set on the
aggregate. This update maintains backward compatibility.

Implements: blueprint aggregatemultitenancyisolation-to-support-unlimited-tenant
Signed-off-by: Sahid Orentino Ferdjaoui <sahid.ferdjaoui@industrialdiscipline.com>
Change-Id: Ic87d142647774b62a6af2cc5eb7a3cd66f9afeb7
This commit is contained in:
Sahid Orentino Ferdjaoui 2023-09-26 14:03:40 +02:00
parent ca1db54f1b
commit 3cd26b0a08
4 changed files with 50 additions and 16 deletions

View File

@ -296,15 +296,6 @@ as candidates during scheduling. A server create request from another tenant
``Y`` will result in only ``HostA`` being a scheduling candidate since
``HostA`` is not part of the tenant-isolated aggregate.
.. note::
There is a `known limitation
<https://bugs.launchpad.net/nova/+bug/1802111>`_ with the number of tenants
that can be isolated per aggregate using this filter. This limitation does
not exist, however, for the :ref:`tenant-isolation-with-placement`
filtering capability added in the 18.0.0 Rocky release.
.. _AggregateNumInstancesFilter:
``AggregateNumInstancesFilter``

View File

@ -31,20 +31,24 @@ class AggregateMultiTenancyIsolation(filters.BaseHostFilter):
RUN_ON_REBUILD = False
def host_passes(self, host_state, spec_obj):
"""If a host is in an aggregate that has the metadata key
"filter_tenant_id" it can only create instances from that tenant(s).
A host can be in different aggregates.
"""If a host is in an aggregate that has the metadata key is prefixed
with "filter_tenant_id" it can only create instances from that
tenant(s). A host can be in different aggregates.
If a host doesn't belong to an aggregate with the metadata key
"filter_tenant_id" it can create instances from all tenants.
prefixed with "filter_tenant_id" The filter keeps non-specified
tenants out of an aggregate that has restrictions, but allows anyone
into unrestricted aggregates.
"""
tenant_id = spec_obj.project_id
metadata = utils.aggregate_metadata_get_by_host(host_state,
key="filter_tenant_id")
metadata = utils.aggregate_metadata_get_by_host(host_state)
if metadata != {}:
configured_tenant_ids = metadata.get("filter_tenant_id")
configured_tenant_ids = set()
for name, values in metadata.items():
if name.startswith("filter_tenant_id"):
configured_tenant_ids.update(set(values))
if configured_tenant_ids:
if tenant_id not in configured_tenant_ids:
LOG.debug("%s fails tenant id on aggregate", host_state)

View File

@ -63,3 +63,30 @@ class TestAggregateMultitenancyIsolationFilter(test.NoDBTestCase):
context=mock.sentinel.ctx, project_id='my_tenantid')
host = fakes.FakeHostState('host1', 'compute', {})
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def test_aggregate_multi_tenancy_isolation_with_prefix(self,
agg_mock):
agg_mock.return_value = {
'filter_tenant_id': set(['my_tenantid']),
'filter_tenant_id_gr1': set([
'my_tenantid1', 'my_tenantid2']),
'filter_tenant_id_gr2': set([
'my_tenantid5', 'my_tenantid4'])}
# my_tenantid should pass considering previous behavior.
spec_obj = objects.RequestSpec(
context=mock.sentinel.ctx, project_id='my_tenantid')
host = fakes.FakeHostState('host1', 'compute', {})
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
# my_tenantid2 should pass considering new behavior.
spec_obj = objects.RequestSpec(
context=mock.sentinel.ctx, project_id='my_tenantid2')
host = fakes.FakeHostState('host1', 'compute', {})
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
# my_tenantid6 still should not pass
spec_obj = objects.RequestSpec(
context=mock.sentinel.ctx, project_id='my_tenantid6')
host = fakes.FakeHostState('host1', 'compute', {})
self.assertFalse(self.filt_cls.host_passes(host, spec_obj))

View File

@ -0,0 +1,12 @@
---
features:
- |
This release removes the limit of the number of tenants that can
be specified for an aggregate and honored by the
`AggregateMultitenancyIsolation` filter. It now respects multiple
keys prefixed by `filter_tenant_id` like the request filter
implementation. You can use `filter_tenant_id` as a prefix to set
an infinite number of properties for tenant IDs on the aggregate.
This change has been implemented in a manner that preserves
backward compatibility. Existing configurations using
`filter_tenant_id` will continue to function as expected.