Skip to content

Commit

Permalink
Merge branch 'mr/forestier/fix-subscription-id' into 'master'
Browse files Browse the repository at this point in the history
Add a prefix to the SQS subscription SID

See merge request it/e3-aws!17
  • Loading branch information
jeromef853 committed Nov 8, 2024
2 parents 07e2a6b + 1f53537 commit 88434d5
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 3 deletions.
20 changes: 17 additions & 3 deletions src/e3/aws/troposphere/sqs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,24 @@ def _get_queue_policy_name(self) -> str:
return name_to_id(f"{self.name}Policy")

def add_allow_service_to_write_statement(
self, service: str, applicant: str, condition: Optional[ConditionType] = None
self,
service: str,
applicant: str,
prefix: str | None = None,
condition: Optional[ConditionType] = None,
) -> str:
"""Add a statement in QueuePolicy allowing a service to send msg to the queue.
:param service: service allowed to send message
:param applicant: applicant name used for the Sid statement
:param prefix: set a prefix to the policy statement sid to prevent duplication
:param condition: condition to be able to send message
:return: the QueuePolicy name for depends_on settings
"""
sid_prefix = prefix if prefix else ""
self.queue_policy_statements.append(
Allow(
sid=f"{applicant}WriteAccess",
sid=f"{sid_prefix}{applicant}WriteAccess",
action="sqs:SendMessage",
resource=self.arn,
principal={"Service": f"{service}.amazonaws.com"},
Expand All @@ -80,6 +86,7 @@ def subscribe_to_sns_topic(
self,
topic_arn: str,
applicant: str,
prefix: str | None = None,
delivery_policy: dict | None = None,
filter_policy: dict | None = None,
filter_policy_scope: str | None = None,
Expand All @@ -88,10 +95,12 @@ def subscribe_to_sns_topic(
:param topic_arn: ARN of the topic to subscribe
:param applicant: applicant name used for the Sid statement
:param prefix: set a prefix to the subscription sid to prevent duplication
:param delivery_policy: The delivery policy to assign to the subscription
:param filter_policy: The filter policy JSON assigned to the subscription.
:param filter_policy_scope: The filtering scope.
"""
sid_prefix = prefix if prefix else ""
sub_params = {
"Endpoint": self.arn,
"Protocol": "sqs",
Expand All @@ -111,11 +120,16 @@ def subscribe_to_sns_topic(
self.add_allow_service_to_write_statement(
applicant=applicant,
service="sns",
prefix=sid_prefix,
condition={"ArnLike": {"aws:SourceArn": topic_arn}},
)

self.optional_resources.extend(
[sns.SubscriptionResource(name_to_id(f"{self.name}Sub"), **sub_params)]
[
sns.SubscriptionResource(
name_to_id(f"{sid_prefix}{self.name}Sub"), **sub_params
)
]
)

@property
Expand Down
91 changes: 91 additions & 0 deletions tests/tests_e3_aws/troposphere/sqs/sqs_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,58 @@
},
}

EXPECTED_MULTI_SQS_SUBSCRIPTION = {
"Myqueue": {
"Properties": {"QueueName": "myqueue", "VisibilityTimeout": 30},
"Type": "AWS::SQS::Queue",
},
"MyqueuePolicy": {
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": "sqs:SendMessage",
"Condition": {"ArnLike": {"aws:SourceArn": "some_topic_arn1"}},
"Effect": "Allow",
"Principal": {"Service": "sns.amazonaws.com"},
"Resource": {"Fn::GetAtt": ["Myqueue", "Arn"]},
"Sid": "SNS1SomeApplicantWriteAccess",
},
{
"Action": "sqs:SendMessage",
"Condition": {"ArnLike": {"aws:SourceArn": "some_topic_arn2"}},
"Effect": "Allow",
"Principal": {"Service": "sns.amazonaws.com"},
"Resource": {"Fn::GetAtt": ["Myqueue", "Arn"]},
"Sid": "SNS2SomeApplicantWriteAccess",
},
],
"Version": "2012-10-17",
},
"Queues": [{"Ref": "Myqueue"}],
},
"Type": "AWS::SQS::QueuePolicy",
},
"SNS1myqueueSub": {
"Properties": {
"Endpoint": {"Fn::GetAtt": ["Myqueue", "Arn"]},
"Protocol": "sqs",
"RawMessageDelivery": True,
"TopicArn": "some_topic_arn1",
},
"Type": "AWS::SNS::Subscription",
},
"SNS2myqueueSub": {
"Properties": {
"Endpoint": {"Fn::GetAtt": ["Myqueue", "Arn"]},
"Protocol": "sqs",
"RawMessageDelivery": True,
"TopicArn": "some_topic_arn2",
},
"Type": "AWS::SNS::Subscription",
},
}


def test_queue_default(stack: Stack) -> None:
"""Test Queue default creation."""
Expand Down Expand Up @@ -163,3 +215,42 @@ def test_subscribe_to_sns_topic_with_policy_filter(stack: Stack) -> None:
stack.add(queue)

assert stack.export()["Resources"] == EXPECTED_SQS_SUBSCRIPTION_WITH_FILTER_TEMPLATE


def test_multi_subscription_to_sns_topic(stack: Stack) -> None:
"""The sqs subscription to multiple sns Topic."""
queue = Queue(name="myqueue")
queue.subscribe_to_sns_topic(
topic_arn="some_topic_arn1",
applicant="SomeApplicant",
prefix="SNS1",
)

queue.subscribe_to_sns_topic(
topic_arn="some_topic_arn2",
applicant="SomeApplicant",
prefix="SNS2",
)

stack.add(queue)

assert stack.export()["Resources"] == EXPECTED_MULTI_SQS_SUBSCRIPTION


def test_multi_subscription_to_sns_topic_without_prefix(stack: Stack) -> None:
"""The sqs subscription to multiple sns Topic without prefix should fail."""
queue = Queue(name="myqueue")
queue.subscribe_to_sns_topic(
topic_arn="some_topic_arn",
applicant="SomeApplicant",
)

queue.subscribe_to_sns_topic(
topic_arn="some_topic_arn",
applicant="SomeApplicant",
)

with pytest.raises(Exception) as ex:
stack.add(queue)

assert str(ex.value) == "Unique Sid is required for QueuePolicy statements"

0 comments on commit 88434d5

Please sign in to comment.