Add include_limits filter
Add include_limits filter for get project to support fetching project hierarchy limits. This filter should be used together with "subtree_as_list" or "parents_as_list" filter bp: strict-two-level-model Change-Id: Ib602887c92b89be0ffec1394a3076f5dd5671511
This commit is contained in:
parent
059fa7eb83
commit
8038c70abf
@ -213,6 +213,8 @@ class ProjectV3(controller.V3Controller):
|
||||
self.query_filter_is_true(params['subtree_as_list']))
|
||||
subtree_as_ids = 'subtree_as_ids' in params and (
|
||||
self.query_filter_is_true(params['subtree_as_ids']))
|
||||
include_limits = 'include_limits' in params and (
|
||||
self.query_filter_is_true(params['include_limits']))
|
||||
|
||||
# parents_as_list and parents_as_ids are mutually exclusive
|
||||
if parents_as_list and parents_as_ids:
|
||||
@ -228,7 +230,7 @@ class ProjectV3(controller.V3Controller):
|
||||
|
||||
if parents_as_list:
|
||||
parents = PROVIDERS.resource_api.list_project_parents(
|
||||
ref['id'], request.context.user_id)
|
||||
ref['id'], request.context.user_id, include_limits)
|
||||
ref['parents'] = [ProjectV3.wrap_member(context, p)
|
||||
for p in parents]
|
||||
elif parents_as_ids:
|
||||
@ -238,7 +240,7 @@ class ProjectV3(controller.V3Controller):
|
||||
|
||||
if subtree_as_list:
|
||||
subtree = PROVIDERS.resource_api.list_projects_in_subtree(
|
||||
ref['id'], request.context.user_id)
|
||||
ref['id'], request.context.user_id, include_limits)
|
||||
ref['subtree'] = [ProjectV3.wrap_member(context, p)
|
||||
for p in subtree]
|
||||
elif subtree_as_ids:
|
||||
|
@ -526,13 +526,28 @@ class Manager(manager.Manager):
|
||||
# Check if project_id exists
|
||||
self.get_project(project_id)
|
||||
|
||||
def list_project_parents(self, project_id, user_id=None):
|
||||
def _include_limits(self, projects):
|
||||
"""Modify a list of projects to include limit information.
|
||||
|
||||
:param projects: a list of project references including an `id`
|
||||
:type projects: list of dictionaries
|
||||
"""
|
||||
for project in projects:
|
||||
hints = driver_hints.Hints()
|
||||
hints.add_filter('project_id', project['id'])
|
||||
limits = PROVIDERS.unified_limit_api.list_limits(hints)
|
||||
project['limits'] = limits
|
||||
|
||||
def list_project_parents(self, project_id, user_id=None,
|
||||
include_limits=False):
|
||||
self._assert_valid_project_id(project_id)
|
||||
parents = self.driver.list_project_parents(project_id)
|
||||
# If a user_id was provided, the returned list should be filtered
|
||||
# against the projects this user has access to.
|
||||
if user_id:
|
||||
parents = self._filter_projects_list(parents, user_id)
|
||||
if include_limits:
|
||||
self._include_limits(parents)
|
||||
return parents
|
||||
|
||||
def _build_parents_as_ids_dict(self, project, parents_by_id):
|
||||
@ -578,13 +593,16 @@ class Manager(manager.Manager):
|
||||
project, {proj['id']: proj for proj in parents_list})
|
||||
return parents_as_ids
|
||||
|
||||
def list_projects_in_subtree(self, project_id, user_id=None):
|
||||
def list_projects_in_subtree(self, project_id, user_id=None,
|
||||
include_limits=False):
|
||||
self._assert_valid_project_id(project_id)
|
||||
subtree = self.driver.list_projects_in_subtree(project_id)
|
||||
# If a user_id was provided, the returned list should be filtered
|
||||
# against the projects this user has access to.
|
||||
if user_id:
|
||||
subtree = self._filter_projects_list(subtree, user_id)
|
||||
if include_limits:
|
||||
self._include_limits(subtree)
|
||||
return subtree
|
||||
|
||||
def _build_subtree_as_ids_dict(self, project_id, subtree_by_parent):
|
||||
|
@ -1090,6 +1090,70 @@ class ResourceTestCase(test_v3.RestfulTestCase,
|
||||
'project_id': projects[1]['project']['id']},
|
||||
expected_status=http_client.BAD_REQUEST)
|
||||
|
||||
def test_get_project_with_include_limits(self):
|
||||
parent, project, subproject = self._create_projects_hierarchy(2)
|
||||
# Assign a role for the user on all the created projects
|
||||
for proj in (parent, project, subproject):
|
||||
self.put(self.build_role_assignment_link(
|
||||
role_id=self.role_id, user_id=self.user_id,
|
||||
project_id=proj['project']['id']))
|
||||
# create a registered limit and three limits for each project.
|
||||
reg_limit = unit.new_registered_limit_ref(service_id=self.service_id,
|
||||
region_id=self.region_id,
|
||||
resource_name='volume')
|
||||
self.post(
|
||||
'/registered_limits',
|
||||
body={'registered_limits': [reg_limit]},
|
||||
expected_status=http_client.CREATED)
|
||||
limit1 = unit.new_limit_ref(project_id=parent['project']['id'],
|
||||
service_id=self.service_id,
|
||||
region_id=self.region_id,
|
||||
resource_name='volume')
|
||||
limit2 = unit.new_limit_ref(project_id=project['project']['id'],
|
||||
service_id=self.service_id,
|
||||
region_id=self.region_id,
|
||||
resource_name='volume')
|
||||
limit3 = unit.new_limit_ref(project_id=subproject['project']['id'],
|
||||
service_id=self.service_id,
|
||||
region_id=self.region_id,
|
||||
resource_name='volume')
|
||||
self.post(
|
||||
'/limits',
|
||||
body={'limits': [limit1, limit2, limit3]},
|
||||
expected_status=http_client.CREATED)
|
||||
# "include_limits" should work together with "parents_as_list" or
|
||||
# "subtree_as_list". Only using "include_limits" really does nothing.
|
||||
r = self.get('/projects/%(project_id)s?include_limits' %
|
||||
{'project_id': subproject['project']['id']})
|
||||
|
||||
self.assertIsNone(r.result['project'].get('parents'))
|
||||
self.assertIsNone(r.result['project'].get('subtree'))
|
||||
self.assertIsNone(r.result['project'].get('limits'))
|
||||
|
||||
# using "include_limits" with "parents_as_list"
|
||||
r = self.get('/projects/%(project_id)s?include_limits&parents_as_list'
|
||||
% {'project_id': subproject['project']['id']})
|
||||
|
||||
self.assertEqual(2, len(r.result['project']['parents']))
|
||||
for parent in r.result['project']['parents']:
|
||||
self.assertEqual(1, len(parent['project']['limits']))
|
||||
self.assertEqual(parent['project']['id'],
|
||||
parent['project']['limits'][0]['project_id'])
|
||||
self.assertEqual(10,
|
||||
parent['project']['limits'][0]['resource_limit'])
|
||||
|
||||
# using "include_limits" with "subtree_as_list"
|
||||
r = self.get('/projects/%(project_id)s?include_limits&subtree_as_list'
|
||||
% {'project_id': parent['project']['id']})
|
||||
|
||||
self.assertEqual(2, len(r.result['project']['subtree']))
|
||||
for child in r.result['project']['subtree']:
|
||||
self.assertEqual(1, len(child['project']['limits']))
|
||||
self.assertEqual(child['project']['id'],
|
||||
child['project']['limits'][0]['project_id'])
|
||||
self.assertEqual(10,
|
||||
child['project']['limits'][0]['resource_limit'])
|
||||
|
||||
def test_list_project_is_domain_filter(self):
|
||||
"""Call ``GET /projects?is_domain=True/False``."""
|
||||
# Get the initial number of projects, both acting as a domain as well
|
||||
|
@ -19,3 +19,10 @@ features:
|
||||
The `project_id` filter is added for listing limits. This filter is used
|
||||
for system-scoped request only to fetch the specified project limits. Non
|
||||
system-scoped request will get empty response body instead.
|
||||
|
||||
- >
|
||||
[`blueprint strict-two-level-model <https://blueprints.launchpad.net/keystone/+spec/strict-two-level-model>`_]
|
||||
The `include_limits` filter is added to `GET /v3/projects/{project_id}` API.
|
||||
This filter should be used together with `parents_as_list` or
|
||||
`subtree_as_list` filter to add parent/sub project's limit information the
|
||||
response body.
|
||||
|
Loading…
Reference in New Issue
Block a user