Skip to content
This repository was archived by the owner on Mar 23, 2026. It is now read-only.

Commit 3e92156

Browse files
SQS: Complete implementation and testing of AWS::SQS:* CloudFormation resource providers (#13548)
1 parent b15ebc5 commit 3e92156

24 files changed

+1257
-119
lines changed

localstack-core/localstack/services/sqs/resource_providers/aws_sqs_queue.py

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,17 @@
22
from __future__ import annotations
33

44
import json
5-
from pathlib import Path
6-
from typing import TypedDict
75

86
import localstack.services.cloudformation.provider_utils as util
97
from localstack.services.cloudformation.resource_provider import (
108
OperationStatus,
119
ProgressEvent,
12-
ResourceProvider,
1310
ResourceRequest,
1411
)
15-
16-
17-
class SQSQueueProperties(TypedDict):
18-
Arn: str | None
19-
ContentBasedDeduplication: bool | None
20-
DeduplicationScope: str | None
21-
DelaySeconds: int | None
22-
FifoQueue: bool | None
23-
FifoThroughputLimit: str | None
24-
KmsDataKeyReusePeriodSeconds: int | None
25-
KmsMasterKeyId: str | None
26-
MaximumMessageSize: int | None
27-
MessageRetentionPeriod: int | None
28-
QueueName: str | None
29-
QueueUrl: str | None
30-
ReceiveMessageWaitTimeSeconds: int | None
31-
RedriveAllowPolicy: dict | str | None
32-
RedrivePolicy: dict | str | None
33-
SqsManagedSseEnabled: bool | None
34-
Tags: list[Tag] | None
35-
VisibilityTimeout: int | None
36-
37-
38-
class Tag(TypedDict):
39-
Key: str | None
40-
Value: str | None
41-
42-
43-
REPEATED_INVOCATION = "repeated_invocation"
12+
from localstack.services.sqs.resource_providers.generated.aws_sqs_queue_base import (
13+
SQSQueueProperties,
14+
SQSQueueProviderBase,
15+
)
4416

4517
_queue_attribute_list = [
4618
"ContentBasedDeduplication",
@@ -60,10 +32,7 @@ class Tag(TypedDict):
6032
]
6133

6234

63-
class SQSQueueProvider(ResourceProvider[SQSQueueProperties]):
64-
TYPE = "AWS::SQS::Queue" # Autogenerated. Don't change
65-
SCHEMA = util.get_schema_path(Path(__file__)) # Autogenerated. Don't change
66-
35+
class SQSQueueProvider(SQSQueueProviderBase):
6736
# Values used when a property is removed from a template and needs to be set to its default.
6837
# If AWS changes their defaults in the future, our parity tests should break.
6938
DEFAULT_ATTRIBUTE_VALUES = {
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# LocalStack Resource Provider Scaffolding v2
2+
import json
3+
4+
from localstack.services.cloudformation.resource_provider import (
5+
OperationStatus,
6+
ProgressEvent,
7+
ResourceRequest,
8+
)
9+
from localstack.services.sqs.resource_providers.generated.aws_sqs_queueinlinepolicy_base import (
10+
SQSQueueInlinePolicyProperties,
11+
SQSQueueInlinePolicyProviderBase,
12+
)
13+
14+
15+
class SQSQueueInlinePolicyProvider(SQSQueueInlinePolicyProviderBase):
16+
def create(
17+
self,
18+
request: ResourceRequest[SQSQueueInlinePolicyProperties],
19+
) -> ProgressEvent[SQSQueueInlinePolicyProperties]:
20+
model = request.desired_state
21+
sqs = request.aws_client_factory.sqs
22+
23+
queue = model.get("Queue")
24+
policy = model.get("PolicyDocument")
25+
sqs.set_queue_attributes(QueueUrl=queue, Attributes={"Policy": json.dumps(policy)})
26+
27+
return ProgressEvent(
28+
status=OperationStatus.SUCCESS,
29+
resource_model=model,
30+
custom_context=request.custom_context,
31+
)
32+
33+
def read(
34+
self,
35+
request: ResourceRequest[SQSQueueInlinePolicyProperties],
36+
) -> ProgressEvent[SQSQueueInlinePolicyProperties]:
37+
raise NotImplementedError
38+
39+
def delete(
40+
self,
41+
request: ResourceRequest[SQSQueueInlinePolicyProperties],
42+
) -> ProgressEvent[SQSQueueInlinePolicyProperties]:
43+
model = request.desired_state
44+
sqs = request.aws_client_factory.sqs
45+
46+
queue = model.get("Queue")
47+
sqs.set_queue_attributes(QueueUrl=queue, Attributes={"Policy": ""})
48+
49+
return ProgressEvent(status=OperationStatus.SUCCESS, resource_model={})
50+
51+
def update(
52+
self,
53+
request: ResourceRequest[SQSQueueInlinePolicyProperties],
54+
) -> ProgressEvent[SQSQueueInlinePolicyProperties]:
55+
model = request.desired_state
56+
sqs = request.aws_client_factory.sqs
57+
58+
queue = model.get("Queue")
59+
policy = model.get("PolicyDocument")
60+
sqs.set_queue_attributes(QueueUrl=queue, Attributes={"Policy": json.dumps(policy)})
61+
62+
return ProgressEvent(
63+
status=OperationStatus.SUCCESS,
64+
resource_model=model,
65+
custom_context=request.custom_context,
66+
)
67+
68+
def list(
69+
self,
70+
request: ResourceRequest[SQSQueueInlinePolicyProperties],
71+
) -> ProgressEvent[SQSQueueInlinePolicyProperties]:
72+
"""
73+
List available resources of this type
74+
75+
"""
76+
raise NotImplementedError

localstack-core/localstack/services/sqs/resource_providers/aws_sqs_queuepolicy.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,19 @@ def update(
7676
"""
7777
model = request.desired_state
7878
sqs = request.aws_client_factory.sqs
79-
for queue in model.get("Queues", []):
79+
80+
# handle new/updated queues
81+
desired_queues = model.get("Queues", [])
82+
for queue in desired_queues:
8083
policy = json.dumps(model["PolicyDocument"])
8184
sqs.set_queue_attributes(QueueUrl=queue, Attributes={"Policy": policy})
8285

86+
# handle queues no longer in the desired state
87+
previous_queues = request.previous_state.get("Queues", [])
88+
outdated_queues = set(previous_queues) - set(desired_queues)
89+
for queue in outdated_queues:
90+
sqs.set_queue_attributes(QueueUrl=queue, Attributes={"Policy": ""})
91+
8392
model["Id"] = request.previous_state["Id"]
8493

8594
return ProgressEvent(

localstack-core/localstack/services/sqs/resource_providers/aws_sqs_queue.schema.json renamed to localstack-core/localstack/services/sqs/resource_providers/generated/aws_sqs_queue.schema.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,13 @@
123123
"taggable": true,
124124
"tagOnCreate": true,
125125
"tagUpdatable": true,
126-
"cloudFormationSystemTags": true,
127-
"tagProperty": "/properties/Tags"
126+
"cloudFormationSystemTags": false,
127+
"tagProperty": "/properties/Tags",
128+
"permissions": [
129+
"sqs:TagQueue",
130+
"sqs:UntagQueue",
131+
"sqs:ListQueueTags"
132+
]
128133
},
129134
"handlers": {
130135
"create": {
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# LocalStack Resource Provider Base Class Scaffolding v2
2+
#
3+
# AUTOGENERATED FILE - DO NOT EDIT
4+
#
5+
6+
from __future__ import annotations
7+
8+
from abc import ABC, abstractmethod
9+
from pathlib import Path
10+
from typing import TypedDict
11+
12+
import localstack.services.cloudformation.provider_utils as util
13+
from localstack.services.cloudformation.resource_provider import (
14+
ProgressEvent,
15+
ResourceProvider,
16+
ResourceRequest,
17+
)
18+
19+
20+
class SQSQueueProperties(TypedDict):
21+
Arn: str | None
22+
ContentBasedDeduplication: bool | None
23+
DeduplicationScope: str | None
24+
DelaySeconds: int | None
25+
FifoQueue: bool | None
26+
FifoThroughputLimit: str | None
27+
KmsDataKeyReusePeriodSeconds: int | None
28+
KmsMasterKeyId: str | None
29+
MaximumMessageSize: int | None
30+
MessageRetentionPeriod: int | None
31+
QueueName: str | None
32+
QueueUrl: str | None
33+
ReceiveMessageWaitTimeSeconds: int | None
34+
RedriveAllowPolicy: dict | str | None
35+
RedrivePolicy: dict | str | None
36+
SqsManagedSseEnabled: bool | None
37+
Tags: list[Tag] | None
38+
VisibilityTimeout: int | None
39+
40+
41+
class Tag(TypedDict):
42+
Key: str | None
43+
Value: str | None
44+
45+
46+
REPEATED_INVOCATION = "repeated_invocation"
47+
48+
49+
class SQSQueueProviderBase(ResourceProvider[SQSQueueProperties], ABC):
50+
TYPE = "AWS::SQS::Queue" # Autogenerated. Don't change
51+
SCHEMA = util.get_schema_path(Path(__file__)) # Autogenerated. Don't change
52+
53+
@abstractmethod
54+
def create(
55+
self,
56+
request: ResourceRequest[SQSQueueProperties],
57+
) -> ProgressEvent[SQSQueueProperties]:
58+
"""
59+
Create a new resource.
60+
61+
Primary identifier fields:
62+
- /properties/QueueUrl
63+
64+
65+
66+
Create-only properties:
67+
- /properties/FifoQueue
68+
- /properties/QueueName
69+
70+
Read-only properties:
71+
- /properties/QueueUrl
72+
- /properties/Arn
73+
74+
IAM permissions required:
75+
- sqs:CreateQueue
76+
- sqs:GetQueueUrl
77+
- sqs:GetQueueAttributes
78+
- sqs:ListQueueTags
79+
- sqs:TagQueue
80+
81+
"""
82+
raise NotImplementedError
83+
84+
@abstractmethod
85+
def read(
86+
self,
87+
request: ResourceRequest[SQSQueueProperties],
88+
) -> ProgressEvent[SQSQueueProperties]:
89+
"""
90+
Fetch resource information
91+
92+
IAM permissions required:
93+
- sqs:GetQueueAttributes
94+
- sqs:ListQueueTags
95+
"""
96+
raise NotImplementedError
97+
98+
@abstractmethod
99+
def delete(
100+
self,
101+
request: ResourceRequest[SQSQueueProperties],
102+
) -> ProgressEvent[SQSQueueProperties]:
103+
"""
104+
Delete a resource
105+
106+
IAM permissions required:
107+
- sqs:DeleteQueue
108+
- sqs:GetQueueAttributes
109+
"""
110+
raise NotImplementedError
111+
112+
@abstractmethod
113+
def update(
114+
self,
115+
request: ResourceRequest[SQSQueueProperties],
116+
) -> ProgressEvent[SQSQueueProperties]:
117+
"""
118+
Update a resource
119+
120+
IAM permissions required:
121+
- sqs:SetQueueAttributes
122+
- sqs:GetQueueAttributes
123+
- sqs:ListQueueTags
124+
- sqs:TagQueue
125+
- sqs:UntagQueue
126+
"""
127+
raise NotImplementedError
128+
129+
@abstractmethod
130+
def list(
131+
self,
132+
request: ResourceRequest[SQSQueueProperties],
133+
) -> ProgressEvent[SQSQueueProperties]:
134+
"""
135+
List available resources of this type
136+
IAM permissions required:
137+
- sqs:ListQueues
138+
"""
139+
raise NotImplementedError

localstack-core/localstack/services/sqs/resource_providers/aws_sqs_queue_plugin.py renamed to localstack-core/localstack/services/sqs/resource_providers/generated/aws_sqs_queue_plugin.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#
2+
# AUTOGENERATED FILE - DO NOT EDIT
3+
#
4+
15
from localstack.services.cloudformation.resource_provider import (
26
CloudFormationResourceProviderPlugin,
37
ResourceProvider,
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{
2+
"typeName": "AWS::SQS::QueueInlinePolicy",
3+
"description": "Schema for SQS QueueInlinePolicy",
4+
"sourceUrl": "https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-sqs.git",
5+
"properties": {
6+
"PolicyDocument": {
7+
"description": "A policy document that contains permissions to add to the specified SQS queue",
8+
"type": "object"
9+
},
10+
"Queue": {
11+
"description": "The URL of the SQS queue.",
12+
"type": "string"
13+
}
14+
},
15+
"additionalProperties": false,
16+
"tagging": {
17+
"taggable": false,
18+
"tagOnCreate": false,
19+
"tagUpdatable": false,
20+
"cloudFormationSystemTags": false
21+
},
22+
"required": [
23+
"PolicyDocument",
24+
"Queue"
25+
],
26+
"primaryIdentifier": [
27+
"/properties/Queue"
28+
],
29+
"createOnlyProperties": [
30+
"/properties/Queue"
31+
],
32+
"handlers": {
33+
"create": {
34+
"permissions": [
35+
"sqs:SetQueueAttributes",
36+
"sqs:GetQueueAttributes",
37+
"sqs:GetQueueUrl"
38+
]
39+
},
40+
"read": {
41+
"permissions": [
42+
"sqs:GetQueueAttributes",
43+
"sqs:GetQueueUrl"
44+
]
45+
},
46+
"delete": {
47+
"permissions": [
48+
"sqs:SetQueueAttributes",
49+
"sqs:GetQueueAttributes"
50+
]
51+
},
52+
"update": {
53+
"permissions": [
54+
"sqs:SetQueueAttributes",
55+
"sqs:GetQueueAttributes",
56+
"sqs:GetQueueUrl"
57+
]
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)