Skip to content

Commit

Permalink
update module using module_utils/cloudfront_facts.py (ansible-collect…
Browse files Browse the repository at this point in the history
…ions#1596)

update module using module_utils/cloudfront_facts.py

Depends-On: ansible-collections#1265
SUMMARY

update cloudfront_* modules, fix some bugs and add integration tests

ISSUE TYPE


Feature Pull Request

Reviewed-by: Alina Buzachis <None>
Reviewed-by: Bikouo Aubin <None>
  • Loading branch information
abikouo authored Feb 1, 2023
1 parent c7c6800 commit dbb482c
Show file tree
Hide file tree
Showing 19 changed files with 454 additions and 432 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
minor_changes:
- minor code fixes and enable integration tests for modules cloudfront_distribution, cloudfront_invalidation and cloudfront_origin_access_identity (https://github.com/ansible-collections/community.aws/pull/1596).
12 changes: 6 additions & 6 deletions plugins/modules/cloudfront_distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -2105,12 +2105,12 @@ def validate_attribute_with_allowed_values(self, attribute, attribute_name, allo

def validate_distribution_from_caller_reference(self, caller_reference):
try:
distributions = self.__cloudfront_facts_mgr.list_distributions(False)
distributions = self.__cloudfront_facts_mgr.list_distributions(keyed=False)
distribution_name = 'Distribution'
distribution_config_name = 'DistributionConfig'
distribution_ids = [dist.get('Id') for dist in distributions]
for distribution_id in distribution_ids:
distribution = self.__cloudfront_facts_mgr.get_distribution(distribution_id)
distribution = self.__cloudfront_facts_mgr.get_distribution(id=distribution_id)
if distribution is not None:
distribution_config = distribution[distribution_name].get(distribution_config_name)
if distribution_config is not None and distribution_config.get('CallerReference') == caller_reference:
Expand All @@ -2128,13 +2128,13 @@ def validate_distribution_from_aliases_caller_reference(self, distribution_id, a
if aliases and distribution_id is None:
distribution_id = self.validate_distribution_id_from_alias(aliases)
if distribution_id:
return self.__cloudfront_facts_mgr.get_distribution(distribution_id)
return self.__cloudfront_facts_mgr.get_distribution(id=distribution_id)
return None
except Exception as e:
self.module.fail_json_aws(e, msg="Error validating distribution_id from alias, aliases and caller reference")

def validate_distribution_id_from_alias(self, aliases):
distributions = self.__cloudfront_facts_mgr.list_distributions(False)
distributions = self.__cloudfront_facts_mgr.list_distributions(keyed=False)
if distributions:
for distribution in distributions:
distribution_aliases = distribution.get('Aliases', {}).get('Items', [])
Expand Down Expand Up @@ -2253,12 +2253,12 @@ def main():
if not (update or create or delete):
module.exit_json(changed=False)

config = {}
if update or delete:
config = distribution['Distribution']['DistributionConfig']
e_tag = distribution['ETag']
distribution_id = distribution['Distribution']['Id']
else:
config = dict()

if update:
config = camel_dict_to_snake_dict(config, reversible=True)

Expand Down
306 changes: 26 additions & 280 deletions plugins/modules/cloudfront_distribution_info.py

Large diffs are not rendered by default.

38 changes: 14 additions & 24 deletions plugins/modules/cloudfront_invalidation.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,10 @@ class CloudFrontInvalidationServiceManager(object):
Handles CloudFront service calls to AWS for invalidations
"""

def __init__(self, module):
def __init__(self, module, cloudfront_facts_mgr):
self.module = module
self.client = module.client('cloudfront')
self.__cloudfront_facts_mgr = cloudfront_facts_mgr

def create_invalidation(self, distribution_id, invalidation_batch):
current_invalidation_response = self.get_invalidation(distribution_id, invalidation_batch['CallerReference'])
Expand All @@ -174,38 +175,26 @@ def create_invalidation(self, distribution_id, invalidation_batch):
self.module.fail_json_aws(e, msg="Error creating CloudFront invalidations.")

def get_invalidation(self, distribution_id, caller_reference):
current_invalidation = {}
# find all invalidations for the distribution
try:
paginator = self.client.get_paginator('list_invalidations')
invalidations = paginator.paginate(DistributionId=distribution_id).build_full_result().get('InvalidationList', {}).get('Items', [])
invalidation_ids = [inv['Id'] for inv in invalidations]
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
self.module.fail_json_aws(e, msg="Error listing CloudFront invalidations.")
invalidations = self.__cloudfront_facts_mgr.list_invalidations(distribution_id=distribution_id)

# check if there is an invalidation with the same caller reference
for inv_id in invalidation_ids:
try:
invalidation = self.client.get_invalidation(DistributionId=distribution_id, Id=inv_id)['Invalidation']
caller_ref = invalidation.get('InvalidationBatch', {}).get('CallerReference')
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
self.module.fail_json_aws(e, msg="Error getting CloudFront invalidation {0}".format(inv_id))
if caller_ref == caller_reference:
current_invalidation = invalidation
break

current_invalidation.pop('ResponseMetadata', None)
return current_invalidation
for invalidation in invalidations:
invalidation_info = self.__cloudfront_facts_mgr.get_invalidation(distribution_id=distribution_id, id=invalidation['Id'])
if invalidation_info.get('InvalidationBatch', {}).get('CallerReference') == caller_reference:
invalidation_info.pop('ResponseMetadata', None)
return invalidation_info
return {}


class CloudFrontInvalidationValidationManager(object):
"""
Manages CloudFront validations for invalidation batches
"""

def __init__(self, module):
def __init__(self, module, cloudfront_facts_mgr):
self.module = module
self.__cloudfront_facts_mgr = CloudFrontFactsServiceManager(module)
self.__cloudfront_facts_mgr = cloudfront_facts_mgr

def validate_distribution_id(self, distribution_id, alias):
try:
Expand Down Expand Up @@ -248,8 +237,9 @@ def main():

module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=False, mutually_exclusive=[['distribution_id', 'alias']])

validation_mgr = CloudFrontInvalidationValidationManager(module)
service_mgr = CloudFrontInvalidationServiceManager(module)
cloudfront_facts_mgr = CloudFrontFactsServiceManager(module)
validation_mgr = CloudFrontInvalidationValidationManager(module, cloudfront_facts_mgr)
service_mgr = CloudFrontInvalidationServiceManager(module, cloudfront_facts_mgr)

caller_reference = module.params.get('caller_reference')
distribution_id = module.params.get('distribution_id')
Expand Down
68 changes: 42 additions & 26 deletions plugins/modules/cloudfront_origin_access_identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@

from ansible_collections.amazon.aws.plugins.module_utils.cloudfront_facts import CloudFrontFactsServiceManager
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


class CloudFrontOriginAccessIdentityServiceManager(object):
Expand All @@ -151,9 +152,10 @@ def create_origin_access_identity(self, caller_reference, comment):

def delete_origin_access_identity(self, origin_access_identity_id, e_tag):
try:
return self.client.delete_cloud_front_origin_access_identity(Id=origin_access_identity_id, IfMatch=e_tag)
result = self.client.delete_cloud_front_origin_access_identity(Id=origin_access_identity_id, IfMatch=e_tag)
return result, True
except (ClientError, BotoCoreError) as e:
self.module.fail_json_aws(e, msg="Error updating Origin Access Identity.")
self.module.fail_json_aws(e, msg="Error deleting Origin Access Identity.")

def update_origin_access_identity(self, caller_reference, comment, origin_access_identity_id, e_tag):
changed = False
Expand Down Expand Up @@ -194,34 +196,45 @@ def __init__(self, module):
self.module = module
self.__cloudfront_facts_mgr = CloudFrontFactsServiceManager(module)

def validate_etag_from_origin_access_identity_id(self, origin_access_identity_id):
def describe_origin_access_identity(self, origin_access_identity_id, fail_if_missing=True):
try:
if origin_access_identity_id is None:
return
oai = self.__cloudfront_facts_mgr.get_origin_access_identity(origin_access_identity_id)
if oai is not None:
return oai.get('ETag')
except (ClientError, BotoCoreError) as e:
return self.__cloudfront_facts_mgr.get_origin_access_identity(id=origin_access_identity_id, fail_if_error=False)
except is_boto3_error_code('NoSuchCloudFrontOriginAccessIdentity') as e: # pylint: disable=duplicate-except
if fail_if_missing:
self.module.fail_json_aws(e, msg="Error getting etag from origin_access_identity.")
return {}
except (ClientError, BotoCoreError) as e: # pylint: disable=duplicate-except
self.module.fail_json_aws(e, msg="Error getting etag from origin_access_identity.")

def validate_etag_from_origin_access_identity_id(self, origin_access_identity_id, fail_if_missing):
oai = self.describe_origin_access_identity(origin_access_identity_id, fail_if_missing)
if oai is not None:
return oai.get('ETag')

def validate_origin_access_identity_id_from_caller_reference(
self, caller_reference):
try:
origin_access_identities = self.__cloudfront_facts_mgr.list_origin_access_identities()
origin_origin_access_identity_ids = [oai.get('Id') for oai in origin_access_identities]
for origin_access_identity_id in origin_origin_access_identity_ids:
oai_config = (self.__cloudfront_facts_mgr.get_origin_access_identity_config(origin_access_identity_id))
temp_caller_reference = oai_config.get('CloudFrontOriginAccessIdentityConfig').get('CallerReference')
if temp_caller_reference == caller_reference:
return origin_access_identity_id
except (ClientError, BotoCoreError) as e:
self.module.fail_json_aws(e, msg="Error getting Origin Access Identity from caller_reference.")
origin_access_identities = self.__cloudfront_facts_mgr.list_origin_access_identities()
origin_origin_access_identity_ids = [oai.get('Id') for oai in origin_access_identities]
for origin_access_identity_id in origin_origin_access_identity_ids:
oai_config = (self.__cloudfront_facts_mgr.get_origin_access_identity_config(id=origin_access_identity_id))
temp_caller_reference = oai_config.get('CloudFrontOriginAccessIdentityConfig').get('CallerReference')
if temp_caller_reference == caller_reference:
return origin_access_identity_id

def validate_comment(self, comment):
if comment is None:
return "origin access identity created by Ansible with datetime " + datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f')
return comment

def validate_caller_reference_from_origin_access_identity_id(self, origin_access_identity_id, caller_reference):
if caller_reference is None:
if origin_access_identity_id is None:
return datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f')
oai = self.describe_origin_access_identity(origin_access_identity_id, fail_if_missing=True)
origin_access_config = oai.get('CloudFrontOriginAccessIdentity', {}).get('CloudFrontOriginAccessIdentityConfig', {})
return origin_access_config.get('CallerReference')
return caller_reference


def main():
argument_spec = dict(
Expand All @@ -248,18 +261,21 @@ def main():
if origin_access_identity_id is None and caller_reference is not None:
origin_access_identity_id = validation_mgr.validate_origin_access_identity_id_from_caller_reference(caller_reference)

e_tag = validation_mgr.validate_etag_from_origin_access_identity_id(origin_access_identity_id)
comment = validation_mgr.validate_comment(comment)

if state == 'present':
if origin_access_identity_id is not None and e_tag is not None:
comment = validation_mgr.validate_comment(comment)
caller_reference = validation_mgr.validate_caller_reference_from_origin_access_identity_id(origin_access_identity_id, caller_reference)
if origin_access_identity_id is not None:
e_tag = validation_mgr.validate_etag_from_origin_access_identity_id(origin_access_identity_id, True)
# update cloudfront origin access identity
result, changed = service_mgr.update_origin_access_identity(caller_reference, comment, origin_access_identity_id, e_tag)
else:
# create cloudfront origin access identity
result = service_mgr.create_origin_access_identity(caller_reference, comment)
changed = True
elif state == 'absent' and origin_access_identity_id is not None and e_tag is not None:
result = service_mgr.delete_origin_access_identity(origin_access_identity_id, e_tag)
changed = True
else:
e_tag = validation_mgr.validate_etag_from_origin_access_identity_id(origin_access_identity_id, False)
if e_tag:
result, changed = service_mgr.delete_origin_access_identity(origin_access_identity_id, e_tag)

result.pop('ResponseMetadata', None)

Expand Down
3 changes: 0 additions & 3 deletions tests/integration/targets/cloudfront_distribution/aliases
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
# reason: broken
disabled

cloud/aws
Loading

0 comments on commit dbb482c

Please sign in to comment.