From 4d320d17e9074839bc10f2357603858c5319b699 Mon Sep 17 00:00:00 2001 From: jillr Date: Mon, 2 Mar 2020 19:25:18 +0000 Subject: [PATCH 01/29] Initial commit This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/eb75681585a23ea79e642b86a0f8e64e0f40a6d7 --- plugins/modules/iam_group.py | 439 ++++++++++++++++++ tests/integration/targets/iam_group/aliases | 2 + .../targets/iam_group/defaults/main.yml | 3 + .../targets/iam_group/meta/main.yml | 3 + .../targets/iam_group/tasks/main.yml | 125 +++++ 5 files changed, 572 insertions(+) create mode 100644 plugins/modules/iam_group.py create mode 100644 tests/integration/targets/iam_group/aliases create mode 100644 tests/integration/targets/iam_group/defaults/main.yml create mode 100644 tests/integration/targets/iam_group/meta/main.yml create mode 100644 tests/integration/targets/iam_group/tasks/main.yml diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py new file mode 100644 index 00000000000..7ce18593e0a --- /dev/null +++ b/plugins/modules/iam_group.py @@ -0,0 +1,439 @@ +#!/usr/bin/python +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = ''' +--- +module: iam_group +short_description: Manage AWS IAM groups +description: + - Manage AWS IAM groups. +author: +- Nick Aslanidis (@naslanidis) +- Maksym Postument (@infectsoldier) +options: + name: + description: + - The name of the group to create. + required: true + type: str + managed_policies: + description: + - A list of managed policy ARNs or friendly names to attach to the role. + - To embed an inline policy, use M(iam_policy). + required: false + type: list + elements: str + aliases: ['managed_policy'] + users: + description: + - A list of existing users to add as members of the group. + required: false + type: list + elements: str + state: + description: + - Create or remove the IAM group. + required: true + choices: [ 'present', 'absent' ] + type: str + purge_policies: + description: + - When I(purge_policies=true) any managed policies not listed in I(managed_policies) will be detatched. + required: false + default: false + type: bool + aliases: ['purge_policy', 'purge_managed_policies'] + purge_users: + description: + - When I(purge_users=true) users which are not included in I(users) will be detached. + required: false + default: false + type: bool +requirements: [ botocore, boto3 ] +extends_documentation_fragment: +- ansible.amazon.aws +- ansible.amazon.ec2 + +''' + +EXAMPLES = ''' +# Note: These examples do not set authentication details, see the AWS Guide for details. + +# Create a group +- iam_group: + name: testgroup1 + state: present + +# Create a group and attach a managed policy using its ARN +- iam_group: + name: testgroup1 + managed_policies: + - arn:aws:iam::aws:policy/AmazonSNSFullAccess + state: present + +# Create a group with users as members and attach a managed policy using its ARN +- iam_group: + name: testgroup1 + managed_policies: + - arn:aws:iam::aws:policy/AmazonSNSFullAccess + users: + - test_user1 + - test_user2 + state: present + +# Remove all managed policies from an existing group with an empty list +- iam_group: + name: testgroup1 + state: present + purge_policies: true + +# Remove all group members from an existing group +- iam_group: + name: testgroup1 + managed_policies: + - arn:aws:iam::aws:policy/AmazonSNSFullAccess + purge_users: true + state: present + + +# Delete the group +- iam_group: + name: testgroup1 + state: absent + +''' +RETURN = ''' +iam_group: + description: dictionary containing all the group information including group membership + returned: success + type: complex + contains: + group: + description: dictionary containing all the group information + returned: success + type: complex + contains: + arn: + description: the Amazon Resource Name (ARN) specifying the group + type: str + sample: "arn:aws:iam::1234567890:group/testgroup1" + create_date: + description: the date and time, in ISO 8601 date-time format, when the group was created + type: str + sample: "2017-02-08T04:36:28+00:00" + group_id: + description: the stable and unique string identifying the group + type: str + sample: AGPAIDBWE12NSFINE55TM + group_name: + description: the friendly name that identifies the group + type: str + sample: testgroup1 + path: + description: the path to the group + type: str + sample: / + users: + description: list containing all the group members + returned: success + type: complex + contains: + arn: + description: the Amazon Resource Name (ARN) specifying the user + type: str + sample: "arn:aws:iam::1234567890:user/test_user1" + create_date: + description: the date and time, in ISO 8601 date-time format, when the user was created + type: str + sample: "2017-02-08T04:36:28+00:00" + user_id: + description: the stable and unique string identifying the user + type: str + sample: AIDAIZTPY123YQRS22YU2 + user_name: + description: the friendly name that identifies the user + type: str + sample: testgroup1 + path: + description: the path to the user + type: str + sample: / +''' + +from ansible_collections.ansible.amazon.plugins.module_utils.aws.core import AnsibleAWSModule +from ansible_collections.ansible.amazon.plugins.module_utils.ec2 import camel_dict_to_snake_dict +from ansible_collections.ansible.amazon.plugins.module_utils.ec2 import AWSRetry + +try: + from botocore.exceptions import BotoCoreError, ClientError +except ImportError: + pass # caught by AnsibleAWSModule + + +def compare_attached_group_policies(current_attached_policies, new_attached_policies): + + # If new_attached_policies is None it means we want to remove all policies + if len(current_attached_policies) > 0 and new_attached_policies is None: + return False + + current_attached_policies_arn_list = [] + for policy in current_attached_policies: + current_attached_policies_arn_list.append(policy['PolicyArn']) + + if set(current_attached_policies_arn_list) == set(new_attached_policies): + return True + else: + return False + + +def compare_group_members(current_group_members, new_group_members): + + # If new_attached_policies is None it means we want to remove all policies + if len(current_group_members) > 0 and new_group_members is None: + return False + if set(current_group_members) == set(new_group_members): + return True + else: + return False + + +def convert_friendly_names_to_arns(connection, module, policy_names): + + if not any([not policy.startswith('arn:') for policy in policy_names if policy is not None]): + return policy_names + allpolicies = {} + paginator = connection.get_paginator('list_policies') + policies = paginator.paginate().build_full_result()['Policies'] + + for policy in policies: + allpolicies[policy['PolicyName']] = policy['Arn'] + allpolicies[policy['Arn']] = policy['Arn'] + try: + return [allpolicies[policy] for policy in policy_names] + except KeyError as e: + module.fail_json(msg="Couldn't find policy: " + str(e)) + + +def create_or_update_group(connection, module): + + params = dict() + params['GroupName'] = module.params.get('name') + managed_policies = module.params.get('managed_policies') + users = module.params.get('users') + purge_users = module.params.get('purge_users') + purge_policies = module.params.get('purge_policies') + changed = False + if managed_policies: + managed_policies = convert_friendly_names_to_arns(connection, module, managed_policies) + + # Get group + try: + group = get_group(connection, module, params['GroupName']) + except (BotoCoreError, ClientError) as e: + module.fail_json_aws(e, msg="Couldn't get group") + + # If group is None, create it + if group is None: + # Check mode means we would create the group + if module.check_mode: + module.exit_json(changed=True) + + try: + group = connection.create_group(**params) + changed = True + except (BotoCoreError, ClientError) as e: + module.fail_json_aws(e, msg="Couldn't create group") + + # Manage managed policies + current_attached_policies = get_attached_policy_list(connection, module, params['GroupName']) + if not compare_attached_group_policies(current_attached_policies, managed_policies): + current_attached_policies_arn_list = [] + for policy in current_attached_policies: + current_attached_policies_arn_list.append(policy['PolicyArn']) + + # If managed_policies has a single empty element we want to remove all attached policies + if purge_policies: + # Detach policies not present + for policy_arn in list(set(current_attached_policies_arn_list) - set(managed_policies)): + changed = True + if not module.check_mode: + try: + connection.detach_group_policy(GroupName=params['GroupName'], PolicyArn=policy_arn) + except (BotoCoreError, ClientError) as e: + module.fail_json_aws(e, msg="Couldn't detach policy from group %s" % params['GroupName']) + # If there are policies to adjust that aren't in the current list, then things have changed + # Otherwise the only changes were in purging above + if set(managed_policies) - set(current_attached_policies_arn_list): + changed = True + # If there are policies in managed_policies attach each policy + if managed_policies != [None] and not module.check_mode: + for policy_arn in managed_policies: + try: + connection.attach_group_policy(GroupName=params['GroupName'], PolicyArn=policy_arn) + except (BotoCoreError, ClientError) as e: + module.fail_json_aws(e, msg="Couldn't attach policy to group %s" % params['GroupName']) + + # Manage group memberships + try: + current_group_members = get_group(connection, module, params['GroupName'])['Users'] + except (BotoCoreError, ClientError) as e: + module.fail_json_aws(e, "Couldn't get group %s" % params['GroupName']) + + current_group_members_list = [] + for member in current_group_members: + current_group_members_list.append(member['UserName']) + + if not compare_group_members(current_group_members_list, users): + + if purge_users: + for user in list(set(current_group_members_list) - set(users)): + # Ensure we mark things have changed if any user gets purged + changed = True + # Skip actions for check mode + if not module.check_mode: + try: + connection.remove_user_from_group(GroupName=params['GroupName'], UserName=user) + except (BotoCoreError, ClientError) as e: + module.fail_json_aws(e, msg="Couldn't remove user %s from group %s" % (user, params['GroupName'])) + # If there are users to adjust that aren't in the current list, then things have changed + # Otherwise the only changes were in purging above + if set(users) - set(current_group_members_list): + changed = True + # Skip actions for check mode + if users != [None] and not module.check_mode: + for user in users: + try: + connection.add_user_to_group(GroupName=params['GroupName'], UserName=user) + except (BotoCoreError, ClientError) as e: + module.fail_json_aws(e, msg="Couldn't add user %s to group %s" % (user, params['GroupName'])) + if module.check_mode: + module.exit_json(changed=changed) + + # Get the group again + try: + group = get_group(connection, module, params['GroupName']) + except (BotoCoreError, ClientError) as e: + module.fail_json_aws(e, "Couldn't get group %s" % params['GroupName']) + + module.exit_json(changed=changed, iam_group=camel_dict_to_snake_dict(group)) + + +def destroy_group(connection, module): + + params = dict() + params['GroupName'] = module.params.get('name') + + try: + group = get_group(connection, module, params['GroupName']) + except (BotoCoreError, ClientError) as e: + module.fail_json_aws(e, "Couldn't get group %s" % params['GroupName']) + if group: + # Check mode means we would remove this group + if module.check_mode: + module.exit_json(changed=True) + + # Remove any attached policies otherwise deletion fails + try: + for policy in get_attached_policy_list(connection, module, params['GroupName']): + connection.detach_group_policy(GroupName=params['GroupName'], PolicyArn=policy['PolicyArn']) + except (BotoCoreError, ClientError) as e: + module.fail_json_aws(e, msg="Couldn't remove policy from group %s" % params['GroupName']) + + # Remove any users in the group otherwise deletion fails + current_group_members_list = [] + try: + current_group_members = get_group(connection, module, params['GroupName'])['Users'] + except (BotoCoreError, ClientError) as e: + module.fail_json_aws(e, "Couldn't get group %s" % params['GroupName']) + for member in current_group_members: + current_group_members_list.append(member['UserName']) + for user in current_group_members_list: + try: + connection.remove_user_from_group(GroupName=params['GroupName'], UserName=user) + except (BotoCoreError, ClientError) as e: + module.fail_json_aws(e, "Couldn't remove user %s from group %s" % (user, params['GroupName'])) + + try: + connection.delete_group(**params) + except (BotoCoreError, ClientError) as e: + module.fail_json_aws(e, "Couldn't delete group %s" % params['GroupName']) + + else: + module.exit_json(changed=False) + + module.exit_json(changed=True) + + +@AWSRetry.exponential_backoff() +def get_group(connection, module, name): + try: + paginator = connection.get_paginator('get_group') + return paginator.paginate(GroupName=name).build_full_result() + except ClientError as e: + if e.response['Error']['Code'] == 'NoSuchEntity': + return None + else: + raise + + +@AWSRetry.exponential_backoff() +def get_attached_policy_list(connection, module, name): + + try: + paginator = connection.get_paginator('list_attached_group_policies') + return paginator.paginate(GroupName=name).build_full_result()['AttachedPolicies'] + except ClientError as e: + if e.response['Error']['Code'] == 'NoSuchEntity': + return None + else: + raise + + +def main(): + + argument_spec = dict( + name=dict(required=True), + managed_policies=dict(default=[], type='list', aliases=['managed_policy']), + users=dict(default=[], type='list'), + state=dict(choices=['present', 'absent'], required=True), + purge_users=dict(default=False, type='bool'), + purge_policies=dict(default=False, type='bool', aliases=['purge_policy', 'purge_managed_policies']) + ) + + module = AnsibleAWSModule( + argument_spec=argument_spec, + supports_check_mode=True + ) + + connection = module.client('iam') + + state = module.params.get("state") + + if state == 'present': + create_or_update_group(connection, module) + else: + destroy_group(connection, module) + + +if __name__ == '__main__': + main() diff --git a/tests/integration/targets/iam_group/aliases b/tests/integration/targets/iam_group/aliases new file mode 100644 index 00000000000..67ae2cc73b6 --- /dev/null +++ b/tests/integration/targets/iam_group/aliases @@ -0,0 +1,2 @@ +unsupported +cloud/aws diff --git a/tests/integration/targets/iam_group/defaults/main.yml b/tests/integration/targets/iam_group/defaults/main.yml new file mode 100644 index 00000000000..f5112b1a423 --- /dev/null +++ b/tests/integration/targets/iam_group/defaults/main.yml @@ -0,0 +1,3 @@ +--- +test_user: '{{ resource_prefix }}-user' +test_group: '{{ resource_prefix }}-group' diff --git a/tests/integration/targets/iam_group/meta/main.yml b/tests/integration/targets/iam_group/meta/main.yml new file mode 100644 index 00000000000..1f64f1169a9 --- /dev/null +++ b/tests/integration/targets/iam_group/meta/main.yml @@ -0,0 +1,3 @@ +dependencies: + - prepare_tests + - setup_ec2 diff --git a/tests/integration/targets/iam_group/tasks/main.yml b/tests/integration/targets/iam_group/tasks/main.yml new file mode 100644 index 00000000000..328fd7dbd0e --- /dev/null +++ b/tests/integration/targets/iam_group/tasks/main.yml @@ -0,0 +1,125 @@ +--- +- name: set up aws connection info + module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + block: + - name: ensure ansible user exists + iam_user: + name: '{{ test_user }}' + state: present + + - name: ensure group exists + iam_group: + name: '{{ test_group }}' + users: + - '{{ test_user }}' + state: present + register: iam_group + + - assert: + that: + - iam_group.iam_group.users + - iam_group is changed + + - name: add non existent user to group + iam_group: + name: '{{ test_group }}' + users: + - '{{ test_user }}' + - NonExistentUser + state: present + ignore_errors: yes + register: iam_group + + - name: assert that adding non existent user to group fails with helpful message + assert: + that: + - iam_group is failed + - iam_group.msg.startswith("Couldn't add user NonExistentUser to group {{ test_group }}") + + - name: remove a user + iam_group: + name: '{{ test_group }}' + purge_users: True + users: [] + state: present + register: iam_group + + - assert: + that: + - iam_group is changed + - not iam_group.iam_group.users + + - name: re-remove a user (no change) + iam_group: + name: '{{ test_group }}' + purge_users: True + users: [] + state: present + register: iam_group + + - assert: + that: + - iam_group is not changed + - not iam_group.iam_group.users + + - name: Add the user again + iam_group: + name: '{{ test_group }}' + users: + - '{{ test_user }}' + state: present + register: iam_group + + - assert: + that: + - iam_group is changed + - iam_group.iam_group.users + + - name: Re-add the user + iam_group: + name: '{{ test_group }}' + users: + - '{{ test_user }}' + state: present + register: iam_group + + - assert: + that: + - iam_group is not changed + - iam_group.iam_group.users + + - name: remove group + iam_group: + name: '{{ test_group }}' + state: absent + register: iam_group + + - assert: + that: + - iam_group is changed + + - name: re-remove group + iam_group: + name: '{{ test_group }}' + state: absent + register: iam_group + + - assert: + that: + - iam_group is not changed + + always: + - name: remove group + iam_group: + name: '{{ test_group }}' + state: absent + + - name: remove ansible user + iam_user: + name: '{{ test_user }}' + state: absent From 8a63f4eb85472411b388d67245fa76237024ed73 Mon Sep 17 00:00:00 2001 From: jillr Date: Tue, 3 Mar 2020 19:43:21 +0000 Subject: [PATCH 02/29] migration test cleanup This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/13b104b912784bb31a0bff23eed4c27b0f5e0283 --- tests/integration/targets/iam_group/tasks/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/integration/targets/iam_group/tasks/main.yml b/tests/integration/targets/iam_group/tasks/main.yml index 328fd7dbd0e..2701d8f3d33 100644 --- a/tests/integration/targets/iam_group/tasks/main.yml +++ b/tests/integration/targets/iam_group/tasks/main.yml @@ -6,6 +6,8 @@ aws_secret_key: "{{ aws_secret_key }}" security_token: "{{ security_token | default(omit) }}" region: "{{ aws_region }}" + collections: + - ansible.amazon block: - name: ensure ansible user exists iam_user: From 97a67c87f3c57ad900ce3b47d8e6dbf27bf8896d Mon Sep 17 00:00:00 2001 From: Jill R <4121322+jillr@users.noreply.github.com> Date: Wed, 25 Mar 2020 15:39:40 -0700 Subject: [PATCH 03/29] Rename collection (#12) * Rename core collection Rename references to ansible.amazon to amazon.aws. * Rename community.amazon to community.aws Fix pep8 line lengths for rewritten amazon.aws imports * Missed a path in shippable.sh * Dependency repos moved This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/235c5db571cc45db5839476c94356c9b91e1f228 --- plugins/modules/iam_group.py | 10 +++++----- tests/integration/targets/iam_group/tasks/main.yml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index 7ce18593e0a..cfac6062c46 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -71,8 +71,8 @@ type: bool requirements: [ botocore, boto3 ] extends_documentation_fragment: -- ansible.amazon.aws -- ansible.amazon.ec2 +- amazon.aws.aws +- amazon.aws.ec2 ''' @@ -180,9 +180,9 @@ sample: / ''' -from ansible_collections.ansible.amazon.plugins.module_utils.aws.core import AnsibleAWSModule -from ansible_collections.ansible.amazon.plugins.module_utils.ec2 import camel_dict_to_snake_dict -from ansible_collections.ansible.amazon.plugins.module_utils.ec2 import AWSRetry +from ansible_collections.amazon.aws.plugins.module_utils.aws.core import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry try: from botocore.exceptions import BotoCoreError, ClientError diff --git a/tests/integration/targets/iam_group/tasks/main.yml b/tests/integration/targets/iam_group/tasks/main.yml index 2701d8f3d33..65b441827ca 100644 --- a/tests/integration/targets/iam_group/tasks/main.yml +++ b/tests/integration/targets/iam_group/tasks/main.yml @@ -7,7 +7,7 @@ security_token: "{{ security_token | default(omit) }}" region: "{{ aws_region }}" collections: - - ansible.amazon + - amazon.aws block: - name: ensure ansible user exists iam_user: From ec4bc1a5c780bbf83609e7a05a9c0847f113d222 Mon Sep 17 00:00:00 2001 From: Jill R <4121322+jillr@users.noreply.github.com> Date: Tue, 19 May 2020 16:06:12 -0700 Subject: [PATCH 04/29] Remove METADATA and cleanup galaxy.yml (#70) * Remove ANSIBLE_METADATA entirely, see ansible/ansible/pull/69454. Remove `license` field from galaxy.yml, in favor of `license_file`. This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/05672a64e2362cc2d865b5af6a57da6bc3cd08e3 --- plugins/modules/iam_group.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index cfac6062c46..672de888fba 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -17,9 +17,6 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} DOCUMENTATION = ''' --- From b89fee9d3486e62e4f3ce3db9341e24fc6ef2b00 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Wed, 17 Jun 2020 01:24:54 +0530 Subject: [PATCH 05/29] Update Examples with FQCN (#67) Updated module examples with FQCN Signed-off-by: Abhijeet Kasurde This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/98173aefbbceed7fc0d9db62687b73f96a55a999 --- plugins/modules/iam_group.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index 672de888fba..121801275eb 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -36,7 +36,7 @@ managed_policies: description: - A list of managed policy ARNs or friendly names to attach to the role. - - To embed an inline policy, use M(iam_policy). + - To embed an inline policy, use M(community.aws.iam_policy). required: false type: list elements: str @@ -76,20 +76,20 @@ EXAMPLES = ''' # Note: These examples do not set authentication details, see the AWS Guide for details. -# Create a group -- iam_group: +- name: Create a group + community.aws.iam_group: name: testgroup1 state: present -# Create a group and attach a managed policy using its ARN -- iam_group: +- name: Create a group and attach a managed policy using its ARN + community.aws.iam_group: name: testgroup1 managed_policies: - arn:aws:iam::aws:policy/AmazonSNSFullAccess state: present -# Create a group with users as members and attach a managed policy using its ARN -- iam_group: +- name: Create a group with users as members and attach a managed policy using its ARN + community.aws.iam_group: name: testgroup1 managed_policies: - arn:aws:iam::aws:policy/AmazonSNSFullAccess @@ -98,23 +98,22 @@ - test_user2 state: present -# Remove all managed policies from an existing group with an empty list -- iam_group: +- name: Remove all managed policies from an existing group with an empty list + community.aws.iam_group: name: testgroup1 state: present purge_policies: true -# Remove all group members from an existing group -- iam_group: +- name: Remove all group members from an existing group + community.aws.iam_group: name: testgroup1 managed_policies: - arn:aws:iam::aws:policy/AmazonSNSFullAccess purge_users: true state: present - -# Delete the group -- iam_group: +- name: Delete the group + community.aws.iam_group: name: testgroup1 state: absent From f346679d759343cc0e9fca50362d50e4b235303a Mon Sep 17 00:00:00 2001 From: flowerysong Date: Tue, 16 Jun 2020 19:30:00 -0400 Subject: [PATCH 06/29] Update module_utils paths to remove aws subdir (#23) Co-authored-by: Ezekiel Hendrickson This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/10853d9441a586ba177006dd889325cfb24a3dd6 --- plugins/modules/iam_group.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index 121801275eb..4a53a870833 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -176,7 +176,7 @@ sample: / ''' -from ansible_collections.amazon.aws.plugins.module_utils.aws.core import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry From ae024cbc4b1d5e799a836da316c7a7d0dbad518d Mon Sep 17 00:00:00 2001 From: Jill R <4121322+jillr@users.noreply.github.com> Date: Wed, 17 Jun 2020 09:31:32 -0700 Subject: [PATCH 07/29] Update docs (#99) * Update docs Remove .git from repo url so links in readme will generate correctly Add required ansible version Run latest version of add_docs.py Add version_added string to modules * galaxy.yml was missing authors This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/96ee268e5267f5b12c3d59892bc1279f75aa3135 --- plugins/modules/iam_group.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index 4a53a870833..7a9da3e6f57 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -21,6 +21,7 @@ DOCUMENTATION = ''' --- module: iam_group +version_added: 1.0.0 short_description: Manage AWS IAM groups description: - Manage AWS IAM groups. From d4104fd25a6a7b24942deba99eaef3177d003616 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Thu, 16 Jul 2020 01:31:41 +0530 Subject: [PATCH 08/29] Docs: sanity fixes (#133) Signed-off-by: Abhijeet Kasurde This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/059cf9efc95bb976de21ab4f8e4d9ddd001983fc --- plugins/modules/iam_group.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index 7a9da3e6f57..b55e32218a2 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -18,7 +18,7 @@ __metaclass__ = type -DOCUMENTATION = ''' +DOCUMENTATION = r''' --- module: iam_group version_added: 1.0.0 @@ -74,7 +74,7 @@ ''' -EXAMPLES = ''' +EXAMPLES = r''' # Note: These examples do not set authentication details, see the AWS Guide for details. - name: Create a group @@ -119,7 +119,7 @@ state: absent ''' -RETURN = ''' +RETURN = r''' iam_group: description: dictionary containing all the group information including group membership returned: success @@ -410,8 +410,8 @@ def main(): argument_spec = dict( name=dict(required=True), - managed_policies=dict(default=[], type='list', aliases=['managed_policy']), - users=dict(default=[], type='list'), + managed_policies=dict(default=[], type='list', aliases=['managed_policy'], elements='str'), + users=dict(default=[], type='list', elements='str'), state=dict(choices=['present', 'absent'], required=True), purge_users=dict(default=False, type='bool'), purge_policies=dict(default=False, type='bool', aliases=['purge_policy', 'purge_managed_policies']) From cab26857794c3579146c8ac82472144ee9daca42 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Fri, 5 Feb 2021 09:43:09 +0100 Subject: [PATCH 09/29] Cleanup - use is_boto3_error_(message|code) (#268) * Reorder imports * Make use of is_boto3_error_message * Mass-migration over to is_boto3_error_code * Remove unused imports * unused vars in exception * Improve consistency around catching BotoCoreError and ClientError * Remove unused imports * Remove unused 'PolicyError' from iam_policy_info * Avoid catching botocore.exceptions.ClientError when we only want some error codes * Import camel_dict_to_snake_dict/snake_dict_to_camel_dict from ansible.module_utils.common.dict_transformations This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/4cf52ef67682fd4f9ed2a707adfbafffe7b88f15 --- plugins/modules/iam_group.py | 52 +++++++++++++++++------------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index b55e32218a2..af9d781a92f 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -177,15 +177,17 @@ sample: / ''' -from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry - try: - from botocore.exceptions import BotoCoreError, ClientError + import botocore except ImportError: pass # caught by AnsibleAWSModule +from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict + +from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry + def compare_attached_group_policies(current_attached_policies, new_attached_policies): @@ -246,7 +248,7 @@ def create_or_update_group(connection, module): # Get group try: group = get_group(connection, module, params['GroupName']) - except (BotoCoreError, ClientError) as e: + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't get group") # If group is None, create it @@ -258,7 +260,7 @@ def create_or_update_group(connection, module): try: group = connection.create_group(**params) changed = True - except (BotoCoreError, ClientError) as e: + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't create group") # Manage managed policies @@ -276,7 +278,7 @@ def create_or_update_group(connection, module): if not module.check_mode: try: connection.detach_group_policy(GroupName=params['GroupName'], PolicyArn=policy_arn) - except (BotoCoreError, ClientError) as e: + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't detach policy from group %s" % params['GroupName']) # If there are policies to adjust that aren't in the current list, then things have changed # Otherwise the only changes were in purging above @@ -287,13 +289,13 @@ def create_or_update_group(connection, module): for policy_arn in managed_policies: try: connection.attach_group_policy(GroupName=params['GroupName'], PolicyArn=policy_arn) - except (BotoCoreError, ClientError) as e: + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't attach policy to group %s" % params['GroupName']) # Manage group memberships try: current_group_members = get_group(connection, module, params['GroupName'])['Users'] - except (BotoCoreError, ClientError) as e: + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, "Couldn't get group %s" % params['GroupName']) current_group_members_list = [] @@ -310,7 +312,7 @@ def create_or_update_group(connection, module): if not module.check_mode: try: connection.remove_user_from_group(GroupName=params['GroupName'], UserName=user) - except (BotoCoreError, ClientError) as e: + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't remove user %s from group %s" % (user, params['GroupName'])) # If there are users to adjust that aren't in the current list, then things have changed # Otherwise the only changes were in purging above @@ -321,7 +323,7 @@ def create_or_update_group(connection, module): for user in users: try: connection.add_user_to_group(GroupName=params['GroupName'], UserName=user) - except (BotoCoreError, ClientError) as e: + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't add user %s to group %s" % (user, params['GroupName'])) if module.check_mode: module.exit_json(changed=changed) @@ -329,7 +331,7 @@ def create_or_update_group(connection, module): # Get the group again try: group = get_group(connection, module, params['GroupName']) - except (BotoCoreError, ClientError) as e: + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, "Couldn't get group %s" % params['GroupName']) module.exit_json(changed=changed, iam_group=camel_dict_to_snake_dict(group)) @@ -342,7 +344,7 @@ def destroy_group(connection, module): try: group = get_group(connection, module, params['GroupName']) - except (BotoCoreError, ClientError) as e: + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, "Couldn't get group %s" % params['GroupName']) if group: # Check mode means we would remove this group @@ -353,26 +355,26 @@ def destroy_group(connection, module): try: for policy in get_attached_policy_list(connection, module, params['GroupName']): connection.detach_group_policy(GroupName=params['GroupName'], PolicyArn=policy['PolicyArn']) - except (BotoCoreError, ClientError) as e: + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't remove policy from group %s" % params['GroupName']) # Remove any users in the group otherwise deletion fails current_group_members_list = [] try: current_group_members = get_group(connection, module, params['GroupName'])['Users'] - except (BotoCoreError, ClientError) as e: + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, "Couldn't get group %s" % params['GroupName']) for member in current_group_members: current_group_members_list.append(member['UserName']) for user in current_group_members_list: try: connection.remove_user_from_group(GroupName=params['GroupName'], UserName=user) - except (BotoCoreError, ClientError) as e: + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, "Couldn't remove user %s from group %s" % (user, params['GroupName'])) try: connection.delete_group(**params) - except (BotoCoreError, ClientError) as e: + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, "Couldn't delete group %s" % params['GroupName']) else: @@ -386,11 +388,8 @@ def get_group(connection, module, name): try: paginator = connection.get_paginator('get_group') return paginator.paginate(GroupName=name).build_full_result() - except ClientError as e: - if e.response['Error']['Code'] == 'NoSuchEntity': - return None - else: - raise + except is_boto3_error_code('NoSuchEntity'): + return None @AWSRetry.exponential_backoff() @@ -399,11 +398,8 @@ def get_attached_policy_list(connection, module, name): try: paginator = connection.get_paginator('list_attached_group_policies') return paginator.paginate(GroupName=name).build_full_result()['AttachedPolicies'] - except ClientError as e: - if e.response['Error']['Code'] == 'NoSuchEntity': - return None - else: - raise + except is_boto3_error_code('NoSuchEntity'): + return None def main(): From 4cfbfb9fbfd76a0bcb37b9625fbd33354481d942 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sat, 13 Feb 2021 14:19:21 +0100 Subject: [PATCH 10/29] Add comments to the disabled/unsupported integration test aliase files (#411) Add some additional comments so we know *why* the various tests aren't running. Looks like most of them just need policy updates This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/0d245596966100516f1eeab5dcf26ee0ebca24b5 --- tests/integration/targets/iam_group/aliases | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/integration/targets/iam_group/aliases b/tests/integration/targets/iam_group/aliases index 67ae2cc73b6..2da398045bd 100644 --- a/tests/integration/targets/iam_group/aliases +++ b/tests/integration/targets/iam_group/aliases @@ -1,2 +1,7 @@ +# reason: missing-policy +# It should be possible to test iam_groups by limiting which policies can be +# attached to the groups as well as which users can be added to the groups. +# Careful review is needed prior to adding this to the main CI. unsupported + cloud/aws From c971280bc4c8f74140c224acd0e9e025ca8c05ca Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Thu, 6 May 2021 21:01:46 +0200 Subject: [PATCH 11/29] Update the default module requirements from python 2.6/boto to python 3.6/boto3 This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/c097c55293be0834a2b9d394733ec28965d142d7 --- plugins/modules/iam_group.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index af9d781a92f..7b534aa0504 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -67,7 +67,6 @@ required: false default: false type: bool -requirements: [ botocore, boto3 ] extends_documentation_fragment: - amazon.aws.aws - amazon.aws.ec2 From 8188828658d08b7ffbdcef6061558b072e6f8cff Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Thu, 12 Aug 2021 21:01:04 +0200 Subject: [PATCH 12/29] use a generator rather than list comprehension when using any()/all() See also https://www.python.org/dev/peps/pep-0289/#rationale This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/87304dd3c476f8cd0b0ae0947dce2070ae87efcb --- plugins/modules/iam_group.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index 7b534aa0504..5f85c4bfc8c 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -217,7 +217,7 @@ def compare_group_members(current_group_members, new_group_members): def convert_friendly_names_to_arns(connection, module, policy_names): - if not any([not policy.startswith('arn:') for policy in policy_names if policy is not None]): + if not any(not policy.startswith('arn:') for policy in policy_names if policy is not None): return policy_names allpolicies = {} paginator = connection.get_paginator('list_policies') From 39d10d78917b31a1af6fac725319f1f8278a7bed Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Fri, 22 Apr 2022 11:44:07 +0200 Subject: [PATCH 13/29] Integration test dependency cleanup (#1086) Integration test dependency cleanup SUMMARY remove dependencies on setup_remote_tmp_dir where it's not used (often just copy & paste from another test) remove setup_ec2 (no main.yml means it's not doing anything) remove prepare_tests (empty main.yml means it's not doing anything) ISSUE TYPE Feature Pull Request COMPONENT NAME tests/integration/targets ADDITIONAL INFORMATION By cleaning up what we have we reduce the chance of people copying things about "because that's what test XYZ did". Reviewed-by: Alina Buzachis Reviewed-by: Mark Woolley This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/dd12046a1e2d5f39692b1890ff07e06c56b3bf0e --- tests/integration/targets/iam_group/meta/main.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/integration/targets/iam_group/meta/main.yml b/tests/integration/targets/iam_group/meta/main.yml index 1f64f1169a9..32cf5dda7ed 100644 --- a/tests/integration/targets/iam_group/meta/main.yml +++ b/tests/integration/targets/iam_group/meta/main.yml @@ -1,3 +1 @@ -dependencies: - - prepare_tests - - setup_ec2 +dependencies: [] From c8afc3fe9babf84ceeae181bf33e359cbde92e6b Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Wed, 28 Sep 2022 13:40:43 +0200 Subject: [PATCH 14/29] Make example AWS UUIDS follow a specific pattern (#1539) Make example AWS UUIDS follow a specific pattern SUMMARY Various AWS IAM resources have UUID which follow a specific pattern. Similarly AWS accounts are all 12 digit numbers (text aliases in a couple of cases). To minimize the risk of accidental data leaks use a consistent Account ID in examples (123456789012), and a specific format for the UUIDS: (AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)12345EXAMPLE54321 While this does nothing about historic data, having consistency makes it easier to prevent future leaks. Note: We should follow this up with an update to the developer docs, however I'd like to get this in prior to 5.0.0 ISSUE TYPE Docs Pull Request COMPONENT NAME plugins/modules/acm_certificate_info.py plugins/modules/application_autoscaling_policy.py plugins/modules/autoscaling_launch_config.py plugins/modules/autoscaling_launch_config_info.py plugins/modules/codecommit_repository.py plugins/modules/directconnect_link_aggregation_group.py plugins/modules/dms_endpoint.py plugins/modules/dynamodb_table.py plugins/modules/ec2_transit_gateway_info.py plugins/modules/ec2_transit_gateway_vpc_attachment.py plugins/modules/ec2_transit_gateway_vpc_attachment_info.py plugins/modules/ec2_vpc_peer.py plugins/modules/ec2_vpc_peering_info.py plugins/modules/ec2_vpc_vpn_info.py plugins/modules/ecs_cluster.py plugins/modules/ecs_ecr.py plugins/modules/ecs_service.py plugins/modules/ecs_service_info.py plugins/modules/ecs_task.py plugins/modules/efs.py plugins/modules/efs_info.py plugins/modules/eks_cluster.py plugins/modules/elasticache_subnet_group.py plugins/modules/elb_network_lb.py plugins/modules/elb_target_group.py plugins/modules/elb_target_group_info.py plugins/modules/elb_target_info.py plugins/modules/iam_group.py plugins/modules/iam_managed_policy.py plugins/modules/iam_mfa_device_info.py plugins/modules/iam_server_certificate_info.py plugins/modules/lightsail.py plugins/modules/lightsail_static_ip.py plugins/modules/msk_cluster.py plugins/modules/s3_bucket_notification.py plugins/modules/sns_topic.py plugins/modules/sns_topic_info.py plugins/modules/sqs_queue.py plugins/modules/stepfunctions_state_machine.py plugins/modules/stepfunctions_state_machine_execution.py plugins/modules/storagegateway_info.py plugins/modules/wafv2_web_acl.py ADDITIONAL INFORMATION While the 'secret' nature of these UUIDs is debatable (they're closer to user names than passwords), deliberately mangling them makes it easier for InfoSec teams to spot when their secret counterparts may have been leaked in combination with a real 'public' part. This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/94764225332c869eefa574a8948da680bb668407 --- plugins/modules/iam_group.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index 5f85c4bfc8c..759be42a74d 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -140,7 +140,7 @@ group_id: description: the stable and unique string identifying the group type: str - sample: AGPAIDBWE12NSFINE55TM + sample: AGPA12345EXAMPLE54321 group_name: description: the friendly name that identifies the group type: str @@ -165,7 +165,7 @@ user_id: description: the stable and unique string identifying the user type: str - sample: AIDAIZTPY123YQRS22YU2 + sample: AIDA12345EXAMPLE54321 user_name: description: the friendly name that identifies the user type: str From c58360dbd4f4b0c965d96d0a5d0ead8c55563f52 Mon Sep 17 00:00:00 2001 From: Alina Buzachis Date: Wed, 5 Oct 2022 17:04:40 +0200 Subject: [PATCH 15/29] Update extends_documentation_fragment with amazon.aws.boto3 (#1459) Update extends_documentation_fragment with amazon.aws.boto3 Depends-On: ansible/ansible-zuul-jobs#1654 SUMMARY As per ansible-collections/amazon.aws#985 add amazon.aws.boto3. ISSUE TYPE Docs Pull Request COMPONENT NAME several Reviewed-by: Jill R Reviewed-by: Mark Chappell Reviewed-by: Markus Bergholz This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/bd3c03fcba0848f593b86309740fa73e986a9646 --- plugins/modules/iam_group.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index 759be42a74d..0bc19d002ee 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -70,7 +70,7 @@ extends_documentation_fragment: - amazon.aws.aws - amazon.aws.ec2 - +- amazon.aws.boto3 ''' EXAMPLES = r''' From 4b656d354523fd19b109e4a3c767ad949125ba37 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Wed, 2 Nov 2022 11:49:57 +0100 Subject: [PATCH 16/29] Fix non-matching defaults in docs (#1576) Fix non-matching defaults in docs Depends-On: #1579 SUMMARY Fix various non-matching default values exposed by ansible/ansible#79267. ISSUE TYPE Docs Pull Request COMPONENT NAME various Reviewed-by: Markus Bergholz This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/15568f01dc839983dc5c79b78f26b53a93fa72ee --- plugins/modules/iam_group.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index 0bc19d002ee..31987ef1de4 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -41,6 +41,7 @@ required: false type: list elements: str + default: [] aliases: ['managed_policy'] users: description: @@ -48,6 +49,7 @@ required: false type: list elements: str + default: [] state: description: - Create or remove the IAM group. From baeb3862df4d2c439056b1e1dd488c3630801481 Mon Sep 17 00:00:00 2001 From: Bikouo Aubin <79859644+abikouo@users.noreply.github.com> Date: Tue, 10 Jan 2023 19:22:13 +0100 Subject: [PATCH 17/29] Ansible User-Agent identification for community.aws (#1632) Ansible User-Agent identification for community.aws SUMMARY The value will be similar to this APN/1.0 Ansible/2.14.1 community.aws/6.0.0-dev0 ISSUE TYPE Feature Pull Request Reviewed-by: Mark Chappell Reviewed-by: Bikouo Aubin Reviewed-by: Alina Buzachis This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/a8cbce24071bcc62fe4594c38aff1baf18bd2862 --- plugins/modules/iam_group.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index 31987ef1de4..cedf41613eb 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -185,7 +185,7 @@ from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict -from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule +from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry From d0134c022026bbf0fceed4b99d1670d9628c3d16 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Wed, 8 Mar 2023 12:07:26 +0100 Subject: [PATCH 18/29] Cleanup headers and imports (#1738) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cleanup headers and imports SUMMARY Mass update of imports, docs fragments and file headers Many of the amazon.aws module_utils and docs fragments got moved about, update community.aws to reflect this. Consistently apply the comment headers as documented at https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_documenting.html#python-shebang-utf-8-coding ISSUE TYPE Docs Pull Request Feature Pull Request COMPONENT NAME ADDITIONAL INFORMATION Header cleanup based upon: https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_documenting.html#python-shebang-utf-8-coding Begin your Ansible module with #!/usr/bin/python - this “shebang” allows ansible_python_interpreter to work. Follow the shebang immediately with # -*- coding: utf-8 -*- to clarify that the file is UTF-8 encoded. and https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_documenting.html#copyright-and-license After the shebang and UTF-8 coding, add a copyright line with the original copyright holder and a license declaration. The license declaration should be ONLY one line, not the full GPL prefix. ... Additions to the module (for instance, rewrites) are not permitted to add additional copyright lines other than the default copyright statement if missing: Reviewed-by: Alina Buzachis This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/a4f20bf114bfab19b1c84c4ecf42efd5614ab80c --- plugins/modules/iam_group.py | 51 ++++++++++++++---------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index cedf41613eb..9dc43ec0a94 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -1,24 +1,10 @@ #!/usr/bin/python -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -DOCUMENTATION = r''' +# -*- coding: utf-8 -*- + +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" --- module: iam_group version_added: 1.0.0 @@ -26,8 +12,8 @@ description: - Manage AWS IAM groups. author: -- Nick Aslanidis (@naslanidis) -- Maksym Postument (@infectsoldier) + - Nick Aslanidis (@naslanidis) + - Maksym Postument (@infectsoldier) options: name: description: @@ -70,12 +56,12 @@ default: false type: bool extends_documentation_fragment: -- amazon.aws.aws -- amazon.aws.ec2 -- amazon.aws.boto3 -''' + - amazon.aws.common.modules + - amazon.aws.region.modules + - amazon.aws.boto3 +""" -EXAMPLES = r''' +EXAMPLES = r""" # Note: These examples do not set authentication details, see the AWS Guide for details. - name: Create a group @@ -119,8 +105,8 @@ name: testgroup1 state: absent -''' -RETURN = r''' +""" +RETURN = r""" iam_group: description: dictionary containing all the group information including group membership returned: success @@ -176,7 +162,7 @@ description: the path to the user type: str sample: / -''' +""" try: import botocore @@ -185,9 +171,10 @@ from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict +from ansible_collections.amazon.aws.plugins.module_utils.botocore import is_boto3_error_code +from ansible_collections.amazon.aws.plugins.module_utils.retries import AWSRetry + from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule -from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry def compare_attached_group_policies(current_attached_policies, new_attached_policies): From 85172a53a2acc81b72d2ec728af527188e9ea685 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Wed, 26 Apr 2023 19:26:07 +0200 Subject: [PATCH 19/29] Big Black PR (#1784) * Black prep * Black * changelog * Fix pylint unused-import in tests * Split SSM connection plugin changes * disable glue tests - bucket's missing * Disable s3_logging and s3_sync tests This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/2c4575c248776c65d66b06cd60fa09b0dae1cd6f --- plugins/modules/iam_group.py | 116 +++++++++++++++++------------------ 1 file changed, 55 insertions(+), 61 deletions(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index 9dc43ec0a94..357671dbdc6 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -178,14 +178,13 @@ def compare_attached_group_policies(current_attached_policies, new_attached_policies): - # If new_attached_policies is None it means we want to remove all policies if len(current_attached_policies) > 0 and new_attached_policies is None: return False current_attached_policies_arn_list = [] for policy in current_attached_policies: - current_attached_policies_arn_list.append(policy['PolicyArn']) + current_attached_policies_arn_list.append(policy["PolicyArn"]) if set(current_attached_policies_arn_list) == set(new_attached_policies): return True @@ -194,7 +193,6 @@ def compare_attached_group_policies(current_attached_policies, new_attached_poli def compare_group_members(current_group_members, new_group_members): - # If new_attached_policies is None it means we want to remove all policies if len(current_group_members) > 0 and new_group_members is None: return False @@ -205,16 +203,15 @@ def compare_group_members(current_group_members, new_group_members): def convert_friendly_names_to_arns(connection, module, policy_names): - - if not any(not policy.startswith('arn:') for policy in policy_names if policy is not None): + if not any(not policy.startswith("arn:") for policy in policy_names if policy is not None): return policy_names allpolicies = {} - paginator = connection.get_paginator('list_policies') - policies = paginator.paginate().build_full_result()['Policies'] + paginator = connection.get_paginator("list_policies") + policies = paginator.paginate().build_full_result()["Policies"] for policy in policies: - allpolicies[policy['PolicyName']] = policy['Arn'] - allpolicies[policy['Arn']] = policy['Arn'] + allpolicies[policy["PolicyName"]] = policy["Arn"] + allpolicies[policy["Arn"]] = policy["Arn"] try: return [allpolicies[policy] for policy in policy_names] except KeyError as e: @@ -222,20 +219,19 @@ def convert_friendly_names_to_arns(connection, module, policy_names): def create_or_update_group(connection, module): - params = dict() - params['GroupName'] = module.params.get('name') - managed_policies = module.params.get('managed_policies') - users = module.params.get('users') - purge_users = module.params.get('purge_users') - purge_policies = module.params.get('purge_policies') + params["GroupName"] = module.params.get("name") + managed_policies = module.params.get("managed_policies") + users = module.params.get("users") + purge_users = module.params.get("purge_users") + purge_policies = module.params.get("purge_policies") changed = False if managed_policies: managed_policies = convert_friendly_names_to_arns(connection, module, managed_policies) # Get group try: - group = get_group(connection, module, params['GroupName']) + group = get_group(connection, module, params["GroupName"]) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't get group") @@ -252,11 +248,11 @@ def create_or_update_group(connection, module): module.fail_json_aws(e, msg="Couldn't create group") # Manage managed policies - current_attached_policies = get_attached_policy_list(connection, module, params['GroupName']) + current_attached_policies = get_attached_policy_list(connection, module, params["GroupName"]) if not compare_attached_group_policies(current_attached_policies, managed_policies): current_attached_policies_arn_list = [] for policy in current_attached_policies: - current_attached_policies_arn_list.append(policy['PolicyArn']) + current_attached_policies_arn_list.append(policy["PolicyArn"]) # If managed_policies has a single empty element we want to remove all attached policies if purge_policies: @@ -265,9 +261,9 @@ def create_or_update_group(connection, module): changed = True if not module.check_mode: try: - connection.detach_group_policy(GroupName=params['GroupName'], PolicyArn=policy_arn) + connection.detach_group_policy(GroupName=params["GroupName"], PolicyArn=policy_arn) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg="Couldn't detach policy from group %s" % params['GroupName']) + module.fail_json_aws(e, msg="Couldn't detach policy from group %s" % params["GroupName"]) # If there are policies to adjust that aren't in the current list, then things have changed # Otherwise the only changes were in purging above if set(managed_policies) - set(current_attached_policies_arn_list): @@ -276,22 +272,21 @@ def create_or_update_group(connection, module): if managed_policies != [None] and not module.check_mode: for policy_arn in managed_policies: try: - connection.attach_group_policy(GroupName=params['GroupName'], PolicyArn=policy_arn) + connection.attach_group_policy(GroupName=params["GroupName"], PolicyArn=policy_arn) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg="Couldn't attach policy to group %s" % params['GroupName']) + module.fail_json_aws(e, msg="Couldn't attach policy to group %s" % params["GroupName"]) # Manage group memberships try: - current_group_members = get_group(connection, module, params['GroupName'])['Users'] + current_group_members = get_group(connection, module, params["GroupName"])["Users"] except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't get group %s" % params['GroupName']) + module.fail_json_aws(e, "Couldn't get group %s" % params["GroupName"]) current_group_members_list = [] for member in current_group_members: - current_group_members_list.append(member['UserName']) + current_group_members_list.append(member["UserName"]) if not compare_group_members(current_group_members_list, users): - if purge_users: for user in list(set(current_group_members_list) - set(users)): # Ensure we mark things have changed if any user gets purged @@ -299,9 +294,11 @@ def create_or_update_group(connection, module): # Skip actions for check mode if not module.check_mode: try: - connection.remove_user_from_group(GroupName=params['GroupName'], UserName=user) + connection.remove_user_from_group(GroupName=params["GroupName"], UserName=user) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg="Couldn't remove user %s from group %s" % (user, params['GroupName'])) + module.fail_json_aws( + e, msg="Couldn't remove user %s from group %s" % (user, params["GroupName"]) + ) # If there are users to adjust that aren't in the current list, then things have changed # Otherwise the only changes were in purging above if set(users) - set(current_group_members_list): @@ -310,30 +307,29 @@ def create_or_update_group(connection, module): if users != [None] and not module.check_mode: for user in users: try: - connection.add_user_to_group(GroupName=params['GroupName'], UserName=user) + connection.add_user_to_group(GroupName=params["GroupName"], UserName=user) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg="Couldn't add user %s to group %s" % (user, params['GroupName'])) + module.fail_json_aws(e, msg="Couldn't add user %s to group %s" % (user, params["GroupName"])) if module.check_mode: module.exit_json(changed=changed) # Get the group again try: - group = get_group(connection, module, params['GroupName']) + group = get_group(connection, module, params["GroupName"]) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't get group %s" % params['GroupName']) + module.fail_json_aws(e, "Couldn't get group %s" % params["GroupName"]) module.exit_json(changed=changed, iam_group=camel_dict_to_snake_dict(group)) def destroy_group(connection, module): - params = dict() - params['GroupName'] = module.params.get('name') + params["GroupName"] = module.params.get("name") try: - group = get_group(connection, module, params['GroupName']) + group = get_group(connection, module, params["GroupName"]) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't get group %s" % params['GroupName']) + module.fail_json_aws(e, "Couldn't get group %s" % params["GroupName"]) if group: # Check mode means we would remove this group if module.check_mode: @@ -341,29 +337,29 @@ def destroy_group(connection, module): # Remove any attached policies otherwise deletion fails try: - for policy in get_attached_policy_list(connection, module, params['GroupName']): - connection.detach_group_policy(GroupName=params['GroupName'], PolicyArn=policy['PolicyArn']) + for policy in get_attached_policy_list(connection, module, params["GroupName"]): + connection.detach_group_policy(GroupName=params["GroupName"], PolicyArn=policy["PolicyArn"]) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg="Couldn't remove policy from group %s" % params['GroupName']) + module.fail_json_aws(e, msg="Couldn't remove policy from group %s" % params["GroupName"]) # Remove any users in the group otherwise deletion fails current_group_members_list = [] try: - current_group_members = get_group(connection, module, params['GroupName'])['Users'] + current_group_members = get_group(connection, module, params["GroupName"])["Users"] except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't get group %s" % params['GroupName']) + module.fail_json_aws(e, "Couldn't get group %s" % params["GroupName"]) for member in current_group_members: - current_group_members_list.append(member['UserName']) + current_group_members_list.append(member["UserName"]) for user in current_group_members_list: try: - connection.remove_user_from_group(GroupName=params['GroupName'], UserName=user) + connection.remove_user_from_group(GroupName=params["GroupName"], UserName=user) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't remove user %s from group %s" % (user, params['GroupName'])) + module.fail_json_aws(e, "Couldn't remove user %s from group %s" % (user, params["GroupName"])) try: connection.delete_group(**params) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't delete group %s" % params['GroupName']) + module.fail_json_aws(e, "Couldn't delete group %s" % params["GroupName"]) else: module.exit_json(changed=False) @@ -374,47 +370,45 @@ def destroy_group(connection, module): @AWSRetry.exponential_backoff() def get_group(connection, module, name): try: - paginator = connection.get_paginator('get_group') + paginator = connection.get_paginator("get_group") return paginator.paginate(GroupName=name).build_full_result() - except is_boto3_error_code('NoSuchEntity'): + except is_boto3_error_code("NoSuchEntity"): return None @AWSRetry.exponential_backoff() def get_attached_policy_list(connection, module, name): - try: - paginator = connection.get_paginator('list_attached_group_policies') - return paginator.paginate(GroupName=name).build_full_result()['AttachedPolicies'] - except is_boto3_error_code('NoSuchEntity'): + paginator = connection.get_paginator("list_attached_group_policies") + return paginator.paginate(GroupName=name).build_full_result()["AttachedPolicies"] + except is_boto3_error_code("NoSuchEntity"): return None def main(): - argument_spec = dict( name=dict(required=True), - managed_policies=dict(default=[], type='list', aliases=['managed_policy'], elements='str'), - users=dict(default=[], type='list', elements='str'), - state=dict(choices=['present', 'absent'], required=True), - purge_users=dict(default=False, type='bool'), - purge_policies=dict(default=False, type='bool', aliases=['purge_policy', 'purge_managed_policies']) + managed_policies=dict(default=[], type="list", aliases=["managed_policy"], elements="str"), + users=dict(default=[], type="list", elements="str"), + state=dict(choices=["present", "absent"], required=True), + purge_users=dict(default=False, type="bool"), + purge_policies=dict(default=False, type="bool", aliases=["purge_policy", "purge_managed_policies"]), ) module = AnsibleAWSModule( argument_spec=argument_spec, - supports_check_mode=True + supports_check_mode=True, ) - connection = module.client('iam') + connection = module.client("iam") state = module.params.get("state") - if state == 'present': + if state == "present": create_or_update_group(connection, module) else: destroy_group(connection, module) -if __name__ == '__main__': +if __name__ == "__main__": main() From 4061295b9dfa92814d7bf43b0aa326bcdfb7479e Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Mon, 8 May 2023 19:21:22 +0200 Subject: [PATCH 20/29] Bulk migration to Python 3.6 f-strings (#1810) Bulk migration to Python 3.6 f-strings SUMMARY We've dropped support for Python <3.6, bulk migrate to fstrings and perform some general string cleanup A combination of black --preview flynt some manual cleanup ISSUE TYPE Feature Pull Request COMPONENT NAME plugins/ tests/ ADDITIONAL INFORMATION Reviewed-by: Alina Buzachis This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/de338210dc1b0bb2eecee1dc16e073163b2d1df7 --- plugins/modules/iam_group.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index 357671dbdc6..c4f77fde772 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -263,7 +263,7 @@ def create_or_update_group(connection, module): try: connection.detach_group_policy(GroupName=params["GroupName"], PolicyArn=policy_arn) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg="Couldn't detach policy from group %s" % params["GroupName"]) + module.fail_json_aws(e, msg=f"Couldn't detach policy from group {params['GroupName']}") # If there are policies to adjust that aren't in the current list, then things have changed # Otherwise the only changes were in purging above if set(managed_policies) - set(current_attached_policies_arn_list): @@ -274,13 +274,13 @@ def create_or_update_group(connection, module): try: connection.attach_group_policy(GroupName=params["GroupName"], PolicyArn=policy_arn) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg="Couldn't attach policy to group %s" % params["GroupName"]) + module.fail_json_aws(e, msg=f"Couldn't attach policy to group {params['GroupName']}") # Manage group memberships try: current_group_members = get_group(connection, module, params["GroupName"])["Users"] except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't get group %s" % params["GroupName"]) + module.fail_json_aws(e, f"Couldn't get group {params['GroupName']}") current_group_members_list = [] for member in current_group_members: @@ -296,9 +296,7 @@ def create_or_update_group(connection, module): try: connection.remove_user_from_group(GroupName=params["GroupName"], UserName=user) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws( - e, msg="Couldn't remove user %s from group %s" % (user, params["GroupName"]) - ) + module.fail_json_aws(e, msg=f"Couldn't remove user {user} from group {params['GroupName']}") # If there are users to adjust that aren't in the current list, then things have changed # Otherwise the only changes were in purging above if set(users) - set(current_group_members_list): @@ -309,7 +307,7 @@ def create_or_update_group(connection, module): try: connection.add_user_to_group(GroupName=params["GroupName"], UserName=user) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg="Couldn't add user %s to group %s" % (user, params["GroupName"])) + module.fail_json_aws(e, msg=f"Couldn't add user {user} to group {params['GroupName']}") if module.check_mode: module.exit_json(changed=changed) @@ -317,7 +315,7 @@ def create_or_update_group(connection, module): try: group = get_group(connection, module, params["GroupName"]) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't get group %s" % params["GroupName"]) + module.fail_json_aws(e, f"Couldn't get group {params['GroupName']}") module.exit_json(changed=changed, iam_group=camel_dict_to_snake_dict(group)) @@ -329,7 +327,7 @@ def destroy_group(connection, module): try: group = get_group(connection, module, params["GroupName"]) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't get group %s" % params["GroupName"]) + module.fail_json_aws(e, f"Couldn't get group {params['GroupName']}") if group: # Check mode means we would remove this group if module.check_mode: @@ -340,26 +338,26 @@ def destroy_group(connection, module): for policy in get_attached_policy_list(connection, module, params["GroupName"]): connection.detach_group_policy(GroupName=params["GroupName"], PolicyArn=policy["PolicyArn"]) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg="Couldn't remove policy from group %s" % params["GroupName"]) + module.fail_json_aws(e, msg=f"Couldn't remove policy from group {params['GroupName']}") # Remove any users in the group otherwise deletion fails current_group_members_list = [] try: current_group_members = get_group(connection, module, params["GroupName"])["Users"] except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't get group %s" % params["GroupName"]) + module.fail_json_aws(e, f"Couldn't get group {params['GroupName']}") for member in current_group_members: current_group_members_list.append(member["UserName"]) for user in current_group_members_list: try: connection.remove_user_from_group(GroupName=params["GroupName"], UserName=user) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't remove user %s from group %s" % (user, params["GroupName"])) + module.fail_json_aws(e, f"Couldn't remove user {user} from group {params['GroupName']}") try: connection.delete_group(**params) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, "Couldn't delete group %s" % params["GroupName"]) + module.fail_json_aws(e, f"Couldn't delete group {params['GroupName']}") else: module.exit_json(changed=False) From 19fe1a3128551740e085d4ab66087e65e99a50a4 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Mon, 26 Jun 2023 23:23:50 +0200 Subject: [PATCH 21/29] Various ARN handling fixes (#1848) Various ARN handling fixes Depends-On: ansible-collections/amazon.aws#1619 SUMMARY fixes: #1846 Various modules had hard-coded ARN handling which assumed the use of the main partition. This causes problems for folks using Gov Cloud (and aws-cn) ISSUE TYPE Bugfix Pull Request COMPONENT NAME plugins/modules/batch_compute_environment.py plugins/modules/ec2_launch_template.py plugins/modules/elasticache_info.py plugins/modules/iam_group.py plugins/modules/iam_role.py plugins/modules/msk_config.py plugins/modules/redshift.py plugins/modules/sns_topic.py ADDITIONAL INFORMATION Reviewed-by: Alina Buzachis This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/25a636cefa0defcd1022c94aa2a38bdcf4763afd --- plugins/modules/iam_group.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index c4f77fde772..f88ebac120d 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -171,6 +171,7 @@ from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict +from ansible_collections.amazon.aws.plugins.module_utils.arn import validate_aws_arn from ansible_collections.amazon.aws.plugins.module_utils.botocore import is_boto3_error_code from ansible_collections.amazon.aws.plugins.module_utils.retries import AWSRetry @@ -203,7 +204,7 @@ def compare_group_members(current_group_members, new_group_members): def convert_friendly_names_to_arns(connection, module, policy_names): - if not any(not policy.startswith("arn:") for policy in policy_names if policy is not None): + if all(validate_aws_arn(policy, service="iam") for policy in policy_names if policy is not None): return policy_names allpolicies = {} paginator = connection.get_paginator("list_policies") @@ -213,7 +214,7 @@ def convert_friendly_names_to_arns(connection, module, policy_names): allpolicies[policy["PolicyName"]] = policy["Arn"] allpolicies[policy["Arn"]] = policy["Arn"] try: - return [allpolicies[policy] for policy in policy_names] + return [allpolicies[policy] for policy in policy_names if policy is not None] except KeyError as e: module.fail_json(msg="Couldn't find policy: " + str(e)) From c2012c8efa4c4d9759ffded3875a20f80c76854f Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Thu, 31 Aug 2023 17:58:59 +0200 Subject: [PATCH 22/29] Mass update of docs and tests (credentials/session tokens) (#1921) Mass update of docs and tests (credentials/session tokens) SUMMARY We had a cleanup of credentials/session parameters which included a batch of deprecations and renames. Ensure that all of our tests and docs are using the 'canonical' names ISSUE TYPE Docs Pull Request COMPONENT NAME plugins/modules/batch_compute_environment.py plugins/modules/cloudformation_exports_info.py plugins/modules/ec2_vpc_vpn.py plugins/modules/elasticache.py plugins/modules/elasticache_parameter_group.py plugins/modules/elasticache_snapshot.py plugins/modules/ses_rule_set.py plugins/modules/sts_assume_role.py plugins/modules/sts_session_token.py tests/integration ADDITIONAL INFORMATION See also ansible-collections/amazon.aws#1172 ansible-collections/amazon.aws#1714 Reviewed-by: Alina Buzachis This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/4a5b50e9b9c0d6ca1a1f802f3b03d4f503c16885 --- tests/integration/targets/iam_group/tasks/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/integration/targets/iam_group/tasks/main.yml b/tests/integration/targets/iam_group/tasks/main.yml index 65b441827ca..a1240846cb8 100644 --- a/tests/integration/targets/iam_group/tasks/main.yml +++ b/tests/integration/targets/iam_group/tasks/main.yml @@ -2,9 +2,9 @@ - name: set up aws connection info module_defaults: group/aws: - aws_access_key: "{{ aws_access_key }}" - aws_secret_key: "{{ aws_secret_key }}" - security_token: "{{ security_token | default(omit) }}" + access_key: "{{ aws_access_key }}" + secret_key: "{{ aws_secret_key }}" + session_token: "{{ security_token | default(omit) }}" region: "{{ aws_region }}" collections: - amazon.aws From f2a9d455073b8ce3a5bcc8e4f1b4414fb28b8c6c Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Wed, 13 Sep 2023 12:33:37 -0700 Subject: [PATCH 23/29] Update runtime --- meta/runtime.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/meta/runtime.yml b/meta/runtime.yml index c627df5be2b..007f42aaa72 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -9,10 +9,10 @@ action_groups: - aws_s3 - backup_plan - backup_plan_info - - backup_tag - - backup_tag_info - backup_selection - backup_selection_info + - backup_tag + - backup_tag_info - backup_vault - backup_vault_info - cloudformation @@ -20,12 +20,12 @@ action_groups: - cloudtrail - cloudtrail_info - cloudwatch_metric_alarm + - cloudwatch_metric_alarm_info - cloudwatchevent_rule - cloudwatchevent_rule - cloudwatchlogs_log_group - cloudwatchlogs_log_group_info - cloudwatchlogs_log_group_metric_filter - - cloudwatch_metric_alarm_info - ec2_ami - ec2_ami_info - ec2_eip @@ -68,6 +68,7 @@ action_groups: - elb_application_lb_info - elb_classic_lb - execute_lambda + - iam_group - iam_instance_profile - iam_instance_profile_info - iam_policy From a60dae3fe76eb2de24c8229cfde0dbf48ebd5953 Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Wed, 13 Sep 2023 12:40:09 -0700 Subject: [PATCH 24/29] iam_group migration --- changelogs/fragments/migrate_iam_group.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelogs/fragments/migrate_iam_group.yml diff --git a/changelogs/fragments/migrate_iam_group.yml b/changelogs/fragments/migrate_iam_group.yml new file mode 100644 index 00000000000..0fa4f7c0c36 --- /dev/null +++ b/changelogs/fragments/migrate_iam_group.yml @@ -0,0 +1,4 @@ +major_changes: +- iam_group - The module has been migrated from the ``community.aws`` collection. + Playbooks using the Fully Qualified Collection Name for this module should be updated + to use ``amazon.aws.iam_group`` (https://github.com/ansible-collections/amazon.aws/pull/1755). From 965bcd21f3324dfde0846cda6a2b747e83d80c6c Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Wed, 13 Sep 2023 13:07:57 -0700 Subject: [PATCH 25/29] update documentation bits from c.aws.iam_group to a.aws.iam_group --- plugins/modules/iam_group.py | 12 ++++++------ plugins/modules/iam_policy.py | 4 ++-- plugins/modules/iam_user.py | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index f88ebac120d..a1037d2f611 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -65,19 +65,19 @@ # Note: These examples do not set authentication details, see the AWS Guide for details. - name: Create a group - community.aws.iam_group: + amazon.aws.iam_group: name: testgroup1 state: present - name: Create a group and attach a managed policy using its ARN - community.aws.iam_group: + amazon.aws.iam_group: name: testgroup1 managed_policies: - arn:aws:iam::aws:policy/AmazonSNSFullAccess state: present - name: Create a group with users as members and attach a managed policy using its ARN - community.aws.iam_group: + amazon.aws.iam_group: name: testgroup1 managed_policies: - arn:aws:iam::aws:policy/AmazonSNSFullAccess @@ -87,13 +87,13 @@ state: present - name: Remove all managed policies from an existing group with an empty list - community.aws.iam_group: + amazon.aws.iam_group: name: testgroup1 state: present purge_policies: true - name: Remove all group members from an existing group - community.aws.iam_group: + amazon.aws.iam_group: name: testgroup1 managed_policies: - arn:aws:iam::aws:policy/AmazonSNSFullAccess @@ -101,7 +101,7 @@ state: present - name: Delete the group - community.aws.iam_group: + amazon.aws.iam_group: name: testgroup1 state: absent diff --git a/plugins/modules/iam_policy.py b/plugins/modules/iam_policy.py index 009dd542e28..71650ac9872 100644 --- a/plugins/modules/iam_policy.py +++ b/plugins/modules/iam_policy.py @@ -12,7 +12,7 @@ description: - Allows uploading or removing inline IAM policies for IAM users, groups or roles. - To administer managed policies please see M(community.aws.iam_user), M(community.aws.iam_role), - M(community.aws.iam_group) and M(community.aws.iam_managed_policy) + M(amazon.aws.iam_group) and M(community.aws.iam_managed_policy) - This module was originally added to C(community.aws) in release 1.0.0. options: iam_type: @@ -61,7 +61,7 @@ # Advanced example, create two new groups and add a READ-ONLY policy to both # groups. - name: Create Two Groups, Mario and Luigi - community.aws.iam_group: + amazon.aws.iam_group: name: "{{ item }}" state: present loop: diff --git a/plugins/modules/iam_user.py b/plugins/modules/iam_user.py index f4f1483cdde..75e35ad5198 100644 --- a/plugins/modules/iam_user.py +++ b/plugins/modules/iam_user.py @@ -11,7 +11,7 @@ short_description: Manage AWS IAM users description: - A module to manage AWS IAM users. - - The module does not manage groups that users belong to, groups memberships can be managed using M(community.aws.iam_group). + - The module does not manage groups that users belong to, groups memberships can be managed using M(amazon.aws.iam_group). - This module was originally added to C(community.aws) in release 1.0.0. author: - Josh Souza (@joshsouza) @@ -102,7 +102,7 @@ EXAMPLES = r""" # Note: These examples do not set authentication details, see the AWS Guide for details. # Note: This module does not allow management of groups that users belong to. -# Groups should manage their membership directly using community.aws.iam_group, +# Groups should manage their membership directly using amazon.aws.iam_group, # as users belong to them. - name: Create a user From bb926542425736a1ec69c54c7cfac05d7d2ae38b Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Wed, 13 Sep 2023 13:44:45 -0700 Subject: [PATCH 26/29] fix AnsibleAWSModule import --- plugins/modules/iam_group.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index a1037d2f611..e2f1c393b28 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -175,7 +175,7 @@ from ansible_collections.amazon.aws.plugins.module_utils.botocore import is_boto3_error_code from ansible_collections.amazon.aws.plugins.module_utils.retries import AWSRetry -from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.modules import AnsibleAWSModule def compare_attached_group_policies(current_attached_policies, new_attached_policies): From 93828d52ccf59abcc58639e3274452bba4143590 Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Fri, 15 Sep 2023 12:49:06 -0700 Subject: [PATCH 27/29] Update plugins/modules/iam_group.py Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com> --- plugins/modules/iam_group.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index e2f1c393b28..1d10003d8be 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -23,7 +23,7 @@ managed_policies: description: - A list of managed policy ARNs or friendly names to attach to the role. - - To embed an inline policy, use M(community.aws.iam_policy). + - To embed an inline policy, use M(amazon.aws.iam_policy). required: false type: list elements: str From 839b3c5b09e3a4b786c2ecbfb02e14a2af64b849 Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Mon, 18 Sep 2023 12:24:00 -0700 Subject: [PATCH 28/29] add note about version_added --- plugins/modules/iam_group.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index 1d10003d8be..4d193317fa3 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -7,10 +7,11 @@ DOCUMENTATION = r""" --- module: iam_group -version_added: 1.0.0 +version_added: 7.0.0 short_description: Manage AWS IAM groups description: - Manage AWS IAM groups. + - This module was originally added to C(community.aws) in release 1.0.0. author: - Nick Aslanidis (@naslanidis) - Maksym Postument (@infectsoldier) From 19c004ebb6ddec35d860d5a7ccb97148a9c95765 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Tue, 19 Sep 2023 15:49:44 +0200 Subject: [PATCH 29/29] use version_added_collection --- plugins/modules/iam_group.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index 4d193317fa3..d9262b424db 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -7,11 +7,11 @@ DOCUMENTATION = r""" --- module: iam_group -version_added: 7.0.0 +version_added: 1.0.0 +version_added_collection: community.aws short_description: Manage AWS IAM groups description: - Manage AWS IAM groups. - - This module was originally added to C(community.aws) in release 1.0.0. author: - Nick Aslanidis (@naslanidis) - Maksym Postument (@infectsoldier)