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:
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user