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

fix: Fix Propagate Tags when Tags is defined in Globals #3284

Merged
merged 1 commit into from
Aug 2, 2023
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
5 changes: 3 additions & 2 deletions samtranslator/plugins/api/implicit_api_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,11 @@ def _add_tags_to_implicit_api_if_necessary(
implicit_api_resource = template.get(self.IMPLICIT_API_LOGICAL_ID)
globals_var = template.get_globals().get(SamResourceType(resource.type).name, {})
should_propagate_tags = resource.properties.get("PropagateTags") or globals_var.get("PropagateTags")
tags_properties = resource.properties.get("Tags") or globals_var.get("Tags")

if implicit_api_resource and resource.properties.get("Tags") and should_propagate_tags:
if implicit_api_resource and tags_properties and should_propagate_tags:
# This makes an assumption that the SAM resource has 'Tags' property and is a dictionary.
implicit_api_resource.properties.setdefault("Tags", {}).update(resource.properties["Tags"])
implicit_api_resource.properties.setdefault("Tags", {}).update(tags_properties)
implicit_api_resource.properties["PropagateTags"] = True

@cw_timer(prefix="Plugin-ImplicitApi")
Expand Down
3 changes: 3 additions & 0 deletions tests/plugins/api/test_implicit_api_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ def test_must_verify_expected_keys_exist(self):
api_events = {"Api1": {"Type": "Api", "Properties": {"Path": "/", "Methid": "POST"}}}

template = Mock()
template.get_globals.return_value = {}
function_events_mock = Mock()
function = SamResource({"Type": SamResourceType.Function.value, "Properties": {"Events": function_events_mock}})
function_events_mock.update = Mock()
Expand All @@ -380,6 +381,7 @@ def test_must_verify_method_is_string(self):
api_events = {"Api1": {"Type": "Api", "Properties": {"Path": "/", "Method": ["POST"]}}}

template = Mock()
template.get_globals.return_value = {}
function_events_mock = Mock()
function = SamResource({"Type": SamResourceType.Function.value, "Properties": {"Events": function_events_mock}})
function_events_mock.update = Mock()
Expand Down Expand Up @@ -411,6 +413,7 @@ def test_must_verify_path_is_string(self):
api_events = {"Api1": {"Type": "Api", "Properties": {"Path": ["/"], "Method": "POST"}}}

template = Mock()
template.get_globals.return_value = {}
function_events_mock = Mock()
function = SamResource({"Type": SamResourceType.Function.value, "Properties": {"Events": function_events_mock}})
function_events_mock.update = Mock()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Globals:
Function:
Tags:
test: 'yes'

Resources:
ApiFunction: # Adds a GET api endpoint at "/" to the ApiGatewayApi via an Api event
Type: AWS::Serverless::Function
Properties:
PropagateTags: true
Events:
ApiEvent:
Type: Api
Properties:
Path: /
Method: get
RequestParameters:
- method.request.header.Authorization
- method.request.querystring.keyword:
Required: true
Caching: false
Runtime: python3.7
Handler: index.handler
InlineCode: |-
def handler(event, context):
return {'body': 'Hello World!', 'statusCode': 200}
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
{
"Resources": {
"ApiFunction": {
"Properties": {
"Code": {
"ZipFile": "def handler(event, context):\n return {'body': 'Hello World!', 'statusCode': 200}"
},
"Handler": "index.handler",
"Role": {
"Fn::GetAtt": [
"ApiFunctionRole",
"Arn"
]
},
"Runtime": "python3.7",
"Tags": [
{
"Key": "test",
"Value": "yes"
}
]
},
"Type": "AWS::Lambda::Function"
},
"ApiFunctionApiEventPermissionProd": {
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": {
"Ref": "ApiFunction"
},
"Principal": "apigateway.amazonaws.com",
"SourceArn": {
"Fn::Sub": [
"arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/",
{
"__ApiId__": {
"Ref": "ServerlessRestApi"
},
"__Stage__": "*"
}
]
}
},
"Type": "AWS::Lambda::Permission"
},
"ApiFunctionRole": {
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
}
}
],
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
"arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
],
"Tags": [
{
"Key": "test",
"Value": "yes"
}
]
},
"Type": "AWS::IAM::Role"
},
"ServerlessRestApi": {
"Properties": {
"Body": {
"info": {
"title": {
"Ref": "AWS::StackName"
},
"version": "1.0"
},
"paths": {
"/": {
"get": {
"parameters": [
{
"in": "header",
"name": "Authorization",
"required": false,
"type": "string"
},
{
"in": "query",
"name": "keyword",
"required": true,
"type": "string"
}
],
"responses": {},
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ApiFunction.Arn}/invocations"
}
}
}
}
},
"swagger": "2.0"
},
"EndpointConfiguration": {
"Types": [
"REGIONAL"
]
},
"Parameters": {
"endpointConfigurationTypes": "REGIONAL"
},
"Tags": [
{
"Key": "test",
"Value": "yes"
}
]
},
"Type": "AWS::ApiGateway::RestApi"
},
"ServerlessRestApiDeployment4036e5c19a": {
"Properties": {
"Description": "RestApi deployment id: 4036e5c19a6892f11f6cc916e1588a5723066abf",
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"StageName": "Stage"
},
"Type": "AWS::ApiGateway::Deployment"
},
"ServerlessRestApiProdStage": {
"Properties": {
"DeploymentId": {
"Ref": "ServerlessRestApiDeployment4036e5c19a"
},
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"StageName": "Prod",
"Tags": [
{
"Key": "test",
"Value": "yes"
}
]
},
"Type": "AWS::ApiGateway::Stage"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
{
"Resources": {
"ApiFunction": {
"Properties": {
"Code": {
"ZipFile": "def handler(event, context):\n return {'body': 'Hello World!', 'statusCode': 200}"
},
"Handler": "index.handler",
"Role": {
"Fn::GetAtt": [
"ApiFunctionRole",
"Arn"
]
},
"Runtime": "python3.7",
"Tags": [
{
"Key": "test",
"Value": "yes"
}
]
},
"Type": "AWS::Lambda::Function"
},
"ApiFunctionApiEventPermissionProd": {
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": {
"Ref": "ApiFunction"
},
"Principal": "apigateway.amazonaws.com",
"SourceArn": {
"Fn::Sub": [
"arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/",
{
"__ApiId__": {
"Ref": "ServerlessRestApi"
},
"__Stage__": "*"
}
]
}
},
"Type": "AWS::Lambda::Permission"
},
"ApiFunctionRole": {
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
}
}
],
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
"arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
],
"Tags": [
{
"Key": "test",
"Value": "yes"
}
]
},
"Type": "AWS::IAM::Role"
},
"ServerlessRestApi": {
"Properties": {
"Body": {
"info": {
"title": {
"Ref": "AWS::StackName"
},
"version": "1.0"
},
"paths": {
"/": {
"get": {
"parameters": [
{
"in": "header",
"name": "Authorization",
"required": false,
"type": "string"
},
{
"in": "query",
"name": "keyword",
"required": true,
"type": "string"
}
],
"responses": {},
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ApiFunction.Arn}/invocations"
}
}
}
}
},
"swagger": "2.0"
},
"EndpointConfiguration": {
"Types": [
"REGIONAL"
]
},
"Parameters": {
"endpointConfigurationTypes": "REGIONAL"
},
"Tags": [
{
"Key": "test",
"Value": "yes"
}
]
},
"Type": "AWS::ApiGateway::RestApi"
},
"ServerlessRestApiDeployment06c7f65191": {
"Properties": {
"Description": "RestApi deployment id: 06c7f651916afb666c61d5700ef27473645d640a",
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"StageName": "Stage"
},
"Type": "AWS::ApiGateway::Deployment"
},
"ServerlessRestApiProdStage": {
"Properties": {
"DeploymentId": {
"Ref": "ServerlessRestApiDeployment06c7f65191"
},
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"StageName": "Prod",
"Tags": [
{
"Key": "test",
"Value": "yes"
}
]
},
"Type": "AWS::ApiGateway::Stage"
}
}
}
Loading