From 9a97c5f14674be864a76db4673a7c2f9ca21df03 Mon Sep 17 00:00:00 2001 From: Gavin Zhang Date: Mon, 21 Nov 2022 14:48:36 -0800 Subject: [PATCH 1/4] Add detaild type to AWS::Serverless::Lambda Schema --- bin/validate_schema.py | 5 + samtranslator/schema/schema.json | 582 +++++++++++++++++++++---------- samtranslator/schema/schema.py | 278 +++++++-------- 3 files changed, 541 insertions(+), 324 deletions(-) diff --git a/bin/validate_schema.py b/bin/validate_schema.py index 5d07d0845..4c5e32071 100755 --- a/bin/validate_schema.py +++ b/bin/validate_schema.py @@ -33,6 +33,11 @@ def get_templates() -> Iterator[Path]: "sns_outside_sqs", # 8 is not of type string "function_with_cwe_dlq_and_retry_policy", # Doesn't match schema at all... "function_with_cwe_dlq_generated", # Doesn't match schema at all... + "function_with_request_parameters", # RequestParameters don't match documentation. Documentation and its example don't match either + "api_with_request_parameters_openapi", # RequestParameters don't match documentation. Documentation and its example don't match either + "api_with_aws_iam_auth_overrides", # null for invokeRole + "eventbridgerule", # missing required field 'Patterns' + "self_managed_kafka_with_intrinsics", # 'EnableValue' is of type bool but defined as string ] def should_skip(s: str) -> bool: diff --git a/samtranslator/schema/schema.json b/samtranslator/schema/schema.json index 83f8e7483..3c5f4d28d 100644 --- a/samtranslator/schema/schema.json +++ b/samtranslator/schema/schema.json @@ -856,30 +856,294 @@ ], "additionalProperties": false }, + "FunctionResourcePolicy": { + "title": "FunctionResourcePolicy", + "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", + "type": "object", + "properties": { + "AwsAccountBlacklist": { + "title": "Awsaccountblacklist", + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } + }, + "AwsAccountWhitelist": { + "title": "Awsaccountwhitelist", + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } + }, + "CustomStatements": { + "title": "Customstatements", + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } + }, + "IntrinsicVpcBlacklist": { + "title": "Intrinsicvpcblacklist", + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } + }, + "IntrinsicVpcWhitelist": { + "title": "Intrinsicvpcwhitelist", + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } + }, + "IntrinsicVpceBlacklist": { + "title": "Intrinsicvpceblacklist", + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } + }, + "IntrinsicVpceWhitelist": { + "title": "Intrinsicvpcewhitelist", + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } + }, + "IpRangeBlacklist": { + "title": "Iprangeblacklist", + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } + }, + "IpRangeWhitelist": { + "title": "Iprangewhitelist", + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } + }, + "SourceVpcBlacklist": { + "title": "Sourcevpcblacklist", + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } + }, + "SourceVpcWhitelist": { + "title": "Sourcevpcwhitelist", + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } + } + }, + "additionalProperties": false + }, + "FunctionApiFunctionAuth": { + "title": "FunctionApiFunctionAuth", + "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", + "type": "object", + "properties": { + "ApiKeyRequired": { + "title": "Apikeyrequired", + "type": "boolean" + }, + "AuthorizationScopes": { + "title": "Authorizationscopes", + "type": "array", + "items": { + "type": "string" + } + }, + "Authorizer": { + "title": "Authorizer", + "type": "string" + }, + "InvokeRole": { + "title": "Invokerole", + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "ResourcePolicy": { + "$ref": "#/definitions/FunctionResourcePolicy" + } + }, + "additionalProperties": false + }, + "FunctionRequestModel": { + "title": "FunctionRequestModel", + "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", + "type": "object", + "properties": { + "Model": { + "title": "Model", + "type": "string" + }, + "Required": { + "title": "Required", + "type": "boolean" + }, + "ValidateBody": { + "title": "Validatebody", + "type": "boolean" + }, + "ValidateParameters": { + "title": "Validateparameters", + "type": "boolean" + } + }, + "required": [ + "Model" + ], + "additionalProperties": false + }, + "FunctionRequestParameter": { + "title": "FunctionRequestParameter", + "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", + "type": "object", + "properties": { + "Caching": { + "title": "Caching", + "type": "boolean" + }, + "Required": { + "title": "Required", + "type": "boolean" + } + }, + "additionalProperties": false + }, "FunctionApiProperties": { "title": "FunctionApiProperties", "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", "type": "object", "properties": { "Auth": { - "title": "Auth" + "$ref": "#/definitions/FunctionApiFunctionAuth" }, "Method": { - "title": "Method" + "title": "Method", + "type": "string" }, "Path": { - "title": "Path" + "title": "Path", + "type": "string" }, "RequestModel": { - "title": "Requestmodel" + "$ref": "#/definitions/FunctionRequestModel" }, "RequestParameters": { - "title": "Requestparameters" + "title": "Requestparameters", + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/FunctionRequestParameter" + } + ] }, "RestApiId": { - "title": "Restapiid" + "title": "Restapiid", + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] } }, + "required": [ + "Method", + "Path" + ], "additionalProperties": false }, "FunctionApiEvent": { @@ -904,19 +1168,42 @@ ], "additionalProperties": false }, - "FunctionScheduleProperties": { - "title": "FunctionScheduleProperties", + "EventsDeadLetterConfig": { + "title": "EventsDeadLetterConfig", + "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", + "type": "object", + "properties": { + "Arn": { + "title": "Arn" + }, + "QueueLogicalId": { + "title": "Queuelogicalid", + "type": "string" + }, + "Type": { + "title": "Type", + "enum": [ + "SQS" + ], + "type": "string" + } + }, + "additionalProperties": false + }, + "EventsScheduleProperties": { + "title": "EventsScheduleProperties", "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", "type": "object", "properties": { "DeadLetterConfig": { - "title": "Deadletterconfig" + "$ref": "#/definitions/EventsDeadLetterConfig" }, "Description": { "title": "Description" }, "Enabled": { - "title": "Enabled" + "title": "Enabled", + "type": "boolean" }, "Input": { "title": "Input" @@ -936,8 +1223,8 @@ }, "additionalProperties": false }, - "FunctionScheduleEvent": { - "title": "FunctionScheduleEvent", + "EventsSchedule": { + "title": "EventsSchedule", "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", "type": "object", "properties": { @@ -949,7 +1236,7 @@ "type": "string" }, "Properties": { - "$ref": "#/definitions/FunctionScheduleProperties" + "$ref": "#/definitions/EventsScheduleProperties" } }, "required": [ @@ -958,13 +1245,13 @@ ], "additionalProperties": false }, - "FunctionScheduleV2Properties": { - "title": "FunctionScheduleV2Properties", + "EventsScheduleV2Properties": { + "title": "EventsScheduleV2Properties", "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", "type": "object", "properties": { "DeadLetterConfig": { - "title": "Deadletterconfig" + "$ref": "#/definitions/EventsDeadLetterConfig" }, "Description": { "title": "Description" @@ -993,6 +1280,9 @@ "RetryPolicy": { "title": "Retrypolicy" }, + "RoleArn": { + "title": "Rolearn" + }, "ScheduleExpression": { "title": "Scheduleexpression" }, @@ -1008,8 +1298,8 @@ }, "additionalProperties": false }, - "FunctionScheduleV2Event": { - "title": "FunctionScheduleV2Event", + "EventsScheduleV2": { + "title": "EventsScheduleV2", "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", "type": "object", "properties": { @@ -1021,7 +1311,7 @@ "type": "string" }, "Properties": { - "$ref": "#/definitions/FunctionScheduleV2Properties" + "$ref": "#/definitions/EventsScheduleV2Properties" } }, "required": [ @@ -1036,7 +1326,8 @@ "type": "object", "properties": { "Enabled": { - "title": "Enabled" + "title": "Enabled", + "type": "boolean" }, "EventBusName": { "title": "Eventbusname" @@ -1084,7 +1375,7 @@ "type": "object", "properties": { "DeadLetterConfig": { - "title": "Deadletterconfig" + "$ref": "#/definitions/EventsDeadLetterConfig" }, "EventBusName": { "title": "Eventbusname" @@ -1207,7 +1498,8 @@ "type": "object", "properties": { "SkillId": { - "title": "Skillid" + "title": "Skillid", + "type": "string" } }, "additionalProperties": false @@ -1242,9 +1534,20 @@ "title": "Trigger" }, "UserPool": { - "title": "Userpool" + "title": "Userpool", + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] } }, + "required": [ + "UserPool" + ], "additionalProperties": false }, "FunctionCognitoEvent": { @@ -1269,31 +1572,76 @@ ], "additionalProperties": false }, + "FunctionHttpApiAuth": { + "title": "FunctionHttpApiAuth", + "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", + "type": "object", + "properties": { + "AuthorizationScopes": { + "title": "Authorizationscopes", + "type": "array", + "items": { + "type": "string" + } + }, + "Authorizer": { + "title": "Authorizer", + "type": "string" + } + }, + "additionalProperties": false + }, "FunctionHttpApiProperties": { "title": "FunctionHttpApiProperties", "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", "type": "object", "properties": { "ApiId": { - "title": "Apiid" + "title": "Apiid", + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] }, "Auth": { - "title": "Auth" + "$ref": "#/definitions/FunctionHttpApiAuth" }, "Method": { - "title": "Method" + "title": "Method", + "type": "string" }, "Path": { - "title": "Path" + "title": "Path", + "type": "string" }, "PayloadFormatVersion": { - "title": "Payloadformatversion" + "title": "Payloadformatversion", + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] }, "RouteSettings": { "title": "Routesettings" }, "TimeoutInMillis": { - "title": "Timeoutinmillis" + "title": "Timeoutinmillis", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "object" + } + ] } }, "additionalProperties": false @@ -1391,7 +1739,8 @@ "title": "Queues" }, "SecretsManagerKmsKeyId": { - "title": "Secretsmanagerkmskeyid" + "title": "Secretsmanagerkmskeyid", + "type": "string" }, "SourceAccessConfigurations": { "title": "Sourceaccessconfigurations" @@ -1439,7 +1788,18 @@ "title": "Filtercriteria" }, "KafkaBootstrapServers": { - "title": "Kafkabootstrapservers" + "title": "Kafkabootstrapservers", + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } }, "SourceAccessConfigurations": { "title": "Sourceaccessconfigurations" @@ -1603,10 +1963,10 @@ "$ref": "#/definitions/FunctionApiEvent" }, { - "$ref": "#/definitions/FunctionScheduleEvent" + "$ref": "#/definitions/EventsSchedule" }, { - "$ref": "#/definitions/FunctionScheduleV2Event" + "$ref": "#/definitions/EventsScheduleV2" }, { "$ref": "#/definitions/FunctionCloudWatchEvent" @@ -1843,158 +2203,6 @@ ], "additionalProperties": false }, - "StateMachineEventsScheduleDeadLetterConfig": { - "title": "StateMachineEventsScheduleDeadLetterConfig", - "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", - "type": "object", - "properties": { - "Arn": { - "title": "Arn" - }, - "QueueLogicalId": { - "title": "Queuelogicalid", - "type": "string" - }, - "Type": { - "title": "Type", - "enum": [ - "SQS" - ], - "type": "string" - } - }, - "additionalProperties": false - }, - "StateMachineEventsScheduleProperties": { - "title": "StateMachineEventsScheduleProperties", - "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", - "type": "object", - "properties": { - "DeadLetterConfig": { - "$ref": "#/definitions/StateMachineEventsScheduleDeadLetterConfig" - }, - "Description": { - "title": "Description" - }, - "Enabled": { - "title": "Enabled", - "type": "boolean" - }, - "Input": { - "title": "Input" - }, - "Name": { - "title": "Name" - }, - "RetryPolicy": { - "title": "Retrypolicy" - }, - "Schedule": { - "title": "Schedule" - }, - "State": { - "title": "State" - } - }, - "additionalProperties": false - }, - "StateMachineEventsSchedule": { - "title": "StateMachineEventsSchedule", - "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", - "type": "object", - "properties": { - "Type": { - "title": "Type", - "enum": [ - "Schedule" - ], - "type": "string" - }, - "Properties": { - "$ref": "#/definitions/StateMachineEventsScheduleProperties" - } - }, - "required": [ - "Type", - "Properties" - ], - "additionalProperties": false - }, - "StateMachineEventsScheduleV2Properties": { - "title": "StateMachineEventsScheduleV2Properties", - "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", - "type": "object", - "properties": { - "DeadLetterConfig": { - "$ref": "#/definitions/StateMachineEventsScheduleDeadLetterConfig" - }, - "Description": { - "title": "Description" - }, - "EndDate": { - "title": "Enddate" - }, - "FlexibleTimeWindow": { - "title": "Flexibletimewindow" - }, - "GroupName": { - "title": "Groupname" - }, - "Input": { - "title": "Input" - }, - "KmsKeyArn": { - "title": "Kmskeyarn" - }, - "Name": { - "title": "Name" - }, - "PermissionsBoundary": { - "title": "Permissionsboundary" - }, - "RetryPolicy": { - "title": "Retrypolicy" - }, - "RoleArn": { - "title": "Rolearn" - }, - "ScheduleExpression": { - "title": "Scheduleexpression" - }, - "ScheduleExpressionTimezone": { - "title": "Scheduleexpressiontimezone" - }, - "StartDate": { - "title": "Startdate" - }, - "State": { - "title": "State" - } - }, - "additionalProperties": false - }, - "StateMachineEventsScheduleV2": { - "title": "StateMachineEventsScheduleV2", - "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", - "type": "object", - "properties": { - "Type": { - "title": "Type", - "enum": [ - "ScheduleV2" - ], - "type": "string" - }, - "Properties": { - "$ref": "#/definitions/StateMachineEventsScheduleV2Properties" - } - }, - "required": [ - "Type", - "Properties" - ], - "additionalProperties": false - }, "StateMachineEventsCloudWatchEventProperties": { "title": "StateMachineEventsCloudWatchEventProperties", "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", @@ -2299,10 +2507,10 @@ "additionalProperties": { "anyOf": [ { - "$ref": "#/definitions/StateMachineEventsSchedule" + "$ref": "#/definitions/EventsSchedule" }, { - "$ref": "#/definitions/StateMachineEventsScheduleV2" + "$ref": "#/definitions/EventsScheduleV2" }, { "$ref": "#/definitions/StateMachineEventsCloudWatchEvent" diff --git a/samtranslator/schema/schema.py b/samtranslator/schema/schema.py index 8c9573cc0..1fd14daa0 100644 --- a/samtranslator/schema/schema.py +++ b/samtranslator/schema/schema.py @@ -12,6 +12,8 @@ # Value passed directly to CloudFormation; not used by SAM PassThrough = Any # TODO: Make it behave like typescript's unknown +ResourcePolicy = Union[str, Dict[str, Any]] + # Intrinsic resolvable by the SAM transform SamIntrinsic = Dict[str, Any] @@ -51,6 +53,52 @@ class AwsServerlessConnector(BaseModel): Properties: ConnectorProperties + +class EventsDeadLetterConfig(BaseModel): + Arn: Optional[PassThrough] + QueueLogicalId: Optional[str] + Type: Optional[Literal["SQS"]] + + +class EventsScheduleProperties(BaseModel): + DeadLetterConfig: Optional[EventsDeadLetterConfig] + Description: Optional[PassThrough] + Enabled: Optional[bool] + Input: Optional[PassThrough] + Name: Optional[PassThrough] + RetryPolicy: Optional[PassThrough] + Schedule: Optional[PassThrough] + State: Optional[PassThrough] + + +class EventsSchedule(BaseModel): + Type: Literal["Schedule"] + Properties: EventsScheduleProperties + + +class EventsScheduleV2Properties(BaseModel): + DeadLetterConfig: Optional[EventsDeadLetterConfig] + Description: Optional[PassThrough] + EndDate: Optional[PassThrough] + FlexibleTimeWindow: Optional[PassThrough] + GroupName: Optional[PassThrough] + Input: Optional[PassThrough] + KmsKeyArn: Optional[PassThrough] + Name: Optional[PassThrough] + PermissionsBoundary: Optional[PassThrough] + RetryPolicy: Optional[PassThrough] + RoleArn: Optional[PassThrough] # TODO: Add to docs + ScheduleExpression: Optional[PassThrough] + ScheduleExpressionTimezone: Optional[PassThrough] + StartDate: Optional[PassThrough] + State: Optional[PassThrough] + + +class EventsScheduleV2(BaseModel): + Type: Literal["ScheduleV2"] + Properties: EventsScheduleV2Properties + + class FunctionCodeUri(BaseModel): Bucket: Union[str, SamIntrinsic] Key: Union[str, SamIntrinsic] @@ -176,65 +224,61 @@ class FunctionSqsEvent(BaseModel): Properties: FunctionSqsProperties -class FunctionApiProperties(BaseModel): - Auth: Unknown - Method: Unknown - Path: Unknown - RequestModel: Unknown - RequestParameters: Unknown - RestApiId: Unknown +class FunctionResourcePolicy(BaseModel): + AwsAccountBlacklist: Optional[List[ResourcePolicy]] + AwsAccountWhitelist: Optional[List[ResourcePolicy]] + CustomStatements: Optional[List[ResourcePolicy]] + IntrinsicVpcBlacklist: Optional[List[ResourcePolicy]] + IntrinsicVpcWhitelist: Optional[List[ResourcePolicy]] + IntrinsicVpceBlacklist: Optional[List[ResourcePolicy]] + IntrinsicVpceWhitelist: Optional[List[ResourcePolicy]] + IpRangeBlacklist: Optional[List[ResourcePolicy]] + IpRangeWhitelist: Optional[List[ResourcePolicy]] + SourceVpcBlacklist: Optional[List[ResourcePolicy]] + SourceVpcWhitelist: Optional[List[ResourcePolicy]] -class FunctionApiEvent(BaseModel): - Type: Literal["Api"] - Properties: FunctionApiProperties +class FunctionApiFunctionAuth(BaseModel): + ApiKeyRequired: Optional[bool] + AuthorizationScopes: Optional[List[str]] + Authorizer: Optional[str] + InvokeRole: Optional[Union[str, SamIntrinsic]] + ResourcePolicy: Optional[FunctionResourcePolicy] -class FunctionScheduleProperties(BaseModel): - DeadLetterConfig: Unknown - Description: Unknown - Enabled: Unknown - Input: Unknown - Name: Unknown - RetryPolicy: Unknown - Schedule: Unknown - State: Unknown +class FunctionRequestModel(BaseModel): + Model: str + Required: Optional[bool] + ValidateBody: Optional[bool] + ValidateParameters: Optional[bool] -class FunctionScheduleEvent(BaseModel): - Type: Literal["Schedule"] - Properties: FunctionScheduleProperties +class FunctionRequestParameter(BaseModel): + Caching: Optional[bool] + Required: Optional[bool] -class FunctionScheduleV2Properties(BaseModel): - DeadLetterConfig: Unknown - Description: Unknown - EndDate: Unknown - FlexibleTimeWindow: Unknown - GroupName: Unknown - Input: Unknown - KmsKeyArn: Unknown - Name: Unknown - PermissionsBoundary: Unknown - RetryPolicy: Unknown - ScheduleExpression: Unknown - ScheduleExpressionTimezone: Unknown - StartDate: Unknown - State: Unknown +class FunctionApiProperties(BaseModel): + Auth: Optional[FunctionApiFunctionAuth] + Method: str + Path: str + RequestModel: Optional[FunctionRequestModel] + RequestParameters: Optional[Union[str, FunctionRequestParameter]] + RestApiId: Optional[Union[str, SamIntrinsic]] -class FunctionScheduleV2Event(BaseModel): - Type: Literal["ScheduleV2"] - Properties: FunctionScheduleV2Properties +class FunctionApiEvent(BaseModel): + Type: Literal["Api"] + Properties: FunctionApiProperties class FunctionCloudWatchProperties(BaseModel): - Enabled: Unknown - EventBusName: Unknown - Input: Unknown - InputPath: Unknown - Pattern: Unknown - State: Unknown + Enabled: Optional[bool] + EventBusName: Optional[PassThrough] + Input: Optional[PassThrough] + InputPath: Optional[PassThrough] + Pattern: Optional[PassThrough] + State: Optional[PassThrough] class FunctionCloudWatchEvent(BaseModel): @@ -243,13 +287,13 @@ class FunctionCloudWatchEvent(BaseModel): class FunctionEventBridgeRuleProperties(BaseModel): - DeadLetterConfig: Unknown - EventBusName: Unknown - Input: Unknown - InputPath: Unknown - Pattern: Unknown - RetryPolicy: Unknown - Target: Unknown + DeadLetterConfig: Optional[EventsDeadLetterConfig] + EventBusName: Optional[PassThrough] + Input: Optional[PassThrough] + InputPath: Optional[PassThrough] + Pattern: PassThrough + RetryPolicy: Optional[PassThrough] + Target: Optional[PassThrough] class FunctionEventBridgeRuleEvent(BaseModel): @@ -258,8 +302,8 @@ class FunctionEventBridgeRuleEvent(BaseModel): class FunctionCloudWatchLogsProperties(BaseModel): - FilterPattern: Unknown - LogGroupName: Unknown + FilterPattern: PassThrough + LogGroupName: PassThrough class FunctionCloudWatchLogsEvent(BaseModel): @@ -268,8 +312,8 @@ class FunctionCloudWatchLogsEvent(BaseModel): class FunctionIoTRuleProperties(BaseModel): - AwsIotSqlVersion: Unknown - Sql: Unknown + AwsIotSqlVersion: Optional[PassThrough] + Sql: PassThrough class FunctionIoTRuleEvent(BaseModel): @@ -278,7 +322,7 @@ class FunctionIoTRuleEvent(BaseModel): class FunctionAlexaSkillProperties(BaseModel): - SkillId: Unknown + SkillId: Optional[str] class FunctionAlexaSkillEvent(BaseModel): @@ -287,8 +331,8 @@ class FunctionAlexaSkillEvent(BaseModel): class FunctionCognitoProperties(BaseModel): - Trigger: Unknown - UserPool: Unknown + Trigger: PassThrough + UserPool: Union[str, SamIntrinsic] class FunctionCognitoEvent(BaseModel): @@ -296,14 +340,19 @@ class FunctionCognitoEvent(BaseModel): Properties: FunctionCognitoProperties +class FunctionHttpApiAuth(BaseModel): + AuthorizationScopes: Optional[List[str]] + Authorizer: Optional[str] + + class FunctionHttpApiProperties(BaseModel): - ApiId: Unknown - Auth: Unknown - Method: Unknown - Path: Unknown - PayloadFormatVersion: Unknown - RouteSettings: Unknown - TimeoutInMillis: Unknown + ApiId: Optional[Union[str, SamIntrinsic]] + Auth: Optional[FunctionHttpApiAuth] + Method: Optional[str] + Path: Optional[str] + PayloadFormatVersion: Optional[Union[str, SamIntrinsic]] + RouteSettings: Optional[PassThrough] + TimeoutInMillis: Optional[Union[int, SamIntrinsic]] class FunctionHttpApiEvent(BaseModel): @@ -312,12 +361,12 @@ class FunctionHttpApiEvent(BaseModel): class FunctionMSKProperties(BaseModel): - ConsumerGroupId: Unknown - FilterCriteria: Unknown - MaximumBatchingWindowInSeconds: Unknown - StartingPosition: Unknown - Stream: Unknown - Topics: Unknown + ConsumerGroupId: Optional[PassThrough] + FilterCriteria: Optional[PassThrough] + MaximumBatchingWindowInSeconds: Optional[PassThrough] + StartingPosition: PassThrough + Stream: PassThrough + Topics: PassThrough class FunctionMSKEvent(BaseModel): @@ -326,14 +375,14 @@ class FunctionMSKEvent(BaseModel): class FunctionMQProperties(BaseModel): - BatchSize: Unknown - Broker: Unknown - Enabled: Unknown - FilterCriteria: Unknown - MaximumBatchingWindowInSeconds: Unknown - Queues: Unknown - SecretsManagerKmsKeyId: Unknown - SourceAccessConfigurations: Unknown + BatchSize: Optional[PassThrough] + Broker: PassThrough + Enabled: Optional[PassThrough] + FilterCriteria: Optional[PassThrough] + MaximumBatchingWindowInSeconds: Optional[PassThrough] + Queues: PassThrough + SecretsManagerKmsKeyId: Optional[str] + SourceAccessConfigurations: PassThrough class FunctionMQEvent(BaseModel): @@ -342,13 +391,13 @@ class FunctionMQEvent(BaseModel): class FunctionSelfManagedKafkaProperties(BaseModel): - BatchSize: Unknown - ConsumerGroupId: Unknown - Enabled: Unknown - FilterCriteria: Unknown - KafkaBootstrapServers: Unknown - SourceAccessConfigurations: Unknown - Topics: Unknown + BatchSize: Optional[PassThrough] + ConsumerGroupId: Optional[PassThrough] + Enabled: Optional[PassThrough] + FilterCriteria: Optional[PassThrough] + KafkaBootstrapServers: Optional[List[Union[str, SamIntrinsic]]] + SourceAccessConfigurations: PassThrough + Topics: PassThrough class FunctionSelfManagedKafkaEvent(BaseModel): @@ -379,8 +428,8 @@ class FunctionProperties(BaseModel): FunctionDynamoDBEvent, FunctionSqsEvent, FunctionApiEvent, - FunctionScheduleEvent, - FunctionScheduleV2Event, + EventsSchedule, + EventsScheduleV2, FunctionCloudWatchEvent, FunctionEventBridgeRuleEvent, FunctionCloudWatchLogsEvent, @@ -446,51 +495,6 @@ class AwsServerlessSimpleTable(BaseModel): Properties: Optional[SimpleTableProperties] -class StateMachineEventsScheduleDeadLetterConfig(BaseModel): - Arn: Optional[PassThrough] - QueueLogicalId: Optional[str] - Type: Optional[Literal["SQS"]] - - -class StateMachineEventsScheduleProperties(BaseModel): - DeadLetterConfig: Optional[StateMachineEventsScheduleDeadLetterConfig] - Description: Optional[PassThrough] - Enabled: Optional[bool] - Input: Optional[PassThrough] - Name: Optional[PassThrough] - RetryPolicy: Optional[PassThrough] - Schedule: Optional[PassThrough] - State: Optional[PassThrough] - - -class StateMachineEventsSchedule(BaseModel): - Type: Literal["Schedule"] - Properties: StateMachineEventsScheduleProperties - - -class StateMachineEventsScheduleV2Properties(BaseModel): - DeadLetterConfig: Optional[StateMachineEventsScheduleDeadLetterConfig] - Description: Optional[PassThrough] - EndDate: Optional[PassThrough] - FlexibleTimeWindow: Optional[PassThrough] - GroupName: Optional[PassThrough] - Input: Optional[PassThrough] - KmsKeyArn: Optional[PassThrough] - Name: Optional[PassThrough] - PermissionsBoundary: Optional[PassThrough] - RetryPolicy: Optional[PassThrough] - RoleArn: Optional[PassThrough] # TODO: Add to docs - ScheduleExpression: Optional[PassThrough] - ScheduleExpressionTimezone: Optional[PassThrough] - StartDate: Optional[PassThrough] - State: Optional[PassThrough] - - -class StateMachineEventsScheduleV2(BaseModel): - Type: Literal["ScheduleV2"] - Properties: StateMachineEventsScheduleV2Properties - - class StateMachineEventsCloudWatchEventProperties(BaseModel): EventBusName: Optional[PassThrough] Input: Optional[PassThrough] @@ -565,8 +569,8 @@ class StateMachineProperties(BaseModel): Dict[ str, Union[ - StateMachineEventsSchedule, - StateMachineEventsScheduleV2, + EventsSchedule, + EventsScheduleV2, StateMachineEventsCloudWatchEvent, StateMachineEventsEventBridgeRule, StateMachineEventsApi, From 3c0f35a216297243f22013ebf41f1f348aa32bc7 Mon Sep 17 00:00:00 2001 From: Gavin Zhang Date: Mon, 21 Nov 2022 14:50:43 -0800 Subject: [PATCH 2/4] Format file --- bin/validate_schema.py | 8 ++++---- samtranslator/schema/schema.py | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/bin/validate_schema.py b/bin/validate_schema.py index 4c5e32071..c353bd253 100755 --- a/bin/validate_schema.py +++ b/bin/validate_schema.py @@ -34,10 +34,10 @@ def get_templates() -> Iterator[Path]: "function_with_cwe_dlq_and_retry_policy", # Doesn't match schema at all... "function_with_cwe_dlq_generated", # Doesn't match schema at all... "function_with_request_parameters", # RequestParameters don't match documentation. Documentation and its example don't match either - "api_with_request_parameters_openapi", # RequestParameters don't match documentation. Documentation and its example don't match either - "api_with_aws_iam_auth_overrides", # null for invokeRole - "eventbridgerule", # missing required field 'Patterns' - "self_managed_kafka_with_intrinsics", # 'EnableValue' is of type bool but defined as string + "api_with_request_parameters_openapi", # RequestParameters don't match documentation. Documentation and its example don't match either + "api_with_aws_iam_auth_overrides", # null for invokeRole + "eventbridgerule", # missing required field 'Patterns' + "self_managed_kafka_with_intrinsics", # 'EnableValue' is of type bool but defined as string ] def should_skip(s: str) -> bool: diff --git a/samtranslator/schema/schema.py b/samtranslator/schema/schema.py index 1fd14daa0..0a79e1f2d 100644 --- a/samtranslator/schema/schema.py +++ b/samtranslator/schema/schema.py @@ -53,7 +53,6 @@ class AwsServerlessConnector(BaseModel): Properties: ConnectorProperties - class EventsDeadLetterConfig(BaseModel): Arn: Optional[PassThrough] QueueLogicalId: Optional[str] From c6320a2cf35b88cba9522e1af911c218c885e30c Mon Sep 17 00:00:00 2001 From: Gavin Zhang Date: Mon, 21 Nov 2022 15:07:23 -0800 Subject: [PATCH 3/4] Refactor resource policy --- samtranslator/schema/schema.json | 93 ++------------------------------ samtranslator/schema/schema.py | 51 +++++++----------- 2 files changed, 22 insertions(+), 122 deletions(-) diff --git a/samtranslator/schema/schema.json b/samtranslator/schema/schema.json index 3c5f4d28d..fb6321edd 100644 --- a/samtranslator/schema/schema.json +++ b/samtranslator/schema/schema.json @@ -856,8 +856,8 @@ ], "additionalProperties": false }, - "FunctionResourcePolicy": { - "title": "FunctionResourcePolicy", + "ResourcePolicy": { + "title": "ResourcePolicy", "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", "type": "object", "properties": { @@ -1050,7 +1050,7 @@ ] }, "ResourcePolicy": { - "$ref": "#/definitions/FunctionResourcePolicy" + "$ref": "#/definitions/ResourcePolicy" } }, "additionalProperties": false @@ -2315,91 +2315,6 @@ ], "additionalProperties": false }, - "StateMachineEventsApiAuthResourcePolicy": { - "title": "StateMachineEventsApiAuthResourcePolicy", - "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", - "type": "object", - "properties": { - "AwsAccountBlacklist": { - "title": "Awsaccountblacklist", - "type": "array", - "items": { - "type": "string" - } - }, - "AwsAccountWhitelist": { - "title": "Awsaccountwhitelist", - "type": "array", - "items": { - "type": "string" - } - }, - "CustomStatements": { - "title": "Customstatements", - "type": "array", - "items": { - "type": "string" - } - }, - "IntrinsicVpcBlacklist": { - "title": "Intrinsicvpcblacklist", - "type": "array", - "items": { - "type": "string" - } - }, - "IntrinsicVpcWhitelist": { - "title": "Intrinsicvpcwhitelist", - "type": "array", - "items": { - "type": "string" - } - }, - "IntrinsicVpceBlacklist": { - "title": "Intrinsicvpceblacklist", - "type": "array", - "items": { - "type": "string" - } - }, - "IntrinsicVpceWhitelist": { - "title": "Intrinsicvpcewhitelist", - "type": "array", - "items": { - "type": "string" - } - }, - "IpRangeBlacklist": { - "title": "Iprangeblacklist", - "type": "array", - "items": { - "type": "string" - } - }, - "IpRangeWhitelist": { - "title": "Iprangewhitelist", - "type": "array", - "items": { - "type": "string" - } - }, - "SourceVpcBlacklist": { - "title": "Sourcevpcblacklist", - "type": "array", - "items": { - "type": "string" - } - }, - "SourceVpcWhitelist": { - "title": "Sourcevpcwhitelist", - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, "StateMachineEventsApiAuth": { "title": "StateMachineEventsApiAuth", "description": "By default strict\nhttps://pydantic-docs.helpmanual.io/usage/model_config/#change-behaviour-globally", @@ -2421,7 +2336,7 @@ "type": "string" }, "ResourcePolicy": { - "$ref": "#/definitions/StateMachineEventsApiAuthResourcePolicy" + "$ref": "#/definitions/ResourcePolicy" } }, "additionalProperties": false diff --git a/samtranslator/schema/schema.py b/samtranslator/schema/schema.py index 0a79e1f2d..be4e2e041 100644 --- a/samtranslator/schema/schema.py +++ b/samtranslator/schema/schema.py @@ -12,8 +12,6 @@ # Value passed directly to CloudFormation; not used by SAM PassThrough = Any # TODO: Make it behave like typescript's unknown -ResourcePolicy = Union[str, Dict[str, Any]] - # Intrinsic resolvable by the SAM transform SamIntrinsic = Dict[str, Any] @@ -98,6 +96,22 @@ class EventsScheduleV2(BaseModel): Properties: EventsScheduleV2Properties +class ResourcePolicy(BaseModel): + AwsAccountBlacklist: Optional[List[Union[str, Dict[str, Any]]]] + AwsAccountWhitelist: Optional[List[Union[str, Dict[str, Any]]]] + CustomStatements: Optional[List[Union[str, Dict[str, Any]]]] + IntrinsicVpcBlacklist: Optional[List[Union[str, Dict[str, Any]]]] + IntrinsicVpcWhitelist: Optional[List[Union[str, Dict[str, Any]]]] + IntrinsicVpceBlacklist: Optional[List[Union[str, Dict[str, Any]]]] + IntrinsicVpceWhitelist: Optional[List[Union[str, Dict[str, Any]]]] + IpRangeBlacklist: Optional[List[Union[str, Dict[str, Any]]]] + IpRangeWhitelist: Optional[List[Union[str, Dict[str, Any]]]] + SourceVpcBlacklist: Optional[List[Union[str, Dict[str, Any]]]] + SourceVpcWhitelist: Optional[List[Union[str, Dict[str, Any]]]] + + + + class FunctionCodeUri(BaseModel): Bucket: Union[str, SamIntrinsic] Key: Union[str, SamIntrinsic] @@ -222,27 +236,12 @@ class FunctionSqsEvent(BaseModel): Type: Literal["SQS"] Properties: FunctionSqsProperties - -class FunctionResourcePolicy(BaseModel): - AwsAccountBlacklist: Optional[List[ResourcePolicy]] - AwsAccountWhitelist: Optional[List[ResourcePolicy]] - CustomStatements: Optional[List[ResourcePolicy]] - IntrinsicVpcBlacklist: Optional[List[ResourcePolicy]] - IntrinsicVpcWhitelist: Optional[List[ResourcePolicy]] - IntrinsicVpceBlacklist: Optional[List[ResourcePolicy]] - IntrinsicVpceWhitelist: Optional[List[ResourcePolicy]] - IpRangeBlacklist: Optional[List[ResourcePolicy]] - IpRangeWhitelist: Optional[List[ResourcePolicy]] - SourceVpcBlacklist: Optional[List[ResourcePolicy]] - SourceVpcWhitelist: Optional[List[ResourcePolicy]] - - class FunctionApiFunctionAuth(BaseModel): ApiKeyRequired: Optional[bool] AuthorizationScopes: Optional[List[str]] Authorizer: Optional[str] InvokeRole: Optional[Union[str, SamIntrinsic]] - ResourcePolicy: Optional[FunctionResourcePolicy] + ResourcePolicy: Optional[ResourcePolicy] class FunctionRequestModel(BaseModel): @@ -526,25 +525,11 @@ class StateMachineEventsEventBridgeRule(BaseModel): Properties: StateMachineEventsEventBridgeRuleProperties -class StateMachineEventsApiAuthResourcePolicy(BaseModel): - AwsAccountBlacklist: Optional[List[str]] - AwsAccountWhitelist: Optional[List[str]] - CustomStatements: Optional[List[str]] - IntrinsicVpcBlacklist: Optional[List[str]] - IntrinsicVpcWhitelist: Optional[List[str]] - IntrinsicVpceBlacklist: Optional[List[str]] - IntrinsicVpceWhitelist: Optional[List[str]] - IpRangeBlacklist: Optional[List[str]] - IpRangeWhitelist: Optional[List[str]] - SourceVpcBlacklist: Optional[List[str]] - SourceVpcWhitelist: Optional[List[str]] - - class StateMachineEventsApiAuth(BaseModel): ApiKeyRequired: Optional[bool] AuthorizationScopes: Optional[List[str]] Authorizer: Optional[str] - ResourcePolicy: Optional[StateMachineEventsApiAuthResourcePolicy] + ResourcePolicy: Optional[ResourcePolicy] class StateMachineEventsApiProperties(BaseModel): From 6a80827fadc59e1fa0cd742eb3c51bb0512d9224 Mon Sep 17 00:00:00 2001 From: Gavin Zhang Date: Mon, 21 Nov 2022 15:09:48 -0800 Subject: [PATCH 4/4] Format file --- samtranslator/schema/schema.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/samtranslator/schema/schema.py b/samtranslator/schema/schema.py index be4e2e041..a287c3484 100644 --- a/samtranslator/schema/schema.py +++ b/samtranslator/schema/schema.py @@ -110,8 +110,6 @@ class ResourcePolicy(BaseModel): SourceVpcWhitelist: Optional[List[Union[str, Dict[str, Any]]]] - - class FunctionCodeUri(BaseModel): Bucket: Union[str, SamIntrinsic] Key: Union[str, SamIntrinsic] @@ -236,6 +234,7 @@ class FunctionSqsEvent(BaseModel): Type: Literal["SQS"] Properties: FunctionSqsProperties + class FunctionApiFunctionAuth(BaseModel): ApiKeyRequired: Optional[bool] AuthorizationScopes: Optional[List[str]]