Add pagination to GET /tokens

* Partially fixes bug 928049

Change-Id: I21943dcc7cea4dabfab672e84fe507e78e430de4
This commit is contained in:
Brian Waldon 2012-02-09 16:25:45 -08:00
parent d049c19227
commit 0e775d628b
5 changed files with 114 additions and 14 deletions

View File

@ -165,6 +165,7 @@ class Application(BaseApplication):
# allow middleware up the stack to provide context & params
context = req.environ.get('openstack.context', {})
context['query_string'] = dict(req.params.iteritems())
params = req.environ.get('openstack.params', {})
params.update(arg_dict)

View File

@ -246,7 +246,11 @@ class TenantController(wsgi.Application):
tenant_refs.append(self.identity_api.get_tenant(
context=context,
tenant_id=tenant_id))
return self._format_tenants_for_token(tenant_refs)
params = {
'limit': context['query_string'].get('limit'),
'marker': context['query_string'].get('marker'),
}
return self._format_tenant_list(tenant_refs, **params)
def get_tenant(self, context, tenant_id):
# TODO(termie): this stuff should probably be moved to middleware
@ -293,7 +297,30 @@ class TenantController(wsgi.Application):
self.assert_admin(context)
raise NotImplementedError()
def _format_tenants_for_token(self, tenant_refs):
def _format_tenant_list(self, tenant_refs, **kwargs):
marker = kwargs.get('marker')
page_idx = 0
if marker is not None:
for (marker_idx, tenant) in enumerate(tenant_refs):
if tenant['id'] == marker:
# we start pagination after the marker
page_idx = marker_idx + 1
break
else:
msg = 'Marker could not be found'
raise webob.exc.HTTPBadRequest(explanation=msg)
limit = kwargs.get('limit')
if limit is not None:
try:
limit = int(limit)
assert limit >= 0
except (ValueError, AssertionError):
msg = 'Invalid limit value'
raise webob.exc.HTTPBadRequest(explanation=msg)
tenant_refs = tenant_refs[page_idx:limit]
for x in tenant_refs:
x['enabled'] = True
o = {'tenants': tenant_refs,

View File

@ -85,3 +85,9 @@ class CliMasterTestCase(test_keystoneclient.KcMasterTestCase):
def test_ec2_credentials_delete_user_forbidden(self):
raise nose.exc.SkipTest('cli testing code does not handle 403 well')
def test_tenant_list_limit_bad_value(self):
raise nose.exc.SkipTest('cli testing code does not handle 400 well')
def test_tenant_list_marker_not_found(self):
raise nose.exc.SkipTest('cli testing code does not handle 400 well')

View File

@ -1,4 +1,7 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
import uuid
import nose.exc
from keystone import test
@ -448,6 +451,58 @@ class KcMasterTestCase(CompatTestCase, KeystoneClientTests):
self.assert_(self.tenant_baz['id'] not in
[x.id for x in tenant_refs])
def test_tenant_list_marker(self):
client = self.get_client()
# Add two arbitrary tenants to user for testing purposes
for i in range(2):
tenant_id = uuid.uuid4().hex
tenant = {'name': 'tenant-%s' % tenant_id, 'id': tenant_id}
self.identity_api.create_tenant(tenant_id, tenant)
self.identity_api.add_user_to_tenant(tenant_id, self.user_foo['id'])
tenants = client.tenants.list()
self.assertEqual(len(tenants), 3)
tenants_marker = client.tenants.list(marker=tenants[0].id)
self.assertEqual(len(tenants_marker), 2)
self.assertEqual(tenants[1].name, tenants_marker[0].name)
self.assertEqual(tenants[2].name, tenants_marker[1].name)
def test_tenant_list_marker_not_found(self):
from keystoneclient import exceptions as client_exceptions
client = self.get_client()
self.assertRaises(client_exceptions.BadRequest,
client.tenants.list, marker=uuid.uuid4().hex)
def test_tenant_list_limit(self):
client = self.get_client()
# Add two arbitrary tenants to user for testing purposes
for i in range(2):
tenant_id = uuid.uuid4().hex
tenant = {'name': 'tenant-%s' % tenant_id, 'id': tenant_id}
self.identity_api.create_tenant(tenant_id, tenant)
self.identity_api.add_user_to_tenant(tenant_id, self.user_foo['id'])
tenants = client.tenants.list()
self.assertEqual(len(tenants), 3)
tenants_limited = client.tenants.list(limit=2)
self.assertEqual(len(tenants_limited), 2)
self.assertEqual(tenants[0].name, tenants_limited[0].name)
self.assertEqual(tenants[1].name, tenants_limited[1].name)
def test_tenant_list_limit_bad_value(self):
from keystoneclient import exceptions as client_exceptions
client = self.get_client()
self.assertRaises(client_exceptions.BadRequest,
client.tenants.list, limit='a')
self.assertRaises(client_exceptions.BadRequest,
client.tenants.list, limit=-1)
def test_roles_get_by_user(self):
client = self.get_client()
roles = client.roles.roles_for_user(user=self.user_foo['id'],

View File

@ -1,25 +1,36 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
import json
import webob
from keystone import test
from keystone.common import wsgi
class FakeApp(wsgi.Application):
def index(self, context):
return {'a': 'b'}
class ApplicationTest(test.TestCase):
def setUp(self):
self.app = FakeApp()
def _make_request(self):
req = webob.Request.blank('/')
args = {'action': 'index', 'controller': self.app}
def _make_request(self, url='/'):
req = webob.Request.blank(url)
args = {'action': 'index', 'controller': None}
req.environ['wsgiorg.routing_args'] = [None, args]
return req
def test_response_content_type(self):
class FakeApp(wsgi.Application):
def index(self, context):
return {'a': 'b'}
app = FakeApp()
req = self._make_request()
resp = req.get_response(self.app)
resp = req.get_response(app)
self.assertEqual(resp.content_type, 'application/json')
def test_query_string_available(self):
class FakeApp(wsgi.Application):
def index(self, context):
return context['query_string']
app = FakeApp()
req = self._make_request(url='/?1=2')
resp = req.get_response(app)
self.assertEqual(json.loads(resp.body), {'1': '2'})