Support filtering resource providers by aggregate membership
This provides the backend for allowing an HTTP query of '/resource_providers?member_of=in:$uuid_1,$uuid_2,$uuid_3' which will return those resource providers which are members of any of the listed aggregates. This is done by extending the ResourceProvider.get_all_by_filters methods to accept an additional 'member_of' filter with a value of a list of aggregate uuids. Change-Id: I1a69f7426b23f7b118bac7877b64700e688e8c6d
This commit is contained in:
parent
aa77e0bd17
commit
a29b1ee419
@ -540,7 +540,7 @@ class ResourceProviderList(base.ObjectListBase, base.NovaObject):
|
||||
}
|
||||
|
||||
allowed_filters = (
|
||||
'name', 'uuid'
|
||||
'name', 'uuid', 'member_of'
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@ -550,6 +550,7 @@ class ResourceProviderList(base.ObjectListBase, base.NovaObject):
|
||||
# filters = {
|
||||
# 'name': <name>,
|
||||
# 'uuid': <uuid>,
|
||||
# 'member_of': [<aggregate_uuid>, <aggregate_uuid>]
|
||||
# 'resources': {
|
||||
# 'VCPU': 1,
|
||||
# 'MEMORY_MB': 1024
|
||||
@ -564,6 +565,7 @@ class ResourceProviderList(base.ObjectListBase, base.NovaObject):
|
||||
name = filters.pop('name', None)
|
||||
uuid = filters.pop('uuid', None)
|
||||
can_host = filters.pop('can_host', 0)
|
||||
member_of = filters.pop('member_of', [])
|
||||
|
||||
resources = filters.pop('resources', {})
|
||||
# NOTE(sbauza): We want to key the dict by the resource class IDs
|
||||
@ -577,6 +579,19 @@ class ResourceProviderList(base.ObjectListBase, base.NovaObject):
|
||||
query = query.filter(models.ResourceProvider.uuid == uuid)
|
||||
query = query.filter(models.ResourceProvider.can_host == can_host)
|
||||
|
||||
# If 'member_of' has values join with the PlacementAggregates to
|
||||
# get those resource providers that are associated with any of the
|
||||
# list of aggregate uuids provided with 'member_of'.
|
||||
if member_of:
|
||||
join_statement = sa.join(_AGG_TBL, _RP_AGG_TBL, sa.and_(
|
||||
_AGG_TBL.c.id == _RP_AGG_TBL.c.aggregate_id,
|
||||
_AGG_TBL.c.uuid.in_(member_of)))
|
||||
resource_provider_id = _RP_AGG_TBL.c.resource_provider_id
|
||||
rps_in_aggregates = sa.select(
|
||||
[resource_provider_id]).select_from(join_statement)
|
||||
query = query.filter(models.ResourceProvider.id.in_(
|
||||
rps_in_aggregates))
|
||||
|
||||
if not resources:
|
||||
# Returns quickly the list in case we don't need to check the
|
||||
# resource usage
|
||||
|
@ -637,6 +637,48 @@ class ResourceProviderListTestCase(ResourceProviderBaseCase):
|
||||
objects.ResourceProviderList.get_all_by_filters,
|
||||
self.context, {'resources': {'FOOBAR': 3}})
|
||||
|
||||
def test_get_all_by_filters_aggregate(self):
|
||||
for rp_i in [1, 2, 3, 4]:
|
||||
uuid = getattr(uuidsentinel, 'rp_uuid_' + str(rp_i))
|
||||
name = 'rp_name_' + str(rp_i)
|
||||
rp = objects.ResourceProvider(self.context, name=name, uuid=uuid)
|
||||
rp.create()
|
||||
if rp_i % 2:
|
||||
aggregate_uuids = [uuidsentinel.agg_a, uuidsentinel.agg_b]
|
||||
rp.set_aggregates(aggregate_uuids)
|
||||
|
||||
resource_providers = objects.ResourceProviderList.get_all_by_filters(
|
||||
self.context, filters={'member_of': [uuidsentinel.agg_a]})
|
||||
|
||||
self.assertEqual(2, len(resource_providers))
|
||||
names = [_rp.name for _rp in resource_providers]
|
||||
self.assertIn('rp_name_1', names)
|
||||
self.assertIn('rp_name_3', names)
|
||||
self.assertNotIn('rp_name_2', names)
|
||||
self.assertNotIn('rp_name_4', names)
|
||||
|
||||
resource_providers = objects.ResourceProviderList.get_all_by_filters(
|
||||
self.context, filters={'member_of':
|
||||
[uuidsentinel.agg_a, uuidsentinel.agg_b]})
|
||||
self.assertEqual(2, len(resource_providers))
|
||||
|
||||
resource_providers = objects.ResourceProviderList.get_all_by_filters(
|
||||
self.context, filters={'member_of':
|
||||
[uuidsentinel.agg_a, uuidsentinel.agg_b],
|
||||
'name': u'rp_name_1'})
|
||||
self.assertEqual(1, len(resource_providers))
|
||||
|
||||
resource_providers = objects.ResourceProviderList.get_all_by_filters(
|
||||
self.context, filters={'member_of':
|
||||
[uuidsentinel.agg_a, uuidsentinel.agg_b],
|
||||
'name': u'barnabas'})
|
||||
self.assertEqual(0, len(resource_providers))
|
||||
|
||||
resource_providers = objects.ResourceProviderList.get_all_by_filters(
|
||||
self.context, filters={'member_of':
|
||||
[uuidsentinel.agg_1, uuidsentinel.agg_2]})
|
||||
self.assertEqual(0, len(resource_providers))
|
||||
|
||||
|
||||
class TestResourceProviderAggregates(test.NoDBTestCase):
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user