Skip to content

Commit 96691c1

Browse files
aaythapaaahungaws-sam-cli-bot
authored
feat: Attach connectors to source (#2772)
Co-authored-by: Sam Liu <[email protected]> Co-authored-by: aws-sam-cli-bot <[email protected]> Co-authored-by: _sam <[email protected]>
1 parent b4f9ea1 commit 96691c1

File tree

56 files changed

+9311
-19
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+9311
-19
lines changed

integration/combination/test_connectors.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ def tearDown(self):
4747
("combination/connector_sqs_to_function",),
4848
("combination/connector_sns_to_function_write",),
4949
("combination/connector_table_to_function_read",),
50+
("combination/embedded_connector",),
5051
]
5152
)
5253
@retry_once
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[
2+
{
3+
"LogicalResourceId": "MyRole1",
4+
"ResourceType": "AWS::IAM::Role"
5+
},
6+
{
7+
"LogicalResourceId": "MyRole2",
8+
"ResourceType": "AWS::IAM::Role"
9+
},
10+
{
11+
"LogicalResourceId": "TriggerFunction",
12+
"ResourceType": "AWS::Lambda::Function"
13+
},
14+
{
15+
"LogicalResourceId": "MyFunction2",
16+
"ResourceType": "AWS::Lambda::Function"
17+
},
18+
{
19+
"LogicalResourceId": "TriggerFunctionMyConnectorPolicy",
20+
"ResourceType": "AWS::IAM::ManagedPolicy"
21+
}
22+
]
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
Resources:
2+
MyRole1:
3+
Type: AWS::IAM::Role
4+
Properties:
5+
AssumeRolePolicyDocument:
6+
Statement:
7+
- Effect: Allow
8+
Action: sts:AssumeRole
9+
Principal:
10+
Service: lambda.amazonaws.com
11+
ManagedPolicyArns:
12+
- !Sub arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
13+
14+
MyRole2:
15+
Type: AWS::IAM::Role
16+
Properties:
17+
AssumeRolePolicyDocument:
18+
Statement:
19+
- Effect: Allow
20+
Action: sts:AssumeRole
21+
Principal:
22+
Service: lambda.amazonaws.com
23+
ManagedPolicyArns:
24+
- !Sub arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
25+
26+
TriggerFunction:
27+
Type: AWS::Lambda::Function
28+
Connectors:
29+
MyConnector:
30+
Properties:
31+
Destination:
32+
Id: MyFunction2
33+
Permissions:
34+
- Write
35+
Properties:
36+
Role: !GetAtt MyRole1.Arn
37+
Runtime: nodejs14.x
38+
Handler: index.handler
39+
Code:
40+
ZipFile: |
41+
const AWS = require('aws-sdk');
42+
exports.handler = async (event) => {
43+
const params = {
44+
FunctionName: process.env.FUNCTION_NAME,
45+
InvocationType: 'RequestResponse',
46+
Payload: '{}',
47+
};
48+
const lambda = new AWS.Lambda();
49+
const response = await lambda.invoke(params).promise();
50+
if(response.StatusCode !== 200){
51+
throw new Error('Failed to get response from lambda function')
52+
}
53+
return response;
54+
};
55+
Environment:
56+
Variables:
57+
FUNCTION_NAME: !Ref MyFunction2
58+
59+
MyFunction2:
60+
Type: AWS::Lambda::Function
61+
Properties:
62+
Role: !GetAtt MyRole2.Arn
63+
Runtime: nodejs14.x
64+
Handler: index.handler
65+
Code:
66+
ZipFile: |
67+
const AWS = require('aws-sdk');
68+
exports.handler = async (event) => {
69+
console.log(JSON.stringify(event));
70+
};
71+
Metadata:
72+
SamTransformTest: true

samtranslator/model/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ def get_pass_through_attributes(cls) -> Tuple[str, ...]:
147147
return tuple(cls._pass_through_attributes)
148148

149149
@classmethod
150-
def from_dict(cls, logical_id, resource_dict, relative_id=None, sam_plugins=None): # type: ignore[no-untyped-def]
150+
def from_dict(cls, logical_id: str, resource_dict: Dict[str, Any], relative_id: Optional[str] = None, sam_plugins=None) -> "Resource": # type: ignore[no-untyped-def]
151151
"""Constructs a Resource object with the given logical id, based on the given resource dict. The resource dict
152152
is the value associated with the logical id in a CloudFormation template's Resources section, and takes the
153153
following format. ::

samtranslator/model/connector/connector.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ def get_event_source_mappings(
8282

8383
def _is_valid_resource_reference(obj: Dict[str, Any]) -> bool:
8484
id_provided = "Id" in obj
85+
# Every property in ResourceReference can be implied using 'Id', except for 'Qualifier', so users should be able to combine 'Id' and 'Qualifier'
8586
non_id_provided = len([k for k in obj.keys() if k not in ["Id", "Qualifier"]]) > 0
8687
# Must provide Id (with optional Qualifier) or a supported combination of other properties.
8788
return id_provided != non_id_provided

samtranslator/model/eventsources/push.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def]
362362
# The de-dupe happens inside `samtranslator.translator.Translator.translate` method when merging results of
363363
# to_cloudformation() to output template.
364364
self._inject_notification_configuration(function, bucket, bucket_id) # type: ignore[no-untyped-call]
365-
resources.append(S3Bucket.from_dict(bucket_id, bucket)) # type: ignore[no-untyped-call]
365+
resources.append(S3Bucket.from_dict(bucket_id, bucket))
366366

367367
return resources
368368

@@ -1142,7 +1142,7 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def]
11421142
resources.append(lambda_permission)
11431143

11441144
self._inject_lambda_config(function, userpool) # type: ignore[no-untyped-call]
1145-
resources.append(CognitoUserPool.from_dict(userpool_id, userpool)) # type: ignore[no-untyped-call]
1145+
resources.append(CognitoUserPool.from_dict(userpool_id, userpool))
11461146
return resources
11471147

11481148
def _inject_lambda_config(self, function, userpool): # type: ignore[no-untyped-def]

samtranslator/plugins/globals/globals.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Dict, List
1+
from typing import Any, Dict, List
22

33
from samtranslator.model.exceptions import ExceptionWithMessage
44
from samtranslator.public.sdk.resource import SamResourceType

samtranslator/schema/aws_serverless_api.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@
44

55
from typing_extensions import Literal
66

7-
from samtranslator.schema.common import PassThroughProp, BaseModel, SamIntrinsicable, get_prop, DictStrAny
7+
from samtranslator.schema.common import (
8+
PassThroughProp,
9+
BaseModel,
10+
SamIntrinsicable,
11+
get_prop,
12+
DictStrAny,
13+
)
14+
from samtranslator.schema.aws_serverless_connector import EmbeddedConnector
815

916
resourcepolicy = get_prop("sam-property-api-resourcepolicystatement")
1017
cognitoauthorizeridentity = get_prop("sam-property-api-cognitoauthorizationidentity")
@@ -217,6 +224,7 @@ class Resource(BaseModel):
217224
Properties: Properties
218225
Condition: Optional[PassThroughProp]
219226
DeletionPolicy: Optional[PassThroughProp]
227+
Connectors: Optional[Dict[str, EmbeddedConnector]]
220228
UpdatePolicy: Optional[PassThroughProp]
221229
UpdateReplacePolicy: Optional[PassThroughProp]
222230
DependsOn: Optional[PassThroughProp]

samtranslator/schema/aws_serverless_connector.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
resourcereference = get_prop("sam-property-connector-resourcereference")
88
properties = get_prop("sam-resource-connector")
99

10+
PermissionsType = List[Literal["Read", "Write"]]
11+
1012

1113
class ResourceReference(BaseModel):
1214
Id: Optional[str] = resourcereference("Id")
@@ -22,9 +24,28 @@ class ResourceReference(BaseModel):
2224
class Properties(BaseModel):
2325
Source: ResourceReference = properties("Source")
2426
Destination: ResourceReference = properties("Destination")
25-
Permissions: List[Literal["Read", "Write"]] = properties("Permissions")
27+
Permissions: PermissionsType = properties("Permissions")
2628

2729

2830
class Resource(BaseModel):
2931
Type: Literal["AWS::Serverless::Connector"]
3032
Properties: Properties
33+
34+
35+
class SourceReference(BaseModel):
36+
Qualifier: Optional[PassThroughProp] = resourcereference("Qualifier")
37+
38+
39+
class EmbeddedConnectorProperties(BaseModel):
40+
SourceReference: Optional[SourceReference] # TODO: add docs for SourceReference
41+
Destination: ResourceReference = properties("Destination")
42+
Permissions: PermissionsType = properties("Permissions")
43+
44+
45+
# TODO make connectors a part of all CFN Resources
46+
class EmbeddedConnector(BaseModel):
47+
Properties: EmbeddedConnectorProperties
48+
DependsOn: Optional[PassThroughProp]
49+
DeletionPolicy: Optional[PassThroughProp]
50+
Metadata: Optional[PassThroughProp]
51+
UpdatePolicy: Optional[PassThroughProp]

samtranslator/schema/aws_serverless_function.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@
44

55
from typing_extensions import Literal
66

7-
from samtranslator.schema.common import PassThroughProp, BaseModel, SamIntrinsicable, get_prop, DictStrAny, Ref
7+
from samtranslator.schema.common import (
8+
PassThroughProp,
9+
BaseModel,
10+
SamIntrinsicable,
11+
get_prop,
12+
DictStrAny,
13+
Ref,
14+
)
15+
from samtranslator.schema.aws_serverless_connector import EmbeddedConnector
816

917

1018
alexaskilleventproperties = get_prop("sam-property-function-alexaskill")
@@ -547,6 +555,7 @@ class Globals(BaseModel):
547555
class Resource(BaseModel):
548556
Type: Literal["AWS::Serverless::Function"]
549557
Properties: Optional[Properties]
558+
Connectors: Optional[Dict[str, EmbeddedConnector]]
550559
DeletionPolicy: Optional[PassThroughProp]
551560
UpdateReplacePolicy: Optional[PassThroughProp]
552561
Condition: Optional[PassThroughProp]

0 commit comments

Comments
 (0)