From 63a7133c1e68aa71ae2cd5e9535babb0c9882b83 Mon Sep 17 00:00:00 2001 From: Brendan Murtagh Date: Wed, 21 Jun 2017 15:28:34 -0400 Subject: [PATCH 1/3] Added validate method to Authorizer class for handling validation for handling optional AuthorizerUri property when Type property is set to TOKEN --- troposphere/apigateway.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/troposphere/apigateway.py b/troposphere/apigateway.py index 875fc0d45..30998389d 100644 --- a/troposphere/apigateway.py +++ b/troposphere/apigateway.py @@ -1,5 +1,5 @@ from . import AWSHelperFn, AWSObject, AWSProperty -from .validators import positive_integer +from .validators import positive_integer, defer import json @@ -47,7 +47,7 @@ class Authorizer(AWSObject): props = { "AuthorizerCredentials": (basestring, False), "AuthorizerResultTtlInSeconds": (validate_authorizer_ttl, False), - "AuthorizerUri": (basestring, True), + "AuthorizerUri": (defer, True), "IdentitySource": (basestring, True), "IdentityValidationExpression": (basestring, False), "Name": (basestring, True), @@ -56,6 +56,23 @@ class Authorizer(AWSObject): "Type": (basestring, True) } + def validate(self): + if 'Type' in self.properties: + + type_property = self.properties.get('Type', None) + + if 'TOKEN' in type_property: + if 'AuthorizerUri' in self.properties: + + authorizer_uri = self.properties.get('AuthorizerUri', None) + + if not isinstance(authorizer_uri, basestring): + raise ValueError('AuthorizerUri value must' + ' be a string') + else: + raise ValueError('AuthorizerUri is required when' + ' Type is set to TOKEN') + class BasePathMapping(AWSObject): resource_type = "AWS::ApiGateway::BasePathMapping" From eaf4a75d7b1c49be783ad1bc1428b747f36c782c Mon Sep 17 00:00:00 2001 From: Brendan Murtagh Date: Wed, 21 Jun 2017 15:34:49 -0400 Subject: [PATCH 2/3] Changed AuthorizerUri from True to False for being required. Logic to ensure it's set is in previous commit --- troposphere/apigateway.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/troposphere/apigateway.py b/troposphere/apigateway.py index 30998389d..3c2bae271 100644 --- a/troposphere/apigateway.py +++ b/troposphere/apigateway.py @@ -47,7 +47,7 @@ class Authorizer(AWSObject): props = { "AuthorizerCredentials": (basestring, False), "AuthorizerResultTtlInSeconds": (validate_authorizer_ttl, False), - "AuthorizerUri": (defer, True), + "AuthorizerUri": (defer, False), "IdentitySource": (basestring, True), "IdentityValidationExpression": (basestring, False), "Name": (basestring, True), From d0dfddbab48e7ead4851d18e750bf8387f703240 Mon Sep 17 00:00:00 2001 From: Brendan Murtagh Date: Thu, 22 Jun 2017 11:02:40 -0400 Subject: [PATCH 3/3] Updated properties to match AWS documentation and enhanced validation --- troposphere/apigateway.py | 75 +++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 7 deletions(-) diff --git a/troposphere/apigateway.py b/troposphere/apigateway.py index 3c2bae271..cb936f898 100644 --- a/troposphere/apigateway.py +++ b/troposphere/apigateway.py @@ -1,7 +1,15 @@ from . import AWSHelperFn, AWSObject, AWSProperty -from .validators import positive_integer, defer +from .validators import ( + positive_integer, defer, floatingpoint +) import json +HTTP = 'HTTP' +AWS = 'AWS' +MOCK = 'MOCK' +HTTP_PROXY = 'HTTP_PROXY' +AWS_PROXY = 'AWS_PROXY' + def validate_authorizer_ttl(ttl_value): """ Validate authorizer ttl timeout @@ -105,7 +113,7 @@ class MethodSetting(AWSProperty): "MetricsEnabled": (bool, False), "ResourcePath": (basestring, True), "ThrottlingBurstLimit": (positive_integer, False), - "ThrottlingRateLimit": (positive_integer, False) + "ThrottlingRateLimit": (floatingpoint, False) } @@ -125,7 +133,7 @@ class StageDescription(AWSProperty): "MetricsEnabled": (bool, False), "StageName": (basestring, False), "ThrottlingBurstLimit": (positive_integer, False), - "ThrottlingRateLimit": (positive_integer, False), + "ThrottlingRateLimit": (floatingpoint, False), "Variables": (dict, False) } @@ -166,6 +174,28 @@ class Integration(AWSProperty): "Uri": (basestring, False) } + def validate(self): + if 'Type' in self.properties: + + valid_values = [ + HTTP, + AWS, + MOCK, + HTTP_PROXY, + AWS_PROXY, + ] + + type_property = self.properties.get('Type', None) + + if type_property not in valid_values: + raise ValueError('Only HTTP, AWS, MOCK, HTTP_PROXY,' + ' and AWS_PROXY are valid values') + + if 'MOCK' not in type_property: + if 'IntegrationHttpMethod' not in self.properties: + raise ValueError('IntegrationHttpMethod must be set when' + ' Type is not defined as MOCK') + class MethodResponse(AWSProperty): @@ -182,7 +212,7 @@ class Method(AWSObject): props = { "ApiKeyRequired": (bool, False), "AuthorizationType": (basestring, True), - "AuthorizerId": (basestring, False), + "AuthorizerId": (defer, False), "HttpMethod": (basestring, True), "Integration": (Integration, False), "MethodResponses": ([MethodResponse], False), @@ -192,6 +222,19 @@ class Method(AWSObject): "RestApiId": (basestring, True) } + def validate(self): + if 'AuthorizerId' in self.properties: + if 'AuthorizationType' in self.properties: + + auth_type = self.properties.get('AuthorizationType', None) + + if 'CUSTOM' not in auth_type: + raise ValueError('AuthorizationType must be set to' + 'CUSTOM when AuthorizerId is defined') + else: + raise ValueError('AuthorizationType must be defined' + ' when AuthorizerId is defined') + class Model(AWSObject): resource_type = "AWS::ApiGateway::Model" @@ -243,15 +286,33 @@ class RestApi(AWSObject): resource_type = "AWS::ApiGateway::RestApi" props = { - "Body": (dict, False), + "Body": ((basestring, dict), False), "BodyS3Location": (S3Location, False), "CloneFrom": (basestring, False), "Description": (basestring, False), - "FailOnWarnings": (basestring, False), + "FailOnWarnings": (bool, False), "Name": (basestring, False), "Parameters": ([basestring], False) } + def validate(self): + if 'Body' in self.properties: + body = self.properties.get('Body') + if isinstance(body, basestring): + # Verify it is a valid json string + json.loads(body) + elif isinstance(body, dict): + # Convert the dict to a basestring + self.properties['Schema'] = json.dumps(body) + elif isinstance(body, AWSHelperFn): + pass + else: + raise ValueError("Body must be a str or dict") + + if 'Body' not in self.properties: + if 'Name' not in self.properties: + raise ValueError('Name must be defined when Body is undefined') + class Stage(AWSObject): resource_type = "AWS::ApiGateway::Stage" @@ -287,7 +348,7 @@ class QuotaSettings(AWSProperty): class ThrottleSettings(AWSProperty): props = { "BurstLimit": (positive_integer, False), - "RateLimit": (positive_integer, False), + "RateLimit": (floatingpoint, False), }