[cloud] Add encryption support to efs module (#32815)
* Add encryption support to efs module * Update the exception handling in AWS EFS module
This commit is contained in:
parent
f0cf1b35d5
commit
2616f9d713
1 changed files with 86 additions and 24 deletions
|
@ -23,6 +23,29 @@ author:
|
|||
- "Ryan Sydnor (@ryansydnor)"
|
||||
- "Artem Kazakov (@akazakov)"
|
||||
options:
|
||||
encrypt:
|
||||
description:
|
||||
- A boolean value that, if true, creates an encrypted file system. This can not be modfied after the file
|
||||
system is created.
|
||||
required: false
|
||||
default: false
|
||||
choices: ['yes', 'no']
|
||||
version_added: 2.5
|
||||
kms_key_id:
|
||||
description:
|
||||
- The id of the AWS KMS CMK that will be used to protect the encrypted file system. This parameter is only
|
||||
required if you want to use a non-default CMK. If this parameter is not specified, the default CMK for
|
||||
Amazon EFS is used. The key id can be Key ID, Key ID ARN, Key Alias or Key Alias ARN.
|
||||
required: false
|
||||
version_added: 2.5
|
||||
purge_tags:
|
||||
description:
|
||||
- If yes, existing tags will be purged from the resource to match exactly what is defined by I(tags) parameter. If the I(tags) parameter
|
||||
is not set then tags will not be modified.
|
||||
required: false
|
||||
default: yes
|
||||
choices: [ 'yes', 'no' ]
|
||||
version_added: 2.5
|
||||
state:
|
||||
description:
|
||||
- Allows to create, search and destroy Amazon EFS file system
|
||||
|
@ -74,6 +97,7 @@ options:
|
|||
default: 0
|
||||
extends_documentation_fragment:
|
||||
- aws
|
||||
- ec2
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
|
@ -193,15 +217,18 @@ tags:
|
|||
|
||||
from time import sleep
|
||||
from time import time as timestamp
|
||||
import traceback
|
||||
|
||||
try:
|
||||
from botocore.exceptions import ClientError
|
||||
from botocore.exceptions import ClientError, BotoCoreError
|
||||
except ImportError as e:
|
||||
pass # Taken care of by ec2.HAS_BOTO3
|
||||
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ec2 import (HAS_BOTO3, boto3_conn, camel_dict_to_snake_dict,
|
||||
ec2_argument_spec, get_aws_connection_info)
|
||||
ec2_argument_spec, get_aws_connection_info, ansible_dict_to_boto3_tag_list,
|
||||
compare_aws_tags, boto3_tag_list_to_ansible_dict)
|
||||
|
||||
|
||||
def _index_by_key(key, items):
|
||||
|
@ -221,6 +248,8 @@ class EFSConnection(object):
|
|||
self.connection = boto3_conn(module, conn_type='client',
|
||||
resource='efs', region=region,
|
||||
**aws_connect_params)
|
||||
|
||||
self.module = module
|
||||
self.region = region
|
||||
self.wait = module.params.get('wait')
|
||||
self.wait_timeout = module.params.get('wait_timeout')
|
||||
|
@ -256,12 +285,8 @@ class EFSConnection(object):
|
|||
"""
|
||||
Returns tag list for selected instance of EFS
|
||||
"""
|
||||
tags = iterate_all(
|
||||
'Tags',
|
||||
self.connection.describe_tags,
|
||||
**kwargs
|
||||
)
|
||||
return dict((tag['Key'], tag['Value']) for tag in tags)
|
||||
tags = self.connection.describe_tags(**kwargs)['Tags']
|
||||
return tags
|
||||
|
||||
def get_mount_targets(self, **kwargs):
|
||||
"""
|
||||
|
@ -331,19 +356,34 @@ class EFSConnection(object):
|
|||
|
||||
return list(targets)
|
||||
|
||||
def create_file_system(self, name, performance_mode):
|
||||
def create_file_system(self, name, performance_mode, encrypt, kms_key_id):
|
||||
"""
|
||||
Creates new filesystem with selected name
|
||||
"""
|
||||
changed = False
|
||||
state = self.get_file_system_state(name)
|
||||
params = {}
|
||||
params['CreationToken'] = name
|
||||
params['PerformanceMode'] = performance_mode
|
||||
if encrypt:
|
||||
params['Encrypted'] = encrypt
|
||||
if kms_key_id is not None:
|
||||
params['KmsKeyId'] = kms_key_id
|
||||
|
||||
if state in [self.STATE_DELETING, self.STATE_DELETED]:
|
||||
wait_for(
|
||||
lambda: self.get_file_system_state(name),
|
||||
self.STATE_DELETED
|
||||
)
|
||||
self.connection.create_file_system(CreationToken=name, PerformanceMode=performance_mode)
|
||||
changed = True
|
||||
try:
|
||||
self.connection.create_file_system(**params)
|
||||
changed = True
|
||||
except ClientError as e:
|
||||
self.module.fail_json(msg="Unable to create file system: {0}".format(to_native(e)),
|
||||
exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response))
|
||||
except BotoCoreError as e:
|
||||
self.module.fail_json(msg="Unable to create file system: {0}".format(to_native(e)),
|
||||
exception=traceback.format_exc())
|
||||
|
||||
# we always wait for the state to be available when creating.
|
||||
# if we try to take any actions on the file system before it's available
|
||||
|
@ -356,7 +396,7 @@ class EFSConnection(object):
|
|||
|
||||
return changed
|
||||
|
||||
def converge_file_system(self, name, tags, targets):
|
||||
def converge_file_system(self, name, tags, purge_tags, targets):
|
||||
"""
|
||||
Change attributes (mount targets and tags) of filesystem by name
|
||||
"""
|
||||
|
@ -364,20 +404,36 @@ class EFSConnection(object):
|
|||
fs_id = self.get_file_system_id(name)
|
||||
|
||||
if tags is not None:
|
||||
tags_to_create, _, tags_to_delete = dict_diff(self.get_tags(FileSystemId=fs_id), tags)
|
||||
tags_need_modify, tags_to_delete = compare_aws_tags(boto3_tag_list_to_ansible_dict(self.get_tags(FileSystemId=fs_id)), tags, purge_tags)
|
||||
|
||||
if tags_to_delete:
|
||||
self.connection.delete_tags(
|
||||
FileSystemId=fs_id,
|
||||
TagKeys=[item[0] for item in tags_to_delete]
|
||||
)
|
||||
try:
|
||||
self.connection.delete_tags(
|
||||
FileSystemId=fs_id,
|
||||
TagKeys=tags_to_delete
|
||||
)
|
||||
except ClientError as e:
|
||||
self.module.fail_json(msg="Unable to delete tags: {0}".format(to_native(e)),
|
||||
exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response))
|
||||
except BotoCoreError as e:
|
||||
self.module.fail_json(msg="Unable to delete tags: {0}".format(to_native(e)),
|
||||
exception=traceback.format_exc())
|
||||
|
||||
result = True
|
||||
|
||||
if tags_to_create:
|
||||
self.connection.create_tags(
|
||||
FileSystemId=fs_id,
|
||||
Tags=[{'Key': item[0], 'Value': item[1]} for item in tags_to_create]
|
||||
)
|
||||
if tags_need_modify:
|
||||
try:
|
||||
self.connection.create_tags(
|
||||
FileSystemId=fs_id,
|
||||
Tags=ansible_dict_to_boto3_tag_list(tags_need_modify)
|
||||
)
|
||||
except ClientError as e:
|
||||
self.module.fail_json(msg="Unable to create tags: {0}".format(to_native(e)),
|
||||
exception=traceback.format_exc(), **camel_dict_to_snake_dict(e.response))
|
||||
except BotoCoreError as e:
|
||||
self.module.fail_json(msg="Unable to create tags: {0}".format(to_native(e)),
|
||||
exception=traceback.format_exc())
|
||||
|
||||
result = True
|
||||
|
||||
if targets is not None:
|
||||
|
@ -561,7 +617,10 @@ def main():
|
|||
"""
|
||||
argument_spec = ec2_argument_spec()
|
||||
argument_spec.update(dict(
|
||||
encrypt=dict(required=False, type="bool", default=False),
|
||||
state=dict(required=False, type='str', choices=["present", "absent"], default="present"),
|
||||
kms_key_id=dict(required=False, type='str', default=None),
|
||||
purge_tags=dict(default=True, type='bool'),
|
||||
id=dict(required=False, type='str', default=None),
|
||||
name=dict(required=False, type='str', default=None),
|
||||
tags=dict(required=False, type="dict", default={}),
|
||||
|
@ -592,7 +651,10 @@ def main():
|
|||
'general_purpose': 'generalPurpose',
|
||||
'max_io': 'maxIO'
|
||||
}
|
||||
encrypt = module.params.get('encrypt')
|
||||
kms_key_id = module.params.get('kms_key_id')
|
||||
performance_mode = performance_mode_translations[module.params.get('performance_mode')]
|
||||
purge_tags = module.params.get('purge_tags')
|
||||
changed = False
|
||||
|
||||
state = str(module.params.get('state')).lower()
|
||||
|
@ -601,8 +663,8 @@ def main():
|
|||
if not name:
|
||||
module.fail_json(msg='Name parameter is required for create')
|
||||
|
||||
changed = connection.create_file_system(name, performance_mode)
|
||||
changed = connection.converge_file_system(name=name, tags=tags, targets=targets) or changed
|
||||
changed = connection.create_file_system(name, performance_mode, encrypt, kms_key_id)
|
||||
changed = connection.converge_file_system(name=name, tags=tags, purge_tags=purge_tags, targets=targets) or changed
|
||||
result = first_or_default(connection.get_file_systems(CreationToken=name))
|
||||
|
||||
elif state == 'absent':
|
||||
|
|
Loading…
Reference in a new issue