-
Notifications
You must be signed in to change notification settings - Fork 23.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New module: manage Amazon CloudFront origin access identities (cloud/amazon/cloudfront_origin_access_identity) #35540
Merged
Merged
Changes from 7 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
0e51578
moved from other PR
wilvk d526a53
bump version
wilvk ec4fdfa
fix description
wilvk a513b36
fix examples
wilvk 2f32e42
add note for no check mode support
wilvk 494329f
Remove trailing whitespace and fix documentation fragment usage
ryansb f61a59e
PEP8
ryansb 931aacc
Allow changed to be false if no changes are made when state is present
s-hertel 04e17bf
Fix doc
s-hertel 005dd5d
fix whitespace
s-hertel daea8e0
Fix metadata version
s-hertel 48647f5
Fix return documentation
s-hertel b4cfa51
fix doc aligment
wilvk 7d0971f
Add more return information
s-hertel d5d06e7
Add new module to CHANGELOG
s-hertel File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
256 changes: 256 additions & 0 deletions
256
lib/ansible/modules/cloud/amazon/cloudfront_origin_access_identity.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,256 @@ | ||
#!/usr/bin/python | ||
# Copyright (c) 2017 Ansible Project | ||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) | ||
|
||
ANSIBLE_METADATA = {'metadata_version': '1.0', | ||
'status': ['preview'], | ||
'supported_by': 'community'} | ||
|
||
DOCUMENTATION = ''' | ||
--- | ||
|
||
module: cloudfront_origin_access_identity | ||
|
||
short_description: create, update and delete origin access identities for a | ||
cloudfront distribution. | ||
|
||
description: | ||
- Allows for easy creation, updating and deletion of origin access | ||
identities. | ||
|
||
requirements: | ||
- boto3 >= 1.0.0 | ||
- python >= 2.6 | ||
|
||
version_added: "2.5" | ||
|
||
author: Willem van Ketwich (@wilvk) | ||
|
||
extends_documentation_fragment; | ||
- aws | ||
- ec2 | ||
|
||
options: | ||
state: | ||
description: If the named resource should exist. | ||
choices: | ||
- present | ||
- absent | ||
default: update_origin_access_identity | ||
origin_access_identity_id: | ||
description: | ||
- The origin_access_identity_id of the cloudfront distribution. | ||
required: false | ||
comment: | ||
description: | ||
- A comment to describe the cloudfront origin access identity. | ||
required: false | ||
caller_reference: | ||
description: | ||
- A unique identifier to reference the origin access identity by. | ||
required: false | ||
|
||
notes: | ||
- does not support check mode | ||
|
||
''' | ||
|
||
EXAMPLES = ''' | ||
|
||
- name: create an origin access identity | ||
cloudfront_origin_access_identity: | ||
state: present | ||
caller_reference: this is an example reference | ||
comment: this is an example comment | ||
|
||
- name: update an existing origin access identity using caller_reference as an identifier | ||
cloudfront_origin_access_identity: | ||
origin_access_identity_id: E17DRN9XUOAHZX | ||
caller_reference: this is an example reference | ||
comment: this is a new comment | ||
|
||
- name: delete an existing origin access identity using caller_reference as an identifier | ||
cloudfront_origin_access_identity: | ||
state: absent | ||
caller_reference: this is an example reference | ||
comment: this is a new comment | ||
|
||
''' | ||
|
||
RETURN = ''' | ||
|
||
cloud_front_origin_access_identity_config: | ||
description: describes a url specifying the origin access identity. | ||
returned: always | ||
type: complex | ||
contains: | ||
caller_reference: | ||
description: a caller reference for the oai | ||
returned: always | ||
type: str | ||
comment: | ||
description: a comment describing the oai | ||
returned: always | ||
type: str | ||
id: | ||
description: a unique identifier of the oai | ||
returned: always | ||
type: str | ||
s3_canonical_user_id: | ||
description: the cannonical user id of the user who created the oai | ||
returned: always | ||
type: str | ||
|
||
''' | ||
|
||
from ansible.module_utils.ec2 import get_aws_connection_info, ec2_argument_spec | ||
from ansible.module_utils.ec2 import boto3_conn | ||
from ansible.module_utils.aws.cloudfront_facts import CloudFrontFactsServiceManager | ||
from ansible.module_utils.ec2 import camel_dict_to_snake_dict | ||
from ansible.module_utils.aws.core import AnsibleAWSModule | ||
import datetime | ||
from functools import partial | ||
import json | ||
import traceback | ||
|
||
try: | ||
import botocore | ||
from botocore.signers import CloudFrontSigner | ||
from botocore.exceptions import ClientError, BotoCoreError | ||
except ImportError: | ||
pass # caught by imported AnsibleAWSModule | ||
|
||
|
||
class CloudFrontOriginAccessIdentityServiceManager(object): | ||
""" | ||
Handles cloudfront origin access identity service calls to aws | ||
""" | ||
|
||
def __init__(self, module): | ||
self.module = module | ||
self.create_client('cloudfront') | ||
|
||
def create_client(self, resource): | ||
try: | ||
region, ec2_url, aws_connect_kwargs = get_aws_connection_info(self.module, boto3=True) | ||
self.client = boto3_conn(self.module, conn_type='client', resource=resource, region=region, endpoint=ec2_url, **aws_connect_kwargs) | ||
except (ClientError, BotoCoreError) as e: | ||
self.module.fail_json_aws(e, msg="Unable to establish connection.") | ||
|
||
def create_origin_access_identity(self, caller_reference, comment): | ||
try: | ||
return self.client.create_cloud_front_origin_access_identity( | ||
CloudFrontOriginAccessIdentityConfig={ | ||
'CallerReference': caller_reference, | ||
'Comment': comment | ||
} | ||
) | ||
except (ClientError, BotoCoreError) as e: | ||
self.module.fail_json_aws(e, msg="Error creating cloud front origin access identity.") | ||
|
||
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) | ||
except (ClientError, BotoCoreError) as e: | ||
self.module.fail_json_aws(e, msg="Error updating Origin Access Identity.") | ||
|
||
def update_origin_access_identity(self, caller_reference, comment, origin_access_identity_id, e_tag): | ||
try: | ||
return self.client.update_cloud_front_origin_access_identity( | ||
CloudFrontOriginAccessIdentityConfig={ | ||
'CallerReference': caller_reference, | ||
'Comment': comment | ||
}, | ||
Id=origin_access_identity_id, | ||
IfMatch=e_tag, | ||
) | ||
except (ClientError, BotoCoreError) as e: | ||
self.module.fail_json_aws(e, msg="Error updating Origin Access Identity.") | ||
|
||
|
||
class CloudFrontOriginAccessIdentityValidationManager(object): | ||
""" | ||
Manages Cloudfront Origin Access Identities | ||
""" | ||
|
||
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): | ||
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: | ||
self.module.fail_json_aws(e, msg="Error getting etag from origin_access_identity.") | ||
|
||
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.") | ||
|
||
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 main(): | ||
argument_spec = ec2_argument_spec() | ||
|
||
argument_spec.update(dict( | ||
state=dict(choices=['present', 'absent'], default='present'), | ||
origin_access_identity_id=dict(), | ||
caller_reference=dict(), | ||
comment=dict(), | ||
)) | ||
|
||
result = {} | ||
e_tag = None | ||
changed = False | ||
|
||
module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=False) | ||
service_mgr = CloudFrontOriginAccessIdentityServiceManager(module) | ||
validation_mgr = CloudFrontOriginAccessIdentityValidationManager(module) | ||
|
||
state = module.params.get('state') | ||
caller_reference = module.params.get('caller_reference') | ||
|
||
comment = module.params.get('comment') | ||
origin_access_identity_id = module.params.get('origin_access_identity_id') | ||
|
||
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: | ||
result = service_mgr.update_origin_access_identity(caller_reference, comment, origin_access_identity_id, e_tag) | ||
else: | ||
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 | ||
|
||
result.pop('ResponseMetadata', None) | ||
|
||
module.exit_json(changed=changed, **camel_dict_to_snake_dict(result)) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If checkmode isn't supported please add this in the
notes:
section inDOCUMENTATION
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have added to documentation under notes: section. let me know if this is incorrect
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, appologies, I think this needs to be a list