Support Pagination for namespace list
The rest api metadefs/namespaces supports pagination using the parameters of limit, marker, sort_dir, & sort_key. However, the glance client isn't passing those parameters through (they come in as kwargs). This is preventing pagination from working properly in horizon. This is affecting Horizon support: https://review.openstack.org/#/c/104063/ Change-Id: Ib349cf3a3a437eb1711f350b37d0bd0e7d01330a Closes-Bug: 1381816
This commit is contained in:
parent
3989cd202d
commit
9a4d8580e8
|
@ -22,6 +22,8 @@ from glanceclient.openstack.common import strutils
|
|||
from glanceclient.v2 import schemas
|
||||
|
||||
DEFAULT_PAGE_SIZE = 20
|
||||
SORT_DIR_VALUES = ('asc', 'desc')
|
||||
SORT_KEY_VALUES = ('created_at', 'namespace')
|
||||
|
||||
|
||||
class NamespaceController(object):
|
||||
|
@ -88,8 +90,17 @@ class NamespaceController(object):
|
|||
|
||||
def list(self, **kwargs):
|
||||
"""Retrieve a listing of Namespace objects
|
||||
|
||||
:param page_size: Number of namespaces to request in each request
|
||||
:param page_size: Number of items to request in each paginated request
|
||||
:param limit: Use to request a specific page size. Expect a response
|
||||
to a limited request to return between zero and limit
|
||||
items.
|
||||
:param marker: Specifies the namespace of the last-seen namespace.
|
||||
The typical pattern of limit and marker is to make an
|
||||
initial limited request and then to use the last
|
||||
namespace from the response as the marker parameter
|
||||
in a subsequent limited request.
|
||||
:param sort_key: The field to sort on (for example, 'created_at')
|
||||
:param sort_dir: The direction to sort ('asc' or 'desc')
|
||||
:returns generator over list of Namespaces
|
||||
"""
|
||||
|
||||
|
@ -129,6 +140,25 @@ class NamespaceController(object):
|
|||
else:
|
||||
filters['limit'] = kwargs['page_size']
|
||||
|
||||
if 'marker' in kwargs:
|
||||
filters['marker'] = kwargs['marker']
|
||||
|
||||
sort_key = kwargs.get('sort_key')
|
||||
if sort_key is not None:
|
||||
if sort_key in SORT_KEY_VALUES:
|
||||
filters['sort_key'] = sort_key
|
||||
else:
|
||||
raise ValueError('sort_key must be one of the following: %s.'
|
||||
% ', '.join(SORT_KEY_VALUES))
|
||||
|
||||
sort_dir = kwargs.get('sort_dir')
|
||||
if sort_dir is not None:
|
||||
if sort_dir in SORT_DIR_VALUES:
|
||||
filters['sort_dir'] = sort_dir
|
||||
else:
|
||||
raise ValueError('sort_dir must be one of the following: %s.'
|
||||
% ', '.join(SORT_DIR_VALUES))
|
||||
|
||||
for param, value in six.iteritems(filters):
|
||||
if isinstance(value, list):
|
||||
filters[param] = strutils.safe_encode(','.join(value))
|
||||
|
|
|
@ -89,7 +89,7 @@ data_fixtures = {
|
|||
"GET": (
|
||||
{},
|
||||
{
|
||||
"first": "/v2/metadefs/namespaces?limit=1",
|
||||
"first": "/v2/metadefs/namespaces?limit=2",
|
||||
"namespaces": [
|
||||
_get_namespace_fixture(NAMESPACE8),
|
||||
],
|
||||
|
@ -97,6 +97,43 @@ data_fixtures = {
|
|||
}
|
||||
)
|
||||
},
|
||||
"/v2/metadefs/namespaces?limit=2&marker=%s" % NAMESPACE6: {
|
||||
"GET": (
|
||||
{},
|
||||
{
|
||||
"first": "/v2/metadefs/namespaces?limit=2",
|
||||
"namespaces": [
|
||||
_get_namespace_fixture(NAMESPACE7),
|
||||
_get_namespace_fixture(NAMESPACE8),
|
||||
],
|
||||
"schema": "/v2/schemas/metadefs/namespaces"
|
||||
}
|
||||
)
|
||||
},
|
||||
"/v2/metadefs/namespaces?limit=20&sort_dir=asc": {
|
||||
"GET": (
|
||||
{},
|
||||
{
|
||||
"first": "/v2/metadefs/namespaces?limit=1",
|
||||
"namespaces": [
|
||||
_get_namespace_fixture(NAMESPACE1),
|
||||
],
|
||||
"schema": "/v2/schemas/metadefs/namespaces"
|
||||
}
|
||||
)
|
||||
},
|
||||
"/v2/metadefs/namespaces?limit=20&sort_key=created_at": {
|
||||
"GET": (
|
||||
{},
|
||||
{
|
||||
"first": "/v2/metadefs/namespaces?limit=1",
|
||||
"namespaces": [
|
||||
_get_namespace_fixture(NAMESPACE1),
|
||||
],
|
||||
"schema": "/v2/schemas/metadefs/namespaces"
|
||||
}
|
||||
)
|
||||
},
|
||||
"/v2/metadefs/namespaces?limit=20&resource_types=%s" % RESOURCE_TYPE1: {
|
||||
"GET": (
|
||||
{},
|
||||
|
@ -269,7 +306,7 @@ data_fixtures = {
|
|||
"updated_at": "2014-08-14T09:07:06Z",
|
||||
}
|
||||
),
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
schema_fixtures = {
|
||||
|
@ -521,6 +558,40 @@ class TestNamespaceController(testtools.TestCase):
|
|||
self.assertEqual(NAMESPACE7, namespaces[0]['namespace'])
|
||||
self.assertEqual(NAMESPACE8, namespaces[1]['namespace'])
|
||||
|
||||
def test_list_with_limit_greater_than_page_size(self):
|
||||
namespaces = list(self.controller.list(page_size=1, limit=2))
|
||||
self.assertEqual(2, len(namespaces))
|
||||
self.assertEqual(NAMESPACE7, namespaces[0]['namespace'])
|
||||
self.assertEqual(NAMESPACE8, namespaces[1]['namespace'])
|
||||
|
||||
def test_list_with_marker(self):
|
||||
namespaces = list(self.controller.list(marker=NAMESPACE6, page_size=2))
|
||||
self.assertEqual(2, len(namespaces))
|
||||
self.assertEqual(NAMESPACE7, namespaces[0]['namespace'])
|
||||
self.assertEqual(NAMESPACE8, namespaces[1]['namespace'])
|
||||
|
||||
def test_list_with_sort_dir(self):
|
||||
namespaces = list(self.controller.list(sort_dir='asc', limit=1))
|
||||
self.assertEqual(1, len(namespaces))
|
||||
self.assertEqual(NAMESPACE1, namespaces[0]['namespace'])
|
||||
|
||||
def test_list_with_sort_dir_invalid(self):
|
||||
# NOTE(TravT): The clients work by returning an iterator.
|
||||
# Invoking the iterator is what actually executes the logic.
|
||||
ns_iterator = self.controller.list(sort_dir='foo')
|
||||
self.assertRaises(ValueError, next, ns_iterator)
|
||||
|
||||
def test_list_with_sort_key(self):
|
||||
namespaces = list(self.controller.list(sort_key='created_at', limit=1))
|
||||
self.assertEqual(1, len(namespaces))
|
||||
self.assertEqual(NAMESPACE1, namespaces[0]['namespace'])
|
||||
|
||||
def test_list_with_sort_key_invalid(self):
|
||||
# NOTE(TravT): The clients work by returning an iterator.
|
||||
# Invoking the iterator is what actually executes the logic.
|
||||
ns_iterator = self.controller.list(sort_key='foo')
|
||||
self.assertRaises(ValueError, next, ns_iterator)
|
||||
|
||||
def test_list_namespaces_with_one_resource_type_filter(self):
|
||||
namespaces = list(self.controller.list(
|
||||
filters={
|
||||
|
|
Loading…
Reference in New Issue