From 09db90db9e9458b7c74d97210d9847be483ed5bd Mon Sep 17 00:00:00 2001 From: jillr Date: Mon, 2 Mar 2020 19:25:18 +0000 Subject: [PATCH 01/30] 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 292a6548649e13bd33a845519284cb64589c828d Mon Sep 17 00:00:00 2001 From: jillr Date: Tue, 3 Mar 2020 19:43:21 +0000 Subject: [PATCH 02/30] 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 16e617df523b01491418fd54337e13cb22fc63f1 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/30] 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 5429b4ee4c14727933f18b6d971fe15dd0685b95 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/30] 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 5994509fb5cc2691f3a46d3009d2abca1f0ee2ea Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Wed, 17 Jun 2020 01:24:54 +0530 Subject: [PATCH 05/30] 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 5cf19b325a319a8002acbec710b172c059926984 Mon Sep 17 00:00:00 2001 From: flowerysong Date: Tue, 16 Jun 2020 19:30:00 -0400 Subject: [PATCH 06/30] 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 4448e72aae12d2f2e2f660b0b48d7efd9a3940ec 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/30] 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 3352bd4f54f9fca40a8a922cef1ef86e4ade58d6 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Thu, 16 Jul 2020 01:31:41 +0530 Subject: [PATCH 08/30] 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 5deed2a6d80dcab305d484e2c3676ae1e8fe1d39 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Fri, 5 Feb 2021 09:43:09 +0100 Subject: [PATCH 09/30] 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 0fdedce7c0a70a83fe8793d0c5b972f93740be8f Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sat, 13 Feb 2021 14:19:21 +0100 Subject: [PATCH 10/30] 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 c4e3d8b266bbbac7a46a10ece720b85f0b6ed12e Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Thu, 6 May 2021 21:01:46 +0200 Subject: [PATCH 11/30] 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 edd346917afe38e562416824ea347d346ae26a31 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Thu, 12 Aug 2021 21:01:04 +0200 Subject: [PATCH 12/30] 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 000ad141de494a0d49eec8096a80ae2a68dea352 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Fri, 22 Apr 2022 11:44:07 +0200 Subject: [PATCH 13/30] 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 1592aed9cdad5c25adeafe57e8e058c057a54878 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Wed, 28 Sep 2022 13:40:43 +0200 Subject: [PATCH 14/30] 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 3323d3c0155818d499244f6e6ac11de7d2c07f30 Mon Sep 17 00:00:00 2001 From: Alina Buzachis Date: Wed, 5 Oct 2022 17:04:40 +0200 Subject: [PATCH 15/30] 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 fb4f98bbe850852e8771c81d12b908f5b0891c68 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Wed, 2 Nov 2022 11:49:57 +0100 Subject: [PATCH 16/30] 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 799a424a9324829dd8e3ec32de78f2643184e7b8 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/30] 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 3ee3bcb6d18d16da9e395d29297487d76f4ff09a Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Wed, 8 Mar 2023 12:07:26 +0100 Subject: [PATCH 18/30] 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 f9f21f0fc7e3af3c61f7dd9c096939e146443293 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Wed, 26 Apr 2023 19:26:07 +0200 Subject: [PATCH 19/30] 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 66fe8ff7510ac10a3d45c23c4f9a5da6c1c91461 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Mon, 8 May 2023 19:21:22 +0200 Subject: [PATCH 20/30] 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 d69d747964baa6defb0518b97d194ded40e27685 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Mon, 26 Jun 2023 23:23:50 +0200 Subject: [PATCH 21/30] 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 d2b44b6f2397fe21848841574d382030e85eca5f Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Thu, 31 Aug 2023 17:58:59 +0200 Subject: [PATCH 22/30] 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 a64432496772347bbcff347e4c6cd3d9cade6fb0 Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Wed, 13 Sep 2023 12:33:37 -0700 Subject: [PATCH 23/30] 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 73279e8d2ed5a03d3f32fefe849d22f37fcb8385 Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Wed, 13 Sep 2023 12:40:09 -0700 Subject: [PATCH 24/30] 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 44ac7f9438ce834175c7b6defd76a2b9e3e7cbfe Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Wed, 13 Sep 2023 13:07:57 -0700 Subject: [PATCH 25/30] 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 53e11227120..16d12f058aa 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 1b0a17a9d2ff2b5c8871b091de77f6de55dbd703 Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Wed, 13 Sep 2023 13:44:45 -0700 Subject: [PATCH 26/30] 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 5d8bc1f606f2abe8c620d9c5fa9d3783d8aaa3cf Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Fri, 15 Sep 2023 12:49:06 -0700 Subject: [PATCH 27/30] 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 add96c02ffc8b43c0dd85eac9470a34ba4a11d95 Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Mon, 18 Sep 2023 12:24:00 -0700 Subject: [PATCH 28/30] 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 93c08a3751ce9428c3d5da3e410bfb340685d48e Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Tue, 19 Sep 2023 15:49:44 +0200 Subject: [PATCH 29/30] 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) From 66c213bdede82a086bae1cbf130d824ae089eef6 Mon Sep 17 00:00:00 2001 From: Alina Buzachis Date: Fri, 6 Oct 2023 14:22:27 +0200 Subject: [PATCH 30/30] Apply isort Signed-off-by: Alina Buzachis --- plugins/modules/iam_group.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/modules/iam_group.py b/plugins/modules/iam_group.py index d9262b424db..d8411191d88 100644 --- a/plugins/modules/iam_group.py +++ b/plugins/modules/iam_group.py @@ -174,9 +174,8 @@ 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 - from ansible_collections.amazon.aws.plugins.module_utils.modules import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.retries import AWSRetry def compare_attached_group_policies(current_attached_policies, new_attached_policies):