diff --git a/cinderclient/base.py b/cinderclient/base.py index 88ab9511c..83f873189 100644 --- a/cinderclient/base.py +++ b/cinderclient/base.py @@ -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 diff --git a/cinderclient/tests/unit/test_base.py b/cinderclient/tests/unit/test_base.py index ce8d9e40b..d4dd517ce 100644 --- a/cinderclient/tests/unit/test_base.py +++ b/cinderclient/tests/unit/test_base.py @@ -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): diff --git a/cinderclient/tests/unit/test_utils.py b/cinderclient/tests/unit/test_utils.py index a2d2256cf..7f39f06f5 100644 --- a/cinderclient/tests/unit/test_utils.py +++ b/cinderclient/tests/unit/test_utils.py @@ -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']