Paginate the results from boto.iam

The default pagination is every 100 items with a maximum of 1000 from
Amazon. This properly uses the marker returned by Amazon to concatenate
the various pages from the results.

This fixes #2440.
This commit is contained in:
Jonathan A. Sternberg 2016-05-19 21:45:37 -04:00 committed by Matt Clay
parent 152a713fd3
commit 97917121a6

View file

@ -158,6 +158,40 @@ def boto_exception(err):
return error return error
def _paginate(func, attr):
'''
paginates the results from func by continuously passing in
the returned marker if the results were truncated. this returns
an iterator over the items in the returned response. `attr` is
the name of the attribute to iterate over in the response.
'''
finished, marker = False, None
while not finished:
res = func(marker=marker)
for item in getattr(res, attr):
yield item
finished = res.is_truncated == 'false'
if not finished:
marker = res.marker
def list_all_groups(iam):
return [item['group_name'] for item in _paginate(iam.get_all_groups, 'groups')]
def list_all_users(iam):
return [item['user_name'] for item in _paginate(iam.get_all_users, 'users')]
def list_all_roles(iam):
return [item['role_name'] for item in _paginate(iam.list_roles, 'roles')]
def list_all_instance_profiles(iam):
return [item['instance_profile_name'] for item in _paginate(iam.list_instance_profiles, 'instance_profiles')]
def create_user(module, iam, name, pwd, path, key_state, key_count): def create_user(module, iam, name, pwd, path, key_state, key_count):
key_qty = 0 key_qty = 0
keys = [] keys = []
@ -452,9 +486,7 @@ def create_role(module, iam, name, path, role_list, prof_list):
except boto.exception.BotoServerError as err: except boto.exception.BotoServerError as err:
module.fail_json(changed=changed, msg=str(err)) module.fail_json(changed=changed, msg=str(err))
else: else:
updated_role_list = [rl['role_name'] for rl in iam.list_roles().list_roles_response. updated_role_list = list_all_roles(iam)
list_roles_result.roles]
return changed, updated_role_list, iam_role_result, instance_profile_result return changed, updated_role_list, iam_role_result, instance_profile_result
@ -500,8 +532,7 @@ def delete_role(module, iam, name, role_list, prof_list):
except boto.exception.BotoServerError as err: except boto.exception.BotoServerError as err:
module.fail_json(changed=changed, msg=str(err)) module.fail_json(changed=changed, msg=str(err))
else: else:
updated_role_list = [rl['role_name'] for rl in iam.list_roles().list_roles_response. updated_role_list = list_all_roles(iam)
list_roles_result.roles]
return changed, updated_role_list, iam_role_result, instance_profile_result return changed, updated_role_list, iam_role_result, instance_profile_result
@ -584,22 +615,13 @@ def main():
changed = False changed = False
try: try:
orig_group_list = [gl['group_name'] for gl in iam.get_all_groups(). orig_group_list = list_all_groups(iam)
list_groups_result.
groups]
orig_user_list = [ul['user_name'] for ul in iam.get_all_users(). orig_user_list = list_all_users(iam)
list_users_result.
users]
orig_role_list = [rl['role_name'] for rl in iam.list_roles().list_roles_response. orig_role_list = list_all_roles(iam)
list_roles_result.
roles]
orig_prof_list = [ap['instance_profile_name'] for ap in iam.list_instance_profiles(). orig_prof_list = list_all_instance_profiles(iam)
list_instance_profiles_response.
list_instance_profiles_result.
instance_profiles]
except boto.exception.BotoServerError as err: except boto.exception.BotoServerError as err:
module.fail_json(msg=err.message) module.fail_json(msg=err.message)