Skip to content

Commit 7d2752b

Browse files
authored
fix: move the normalized open api version to feature flag normalized_open_api_version (#3555)
1 parent 7593908 commit 7d2752b

10 files changed

+1866
-7
lines changed

samtranslator/model/api/api_generator.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from dataclasses import dataclass
44
from typing import Any, Dict, List, Optional, Set, Tuple, Union, cast
55

6+
from samtranslator.feature_toggle.feature_toggle import FeatureToggle
67
from samtranslator.metrics.method_decorator import cw_timer
78
from samtranslator.model import Resource
89
from samtranslator.model.apigateway import (
@@ -40,6 +41,8 @@
4041

4142
LOG = logging.getLogger(__name__)
4243

44+
FEATURE_FLAG_NORMALIZED_OPENAPI_VERSION = "normalized_open_api_version"
45+
4346
_CORS_WILDCARD = "'*'"
4447
CorsProperties = namedtuple(
4548
"CorsProperties", ["AllowMethods", "AllowHeaders", "AllowOrigin", "MaxAge", "AllowCredentials"]
@@ -205,6 +208,7 @@ def __init__( # noqa: PLR0913
205208
mode: Optional[Intrinsicable[str]] = None,
206209
api_key_source_type: Optional[Intrinsicable[str]] = None,
207210
always_deploy: Optional[bool] = False,
211+
feature_toggle: Optional[FeatureToggle] = None,
208212
):
209213
"""Constructs an API Generator class that generates API Gateway resources
210214
@@ -261,6 +265,7 @@ def __init__( # noqa: PLR0913
261265
self.mode = mode
262266
self.api_key_source_type = api_key_source_type
263267
self.always_deploy = always_deploy
268+
self.feature_toggle = feature_toggle
264269

265270
def _construct_rest_api(self) -> ApiGatewayRestApi:
266271
"""Constructs and returns the ApiGateway RestApi.
@@ -1125,11 +1130,15 @@ def _openapi_postprocess(self, definition_body: Dict[str, Any]) -> Dict[str, Any
11251130
if definition_body.get("swagger") is not None:
11261131
return definition_body
11271132

1128-
if definition_body.get("openapi") is not None and self.open_api_version is None:
1129-
self.open_api_version = definition_body.get("openapi")
1133+
if self.feature_toggle and self.feature_toggle.is_enabled(FEATURE_FLAG_NORMALIZED_OPENAPI_VERSION):
1134+
normalized_open_api_version = definition_body.get("openapi", self.open_api_version)
1135+
elif definition_body.get("openapi") is not None and self.open_api_version is None:
1136+
normalized_open_api_version = definition_body.get("openapi")
1137+
else:
1138+
normalized_open_api_version = self.open_api_version
11301139

1131-
if self.open_api_version and SwaggerEditor.safe_compare_regex_with_string(
1132-
SwaggerEditor._OPENAPI_VERSION_3_REGEX, self.open_api_version
1140+
if normalized_open_api_version and SwaggerEditor.safe_compare_regex_with_string(
1141+
SwaggerEditor._OPENAPI_VERSION_3_REGEX, normalized_open_api_version
11331142
):
11341143
if definition_body.get("securityDefinitions"):
11351144
components = definition_body.get("components", Py27Dict())

samtranslator/model/sam_resources.py

+2
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,7 @@ def to_cloudformation(self, **kwargs) -> List[Resource]: # type: ignore[no-unty
12941294
shared_api_usage_plan = kwargs.get("shared_api_usage_plan")
12951295
template_conditions = kwargs.get("conditions")
12961296
route53_record_set_groups = kwargs.get("route53_record_set_groups", {})
1297+
feature_toggle = kwargs.get("feature_toggle")
12971298

12981299
api_generator = ApiGenerator(
12991300
self.logical_id,
@@ -1330,6 +1331,7 @@ def to_cloudformation(self, **kwargs) -> List[Resource]: # type: ignore[no-unty
13301331
mode=self.Mode,
13311332
api_key_source_type=self.ApiKeySourceType,
13321333
always_deploy=self.AlwaysDeploy,
1334+
feature_toggle=feature_toggle,
13331335
)
13341336

13351337
generated_resources = api_generator.to_cloudformation(redeploy_restapi_parameters, route53_record_set_groups)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
Transform:
2+
- AWS::Serverless-2016-10-31
3+
Resources:
4+
ApiGatewayCognitoExecutionRole4F7CB5C8:
5+
Type: AWS::IAM::Role
6+
Properties:
7+
AssumeRolePolicyDocument:
8+
Statement:
9+
- Action: sts:AssumeRole
10+
Effect: Allow
11+
Principal:
12+
Service: apigateway.amazonaws.com
13+
Version: '2012-10-17'
14+
Policies:
15+
- PolicyDocument:
16+
Statement:
17+
- Action: lambda:Invoke*
18+
Effect: Allow
19+
Resource:
20+
Fn::GetAtt:
21+
- LambdaFunction7804BD21
22+
- Arn
23+
Version: '2012-10-17'
24+
PolicyName: apigInvokeLambda
25+
LambdaFunctionServiceRoleD6E423C9:
26+
Type: AWS::IAM::Role
27+
Properties:
28+
AssumeRolePolicyDocument:
29+
Statement:
30+
- Action: sts:AssumeRole
31+
Effect: Allow
32+
Principal:
33+
Service: lambda.amazonaws.com
34+
Version: '2012-10-17'
35+
ManagedPolicyArns:
36+
- Fn::Join:
37+
- ''
38+
- - 'arn:'
39+
- Ref: AWS::Partition
40+
- :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
41+
LambdaFunctionServiceRoleDefaultPolicyF01A7EDC:
42+
Type: AWS::IAM::Policy
43+
Properties:
44+
PolicyDocument:
45+
Statement:
46+
- Action: sns:Publish
47+
Effect: Allow
48+
Resource: '*'
49+
Version: '2012-10-17'
50+
PolicyName: LambdaFunctionServiceRoleDefaultPolicyF01A7EDC
51+
Roles:
52+
- Ref: LambdaFunctionServiceRoleD6E423C9
53+
LambdaFunction7804BD21:
54+
Type: AWS::Lambda::Function
55+
Properties:
56+
Code:
57+
ZipFile: |
58+
exports.handler = async (event, context, callback) => {
59+
const auth = event.queryStringParameters.authorization
60+
const policyDocument = {
61+
Version: '2012-10-17',
62+
Statement: [{
63+
Action: 'execute-api:Invoke',
64+
Effect: auth && auth.toLowerCase() === 'allow' ? 'Allow' : 'Deny',
65+
Resource: event.methodArn
66+
}]
67+
}
68+
69+
return {
70+
principalId: 'user',
71+
context: {},
72+
policyDocument
73+
}
74+
}
75+
Role:
76+
Fn::GetAtt:
77+
- LambdaFunctionServiceRoleD6E423C9
78+
- Arn
79+
Handler: index.handler
80+
Runtime: nodejs16.x
81+
MyCognitoUserPool:
82+
Type: AWS::Cognito::UserPool
83+
Properties:
84+
UserPoolName: MyCognitoUserPool
85+
ApiGatewayCognitoService15108F0B:
86+
Type: AWS::Serverless::Api
87+
Properties:
88+
StageName: prod
89+
Auth:
90+
AddDefaultAuthorizerToCorsPreflight: false
91+
Authorizers:
92+
CognitoAuthorizer:
93+
UserPoolArn:
94+
Fn::GetAtt: MyCognitoUserPool.Arn
95+
DefaultAuthorizer: CognitoAuthorizer
96+
DefinitionBody:
97+
openapi: 3.0.2
98+
info:
99+
title: RxtHofApprovalServiceLambdaCognito
100+
version: '2018-05-10'
101+
paths:
102+
/reviews:
103+
post:
104+
operationId: CreateReview
105+
requestBody:
106+
content:
107+
application/json:
108+
schema:
109+
$ref: '#/components/schemas/CreateReviewRequestContent'
110+
required: true
111+
responses:
112+
'200':
113+
description: CreateReview 200 response
114+
headers:
115+
Access-Control-Allow-Origin:
116+
schema:
117+
type: string
118+
Access-Control-Expose-Headers:
119+
schema:
120+
type: string
121+
content:
122+
application/json:
123+
schema:
124+
$ref: '#/components/schemas/CreateReviewResponseContent'
125+
x-amazon-apigateway-integration:
126+
type: aws_proxy
127+
httpMethod: POST
128+
uri:
129+
Fn::Sub: arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction7804BD21.Arn}/invocations
130+
credentials:
131+
Fn::Sub: ${ApiGatewayCognitoExecutionRole4F7CB5C8.Arn}
132+
responses:
133+
default:
134+
statusCode: '200'
135+
responseParameters:
136+
method.response.header.Access-Control-Allow-Origin: "'*'"
137+
method.response.header.Access-Control-Expose-Headers: "'Content-Length,Content-Type,X-Amzn-Errortype,X-Amzn-Requestid'"
138+
components:
139+
schemas:
140+
CreateReviewRequestContent:
141+
type: object
142+
properties:
143+
reviewId:
144+
type: string
145+
CreateReviewResponseContent:
146+
type: object
147+
properties:
148+
reviewId:
149+
type: string
150+
securitySchemes:
151+
aws.auth.sigv4:
152+
type: apiKey
153+
description: AWS Signature Version 4 authentication
154+
name: Authorization
155+
in: header
156+
x-amazon-apigateway-authtype: awsSigv4
157+
security:
158+
- aws.auth.sigv4: []
159+
x-amazon-apigateway-gateway-responses:
160+
DEFAULT_5XX:
161+
responseTemplates:
162+
application/json: '{"message":$context.error.messageString}'
163+
responseParameters:
164+
gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
165+
OpenApiVersion: '2.0'
166+
TracingEnabled: true

0 commit comments

Comments
 (0)