Skip to content

Commit 5bfa1de

Browse files
authored
add resource providers for vpc endpoint and prefix list (localstack#10735)
1 parent a577f1e commit 5bfa1de

File tree

11 files changed

+1017
-1
lines changed

11 files changed

+1017
-1
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# LocalStack Resource Provider Scaffolding v2
2+
from __future__ import annotations
3+
4+
from pathlib import Path
5+
from typing import Optional, TypedDict
6+
7+
import localstack.services.cloudformation.provider_utils as util
8+
from localstack.services.cloudformation.resource_provider import (
9+
OperationStatus,
10+
ProgressEvent,
11+
ResourceProvider,
12+
ResourceRequest,
13+
)
14+
15+
16+
class EC2PrefixListProperties(TypedDict):
17+
AddressFamily: Optional[str]
18+
MaxEntries: Optional[int]
19+
PrefixListName: Optional[str]
20+
Arn: Optional[str]
21+
Entries: Optional[list[Entry]]
22+
OwnerId: Optional[str]
23+
PrefixListId: Optional[str]
24+
Tags: Optional[list[Tag]]
25+
Version: Optional[int]
26+
27+
28+
class Tag(TypedDict):
29+
Key: Optional[str]
30+
Value: Optional[str]
31+
32+
33+
class Entry(TypedDict):
34+
Cidr: Optional[str]
35+
Description: Optional[str]
36+
37+
38+
REPEATED_INVOCATION = "repeated_invocation"
39+
40+
41+
class EC2PrefixListProvider(ResourceProvider[EC2PrefixListProperties]):
42+
TYPE = "AWS::EC2::PrefixList" # Autogenerated. Don't change
43+
SCHEMA = util.get_schema_path(Path(__file__)) # Autogenerated. Don't change
44+
45+
def create(
46+
self,
47+
request: ResourceRequest[EC2PrefixListProperties],
48+
) -> ProgressEvent[EC2PrefixListProperties]:
49+
"""
50+
Create a new resource.
51+
52+
Primary identifier fields:
53+
- /properties/PrefixListId
54+
55+
Required properties:
56+
- PrefixListName
57+
- MaxEntries
58+
- AddressFamily
59+
60+
61+
62+
Read-only properties:
63+
- /properties/PrefixListId
64+
- /properties/OwnerId
65+
- /properties/Version
66+
- /properties/Arn
67+
68+
IAM permissions required:
69+
- EC2:CreateManagedPrefixList
70+
- EC2:DescribeManagedPrefixLists
71+
- EC2:CreateTags
72+
73+
"""
74+
model = request.desired_state
75+
76+
if not request.custom_context.get(REPEATED_INVOCATION):
77+
create_params = util.select_attributes(
78+
model, ["PrefixListName", "Entries", "MaxEntries", "AddressFamily", "Tags"]
79+
)
80+
81+
if "Tags" in create_params:
82+
create_params["TagSpecifications"] = [
83+
{"ResourceType": "prefix-list", "Tags": create_params.pop("Tags")}
84+
]
85+
86+
response = request.aws_client_factory.ec2.create_managed_prefix_list(**create_params)
87+
model["Arn"] = response["PrefixList"]["PrefixListId"]
88+
model["OwnerId"] = response["PrefixList"]["OwnerId"]
89+
model["PrefixListId"] = response["PrefixList"]["PrefixListId"]
90+
model["Version"] = response["PrefixList"]["Version"]
91+
request.custom_context[REPEATED_INVOCATION] = True
92+
return ProgressEvent(
93+
status=OperationStatus.IN_PROGRESS,
94+
resource_model=model,
95+
custom_context=request.custom_context,
96+
)
97+
98+
response = request.aws_client_factory.ec2.describe_managed_prefix_lists(
99+
PrefixListIds=[model["PrefixListId"]]
100+
)
101+
if not response["PrefixLists"]:
102+
return ProgressEvent(
103+
status=OperationStatus.FAILED,
104+
resource_model=model,
105+
custom_context=request.custom_context,
106+
message="Resource not found after creation",
107+
)
108+
109+
return ProgressEvent(
110+
status=OperationStatus.SUCCESS,
111+
resource_model=model,
112+
custom_context=request.custom_context,
113+
)
114+
115+
def read(
116+
self,
117+
request: ResourceRequest[EC2PrefixListProperties],
118+
) -> ProgressEvent[EC2PrefixListProperties]:
119+
"""
120+
Fetch resource information
121+
122+
IAM permissions required:
123+
- EC2:GetManagedPrefixListEntries
124+
- EC2:DescribeManagedPrefixLists
125+
"""
126+
raise NotImplementedError
127+
128+
def delete(
129+
self,
130+
request: ResourceRequest[EC2PrefixListProperties],
131+
) -> ProgressEvent[EC2PrefixListProperties]:
132+
"""
133+
Delete a resource
134+
135+
IAM permissions required:
136+
- EC2:DeleteManagedPrefixList
137+
- EC2:DescribeManagedPrefixLists
138+
"""
139+
140+
model = request.previous_state
141+
response = request.aws_client_factory.ec2.describe_managed_prefix_lists(
142+
PrefixListIds=[model["PrefixListId"]]
143+
)
144+
145+
if not response["PrefixLists"]:
146+
return ProgressEvent(status=OperationStatus.SUCCESS, resource_model=model)
147+
148+
request.aws_client_factory.ec2.delete_managed_prefix_list(
149+
PrefixListId=request.previous_state["PrefixListId"]
150+
)
151+
return ProgressEvent(status=OperationStatus.IN_PROGRESS, resource_model=model)
152+
153+
def update(
154+
self,
155+
request: ResourceRequest[EC2PrefixListProperties],
156+
) -> ProgressEvent[EC2PrefixListProperties]:
157+
"""
158+
Update a resource
159+
160+
IAM permissions required:
161+
- EC2:DescribeManagedPrefixLists
162+
- EC2:GetManagedPrefixListEntries
163+
- EC2:ModifyManagedPrefixList
164+
- EC2:CreateTags
165+
- EC2:DeleteTags
166+
"""
167+
raise NotImplementedError
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
{
2+
"typeName": "AWS::EC2::PrefixList",
3+
"description": "Resource schema of AWS::EC2::PrefixList Type",
4+
"sourceUrl": "https://github.com/aws-cloudformation/aws-cloudformation-rpdk.git",
5+
"definitions": {
6+
"Tag": {
7+
"type": "object",
8+
"properties": {
9+
"Key": {
10+
"type": "string",
11+
"minLength": 1,
12+
"maxLength": 128
13+
},
14+
"Value": {
15+
"type": "string",
16+
"maxLength": 256
17+
}
18+
},
19+
"required": [
20+
"Key"
21+
],
22+
"additionalProperties": false
23+
},
24+
"Entry": {
25+
"type": "object",
26+
"properties": {
27+
"Cidr": {
28+
"type": "string",
29+
"minLength": 1,
30+
"maxLength": 46
31+
},
32+
"Description": {
33+
"type": "string",
34+
"minLength": 0,
35+
"maxLength": 255
36+
}
37+
},
38+
"required": [
39+
"Cidr"
40+
],
41+
"additionalProperties": false
42+
}
43+
},
44+
"properties": {
45+
"PrefixListName": {
46+
"description": "Name of Prefix List.",
47+
"type": "string",
48+
"minLength": 1,
49+
"maxLength": 255
50+
},
51+
"PrefixListId": {
52+
"description": "Id of Prefix List.",
53+
"type": "string"
54+
},
55+
"OwnerId": {
56+
"description": "Owner Id of Prefix List.",
57+
"type": "string"
58+
},
59+
"AddressFamily": {
60+
"description": "Ip Version of Prefix List.",
61+
"type": "string",
62+
"enum": [
63+
"IPv4",
64+
"IPv6"
65+
]
66+
},
67+
"MaxEntries": {
68+
"description": "Max Entries of Prefix List.",
69+
"type": "integer",
70+
"minimum": 1
71+
},
72+
"Version": {
73+
"description": "Version of Prefix List.",
74+
"type": "integer"
75+
},
76+
"Tags": {
77+
"description": "Tags for Prefix List",
78+
"type": "array",
79+
"items": {
80+
"$ref": "#/definitions/Tag"
81+
}
82+
},
83+
"Entries": {
84+
"description": "Entries of Prefix List.",
85+
"type": "array",
86+
"items": {
87+
"$ref": "#/definitions/Entry"
88+
}
89+
},
90+
"Arn": {
91+
"description": "The Amazon Resource Name (ARN) of the Prefix List.",
92+
"type": "string"
93+
}
94+
},
95+
"required": [
96+
"PrefixListName",
97+
"MaxEntries",
98+
"AddressFamily"
99+
],
100+
"readOnlyProperties": [
101+
"/properties/PrefixListId",
102+
"/properties/OwnerId",
103+
"/properties/Version",
104+
"/properties/Arn"
105+
],
106+
"primaryIdentifier": [
107+
"/properties/PrefixListId"
108+
],
109+
"tagging": {
110+
"taggable": true,
111+
"tagOnCreate": true,
112+
"tagUpdatable": true,
113+
"cloudFormationSystemTags": true
114+
},
115+
"handlers": {
116+
"create": {
117+
"permissions": [
118+
"EC2:CreateManagedPrefixList",
119+
"EC2:DescribeManagedPrefixLists",
120+
"EC2:CreateTags"
121+
]
122+
},
123+
"read": {
124+
"permissions": [
125+
"EC2:GetManagedPrefixListEntries",
126+
"EC2:DescribeManagedPrefixLists"
127+
]
128+
},
129+
"update": {
130+
"permissions": [
131+
"EC2:DescribeManagedPrefixLists",
132+
"EC2:GetManagedPrefixListEntries",
133+
"EC2:ModifyManagedPrefixList",
134+
"EC2:CreateTags",
135+
"EC2:DeleteTags"
136+
]
137+
},
138+
"delete": {
139+
"permissions": [
140+
"EC2:DeleteManagedPrefixList",
141+
"EC2:DescribeManagedPrefixLists"
142+
]
143+
},
144+
"list": {
145+
"permissions": [
146+
"EC2:DescribeManagedPrefixLists",
147+
"EC2:GetManagedPrefixListEntries"
148+
]
149+
}
150+
},
151+
"additionalProperties": false
152+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from typing import Optional, Type
2+
3+
from localstack.services.cloudformation.resource_provider import (
4+
CloudFormationResourceProviderPlugin,
5+
ResourceProvider,
6+
)
7+
8+
9+
class EC2PrefixListProviderPlugin(CloudFormationResourceProviderPlugin):
10+
name = "AWS::EC2::PrefixList"
11+
12+
def __init__(self):
13+
self.factory: Optional[Type[ResourceProvider]] = None
14+
15+
def load(self):
16+
from localstack.services.ec2.resource_providers.aws_ec2_prefixlist import (
17+
EC2PrefixListProvider,
18+
)
19+
20+
self.factory = EC2PrefixListProvider

0 commit comments

Comments
 (0)