placement: add filtering by attrs to resource_providers

Make it possible to GET /resource_providers passing filters as query
params to get only a subset of resource providers.

Partially-Implements: blueprint generic-resource-pools

Change-Id: I2c905d55ac20fd1c5a285b1e460cdd31dff8c7dd
This commit is contained in:
Roman Podoliaka 2016-07-15 21:51:31 +03:00 committed by Chris Dent
parent 125cfc97fb
commit b838f2225c
4 changed files with 76 additions and 3 deletions

View File

@ -175,8 +175,27 @@ def list_resource_providers(req):
a collection of resource providers.
"""
context = req.environ['placement.context']
allowed_filters = set(objects.ResourceProviderList.allowed_filters)
passed_filters = set(req.GET.keys())
invalid_filters = passed_filters - allowed_filters
if invalid_filters:
raise webob.exc.HTTPBadRequest(
'Invalid filters: %s' % ', '.join(invalid_filters),
json_formatter=util.json_error_formatter)
if 'uuid' in req.GET and not uuidutils.is_uuid_like(req.GET['uuid']):
raise webob.exc.HTTPBadRequest(
'Invalid uuid value: %s' % req.GET['uuid'],
json_formatter=util.json_error_formatter)
filters = {}
for attr in objects.ResourceProviderList.allowed_filters:
if attr in req.GET:
filters[attr] = req.GET[attr]
resource_providers = objects.ResourceProviderList.get_all_by_filters(
context)
context, filters)
response = req.response
response.body = jsonutils.dumps(_serialize_providers(
req.environ, resource_providers))

View File

@ -358,14 +358,20 @@ class ResourceProviderList(base.ObjectListBase, base.NovaObject):
'objects': fields.ListOfObjectsField('ResourceProvider'),
}
allowed_filters = (
'name', 'uuid'
)
@staticmethod
@db_api.placement_context_manager.reader
def _get_all_by_filters_from_db(context, filters):
if not filters:
filters = {}
query = context.session.query(models.ResourceProvider)
if 'name' in filters:
query = query.filter_by(name=filters['name'])
for attr in ResourceProviderList.allowed_filters:
if attr in filters:
query = query.filter(
getattr(models.ResourceProvider, attr) == filters[attr])
query = query.filter_by(can_host=filters.get('can_host', 0))
return query.all()

View File

@ -98,6 +98,50 @@ tests:
$.resource_providers[0].links[?rel = "aggregates"].href: /resource_providers/$ENVIRON['RP_UUID']/aggregates
$.resource_providers[0].links[?rel = "usages"].href: /resource_providers/$ENVIRON['RP_UUID']/usages
- name: filter out all resource providers by name
GET: /resource_providers?name=flubblebubble
response_json_paths:
$.resource_providers.`len`: 0
- name: filter out all resource providers by uuid
GET: /resource_providers?uuid=d67370b5-4dc0-470d-a4fa-85e8e89abc6c
response_json_paths:
$.resource_providers.`len`: 0
- name: list one resource provider filtering by name
GET: /resource_providers?name=$ENVIRON['RP_NAME']
response_json_paths:
$.resource_providers.`len`: 1
$.resource_providers[0].uuid: $ENVIRON['RP_UUID']
$.resource_providers[0].name: $ENVIRON['RP_NAME']
$.resource_providers[0].links[?rel = "self"].href: /resource_providers/$ENVIRON['RP_UUID']
$.resource_providers[0].links[?rel = "inventories"].href: /resource_providers/$ENVIRON['RP_UUID']/inventories
$.resource_providers[0].links[?rel = "aggregates"].href: /resource_providers/$ENVIRON['RP_UUID']/aggregates
$.resource_providers[0].links[?rel = "usages"].href: /resource_providers/$ENVIRON['RP_UUID']/usages
- name: list resource providers filtering by invalid uuid
GET: /resource_providers?uuid=spameggs
status: 400
response_strings:
- 'Invalid uuid value: spameggs'
- name: list resource providers providing an invalid filter
GET: /resource_providers?spam=eggs
status: 400
response_strings:
- 'Invalid filters: spam'
- name: list one resource provider filtering by uuid
GET: /resource_providers?uuid=$ENVIRON['RP_UUID']
response_json_paths:
$.resource_providers.`len`: 1
$.resource_providers[0].uuid: $ENVIRON['RP_UUID']
$.resource_providers[0].name: $ENVIRON['RP_NAME']
$.resource_providers[0].links[?rel = "self"].href: /resource_providers/$ENVIRON['RP_UUID']
$.resource_providers[0].links[?rel = "inventories"].href: /resource_providers/$ENVIRON['RP_UUID']/inventories
$.resource_providers[0].links[?rel = "aggregates"].href: /resource_providers/$ENVIRON['RP_UUID']/aggregates
$.resource_providers[0].links[?rel = "usages"].href: /resource_providers/$ENVIRON['RP_UUID']/usages
- name: update a resource provider
PUT: /resource_providers/$RESPONSE['$.resource_providers[0].uuid']
request_headers:

View File

@ -387,6 +387,10 @@ class ResourceProviderListTestCase(test.NoDBTestCase):
resource_providers = objects.ResourceProviderList.get_all_by_filters(
self.context, filters={'can_host': 1})
self.assertEqual(0, len(resource_providers))
resource_providers = objects.ResourceProviderList.get_all_by_filters(
self.context, filters={'uuid': getattr(uuidsentinel, 'rp_uuid_2')})
self.assertEqual(1, len(resource_providers))
self.assertEqual('rp_name_2', resource_providers[0].name)
class TestAllocation(ResourceProviderBaseCase):