Skip to content

Commit

Permalink
feat(api): Add Access log and canary setting support to templates (#643)
Browse files Browse the repository at this point in the history
  • Loading branch information
tryantwit authored and jlhood committed Oct 26, 2018
1 parent c61d17e commit 8d8a53b
Show file tree
Hide file tree
Showing 16 changed files with 1,260 additions and 8 deletions.
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

0 comments on commit 8d8a53b

Please sign in to comment.