Skip to content

Commit

Permalink
Merge pull request #2412 from aws/release-v1.46.0
Browse files Browse the repository at this point in the history
Release 1.46.0 (to main)
  • Loading branch information
hawflau authored Jun 7, 2022
2 parents e38e0dc + aab2d11 commit 496d3ab
Show file tree
Hide file tree
Showing 165 changed files with 13,904 additions and 899 deletions.
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

0 comments on commit 496d3ab

Please sign in to comment.