Add pagination for snapshots, backups

Allow cinderclient to retrieve more than osapi_max_limit
(default 1000) snapshots, backups, etc.

Cinder pagination support has been added to the API quite some
time ago.  Client support was only implemented for volumes.

This commit allows other resources to be paginated as well.

Change-Id: I9a6f446b680dadedccd14ba49efdef7f5ef0a58a
Closes-Bug: #1691229
Co-Authored-By: Gorka Eguileor <geguileo@redhat.com>
This commit is contained in:
Gerhard Muntingh 2017-05-16 21:03:48 +02:00 committed by Gorka Eguileor
parent b910f5bea3
commit d11b1059a4
3 changed files with 39 additions and 7 deletions

View File

@ -115,12 +115,13 @@ class Manager(common_base.HookableMixin):
# than osapi_max_limit, so we have to retrieve multiple times to
# get the complete list.
next = None
if 'volumes_links' in body:
volumes_links = body['volumes_links']
if volumes_links:
for volumes_link in volumes_links:
if 'rel' in volumes_link and 'next' == volumes_link['rel']:
next = volumes_link['href']
link_name = response_key + '_links'
if link_name in body:
links = body[link_name]
if links:
for link in links:
if 'rel' in link and 'next' == link['rel']:
next = link['href']
break
if next:
# As long as the 'next' link is not empty, keep requesting it

View File

@ -126,6 +126,37 @@ class BaseTest(utils.TestCase):
manager._build_list_url,
**arguments)
def test__list_no_link(self):
api = mock.Mock()
api.client.get.return_value = (mock.sentinel.resp,
{'resp_keys': [{'name': '1'}]})
manager = test_utils.FakeManager(api)
res = manager._list(mock.sentinel.url, 'resp_keys')
api.client.get.assert_called_once_with(mock.sentinel.url)
result = [r.name for r in res]
self.assertListEqual(['1'], result)
def test__list_with_link(self):
api = mock.Mock()
api.client.get.side_effect = [
(mock.sentinel.resp,
{'resp_keys': [{'name': '1'}],
'resp_keys_links': [{'rel': 'next', 'href': mock.sentinel.u2}]}),
(mock.sentinel.resp,
{'resp_keys': [{'name': '2'}],
'resp_keys_links': [{'rel': 'next', 'href': mock.sentinel.u3}]}),
(mock.sentinel.resp,
{'resp_keys': [{'name': '3'}],
'resp_keys_links': [{'rel': 'next', 'href': None}]}),
]
manager = test_utils.FakeManager(api)
res = manager._list(mock.sentinel.url, 'resp_keys')
api.client.get.assert_has_calls([mock.call(mock.sentinel.url),
mock.call(mock.sentinel.u2),
mock.call(mock.sentinel.u3)])
result = [r.name for r in res]
self.assertListEqual(['1', '2', '3'], result)
class ListWithMetaTest(utils.TestCase):
def test_list_with_meta(self):

View File

@ -34,7 +34,7 @@ UUID = '8e8ec658-c7b0-4243-bdf8-6f7f2952c0d0'
class FakeResource(object):
NAME_ATTR = 'name'
def __init__(self, _id, properties):
def __init__(self, _id, properties, **kwargs):
self.id = _id
try:
self.name = properties['name']