diff --git a/lib/ansible/modules/cloud/amazon/iam.py b/lib/ansible/modules/cloud/amazon/iam.py index 37548b9c54f..9cb76eb85ea 100644 --- a/lib/ansible/modules/cloud/amazon/iam.py +++ b/lib/ansible/modules/cloud/amazon/iam.py @@ -291,20 +291,18 @@ def update_user(module, iam, name, new_name, new_path, key_state, key_count, key if updated and new_name: name = new_name try: - current_keys, status = \ - [ck['access_key_id'] for ck in - iam.get_all_access_keys(name).list_access_keys_result.access_key_metadata],\ - [ck['status'] for ck in - iam.get_all_access_keys(name).list_access_keys_result.access_key_metadata] + current_keys = [ck['access_key_id'] for ck in + iam.get_all_access_keys(name).list_access_keys_result.access_key_metadata] + status = [ck['status'] for ck in + iam.get_all_access_keys(name).list_access_keys_result.access_key_metadata] key_qty = len(current_keys) except boto.exception.BotoServerError as err: error_msg = boto_exception(err) if 'cannot be found' in error_msg and updated: - current_keys, status = \ - [ck['access_key_id'] for ck in - iam.get_all_access_keys(new_name).list_access_keys_result.access_key_metadata],\ - [ck['status'] for ck in - iam.get_all_access_keys(new_name).list_access_keys_result.access_key_metadata] + current_keys = [ck['access_key_id'] for ck in + iam.get_all_access_keys(new_name).list_access_keys_result.access_key_metadata] + status = [ck['status'] for ck in + iam.get_all_access_keys(new_name).list_access_keys_result.access_key_metadata] name = new_name else: module.fail_json(changed=False, msg=str(err)) @@ -346,11 +344,29 @@ def update_user(module, iam, name, new_name, new_path, key_state, key_count, key else: module.fail_json(msg=error_msg) + try: + current_keys = [ck['access_key_id'] for ck in + iam.get_all_access_keys(name).list_access_keys_result.access_key_metadata] + status = [ck['status'] for ck in + iam.get_all_access_keys(name).list_access_keys_result.access_key_metadata] + key_qty = len(current_keys) + except boto.exception.BotoServerError as err: + error_msg = boto_exception(err) + if 'cannot be found' in error_msg and updated: + current_keys = [ck['access_key_id'] for ck in + iam.get_all_access_keys(new_name).list_access_keys_result.access_key_metadata] + status = [ck['status'] for ck in + iam.get_all_access_keys(new_name).list_access_keys_result.access_key_metadata] + name = new_name + else: + module.fail_json(changed=False, msg=str(err)) + + new_keys = [] if key_state == 'create': try: while key_count > key_qty: - new_key = iam.create_access_key( - user_name=name).create_access_key_response.create_access_key_result.access_key + new_keys.append(iam.create_access_key( + user_name=name).create_access_key_response.create_access_key_result.access_key) key_qty += 1 changed = True @@ -359,18 +375,24 @@ def update_user(module, iam, name, new_name, new_path, key_state, key_count, key if keys and key_state: for access_key in keys: - if access_key in current_keys: - for current_key, current_key_state in zip(current_keys, status): - if key_state != current_key_state.lower(): - try: - iam.update_access_key( - access_key, key_state.capitalize(), user_name=name) - except boto.exception.BotoServerError as err: - module.fail_json(changed=False, msg=str(err)) - else: - changed = True + if key_state in ('active', 'inactive'): + if access_key in current_keys: + for current_key, current_key_state in zip(current_keys, status): + if key_state != current_key_state.lower(): + try: + iam.update_access_key(access_key, key_state.capitalize(), user_name=name) + changed = True + except boto.exception.BotoServerError as err: + module.fail_json(changed=False, msg=str(err)) + else: + module.fail_json(msg="Supplied keys not found for %s. " + "Current keys: %s. " + "Supplied key(s): %s" % + (name, current_keys, keys) + ) - if key_state == 'remove': + if key_state == 'remove': + if access_key in current_keys: try: iam.delete_access_key(access_key, user_name=name) except boto.exception.BotoServerError as err: @@ -394,7 +416,7 @@ def update_user(module, iam, name, new_name, new_path, key_state, key_count, key for fk, fks in zip(final_keys, final_key_status): updated_key_list.update({fk: fks}) - return name_change, updated_key_list, changed + return name_change, updated_key_list, changed, new_keys def set_users_groups(module, iam, name, groups, updated=None, @@ -703,8 +725,17 @@ def main(): password = None if name not in orig_user_list and new_name in orig_user_list: been_updated = True - name_change, key_list, user_changed = update_user( + name_change, key_list, user_changed, new_key = update_user( module, iam, name, new_name, new_path, key_state, key_count, key_ids, password, been_updated) + if new_key: + user_meta = {'access_keys': list(new_key)} + user_meta['access_keys'].extend( + [{'access_key_id': key, 'status': value} for key, value in key_list.items() if + key not in [it['access_key_id'] for it in new_key]]) + else: + user_meta = { + 'access_keys': [{'access_key_id': key, 'status': value} for key, value in key_list.items()]} + if name_change and new_name: orig_name = name name = new_name @@ -719,19 +750,24 @@ def main(): changed = user_changed if new_name and new_path: module.exit_json(changed=changed, groups=user_groups, old_user_name=orig_name, - new_user_name=new_name, old_path=path, new_path=new_path, keys=key_list) + new_user_name=new_name, old_path=path, new_path=new_path, keys=key_list, + created_keys=new_key, user_meta=user_meta) elif new_name and not new_path and not been_updated: module.exit_json( - changed=changed, groups=user_groups, old_user_name=orig_name, new_user_name=new_name, keys=key_list) + changed=changed, groups=user_groups, old_user_name=orig_name, new_user_name=new_name, keys=key_list, + created_keys=new_key, user_meta=user_meta) elif new_name and not new_path and been_updated: module.exit_json( - changed=changed, groups=user_groups, user_name=new_name, keys=key_list, key_state=key_state) + changed=changed, groups=user_groups, user_name=new_name, keys=key_list, key_state=key_state, + created_keys=new_key, user_meta=user_meta) elif not new_name and new_path: module.exit_json( - changed=changed, groups=user_groups, user_name=name, old_path=path, new_path=new_path, keys=key_list) + changed=changed, groups=user_groups, user_name=name, old_path=path, new_path=new_path, + keys=key_list, created_keys=new_key, user_meta=user_meta) else: module.exit_json( - changed=changed, groups=user_groups, user_name=name, keys=key_list) + changed=changed, groups=user_groups, user_name=name, keys=key_list, created_keys=new_key, + user_meta=user_meta) elif state == 'update' and not user_exists: module.fail_json(