Skip to content

Commit

Permalink
Add tag support for redshift module (ansible-collections#34)
Browse files Browse the repository at this point in the history
* tag support for redshift module
* add changelog
* Switch to using module_defaults for the tests
  • Loading branch information
rafaeldriutti authored Oct 21, 2020
1 parent 43c8e36 commit f25cfeb
Showing 1 changed file with 74 additions and 11 deletions.
85 changes: 74 additions & 11 deletions redshift.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,22 @@
- Whether the cluster should have enhanced VPC routing enabled.
default: false
type: bool
tags:
description:
- A dictionary of resource tags.
type: dict
aliases: ['resource_tags']
version_added: "1.3.0"
purge_tags:
description:
- Purge existing tags that are not found in the cluster
type: bool
default: 'yes'
version_added: "1.3.0"
requirements: [ 'boto3' ]
extends_documentation_fragment:
- amazon.aws.aws
- amazon.aws.ec2
- amazon.aws.aws
- amazon.aws.ec2
'''

EXAMPLES = r'''
Expand Down Expand Up @@ -251,17 +262,52 @@
description: status of the enhanced vpc routing feature.
returned: success
type: bool
tags:
description: aws tags for cluster.
returned: success
type: dict
'''

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

from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import snake_dict_to_camel_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
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ansible_dict_to_boto3_tag_list
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_tag_list_to_ansible_dict
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import compare_aws_tags
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import snake_dict_to_camel_dict
from ansible_collections.amazon.aws.plugins.module_utils.iam import get_aws_account_id


def _ensure_tags(redshift, identifier, existing_tags, module):
"""Compares and update resource tags"""

account_id = get_aws_account_id(module)
region = module.params.get('region')
resource_arn = "arn:aws:redshift:{0}:{1}:cluster:{2}" .format(region, account_id, identifier)
tags = module.params.get('tags')
purge_tags = module.params.get('purge_tags')

tags_to_add, tags_to_remove = compare_aws_tags(boto3_tag_list_to_ansible_dict(existing_tags), tags, purge_tags)

if tags_to_add:
try:
redshift.create_tags(ResourceName=resource_arn, Tags=ansible_dict_to_boto3_tag_list(tags_to_add))
except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
module.fail_json_aws(e, msg="Failed to add tags to cluster")

if tags_to_remove:
try:
redshift.delete_tags(ResourceName=resource_arn, TagKeys=tags_to_remove)
except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
module.fail_json_aws(e, msg="Failed to delete tags on cluster")

changed = bool(tags_to_add or tags_to_remove)
return changed


def _collect_facts(resource):
Expand Down Expand Up @@ -291,12 +337,14 @@ def _collect_facts(resource):
facts['url'] = None
facts['port'] = None
facts['availability_zone'] = None
facts['tags'] = {}

if resource['ClusterStatus'] != "creating":
facts['create_time'] = resource['ClusterCreateTime']
facts['url'] = resource['Endpoint']['Address']
facts['port'] = resource['Endpoint']['Port']
facts['availability_zone'] = resource['AvailabilityZone']
facts['tags'] = boto3_tag_list_to_ansible_dict(resource['Tags'])

return facts

Expand Down Expand Up @@ -357,6 +405,7 @@ def create_cluster(module, redshift):
d_b_name = module.params.get('db_name')
wait = module.params.get('wait')
wait_timeout = module.params.get('wait_timeout')
tags = module.params.get('tags')

changed = True
# Package up the optional parameters
Expand All @@ -367,14 +416,17 @@ def create_cluster(module, redshift):
'cluster_parameter_group_name',
'automated_snapshot_retention_period', 'port',
'cluster_version', 'allow_version_upgrade',
'number_of_nodes', 'publicly_accessible',
'encrypted', 'elastic_ip', 'enhanced_vpc_routing'):
'number_of_nodes', 'publicly_accessible', 'encrypted',
'elastic_ip', 'enhanced_vpc_routing'):
# https://github.com/boto/boto3/issues/400
if module.params.get(p) is not None:
params[p] = module.params.get(p)

if d_b_name:
params['d_b_name'] = d_b_name
if tags:
tags = ansible_dict_to_boto3_tag_list(tags)
params['tags'] = tags

try:
_describe_cluster(redshift, identifier)
Expand Down Expand Up @@ -406,6 +458,11 @@ def create_cluster(module, redshift):
except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
module.fail_json_aws(e, msg="Failed to describe cluster")

if tags:
if _ensure_tags(redshift, identifier, resource['Tags'], module):
changed = True
resource = _describe_cluster(redshift, identifier)

return(changed, _collect_facts(resource))


Expand Down Expand Up @@ -481,6 +538,9 @@ def modify_cluster(module, redshift):
identifier = module.params.get('identifier')
wait = module.params.get('wait')
wait_timeout = module.params.get('wait_timeout')
tags = module.params.get('tags')
purge_tags = module.params.get('purge_tags')
region = region = module.params.get('region')

# Package up the optional parameters
params = {}
Expand Down Expand Up @@ -509,12 +569,10 @@ def modify_cluster(module, redshift):
try:
waiter.wait(
ClusterIdentifier=identifier,
WaiterConfig=dict(MaxAttempts=attempts)
)
WaiterConfig=dict(MaxAttempts=attempts))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e,
msg="Timeout waiting for cluster enhanced vpc routing modification"
)
msg="Timeout waiting for cluster enhanced vpc routing modification")

# change the rest
try:
Expand Down Expand Up @@ -543,6 +601,9 @@ def modify_cluster(module, redshift):
except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
module.fail_json(e, msg="Couldn't modify redshift cluster %s " % identifier)

if _ensure_tags(redshift, identifier, resource['Tags'], module):
resource = redshift.describe_clusters(ClusterIdentifier=identifier)['Clusters'][0]

return(True, _collect_facts(resource))


Expand Down Expand Up @@ -579,6 +640,8 @@ def main():
enhanced_vpc_routing=dict(type='bool', default=False),
wait=dict(type='bool', default=False),
wait_timeout=dict(type='int', default=300),
tags=dict(type='dict', aliases=['resource_tags']),
purge_tags=dict(type='bool', default=True)
)

required_if = [
Expand Down

0 comments on commit f25cfeb

Please sign in to comment.