Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge main to develop #3689

Merged
merged 7 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .cfnlintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ ignore_templates:
- tests/translator/output/**/function_with_intrinsics_resource_attribute.json # CFN now supports intrinsics in DeletionPolicy
- tests/translator/output/**/function_with_snapstart.json # Snapstart intentionally not attached to a lambda version which causes lint issues
- tests/translator/output/**/managed_policies_everything.json # intentionally contains wrong arns
- tests/translator/output/**/function_with_metrics_config.json
ignore_checks:
- E2531 # Deprecated runtime; not relevant for transform tests
- E2533 # Another deprecated runtime; not relevant for transform tests
Expand Down
2 changes: 1 addition & 1 deletion samtranslator/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.92.0"
__version__ = "1.93.0"
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,12 @@ class DeadLetterQueue(BaseModel):

class EventInvokeOnFailure(BaseModel):
Destination: Optional[SamIntrinsicable[str]] = eventinvokeonfailure("Destination")
Type: Optional[Literal["SQS", "SNS", "Lambda", "EventBridge"]] = eventinvokeonfailure("Type")
Type: Optional[Literal["SQS", "SNS", "Lambda", "EventBridge", "S3Bucket"]] = eventinvokeonfailure("Type")


class EventInvokeOnSuccess(BaseModel):
Destination: Optional[SamIntrinsicable[str]] = eventinvokeonsuccess("Destination")
Type: Optional[Literal["SQS", "SNS", "Lambda", "EventBridge"]] = eventinvokeonsuccess("Type")
Type: Optional[Literal["SQS", "SNS", "Lambda", "EventBridge", "S3Bucket"]] = eventinvokeonsuccess("Type")


class EventInvokeDestinationConfig(BaseModel):
Expand Down Expand Up @@ -178,6 +178,7 @@ class KinesisEventProperties(BaseModel):
StartingPositionTimestamp: Optional[PassThroughProp] = kinesiseventproperties("StartingPositionTimestamp")
Stream: PassThroughProp = kinesiseventproperties("Stream")
TumblingWindowInSeconds: Optional[PassThroughProp] = kinesiseventproperties("TumblingWindowInSeconds")
MetricsConfig: Optional[PassThroughProp]


class KinesisEvent(BaseModel):
Expand All @@ -203,6 +204,7 @@ class DynamoDBEventProperties(BaseModel):
StartingPositionTimestamp: Optional[PassThroughProp] = dynamodbeventproperties("StartingPositionTimestamp")
Stream: PassThroughProp = dynamodbeventproperties("Stream")
TumblingWindowInSeconds: Optional[PassThroughProp] = dynamodbeventproperties("TumblingWindowInSeconds")
MetricsConfig: Optional[PassThroughProp]


class DynamoDBEvent(BaseModel):
Expand Down Expand Up @@ -241,6 +243,7 @@ class SQSEventProperties(BaseModel):
MaximumBatchingWindowInSeconds: Optional[PassThroughProp] = sqseventproperties("MaximumBatchingWindowInSeconds")
Queue: PassThroughProp = sqseventproperties("Queue")
ScalingConfig: Optional[PassThroughProp] # Update docs when live
MetricsConfig: Optional[PassThroughProp]


class SQSEvent(BaseModel):
Expand Down
3 changes: 3 additions & 0 deletions samtranslator/model/eventsources/pull.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class PullEventSource(ResourceMacro, metaclass=ABCMeta):
"KmsKeyArn": PassThroughProperty(False),
"ConsumerGroupId": PropertyType(False, IS_STR),
"ScalingConfig": PropertyType(False, IS_DICT),
"MetricsConfig": PropertyType(False, IS_DICT),
}

BatchSize: Optional[Intrinsicable[int]]
Expand All @@ -78,6 +79,7 @@ class PullEventSource(ResourceMacro, metaclass=ABCMeta):
KmsKeyArn: Optional[Intrinsicable[str]]
ConsumerGroupId: Optional[Intrinsicable[str]]
ScalingConfig: Optional[Dict[str, Any]]
MetricsConfig: Optional[Dict[str, Any]]

@abstractmethod
def get_policy_arn(self) -> Optional[str]:
Expand Down Expand Up @@ -145,6 +147,7 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] # noqa: P
lambda_eventsourcemapping.FilterCriteria = self.FilterCriteria
lambda_eventsourcemapping.KmsKeyArn = self.KmsKeyArn
lambda_eventsourcemapping.ScalingConfig = self.ScalingConfig
lambda_eventsourcemapping.MetricsConfig = self.MetricsConfig
self._validate_filter_criteria()

if self.KafkaBootstrapServers:
Expand Down
1 change: 1 addition & 0 deletions samtranslator/model/lambda_.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class LambdaEventSourceMapping(Resource):
"AmazonManagedKafkaEventSourceConfig": GeneratedProperty(),
"SelfManagedKafkaEventSourceConfig": GeneratedProperty(),
"ScalingConfig": GeneratedProperty(),
"MetricsConfig": GeneratedProperty(),
}

runtime_attrs = {"name": lambda self: ref(self.logical_id)}
Expand Down
6 changes: 4 additions & 2 deletions samtranslator/model/sam_resources.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
""" SAM macro definitions """
""" SAM macro definitions """

import copy
from contextlib import suppress
Expand Down Expand Up @@ -441,7 +441,7 @@ def _validate_and_inject_resource(
ARN property, so to handle conditional ifs we have to inject if conditions in the auto created
SQS/SNS resources as well as in the policy documents.
"""
accepted_types_list = ["SQS", "SNS", "EventBridge", "Lambda"]
accepted_types_list = ["SQS", "SNS", "EventBridge", "Lambda", "S3Bucket"]
auto_inject_list = ["SQS", "SNS"]
resource: Optional[Union[SNSTopic, SQSQueue]] = None
policy = {}
Expand Down Expand Up @@ -632,6 +632,8 @@ def _add_event_invoke_managed_policy(
return IAMRolePolicies.event_bus_put_events_role_policy(dest_arn, logical_id)
if _type == "Lambda":
return IAMRolePolicies.lambda_invoke_function_role_policy(dest_arn, logical_id)
if _type == "S3Bucket":
return IAMRolePolicies.s3_send_event_payload_role_policy(dest_arn, logical_id)
return {}

def _construct_role(
Expand Down
15 changes: 13 additions & 2 deletions samtranslator/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -274755,6 +274755,9 @@
"markdownDescription": "The maximum number of times to retry when the function returns an error\\. \n*Type*: Integer \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`MaximumRetryAttempts`](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html#cfn-lambda-eventsourcemapping-maximumretryattempts) property of an `AWS::Lambda::EventSourceMapping` resource\\.",
"title": "MaximumRetryAttempts"
},
"MetricsConfig": {
"$ref": "#/definitions/PassThroughProp"
},
"ParallelizationFactor": {
"allOf": [
{
Expand Down Expand Up @@ -274990,7 +274993,8 @@
"SQS",
"SNS",
"Lambda",
"EventBridge"
"EventBridge",
"S3Bucket"
],
"markdownDescription": "Type of the resource referenced in the destination\\. Supported types are `SQS`, `SNS`, `Lambda`, and `EventBridge`\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is unique to AWS SAM and doesn't have an AWS CloudFormation equivalent\\. \n*Additional notes*: If the type is SQS/SNS and the `Destination` property is left blank, then the SQS/SNS resource is auto generated by SAM\\. To reference the resource, use `<function-logical-id>.DestinationQueue` for SQS or `<function-logical-id>.DestinationTopic` for SNS\\. If the type is Lambda/EventBridge, `Destination` is required\\.",
"title": "Type",
Expand Down Expand Up @@ -275020,7 +275024,8 @@
"SQS",
"SNS",
"Lambda",
"EventBridge"
"EventBridge",
"S3Bucket"
],
"markdownDescription": "Type of the resource referenced in the destination\\. Supported types are `SQS`, `SNS`, `Lambda`, and `EventBridge`\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is unique to AWS SAM and doesn't have an AWS CloudFormation equivalent\\. \n*Additional notes*: If the type is SQS/SNS and the `Destination` property is left blank, then the SQS/SNS resource is auto generated by SAM\\. To reference the resource, use `<function-logical-id>.DestinationQueue` for SQS or `<function-logical-id>.DestinationTopic` for SNS\\. If the type is Lambda/EventBridge, `Destination` is required\\.",
"title": "Type",
Expand Down Expand Up @@ -275502,6 +275507,9 @@
"markdownDescription": "The maximum number of times to retry when the function returns an error\\. \n*Type*: Integer \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`MaximumRetryAttempts`](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html#cfn-lambda-eventsourcemapping-maximumretryattempts) property of an `AWS::Lambda::EventSourceMapping` resource\\.",
"title": "MaximumRetryAttempts"
},
"MetricsConfig": {
"$ref": "#/definitions/PassThroughProp"
},
"ParallelizationFactor": {
"allOf": [
{
Expand Down Expand Up @@ -276759,6 +276767,9 @@
"markdownDescription": "The maximum amount of time, in seconds, to gather records before invoking the function\\. \n*Type*: Integer \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`MaximumBatchingWindowInSeconds`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html#cfn-lambda-eventsourcemapping-maximumbatchingwindowinseconds) property of an `AWS::Lambda::EventSourceMapping` resource\\.",
"title": "MaximumBatchingWindowInSeconds"
},
"MetricsConfig": {
"$ref": "#/definitions/PassThroughProp"
},
"Queue": {
"allOf": [
{
Expand Down
15 changes: 13 additions & 2 deletions schema_source/sam.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,9 @@
"markdownDescription": "The maximum number of times to retry when the function returns an error\\. \n*Type*: Integer \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`MaximumRetryAttempts`](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html#cfn-lambda-eventsourcemapping-maximumretryattempts) property of an `AWS::Lambda::EventSourceMapping` resource\\.",
"title": "MaximumRetryAttempts"
},
"MetricsConfig": {
"$ref": "#/definitions/PassThroughProp"
},
"ParallelizationFactor": {
"allOf": [
{
Expand Down Expand Up @@ -1257,7 +1260,8 @@
"SQS",
"SNS",
"Lambda",
"EventBridge"
"EventBridge",
"S3Bucket"
],
"markdownDescription": "Type of the resource referenced in the destination\\. Supported types are `SQS`, `SNS`, `Lambda`, and `EventBridge`\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is unique to AWS SAM and doesn't have an AWS CloudFormation equivalent\\. \n*Additional notes*: If the type is SQS/SNS and the `Destination` property is left blank, then the SQS/SNS resource is auto generated by SAM\\. To reference the resource, use `<function-logical-id>.DestinationQueue` for SQS or `<function-logical-id>.DestinationTopic` for SNS\\. If the type is Lambda/EventBridge, `Destination` is required\\.",
"title": "Type",
Expand Down Expand Up @@ -1287,7 +1291,8 @@
"SQS",
"SNS",
"Lambda",
"EventBridge"
"EventBridge",
"S3Bucket"
],
"markdownDescription": "Type of the resource referenced in the destination\\. Supported types are `SQS`, `SNS`, `Lambda`, and `EventBridge`\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is unique to AWS SAM and doesn't have an AWS CloudFormation equivalent\\. \n*Additional notes*: If the type is SQS/SNS and the `Destination` property is left blank, then the SQS/SNS resource is auto generated by SAM\\. To reference the resource, use `<function-logical-id>.DestinationQueue` for SQS or `<function-logical-id>.DestinationTopic` for SNS\\. If the type is Lambda/EventBridge, `Destination` is required\\.",
"title": "Type",
Expand Down Expand Up @@ -1769,6 +1774,9 @@
"markdownDescription": "The maximum number of times to retry when the function returns an error\\. \n*Type*: Integer \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`MaximumRetryAttempts`](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html#cfn-lambda-eventsourcemapping-maximumretryattempts) property of an `AWS::Lambda::EventSourceMapping` resource\\.",
"title": "MaximumRetryAttempts"
},
"MetricsConfig": {
"$ref": "#/definitions/PassThroughProp"
},
"ParallelizationFactor": {
"allOf": [
{
Expand Down Expand Up @@ -2957,6 +2965,9 @@
"markdownDescription": "The maximum amount of time, in seconds, to gather records before invoking the function\\. \n*Type*: Integer \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`MaximumBatchingWindowInSeconds`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html#cfn-lambda-eventsourcemapping-maximumbatchingwindowinseconds) property of an `AWS::Lambda::EventSourceMapping` resource\\.",
"title": "MaximumBatchingWindowInSeconds"
},
"MetricsConfig": {
"$ref": "#/definitions/PassThroughProp"
},
"Queue": {
"allOf": [
{
Expand Down
77 changes: 77 additions & 0 deletions tests/translator/input/function_with_event_dest_s3_bucket.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
Parameters:
S3BucketArn1:
Type: String
Default: arn:aws:s3::123456789012:my_bucket-1
S3BucketArn2:
Type: String
Default: arn:aws:s3::123456789012:my_bucket-2
Globals:
Function:
AutoPublishAlias: live
EventInvokeConfig:
MaximumEventAgeInSeconds: 70
MaximumRetryAttempts: 1
DestinationConfig:
OnSuccess:
Type: S3Bucket
Destination: !Ref S3BucketArn1
OnFailure:
Type: S3Bucket
Destination: !Ref S3BucketArn2

Resources:
MyTestFunction:
Type: AWS::Serverless::Function
Properties:
InlineCode: |
exports.handler = function(event, context, callback) {
var event_received_at = new Date().toISOString();
console.log('Event received at: ' + event_received_at);
console.log('Received event:', JSON.stringify(event, null, 2));

if (event.Success) {
console.log("Success");
context.callbackWaitsForEmptyEventLoop = false;
callback(null);
} else {
console.log("Failure");
context.callbackWaitsForEmptyEventLoop = false;
callback(new Error("Failure from event, Success = false, I am failing!"), 'Destination Function Error Thrown');
}
};
Handler: index.handler
Runtime: nodejs12.x
MemorySize: 1024

MyTestFunction2:
Type: AWS::Serverless::Function
Properties:
EventInvokeConfig:
MaximumEventAgeInSeconds: 70
MaximumRetryAttempts: 1
DestinationConfig:
OnSuccess:
Type: S3Bucket
Destination: arn:aws:s3::123456789012:my_bucket-3
OnFailure:
Type: S3Bucket
Destination: arn:aws:s3::123456789012:my_bucket-4
InlineCode: |
exports.handler = function(event, context, callback) {
var event_received_at = new Date().toISOString();
console.log('Event received at: ' + event_received_at);
console.log('Received event:', JSON.stringify(event, null, 2));

if (event.Success) {
console.log("Success");
context.callbackWaitsForEmptyEventLoop = false;
callback(null);
} else {
console.log("Failure");
context.callbackWaitsForEmptyEventLoop = false;
callback(new Error("Failure from event, Success = false, I am failing!"), 'Destination Function Error Thrown');
}
};
Handler: index.handler
Runtime: nodejs12.x
MemorySize: 1024
58 changes: 58 additions & 0 deletions tests/translator/input/function_with_metrics_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
Resources:
FilteredEventsFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: s3://sam-demo-bucket/metricsConfig.zip
Handler: index.handler
Runtime: nodejs16.x
Events:
KinesisStream:
Type: Kinesis
Properties:
Stream: !GetAtt KinesisStream.Arn
StartingPosition: LATEST
MetricsConfig:
Metrics:
- EventCount
FilterCriteria:
Filters:
- Pattern: '{"name": "value"}'
- Pattern: '{"name2": "value2"}'
DynamoDBStreamEvent:
Type: DynamoDB
Properties:
Stream: !GetAtt DynamoDBTable.StreamArn
StartingPosition: TRIM_HORIZON
MetricsConfig:
Metrics: []
FilterCriteria:
Filters: []
MySqsQueue:
Type: SQS
Properties:
Queue: !GetAtt MySqsQueue.Arn
MetricsConfig:
Metrics:
- EventCount
FilterCriteria:
Filters:
- Pattern: '{"name": "value"}'

KinesisStream:
Type: AWS::Kinesis::Stream
Properties:
ShardCount: 1

DynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
- AttributeName: id
AttributeType: S
BillingMode: PAY_PER_REQUEST
KeySchema:
- AttributeName: id
KeyType: HASH

MySqsQueue:
Type: AWS::SQS::Queue
Loading