Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
02921bc
fix: add validation for API property Model (#2340)
jonife Mar 22, 2022
57d2509
refactor: Make _get_function_names less verbose (#2223)
aahung Mar 23, 2022
97794f0
Merge pull request #2363 from aws/release/v1.44.0
hawflau Mar 28, 2022
6625df9
fix: Add validation for SecretsManagerKmsKeyId (#2323)
jonife Mar 29, 2022
66f6d3b
Bump minimal boto3 version to 1.19.5 (#2365)
hawflau Mar 31, 2022
a3c40bb
fix: Add retries to SAR service calls on throttle (#2352)
mildaniel Apr 4, 2022
86522b2
fix: use formatting instead of concatenating when preparing the excep…
mndeveci Apr 4, 2022
b94a290
Merge pull request #2371 from aws/release/v1.45.0
hawflau Apr 6, 2022
c1a6690
chore: sync foss changes (#2359)
mingkun2020 Apr 8, 2022
e4ffc6e
feat(http-api): Add a built-in AWS_IAM authorizer for HTTP APIs (#1924)
harrisonhjones Apr 13, 2022
2b3b5b4
reduce CloudFormation template size (#2368)
PatMyron Apr 19, 2022
10a100b
chore: Add checkbox for intrinsic validation changes (#2379)
mildaniel Apr 21, 2022
6b5de87
Adding ApiKeySourceType. (#2298)
lee-11 Apr 21, 2022
6638c32
chore: Update PR template wording (#2383)
mildaniel Apr 21, 2022
366fc39
chore(test): Move assert_ to assertTrue (#2382)
jfuss Apr 22, 2022
9306a03
fix: use InvalidDocumentException instead of ValueError (#2376)
mndeveci Apr 22, 2022
2be47df
chore: remove sys.path override (#2380)
jfuss Apr 25, 2022
8730d26
fix: wrap InvalidTemplateException's with InvalidDocumentException (#…
torresxb1 May 3, 2022
2af8d47
fix(furl): Support condition attribute on generated function url reso…
moelasmar May 3, 2022
bdbe412
fix: raise InvalidEventException for incorrect Properties field usage…
mndeveci May 9, 2022
8d0e058
fix: apply resource conditions to DeploymentPreference resources (#1578)
keetonian May 19, 2022
f7418d8
feat: improve new PR and issue labeling for triaging (#2400)
torresxb1 May 19, 2022
6188d82
Furl AutopublishAlias bug fix (#2378)
jonife May 19, 2022
6f73f4a
chore(tests): Update FURL integ test to test invoke (#2401)
hawflau May 23, 2022
24fd3a1
chore(docs): Update policy_templates.rst (#2403)
danxgh10 May 24, 2022
aab2d11
chore: bump version to 1.46.0
aws-sam-cli-bot Jun 7, 2022
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
28 changes: 0 additions & 28 deletions .github/ISSUE_TEMPLATE.md

This file was deleted.

4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
name: Bug report
about: Create an issue to report a bug for the SAM Translator
title: ''
labels: ''
title: "Bug: TITLE"
labels: ['type/bug', 'stage/needs-triage']
assignees: ''

---
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
blank_issues_enabled: false
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
name: Feature request
about: Suggest an idea/feature/enhancement for the SAM Translator
title: ''
labels: ''
title: "Feature request: TITLE"
labels: ['type/feature', 'stage/needs-triage']
assignees: ''

---
Expand Down
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATE/other.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
name: Other
about: Choose if your issue doesn't apply to the other templates
title: ''
labels: ['stage/needs-triage']
assignees: ''

---
3 changes: 3 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
- [ ] `make pr` passes
- [ ] Update documentation
- [ ] Verify transformed template deploys and application functions as expected
- [ ] Do these changes include any template validations?
- [ ] Did the newly validated properties support intrinsics prior to adding the validations? (If unsure, please review [Intrinsic Functions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html) before proceeding).
- [ ] Does the pull request ensure that intrinsics remain functional with the new validations?

*Examples?*

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ jobs:
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['pr/external']
labels: ['pr/external', 'stage/needs-triage']
})
}
4 changes: 3 additions & 1 deletion DEVELOPMENT_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ Running Tests

### Unit testing with one Python version

If you're trying to do a quick run, it's ok to use the current python version. Run `make pr`.
If you're trying to do a quick run, it's ok to use the current python version.
Run `make test` or `make test-fast`. Once all tests pass make sure to run
`make pr` before sending out your PR.

### Unit testing with multiple Python versions

Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
target:
$(info ${HELP_MESSAGE})
@exit 0

init:
pip install -e '.[dev]'

test:
pytest --cov samtranslator --cov-report term-missing --cov-fail-under 95 -n auto tests/*

test-fast:
pytest -x --cov samtranslator --cov-report term-missing --cov-fail-under 95 -n auto tests/*

test-cov-report:
pytest --cov samtranslator --cov-report term-missing --cov-report html --cov-fail-under 95 tests/*

Expand Down
13 changes: 2 additions & 11 deletions bin/sam-translate.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
from samtranslator.translator.transform import transform
from samtranslator.yaml_helper import yaml_parse
from samtranslator.model.exceptions import InvalidDocumentException
from samtranslator.feature_toggle.feature_toggle import FeatureToggleLocalConfigProvider, FeatureToggle

LOG = logging.getLogger(__name__)
cli_options = docopt(__doc__)
Expand Down Expand Up @@ -98,16 +97,8 @@ def transform_template(input_file_path, output_file_path):
sam_template = yaml_parse(f)

try:
feature_toggle = FeatureToggle(
FeatureToggleLocalConfigProvider(
os.path.join(my_path, "..", "tests", "feature_toggle", "input", "feature_toggle_config.json")
),
stage=None,
account_id=None,
region=None,
)
cloud_formation_template = transform(sam_template, {}, ManagedPolicyLoader(iam_client), feature_toggle)
cloud_formation_template_prettified = json.dumps(cloud_formation_template, indent=2)
cloud_formation_template = transform(sam_template, {}, ManagedPolicyLoader(iam_client))
cloud_formation_template_prettified = json.dumps(cloud_formation_template, indent=1)

with open(output_file_path, "w") as f:
f.write(cloud_formation_template_prettified)
Expand Down
2 changes: 1 addition & 1 deletion docs/policy_templates.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ For Example:
Properties:
...
Policies:
# Give DynamoDB Full Access to your Lambda Function
# Give your Lambda Function Full Access to DynamoDB
- AmazonDynamoDBFullAccess
...

Expand Down
130 changes: 130 additions & 0 deletions integration/combination/test_api_with_authorizer_apikey.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
from unittest.case import skipIf

import requests

from integration.helpers.base_test import BaseTest
from integration.helpers.deployer.utils.retry import retry
from integration.helpers.exception import StatusCodeError
from integration.helpers.resource import current_region_does_not_support
from integration.config.service_names import COGNITO


class TestApiWithAuthorizerApiKey(BaseTest):
def test_authorizer_apikey(self):
self.create_and_verify_stack("combination/api_with_authorizer_apikey")
stack_outputs = self.get_stack_outputs()

rest_api_id = self.get_physical_id_by_type("AWS::ApiGateway::RestApi")
apigw_client = self.client_provider.api_client

authorizers = apigw_client.get_authorizers(restApiId=rest_api_id)["items"]
lambda_authorizer_uri = (
"arn:aws:apigateway:"
+ self.my_region
+ ":lambda:path/2015-03-31/functions/"
+ stack_outputs["AuthorizerFunctionArn"]
+ "/invocations"
)

lambda_token_authorizer = get_authorizer_by_name(authorizers, "MyLambdaTokenAuth")
self.assertEqual(lambda_token_authorizer["type"], "TOKEN", "lambdaTokenAuthorizer: Type must be TOKEN")
self.assertEqual(
lambda_token_authorizer["identitySource"],
"method.request.header.Authorization",
"lambdaTokenAuthorizer: identity source must be method.request.header.Authorization",
)
self.assertIsNone(
lambda_token_authorizer.get("authorizerCredentials"),
"lambdaTokenAuthorizer: authorizer credentials must not be set",
)
self.assertIsNone(
lambda_token_authorizer.get("identityValidationExpression"),
"lambdaTokenAuthorizer: validation expression must not be set",
)
self.assertEqual(
lambda_token_authorizer["authorizerUri"],
lambda_authorizer_uri,
"lambdaTokenAuthorizer: authorizer URI must be the Lambda Function Authorizer's URI",
)
self.assertIsNone(
lambda_token_authorizer.get("authorizerResultTtlInSeconds"), "lambdaTokenAuthorizer: TTL must not be set"
)

resources = apigw_client.get_resources(restApiId=rest_api_id)["items"]

lambda_token_get_method_result = get_method(resources, "/lambda-token-api-key", rest_api_id, apigw_client)
self.assertEqual(
lambda_token_get_method_result["authorizerId"],
lambda_token_authorizer["id"],
"lambdaTokenAuthorizer: GET method must be configured to use the Lambda Token Authorizer",
)

base_url = stack_outputs["ApiUrl"]

self.verify_authorized_request(base_url + "none", 200)
self.verify_authorized_request(base_url + "lambda-token-api-key", 401)
# ApiKeySourceType is AUTHORIZER. This will trigger the Lambda Authorizer and in turn returns the api key
self.verify_authorized_request(base_url + "lambda-token-api-key", 200, "Authorization", "allow")

api_key_id = stack_outputs["ApiKeyId"]
key = apigw_client.get_api_key(apiKey=api_key_id, includeValue=True)

self.verify_authorized_request(base_url + "lambda-token-api-key", 401)
# ApiKeySourceType is AUTHORIZER. Passing api key via x-api-key will not get authorized
self.verify_authorized_request(base_url + "lambda-token-api-key", 401, "x-api-key", key["value"])

@retry(StatusCodeError, 10)
def verify_authorized_request(
self,
url,
expected_status_code,
header_key=None,
header_value=None,
):
if not header_key or not header_value:
response = requests.get(url)
else:
headers = {header_key: header_value}
response = requests.get(url, headers=headers)
status = response.status_code
if status != expected_status_code:
raise StatusCodeError(
"Request to {} failed with status: {}, expected status: {}".format(url, status, expected_status_code)
)

if not header_key or not header_value:
self.assertEqual(
status, expected_status_code, "Request to " + url + " must return HTTP " + str(expected_status_code)
)
else:
self.assertEqual(
status,
expected_status_code,
"Request to "
+ url
+ " ("
+ header_key
+ ": "
+ header_value
+ ") must return HTTP "
+ str(expected_status_code),
)


def get_authorizer_by_name(authorizers, name):
for authorizer in authorizers:
if authorizer["name"] == name:
return authorizer
return None


def get_resource_by_path(resources, path):
for resource in resources:
if resource["path"] == path:
return resource
return None


def get_method(resources, path, rest_api_id, apigw_client):
resource = get_resource_by_path(resources, path)
return apigw_client.get_method(restApiId=rest_api_id, resourceId=resource["id"], httpMethod="GET")
48 changes: 48 additions & 0 deletions integration/combination/test_custom_http_api_domains_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from unittest.case import skipIf

from integration.config.service_names import CUSTOM_DOMAIN
from integration.helpers.base_internal_test import BaseInternalTest
from integration.helpers.file_resources import FILE_TO_S3_URI_MAP
from integration.helpers.resource import current_region_not_included


@skipIf(
current_region_not_included([CUSTOM_DOMAIN]),
"CustomDomain is not supported in this testing region",
)
class TestCustomHttpApiDomains(BaseInternalTest):
def test_custom_http_api_domains_regional(self):
self.create_and_verify_stack("combination/http_api_with_custom_domains_regional")

domain_name_list = self.get_stack_resources("AWS::ApiGatewayV2::DomainName")
self.assertEqual(1, len(domain_name_list))

domain_name_id = self.get_physical_id_by_type("AWS::ApiGatewayV2::DomainName")

api_gateway_client = self.client_provider.api_v2_client
result = api_gateway_client.get_domain_name(DomainName=domain_name_id)

self.assertEqual("httpapi.sam-gamma-regional.com", result["DomainName"])

mtls_auth_config = result["MutualTlsAuthentication"]
self.assertEqual(FILE_TO_S3_URI_MAP["MTLSCert.pem"]["uri"], mtls_auth_config["TruststoreUri"])

domain_name_configs = result["DomainNameConfigurations"]
self.assertEqual(1, len(domain_name_configs))
domain_name_config = domain_name_configs[0]

self.assertEqual("REGIONAL", domain_name_config["EndpointType"])
self.assertEqual("TLS_1_2", domain_name_config["SecurityPolicy"])

def test_custom_http_api_domains_regional_ownership_verification(self):
self.create_and_verify_stack("combination/http_api_with_custom_domains_regional_ownership_verification")

domain_name_id = self.get_physical_id_by_type("AWS::ApiGatewayV2::DomainName")
api_gateway_client = self.client_provider.api_v2_client
result = api_gateway_client.get_domain_name(DomainName=domain_name_id)

domain_name_configs = result["DomainNameConfigurations"]
self.assertEqual(1, len(domain_name_configs))
domain_name_config = domain_name_configs[0]

self.assertIsNotNone(domain_name_config.get("OwnershipVerificationCertificateArn"))
59 changes: 59 additions & 0 deletions integration/combination/test_custom_rest_api_domains.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from unittest.case import skipIf

from integration.config.service_names import CUSTOM_DOMAIN
from integration.helpers.base_internal_test import BaseInternalTest
from integration.helpers.file_resources import FILE_TO_S3_URI_MAP
from integration.helpers.resource import current_region_not_included


@skipIf(
current_region_not_included([CUSTOM_DOMAIN]),
"CustomDomain is not supported in this testing region",
)
class TestCustomRestApiDomains(BaseInternalTest):
def test_custom_rest_api_domains_edge(self):
self.create_and_verify_stack("combination/api_with_custom_domains_edge")
domain_name_list = self.get_stack_resources("AWS::ApiGateway::DomainName")
self.assertEqual(1, len(domain_name_list))

domain_name_id = self.get_physical_id_by_type("AWS::ApiGateway::DomainName")
api_gateway_client = self.client_provider.api_client
result = api_gateway_client.get_domain_name(domainName=domain_name_id)

self.assertEqual("sam-gamma-edge.com", result["domainName"])

end_point_config = result["endpointConfiguration"]
end_point_types = end_point_config["types"]
self.assertEqual(1, len(end_point_types))
self.assertEqual("EDGE", end_point_types[0])

def test_custom_rest_api_domains_regional(self):
self.create_and_verify_stack("combination/api_with_custom_domains_regional")

domain_name_list = self.get_stack_resources("AWS::ApiGateway::DomainName")
self.assertEqual(1, len(domain_name_list))

domain_name_id = self.get_physical_id_by_type("AWS::ApiGateway::DomainName")

api_gateway_client = self.client_provider.api_client
result = api_gateway_client.get_domain_name(domainName=domain_name_id)

self.assertEqual("sam-gamma-regional.com", result["domainName"])
self.assertEqual("TLS_1_2", result["securityPolicy"])

end_point_config = result["endpointConfiguration"]
end_point_types = end_point_config["types"]
self.assertEqual(1, len(end_point_types))
self.assertEqual("REGIONAL", end_point_types[0])

mtls_auth_config = result["mutualTlsAuthentication"]
self.assertEqual(FILE_TO_S3_URI_MAP["MTLSCert.pem"]["uri"], mtls_auth_config["truststoreUri"])

def test_custom_rest_api_domains_regional_ownership_verification(self):
self.create_and_verify_stack("combination/api_with_custom_domains_regional_ownership_verification")

domain_name_id = self.get_physical_id_by_type("AWS::ApiGateway::DomainName")
api_gateway_client = self.client_provider.api_client
result = api_gateway_client.get_domain_name(domainName=domain_name_id)

self.assertIsNotNone(result.get("ownershipVerificationCertificateArn"))
Loading