Skip to content

Commit

Permalink
Merge release-v1.49.0 into main
Browse files Browse the repository at this point in the history
  • Loading branch information
aws-sam-cli-bot committed Aug 8, 2022
2 parents 4c3f5f8 + 1eebf86 commit 8505451
Show file tree
Hide file tree
Showing 16 changed files with 719 additions and 5 deletions.
5 changes: 5 additions & 0 deletions integration/combination/test_function_with_s3_bucket.py
@@ -1,6 +1,11 @@
from unittest.case import skipIf

from integration.helpers.base_test import BaseTest
from integration.helpers.resource import current_region_does_not_support
from integration.config.service_names import S3_EVENTS


@skipIf(current_region_does_not_support([S3_EVENTS]), "S3 Events feature is not supported in this testing region")
class TestFunctionWithS3Bucket(BaseTest):
def test_function_with_s3_bucket_trigger(self):
self.create_and_verify_stack("combination/function_with_s3")
Expand Down
1 change: 1 addition & 0 deletions integration/config/service_names.py
Expand Up @@ -23,3 +23,4 @@
CUSTOM_DOMAIN = "CustomDomain"
ARM = "ARM"
EFS = "EFS"
S3_EVENTS = "S3Events"
16 changes: 16 additions & 0 deletions integration/single/test_function_with_http_api_and_auth.py
@@ -1,11 +1,27 @@
import logging
from unittest.case import skipIf

from tenacity import stop_after_attempt, retry_if_exception_type, after_log, wait_exponential, retry, wait_random

from integration.helpers.base_test import BaseTest
from integration.helpers.resource import current_region_does_not_support

LOG = logging.getLogger(__name__)


@skipIf(current_region_does_not_support(["HttpApi"]), "HttpApi is not supported in this testing region")
class TestFunctionWithHttpApiAndAuth(BaseTest):
"""
AWS::Lambda::Function tests with http api events and auth
"""

@retry(
stop=stop_after_attempt(5),
wait=wait_exponential(multiplier=1, min=4, max=10) + wait_random(0, 1),
retry=retry_if_exception_type(AssertionError),
after=after_log(LOG, logging.WARNING),
reraise=True,
)
def test_function_with_http_api_and_auth(self):
# If the request is not signed, which none of the below are, IAM will respond with a "Forbidden" message.
# We are not testing that IAM auth works here, we are simply testing if it was applied.
Expand Down
2 changes: 1 addition & 1 deletion samtranslator/__init__.py
@@ -1 +1 @@
__version__ = "1.48.0"
__version__ = "1.49.0"
9 changes: 9 additions & 0 deletions samtranslator/model/eventsources/push.py
Expand Up @@ -96,6 +96,7 @@ class Schedule(PushEventSource):
"Schedule": PropertyType(True, is_str()),
"Input": PropertyType(False, is_str()),
"Enabled": PropertyType(False, is_type(bool)),
"State": PropertyType(False, is_str()),
"Name": PropertyType(False, is_str()),
"Description": PropertyType(False, is_str()),
"DeadLetterConfig": PropertyType(False, is_type(dict)),
Expand All @@ -122,8 +123,16 @@ def to_cloudformation(self, **kwargs):
resources.append(events_rule)

events_rule.ScheduleExpression = self.Schedule

if self.State and self.Enabled is not None:
raise InvalidEventException(self.relative_id, "State and Enabled Properties cannot both be specified.")

if self.State:
events_rule.State = self.State

if self.Enabled is not None:
events_rule.State = "ENABLED" if self.Enabled else "DISABLED"

events_rule.Name = self.Name
events_rule.Description = self.Description

Expand Down
13 changes: 11 additions & 2 deletions samtranslator/swagger/swagger.py
Expand Up @@ -647,7 +647,10 @@ def set_path_default_authorizer(
# We want to ensure only a single Authorizer security entry exists while keeping everything else
for security in existing_security:
SwaggerEditor.validate_is_dict(
security, "{} in Security for path {} is not a valid dictionary.".format(security, path)
security,
"{} in Security for path {} method {} is not a valid dictionary.".format(
security, path, method_name
),
)
if authorizer_names.isdisjoint(security.keys()):
existing_non_authorizer_security.append(security)
Expand Down Expand Up @@ -703,7 +706,7 @@ def set_path_default_apikey_required(self, path):
:param string path: Path name
"""

for _, method_definition in self.iter_on_all_methods_for_path(path):
for method_name, method_definition in self.iter_on_all_methods_for_path(path):
existing_security = method_definition.get("security", [])
apikey_security_names = set(["api_key", "api_key_false"])
existing_non_apikey_security = []
Expand All @@ -714,6 +717,12 @@ def set_path_default_apikey_required(self, path):
# (e.g. sigv4 (AWS_IAM), authorizers, NONE (marker for ignoring default authorizer))
# We want to ensure only a single ApiKey security entry exists while keeping everything else
for security in existing_security:
SwaggerEditor.validate_is_dict(
security,
"{} in Security for path {} method {} is not a valid dictionary.".format(
security, path, method_name
),
)
if apikey_security_names.isdisjoint(security.keys()):
existing_non_apikey_security.append(security)
else:
Expand Down
39 changes: 38 additions & 1 deletion tests/model/eventsources/test_schedule_event_source.py
@@ -1,9 +1,9 @@
from unittest.mock import Mock, patch
from unittest import TestCase

from samtranslator.model.eventsources.push import Schedule
from samtranslator.model.lambda_ import LambdaFunction
from samtranslator.model.exceptions import InvalidEventException
from parameterized import parameterized


class ScheduleEventSource(TestCase):
Expand All @@ -13,6 +13,27 @@ def setUp(self):
self.schedule_event_source.Schedule = "rate(1 minute)"
self.func = LambdaFunction("func")

def test_to_cloudformation_returns_permission_and_schedule_resources(self):
resources = self.schedule_event_source.to_cloudformation(function=self.func)
self.assertEqual(len(resources), 2)
self.assertEqual(resources[0].resource_type, "AWS::Events::Rule")
self.assertEqual(resources[1].resource_type, "AWS::Lambda::Permission")

schedule = resources[0]
self.assertEqual(schedule.ScheduleExpression, "rate(1 minute)")
self.assertIsNone(schedule.State)

def test_to_cloudformation_transforms_enabled_boolean_to_state(self):
self.schedule_event_source.Enabled = True
resources = self.schedule_event_source.to_cloudformation(function=self.func)
schedule = resources[0]
self.assertEqual(schedule.State, "ENABLED")

self.schedule_event_source.Enabled = False
resources = self.schedule_event_source.to_cloudformation(function=self.func)
schedule = resources[0]
self.assertEqual(schedule.State, "DISABLED")

def test_to_cloudformation_with_retry_policy(self):
retry_policy = {"MaximumRetryAttempts": "10", "MaximumEventAgeInSeconds": "300"}
self.schedule_event_source.RetryPolicy = retry_policy
Expand Down Expand Up @@ -70,3 +91,19 @@ def test_to_cloudformation_with_dlq_generated_with_intrinsic_function_custom_log
self.schedule_event_source.DeadLetterConfig = dead_letter_config
with self.assertRaises(InvalidEventException):
self.schedule_event_source.to_cloudformation(function=self.func)

@parameterized.expand(
[
(True, "Enabled"),
(True, "Disabled"),
(True, {"FN:FakeIntrinsic": "something"}),
(False, "Enabled"),
(False, "Disabled"),
(False, {"FN:FakeIntrinsic": "something"}),
]
)
def test_to_cloudformation_invalid_defined_both_enabled_and_state_provided(self, enabled_value, state_value):
self.schedule_event_source.Enabled = enabled_value
self.schedule_event_source.State = state_value
with self.assertRaises(InvalidEventException):
self.schedule_event_source.to_cloudformation(function=self.func)
@@ -0,0 +1,18 @@
Transform: "AWS::Serverless-2016-10-31"

Resources:
ScheduledFunction:
Type: 'AWS::Serverless::Function'
Properties:
CodeUri: s3://sam-demo-bucket/hello.zip?versionId=3Tcgv52_0GaDvhDva4YciYeqRyPnpIcO
Handler: hello.handler
Runtime: python3.10
Events:
Schedule1:
Type: Schedule
Properties:
Schedule: 'rate(1 minute)'
Name: test-schedule
Description: Test Schedule
State: "Enabled"
Enabled: True
@@ -0,0 +1,45 @@
transformId: AWS::Serverless-2016-10-31
AWSTemplateFormatVersion: '2010-09-09'
Resources:
AuthFunction:
Type: AWS::Serverless::Function
AccessingPartyAPI:
Type: AWS::Serverless::Api
Properties:
EndpointConfiguration: REGIONAL
StageName: demo
Auth:
ApiKeyRequired: true

DefinitionBody:
paths:
"/path":
put:
responses:
'201':
content:
application/json:
schema:
"$ref": "abcd"
x-amazon-apigateway-integration:
contentHandling: CONVERT_TO_TEXT
responses:
default:
statusCode: '200'
uri:
Fn::Sub: foobar
httpMethod: POST
passthroughBehavior: when_no_match
type: aws_proxy
requestBody:
content:
application/json:
schema:
required:
- readoutId
- status
type: object
security:
- []

openapi: 3.0.3
35 changes: 35 additions & 0 deletions tests/translator/input/function_with_event_schedule_state.yaml
@@ -0,0 +1,35 @@
Transform: "AWS::Serverless-2016-10-31"
Parameters:
ScheduleState:
Type: String
Default: Disabled

Resources:
ScheduledFunction:
Type: 'AWS::Serverless::Function'
Properties:
CodeUri: s3://sam-demo-bucket/hello.zip?versionId=3Tcgv52_0GaDvhDva4YciYeqRyPnpIcO
Handler: hello.handler
Runtime: python3.10
Events:
Schedule1:
Type: Schedule
Properties:
Schedule: 'rate(1 minute)'
Name: test-schedule
Description: Test Schedule
State: "Enabled"
Schedule2:
Type: Schedule
Properties:
Schedule: 'rate(1 minute)'
Name: test-schedule
Description: Test Schedule
State: !Sub "Enabled"
Schedule3:
Type: Schedule
Properties:
Schedule: 'rate(1 minute)'
Name: test-schedule
Description: Test Schedule
State: !Ref ScheduleState

0 comments on commit 8505451

Please sign in to comment.