1
0
mirror of https://github.com/ansible/tower-cli.git synced 2026-02-06 00:48:50 +01:00

Ability to get all pages from tower_cli {resource} list.

This commit adds the ability to send `-a` or `--all-pages` to
`tower_cli {resource} list`, and it sends back all pages the API sends
down, if there is more than one page.
This commit is contained in:
Luke Sneeringer
2014-07-10 12:59:08 -05:00
parent bbf758be77
commit 2befd0a683
2 changed files with 44 additions and 3 deletions

View File

@@ -578,9 +578,14 @@ class Resource(BaseResource):
return response['results'][0]
@resources.command(ignore_defaults=True, no_args_is_help=False)
@click.option('--page', default=1, type=int, help='The page to show.',
show_default=True)
def list(self, **kwargs):
@click.option('all_pages', '-a', '--all-pages',
is_flag=True, default=False, show_default=True,
help='If set, collate all pages of content from the API '
'when returning results.')
@click.option('--page', default=1, type=int, show_default=True,
help='The page to show. Ignored if --all-pages '
'is sent.')
def list(self, all_pages=False, **kwargs):
"""Return a list of objects.
If one or more filters are provided through keyword arguments,
@@ -588,6 +593,11 @@ class Resource(BaseResource):
If no filters are provided, return all results.
"""
# If the `all_pages` flag is set, then ignore any page that might
# also be sent.
if all_pages:
kwargs.pop('page', None)
# Get the response.
debug.log('Getting records.', header='details')
response = self.read(**kwargs)
@@ -600,6 +610,14 @@ class Resource(BaseResource):
match = re.search(r'page=(?P<num>[\d]+)', response[key])
response[key] = int(match.groupdict()['num'])
# If we were asked for all pages, keep retrieving pages until we
# have them all.
if all_pages and response['next']:
cursor = copy(response)
while cursor['next']:
cursor = self.list(**dict(kwargs, page=cursor['next']))
response['results'] += cursor['results']
# Done; return the response
return response

View File

@@ -391,6 +391,29 @@ class ResourceTests(unittest.TestCase):
self.assertEqual(result['count'], 2)
self.assertEqual(result['results'][0]['id'], 1)
def test_list_all_pages(self):
"""Establish that the Resource class' `list` method correctly
accepts the --all-pages flag and checks follow-up pages.
"""
with client.test_mode as t:
# Register the first, second, and third page.
t.register_json('/foo/', {'count': 3, 'results': [
{'id': 1, 'name': 'foo', 'description': 'bar'},
], 'next': '/foo/?page=2', 'previous': None})
t.register_json('/foo/?page=2', {'count': 3, 'results': [
{'id': 2, 'name': 'spam', 'description': 'eggs'},
], 'next': '/foo/?page=3', 'previous': None})
t.register_json('/foo/?page=3', {'count': 3, 'results': [
{'id': 3, 'name': 'bacon', 'description': 'cheese'},
], 'next': None, 'previous': None})
# Get the list
result = self.res.list(all_pages=True)
# Assert that there are three results, and three requests.
self.assertEqual(len(t.requests), 3)
self.assertEqual(len(result['results']), 3)
def test_get_unexpected_zero_results(self):
"""Establish that if a read method gets 0 results when it should have
gotten one or more, that it raises NotFound.