Skip to content

Commit

Permalink
Bulk migration to fail_json_aws (ansible-collections#361)
Browse files Browse the repository at this point in the history
* Split imports and sort
* Move camel_dict_to_snake_dict imports to ansible.module_utils.common.dict_transformations
* Cleanup unused imports
* Bulk migration to fail_json_aws
* Changelog

This commit was initially merged in https://github.com/ansible-collections/community.aws
See: ansible-collections/community.aws@6c88315
  • Loading branch information
tremble authored and alinabuzachis committed Oct 6, 2023
1 parent b514417 commit 24850bd
Showing 1 changed file with 39 additions and 75 deletions.
114 changes: 39 additions & 75 deletions plugins/modules/iam_managed_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,17 @@
'''

import json
import traceback

try:
import botocore
except ImportError:
pass # Handled by AnsibleAWSModule

from ansible.module_utils._text import to_native
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.ec2 import AWSRetry
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 compare_policies


Expand All @@ -154,10 +153,8 @@ def list_policies_with_backoff(iam):
def get_policy_by_name(module, iam, name):
try:
response = list_policies_with_backoff(iam)
except botocore.exceptions.ClientError as e:
module.fail_json(msg="Couldn't list policies: %s" % str(e),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't list policies")
for policy in response['Policies']:
if policy['PolicyName'] == name:
return policy
Expand All @@ -168,36 +165,28 @@ def delete_oldest_non_default_version(module, iam, policy):
try:
versions = [v for v in iam.list_policy_versions(PolicyArn=policy['Arn'])['Versions']
if not v['IsDefaultVersion']]
except botocore.exceptions.ClientError as e:
module.fail_json(msg="Couldn't list policy versions: %s" % str(e),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't list policy versions")
versions.sort(key=lambda v: v['CreateDate'], reverse=True)
for v in versions[-1:]:
try:
iam.delete_policy_version(PolicyArn=policy['Arn'], VersionId=v['VersionId'])
except botocore.exceptions.ClientError as e:
module.fail_json(msg="Couldn't delete policy version: %s" % str(e),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't delete policy version")


# This needs to return policy_version, changed
def get_or_create_policy_version(module, iam, policy, policy_document):
try:
versions = iam.list_policy_versions(PolicyArn=policy['Arn'])['Versions']
except botocore.exceptions.ClientError as e:
module.fail_json(msg="Couldn't list policy versions: %s" % str(e),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't list policy versions")
for v in versions:
try:
document = iam.get_policy_version(PolicyArn=policy['Arn'],
VersionId=v['VersionId'])['PolicyVersion']['Document']
except botocore.exceptions.ClientError as e:
module.fail_json(msg="Couldn't get policy version %s: %s" % (v['VersionId'], str(e)),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't get policy version {0}".format(v['VersionId']))
# If the current policy matches the existing one
if not compare_policies(document, json.loads(to_native(policy_document))):
return v, False
Expand All @@ -217,23 +206,19 @@ def get_or_create_policy_version(module, iam, policy, policy_document):
try:
version = iam.create_policy_version(PolicyArn=policy['Arn'], PolicyDocument=policy_document)['PolicyVersion']
return version, True
except botocore.exceptions.ClientError as second_e:
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as second_e:
e = second_e
# Handle both when the exception isn't LimitExceeded or
# the second attempt still failed
module.fail_json(msg="Couldn't create policy version: %s" % str(e),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
module.fail_json_aws(e, msg="Couldn't create policy version")


def set_if_default(module, iam, policy, policy_version, is_default):
if is_default and not policy_version['IsDefaultVersion']:
try:
iam.set_default_policy_version(PolicyArn=policy['Arn'], VersionId=policy_version['VersionId'])
except botocore.exceptions.ClientError as e:
module.fail_json(msg="Couldn't set default policy version: %s" % str(e),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't set default policy version")
return True
return False

Expand All @@ -243,50 +228,38 @@ def set_if_only(module, iam, policy, policy_version, is_only):
try:
versions = [v for v in iam.list_policy_versions(PolicyArn=policy['Arn'])[
'Versions'] if not v['IsDefaultVersion']]
except botocore.exceptions.ClientError as e:
module.fail_json(msg="Couldn't list policy versions: %s" % str(e),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't list policy versions")
for v in versions:
try:
iam.delete_policy_version(PolicyArn=policy['Arn'], VersionId=v['VersionId'])
except botocore.exceptions.ClientError as e:
module.fail_json(msg="Couldn't delete policy version: %s" % str(e),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't delete policy version")
return len(versions) > 0
return False


def detach_all_entities(module, iam, policy, **kwargs):
try:
entities = iam.list_entities_for_policy(PolicyArn=policy['Arn'], **kwargs)
except botocore.exceptions.ClientError as e:
module.fail_json(msg="Couldn't detach list entities for policy %s: %s" % (policy['PolicyName'], str(e)),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't detach list entities for policy {0}".format(policy['PolicyName']))

for g in entities['PolicyGroups']:
try:
iam.detach_group_policy(PolicyArn=policy['Arn'], GroupName=g['GroupName'])
except botocore.exceptions.ClientError as e:
module.fail_json(msg="Couldn't detach group policy %s: %s" % (g['GroupName'], str(e)),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't detach group policy {0}".format(g['GroupName']))
for u in entities['PolicyUsers']:
try:
iam.detach_user_policy(PolicyArn=policy['Arn'], UserName=u['UserName'])
except botocore.exceptions.ClientError as e:
module.fail_json(msg="Couldn't detach user policy %s: %s" % (u['UserName'], str(e)),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't detach user policy {0}".format(u['UserName']))
for r in entities['PolicyRoles']:
try:
iam.detach_role_policy(PolicyArn=policy['Arn'], RoleName=r['RoleName'])
except botocore.exceptions.ClientError as e:
module.fail_json(msg="Couldn't detach role policy %s: %s" % (r['RoleName'], str(e)),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't detach role policy {0}".format(r['RoleName']))
if entities['IsTruncated']:
detach_all_entities(module, iam, policy, marker=entities['Marker'])

Expand Down Expand Up @@ -330,10 +303,8 @@ def main():
try:
rvalue = iam.create_policy(PolicyName=name, Path='/',
PolicyDocument=policy, Description=description)
except Exception as e:
module.fail_json(msg="Couldn't create policy %s: %s" % (name, to_native(e)),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't create policy {0}".format(name))

module.exit_json(changed=True, policy=camel_dict_to_snake_dict(rvalue['Policy']))
else:
Expand All @@ -344,10 +315,8 @@ def main():
if changed:
try:
p = iam.get_policy(PolicyArn=p['Arn'])['Policy']
except Exception as e:
module.fail_json(msg="Couldn't get policy: %s" % to_native(e),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json(msg="Couldn't get policy")

module.exit_json(changed=changed, policy=camel_dict_to_snake_dict(p))
else:
Expand All @@ -358,26 +327,21 @@ def main():
# Delete Versions
try:
versions = iam.list_policy_versions(PolicyArn=p['Arn'])['Versions']
except botocore.exceptions.ClientError as e:
module.fail_json(msg="Couldn't list policy versions: %s" % to_native(e),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't list policy versions")
for v in versions:
if not v['IsDefaultVersion']:
try:
iam.delete_policy_version(PolicyArn=p['Arn'], VersionId=v['VersionId'])
except botocore.exceptions.ClientError as e:
module.fail_json(msg="Couldn't delete policy version %s: %s" %
(v['VersionId'], to_native(e)),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(
e, msg="Couldn't delete policy version {0}".format(v['VersionId']))
# Delete policy
try:
iam.delete_policy(PolicyArn=p['Arn'])
except Exception as e:
module.fail_json(msg="Couldn't delete policy %s: %s" % (p['PolicyName'], to_native(e)),
exception=traceback.format_exc(),
**camel_dict_to_snake_dict(e.response))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Couldn't delete policy {0}".format(p['PolicyName']))

# This is the one case where we will return the old policy
module.exit_json(changed=True, policy=camel_dict_to_snake_dict(p))
else:
Expand Down

0 comments on commit 24850bd

Please sign in to comment.