From 26bebba5074378d88c138d5c954245a091a40e2f Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Tue, 12 Oct 2021 13:52:39 +0200 Subject: [PATCH] Rework route53 tagging logic a little --- plugins/module_utils/route53.py | 72 +++++++++++-------- plugins/modules/route53_zone.py | 14 ++-- .../targets/route53_zone/tasks/main.yml | 2 + 3 files changed, 54 insertions(+), 34 deletions(-) diff --git a/plugins/module_utils/route53.py b/plugins/module_utils/route53.py index 15b9f63cc3e..3d21d8b0802 100644 --- a/plugins/module_utils/route53.py +++ b/plugins/module_utils/route53.py @@ -4,44 +4,58 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -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 - - -def manage_tags(module, client, resource_type, resource_spec, resource_id): - tagset = client.list_tags_for_resource( - ResourceType=resource_type, - ResourceId=resource_id, - ) - old_tags = boto3_tag_list_to_ansible_dict(tagset['ResourceTagSet']['Tags']) - new_tags = {} - if resource_spec['tags']: - new_tags = resource_spec['tags'] - tags_to_set, tags_to_delete = compare_aws_tags( - old_tags, new_tags, - purge_tags=resource_spec['purge_tags'], - ) - - if not tags_to_set and not tags_to_delete: +try: + import botocore +except ImportError: + pass # caught by AnsibleAWSModule + +from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code +from ansible_collections.amazon.aws.plugins.module_utils.tagging import ansible_dict_to_boto3_tag_list +from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_list_to_ansible_dict +from ansible_collections.amazon.aws.plugins.module_utils.tagging import compare_aws_tags + + +def manage_tags(module, client, resource_type, resource_id, new_tags, purge_tags): + old_tags = get_tags(module, client, resource_type, resource_id) + tags_to_set, tags_to_delete = compare_aws_tags(old_tags, new_tags, purge_tags=purge_tags) + + change_params = dict() + if tags_to_set: + change_params['AddTags'] = ansible_dict_to_boto3_tag_list(tags_to_set) + if tags_to_delete: + change_params['RemoveTagKeys'] = tags_to_delete + + if not change_params: return False if module.check_mode: return True - # boto3 does not provide create/remove functions for tags in Route 53, - # neither it works with empty values as parameters to change_tags_for_resource, - # so we need to call the change function twice - if tags_to_set: + try: client.change_tags_for_resource( ResourceType=resource_type, ResourceId=resource_id, - AddTags=ansible_dict_to_boto3_tag_list(tags_to_set), + **change_params ) - if tags_to_delete: - client.change_tags_for_resource( + except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e: + module.fail_json_aws(e, msg='Failed to update tags on {0}'.format(resource_type), + resource_id=resource_id, change_params=change_params) + return True + + +def get_tags(module, client, resource_type, resource_id): + try: + tagset = client.list_tags_for_resource( ResourceType=resource_type, ResourceId=resource_id, - RemoveTagKeys=tags_to_delete, ) - return True + except is_boto3_error_code('NoSuchHealthCheck'): + return {} + except is_boto3_error_code('NoSuchHostedZone'): # pylint: disable=duplicate-except + return {} + except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e: # pylint: disable=duplicate-except + module.fail_json_aws(e, msg='Failed to fetch tags on {0}'.format(resource_type), + resource_id=resource_id) + + tags = boto3_tag_list_to_ansible_dict(tagset['ResourceTagSet']['Tags']) + return tags diff --git a/plugins/modules/route53_zone.py b/plugins/modules/route53_zone.py index 6bc2443f2bd..334e6d62718 100644 --- a/plugins/modules/route53_zone.py +++ b/plugins/modules/route53_zone.py @@ -150,6 +150,7 @@ import time from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule from ansible_collections.community.aws.plugins.module_utils.route53 import manage_tags +from ansible_collections.community.aws.plugins.module_utils.route53 import get_tags try: from botocore.exceptions import BotoCoreError, ClientError @@ -197,8 +198,6 @@ def create(module, client, matching_zones): 'name': zone_in, 'delegation_set_id': delegation_set_id, 'zone_id': None, - 'tags': tags, - 'purge_tags': purge_tags, } if private_zone: @@ -206,6 +205,14 @@ def create(module, client, matching_zones): else: changed, result = create_or_update_public(module, client, matching_zones, record) + zone_id = result.get('zone_id') + if zone_id: + if tags is not None: + changed |= manage_tags(module, client, 'hostedzone', zone_id, tags, purge_tags) + result['tags'] = get_tags(module, client, 'hostedzone', zone_id) + else: + result['tags'] = tags + return changed, result @@ -322,9 +329,6 @@ def create_or_update_public(module, client, matching_zones, record): record['name'] = zone_details['Name'] record['delegation_set_id'] = zone_delegation_set_details.get('Id', '').replace('/delegationset/', '') - if record['tags'] or record['purge_tags']: - changed = manage_tags(module, client, 'hostedzone', record, zone_details['Id'].replace('/hostedzone/', '')) - return changed, record diff --git a/tests/integration/targets/route53_zone/tasks/main.yml b/tests/integration/targets/route53_zone/tasks/main.yml index db430df5efc..9b02fd607af 100644 --- a/tests/integration/targets/route53_zone/tasks/main.yml +++ b/tests/integration/targets/route53_zone/tasks/main.yml @@ -118,6 +118,7 @@ comment: updated comment state: present purge_tags: true + tags: {} register: output - assert: @@ -132,6 +133,7 @@ comment: updated comment for check state: present purge_tags: true + tags: {} register: output check_mode: yes