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

Add Access log and canary setting support to templates. #643

Merged
merged 7 commits into from
Oct 26, 2018
Merged
2 changes: 2 additions & 0 deletions docs/globals.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ Currently, the following resources and properties are being supported:
MethodSettings:
BinaryMediaTypes:
Cors:
AccessLogSetting:
CanarySetting:

SimpleTable:
# Properties of AWS::Serverless::SimpleTable
Expand Down
8 changes: 7 additions & 1 deletion samtranslator/model/api/api_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

class ApiGenerator(object):

def __init__(self, logical_id, cache_cluster_enabled, cache_cluster_size, variables, depends_on, definition_body, definition_uri, name, stage_name, endpoint_configuration=None, method_settings=None, binary_media=None, cors=None, auth=None):
def __init__(self, logical_id, cache_cluster_enabled, cache_cluster_size, variables, depends_on, definition_body, definition_uri, name, stage_name, endpoint_configuration=None, method_settings=None, binary_media=None, cors=None, auth=None, access_log_setting=None, canary_setting=None):
"""Constructs an API Generator class that generates API Gateway resources

:param logical_id: Logical id of the SAM API Resource
Expand All @@ -35,6 +35,8 @@ def __init__(self, logical_id, cache_cluster_enabled, cache_cluster_size, variab
:param definition_uri: URI to API definition
:param name: Name of the API Gateway resource
:param stage_name: Name of the Stage
:param access_log_setting: Whether to send access logs and where for Stage
:param canary_setting: Canary Setting for Stage
"""
self.logical_id = logical_id
self.cache_cluster_enabled = cache_cluster_enabled
Expand All @@ -50,6 +52,8 @@ def __init__(self, logical_id, cache_cluster_enabled, cache_cluster_size, variab
self.binary_media = binary_media
self.cors = cors
self.auth = auth
self.access_log_setting = access_log_setting
self.canary_setting = canary_setting

def _construct_rest_api(self):
"""Constructs and returns the ApiGateway RestApi.
Expand Down Expand Up @@ -148,6 +152,8 @@ def _construct_stage(self, deployment, swagger):
stage.CacheClusterSize = self.cache_cluster_size
stage.Variables = self.variables
stage.MethodSettings = self.method_settings
stage.AccessLogSetting = self.access_log_setting
stage.CanarySetting = self.canary_setting

if swagger is not None:
deployment.make_auto_deployable(stage, swagger)
Expand Down
2 changes: 2 additions & 0 deletions samtranslator/model/apigateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ class ApiGatewayRestApi(Resource):
class ApiGatewayStage(Resource):
resource_type = 'AWS::ApiGateway::Stage'
property_types = {
'AccessLogSetting': PropertyType(False, is_type(dict)),
'CacheClusterEnabled': PropertyType(False, is_type(bool)),
'CacheClusterSize': PropertyType(False, is_str()),
'CanarySetting': PropertyType(False, is_type(dict)),
'ClientCertificateId': PropertyType(False, is_str()),
'DeploymentId': PropertyType(True, is_str()),
'Description': PropertyType(False, is_str()),
Expand Down
8 changes: 6 additions & 2 deletions samtranslator/model/sam_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,9 @@ class SamApi(SamResourceMacro):
'MethodSettings': PropertyType(False, is_type(list)),
'BinaryMediaTypes': PropertyType(False, is_type(list)),
'Cors': PropertyType(False, one_of(is_str(), is_type(dict))),
'Auth': PropertyType(False, is_type(dict))
'Auth': PropertyType(False, is_type(dict)),
'AccessLogSetting': PropertyType(False, is_type(dict)),
'CanarySetting': PropertyType(False, is_type(dict))
}

referable_properties = {
Expand Down Expand Up @@ -509,7 +511,9 @@ def to_cloudformation(self, **kwargs):
method_settings=self.MethodSettings,
binary_media=self.BinaryMediaTypes,
cors=self.Cors,
auth=self.Auth)
auth=self.Auth,
access_log_setting=self.AccessLogSetting,
canary_setting=self.CanarySetting)

rest_api, deployment, stage, permissions = api_generator.to_cloudformation()

Expand Down
4 changes: 3 additions & 1 deletion samtranslator/plugins/globals/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ class Globals(object):
"EndpointConfiguration",
"MethodSettings",
"BinaryMediaTypes",
"Cors"
"Cors",
"AccessLogSetting",
"CanarySetting"
],

SamResourceType.SimpleTable.value: [
Expand Down
25 changes: 25 additions & 0 deletions tests/translator/input/api_with_access_log_setting.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Globals:
Api:
AccessLogSetting:
DestinationArn: "arn:aws:logs:us-west-2:012345678901/API-Gateway-Execution-Logs_0123456789/prod:log-stream:12345678910"
Format: "$context.requestId"

Resources:
ImplicitApiFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: s3://sam-demo-bucket/member_portal.zip
Handler: index.gethtml
Runtime: nodejs4.3
Events:
GetHtml:
Type: Api
Properties:
Path: /
Method: get

ExplicitApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
DefinitionUri: s3://sam-demo-bucket/webpage_swagger.json
28 changes: 28 additions & 0 deletions tests/translator/input/api_with_canary_setting.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Globals:
Api:
CanarySetting:
PercentTraffic: 100
StageVariablesOverrides:
sv1: "test"
sv2: "test2"
UseStageCache: false

Resources:
ImplicitApiFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: s3://sam-demo-bucket/member_portal.zip
Handler: index.gethtml
Runtime: nodejs4.3
Events:
GetHtml:
Type: Api
Properties:
Path: /
Method: get

ExplicitApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
DefinitionUri: s3://sam-demo-bucket/webpage_swagger.json
182 changes: 182 additions & 0 deletions tests/translator/output/api_with_access_log_setting.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
{
"Resources": {
"ImplicitApiFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "sam-demo-bucket",
"S3Key": "member_portal.zip"
},
"Handler": "index.gethtml",
"Role": {
"Fn::GetAtt": [
"ImplicitApiFunctionRole",
"Arn"
]
},
"Runtime": "nodejs4.3",
"Tags": [
{
"Value": "SAM",
"Key": "lambda:createdBy"
}
]
}
},
"ImplicitApiFunctionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
],
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
}
}
]
}
}
},
"ExplicitApiDeploymentf117c932f7": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "ExplicitApi"
},
"Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289",
"StageName": "Stage"
}
},
"ImplicitApiFunctionGetHtmlPermissionTest": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:invokeFunction",
"Principal": "apigateway.amazonaws.com",
"FunctionName": {
"Ref": "ImplicitApiFunction"
},
"SourceArn": {
"Fn::Sub": [
"arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/",
{
"__Stage__": "*",
"__ApiId__": {
"Ref": "ServerlessRestApi"
}
}
]
}
}
},
"ImplicitApiFunctionGetHtmlPermissionProd": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:invokeFunction",
"Principal": "apigateway.amazonaws.com",
"FunctionName": {
"Ref": "ImplicitApiFunction"
},
"SourceArn": {
"Fn::Sub": [
"arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/",
{
"__Stage__": "Prod",
"__ApiId__": {
"Ref": "ServerlessRestApi"
}
}
]
}
}
},
"ExplicitApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"BodyS3Location": {
"Bucket": "sam-demo-bucket",
"Key": "webpage_swagger.json"
}
}
},
"ExplicitApiProdStage": {
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"AccessLogSetting": {
"DestinationArn": "arn:aws:logs:us-west-2:012345678901/API-Gateway-Execution-Logs_0123456789/prod:log-stream:12345678910",
"Format": "$context.requestId"
},
"DeploymentId": {
"Ref": "ExplicitApiDeploymentf117c932f7"
},
"RestApiId": {
"Ref": "ExplicitApi"
},
"StageName": "Prod"
}
},
"ServerlessRestApiProdStage": {
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"AccessLogSetting": {
"DestinationArn": "arn:aws:logs:us-west-2:012345678901/API-Gateway-Execution-Logs_0123456789/prod:log-stream:12345678910",
"Format": "$context.requestId"
},
"DeploymentId": {
"Ref": "ServerlessRestApiDeployment62b96c1a61"
},
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"StageName": "Prod"
}
},
"ServerlessRestApiDeployment62b96c1a61": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"Description": "RestApi deployment id: 62b96c1a611878eefb13e8ef66dbc71b9ba3dd19",
"StageName": "Stage"
}
},
"ServerlessRestApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Body": {
"info": {
"version": "1.0",
"title": {
"Ref": "AWS::StackName"
}
},
"paths": {
"/": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ImplicitApiFunction.Arn}/invocations"
}
},
"responses": {}
}
}
},
"swagger": "2.0"
}
}
}
}
}
Loading