From 28b5baf32900da6e10c255b0d95d4bc828143a47 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Thu, 2 Feb 2023 16:02:50 +0100 Subject: [PATCH] SNS: content-based deduplication (#1693) SNS: content-based deduplication SUMMARY Original Author: redradrat Original PR: #1602 Adds the missing option of "content-based deduplication" for fifo topics. Also fixes looking up fifo topic ARNs, which resulted in changing always be True. ISSUE TYPE Feature Pull Request COMPONENT NAME sns_topic ADDITIONAL INFORMATION #1602 is missing tests and has merge conflicts. Fixes the conflicts and adds integration tests Reviewed-by: Alina Buzachis Reviewed-by: Mark Chappell (cherry picked from commit aace7ff52cb0006491f6426382397bfd574047a0) --- changelogs/fragments/1693-sns_topic.yml | 2 + plugins/module_utils/sns.py | 2 + plugins/modules/sns_topic.py | 54 +++++++++++++++---- plugins/modules/sns_topic_info.py | 5 ++ .../targets/sns_topic/tasks/main.yml | 38 +++++++++++++ 5 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 changelogs/fragments/1693-sns_topic.yml diff --git a/changelogs/fragments/1693-sns_topic.yml b/changelogs/fragments/1693-sns_topic.yml new file mode 100644 index 00000000000..7cd3602f48d --- /dev/null +++ b/changelogs/fragments/1693-sns_topic.yml @@ -0,0 +1,2 @@ +minor_changes: +- sns_topic - add support for ``content_based_deduplication`` parameter (https://github.com/ansible-collections/community.aws/pull/1693). diff --git a/plugins/module_utils/sns.py b/plugins/module_utils/sns.py index 17fc136a1d6..44327d49362 100644 --- a/plugins/module_utils/sns.py +++ b/plugins/module_utils/sns.py @@ -107,6 +107,7 @@ def get_info(connection, module, topic_arn): state = module.params.get('state') subscriptions = module.params.get('subscriptions') purge_subscriptions = module.params.get('purge_subscriptions') + content_based_deduplication = module.params.get('content_based_deduplication') subscriptions_existing = module.params.get('subscriptions_existing', []) subscriptions_deleted = module.params.get('subscriptions_deleted', []) subscriptions_added = module.params.get('subscriptions_added', []) @@ -125,6 +126,7 @@ def get_info(connection, module, topic_arn): 'subscriptions_deleted': subscriptions_deleted, 'subscriptions_added': subscriptions_added, 'subscriptions_purge': purge_subscriptions, + 'content_based_deduplication': content_based_deduplication, 'check_mode': check_mode, 'topic_created': topic_created, 'topic_deleted': topic_deleted, diff --git a/plugins/modules/sns_topic.py b/plugins/modules/sns_topic.py index f8e44358cb7..a1a4422ad52 100644 --- a/plugins/modules/sns_topic.py +++ b/plugins/modules/sns_topic.py @@ -148,6 +148,14 @@ Blame Amazon." default: true type: bool + content_based_deduplication: + description: + - Whether to enable content-based deduplication for this topic. + - Ignored unless I(topic_type=fifo). + - Defaults to C(disabled). + choices: ["disabled", "enabled"] + type: str + version_added: 5.3.0 notes: - Support for I(tags) and I(purge_tags) was added in release 5.3.0. extends_documentation_fragment: @@ -229,6 +237,12 @@ returned: always type: bool sample: false + content_based_deduplication: + description: Whether or not content_based_deduplication was set + returned: always + type: str + sample: disabled + version_added: 5.3.0 delivery_policy: description: Delivery policy for the SNS topic returned: when topic is owned by this AWS account @@ -355,6 +369,7 @@ def __init__(self, purge_subscriptions, tags, purge_tags, + content_based_deduplication, check_mode): self.connection = module.client('sns') @@ -372,6 +387,7 @@ def __init__(self, self.subscriptions_attributes_set = [] self.desired_subscription_attributes = dict() self.purge_subscriptions = purge_subscriptions + self.content_based_deduplication = content_based_deduplication self.check_mode = check_mode self.topic_created = False self.topic_deleted = False @@ -431,6 +447,20 @@ def _set_topic_attrs(self): except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: self.module.fail_json_aws(e, msg="Couldn't set topic policy") + # Set content-based deduplication attribute. Ignore if topic_type is not fifo. + if ("FifoTopic" in topic_attributes and topic_attributes["FifoTopic"] == "true") and \ + self.content_based_deduplication: + enabled = "true" if self.content_based_deduplication in 'enabled' else "false" + if enabled != topic_attributes['ContentBasedDeduplication']: + changed = True + self.attributes_set.append('content_based_deduplication') + if not self.check_mode: + try: + self.connection.set_topic_attributes(TopicArn=self.topic_arn, AttributeName='ContentBasedDeduplication', + AttributeValue=enabled) + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: + self.module.fail_json_aws(e, msg="Couldn't set content-based deduplication") + if self.delivery_policy and ('DeliveryPolicy' not in topic_attributes or compare_delivery_policies(self.delivery_policy, json.loads(topic_attributes['DeliveryPolicy']))): changed = True @@ -542,10 +572,7 @@ def _name_is_arn(self): def ensure_ok(self): changed = False - if self._name_is_arn(): - self.topic_arn = self.name - else: - self.topic_arn = topic_arn_lookup(self.connection, self.module, self.name) + self.populate_topic_arn() if not self.topic_arn: changed = self._create_topic() if self.topic_arn in list_topics(self.connection, self.module): @@ -565,10 +592,7 @@ def ensure_ok(self): def ensure_gone(self): changed = False - if self._name_is_arn(): - self.topic_arn = self.name - else: - self.topic_arn = topic_arn_lookup(self.connection, self.module, self.name) + self.populate_topic_arn() if self.topic_arn: if self.topic_arn not in list_topics(self.connection, self.module): self.module.fail_json(msg="Cannot use state=absent with third party ARN. Use subscribers=[] to unsubscribe") @@ -576,6 +600,16 @@ def ensure_gone(self): changed |= self._delete_topic() return changed + def populate_topic_arn(self): + if self._name_is_arn(): + self.topic_arn = self.name + return + + name = self.name + if self.topic_type == 'fifo' and not name.endswith('.fifo'): + name += ".fifo" + self.topic_arn = topic_arn_lookup(self.connection, self.module, name) + def main(): # We're kinda stuck with CamelCase here, it would be nice to switch to @@ -614,6 +648,7 @@ def main(): purge_subscriptions=dict(type='bool', default=True), tags=dict(type='dict', aliases=['resource_tags']), purge_tags=dict(type='bool', default=True), + content_based_deduplication=dict(choices=['enabled', 'disabled']) ) module = AnsibleAWSModule(argument_spec=argument_spec, @@ -627,6 +662,7 @@ def main(): delivery_policy = module.params.get('delivery_policy') subscriptions = module.params.get('subscriptions') purge_subscriptions = module.params.get('purge_subscriptions') + content_based_deduplication = module.params.get('content_based_deduplication') check_mode = module.check_mode tags = module.params.get('tags') purge_tags = module.params.get('purge_tags') @@ -642,11 +678,11 @@ def main(): purge_subscriptions, tags, purge_tags, + content_based_deduplication, check_mode) if state == 'present': changed = sns_topic.ensure_ok() - elif state == 'absent': changed = sns_topic.ensure_gone() diff --git a/plugins/modules/sns_topic_info.py b/plugins/modules/sns_topic_info.py index d3180ed6584..ca6dd1aabb7 100644 --- a/plugins/modules/sns_topic_info.py +++ b/plugins/modules/sns_topic_info.py @@ -54,6 +54,11 @@ type: complex returned: always contains: + content_based_deduplication: + description: Whether or not content_based_deduplication was set + returned: always + type: str + sample: "true" delivery_policy: description: Delivery policy for the SNS topic. returned: when topic is owned by this AWS account diff --git a/tests/integration/targets/sns_topic/tasks/main.yml b/tests/integration/targets/sns_topic/tasks/main.yml index 5465aad4fdb..d5b389e4d5f 100644 --- a/tests/integration/targets/sns_topic/tasks/main.yml +++ b/tests/integration/targets/sns_topic/tasks/main.yml @@ -112,6 +112,18 @@ - sns_fifo_topic.sns_topic.topic_type == 'fifo' - sns_fifo_topic.sns_topic.name == '{{ sns_topic_topic_name }}-fifo' + - name: Run create a FIFO topic again for idempotence test (with .fifo) + sns_topic: + name: '{{ sns_topic_topic_name }}-fifo.fifo' + topic_type: fifo + display_name: My FIFO topic + register: sns_fifo_topic + + - name: assert that FIFO SNS topic creation worked (without .fifo) + assert: + that: + - not sns_fifo_topic.changed + - name: Run create a FIFO topic again for idempotence test sns_topic: name: '{{ sns_topic_topic_name }}-fifo.fifo' @@ -124,6 +136,32 @@ that: - not sns_fifo_topic.changed + - name: set content_based_deduplication + sns_topic: + name: '{{ sns_topic_topic_name }}-fifo' + topic_type: fifo + display_name: My FIFO topic + content_based_deduplication: "enabled" + register: sns_fifo_topic + + - name: assert that FIFO SNS topic creation worked + assert: + that: + - sns_fifo_topic.changed + + - name: set content_based_deduplication (idemopotence) + sns_topic: + name: '{{ sns_topic_topic_name }}-fifo' + topic_type: fifo + display_name: My FIFO topic + content_based_deduplication: "enabled" + register: sns_fifo_topic + + - name: assert that FIFO SNS topic creation worked + assert: + that: + - not sns_fifo_topic.changed + - name: update display name sns_topic: name: '{{ sns_topic_topic_name }}'