Skip to content

Commit

Permalink
feat: improve schema pass-through handling (#3056)
Browse files Browse the repository at this point in the history
  • Loading branch information
hoffa committed Mar 23, 2023
1 parent de9673e commit a28afd4
Show file tree
Hide file tree
Showing 9 changed files with 270 additions and 30 deletions.
45 changes: 39 additions & 6 deletions samtranslator/internal/schema_source/aws_serverless_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
passthrough_prop,
)

PROPERTIES_STEM = "sam-resource-function"

alexaskilleventproperties = get_prop("sam-property-function-alexaskill")
apiauth = get_prop("sam-property-function-apifunctionauth")
apieventproperties = get_prop("sam-property-function-api")
Expand Down Expand Up @@ -502,8 +504,19 @@ class Properties(BaseModel):
DeadLetterQueue: Optional[DeadLetterQueueType] = prop("DeadLetterQueue")
DeploymentPreference: Optional[DeploymentPreference] = prop("DeploymentPreference")
Description: Optional[Description] = prop("Description")
Environment: Optional[Environment] = passthrough_prop("AWS::Lambda::Function", "Environment")
EphemeralStorage: Optional[EphemeralStorage] = passthrough_prop("AWS::Lambda::Function", "EphemeralStorage")
# TODO: Make the notation shorter; resource type and SAM/CFN property names usually same
Environment: Optional[Environment] = passthrough_prop(
PROPERTIES_STEM,
"Environment",
"AWS::Lambda::Function",
"Environment",
)
EphemeralStorage: Optional[EphemeralStorage] = passthrough_prop(
PROPERTIES_STEM,
"EphemeralStorage",
"AWS::Lambda::Function",
"EphemeralStorage",
)
EventInvokeConfig: Optional[EventInvokeConfig] = prop("EventInvokeConfig")
Events: Optional[
Dict[
Expand Down Expand Up @@ -532,7 +545,12 @@ class Properties(BaseModel):
]
] = prop("Events")
FileSystemConfigs: Optional[PassThroughProp] = prop("FileSystemConfigs")
FunctionName: Optional[PassThroughProp] = passthrough_prop("AWS::Lambda::Function", "FunctionName")
FunctionName: Optional[PassThroughProp] = passthrough_prop(
PROPERTIES_STEM,
"FunctionName",
"AWS::Lambda::Function",
"FunctionName",
)
FunctionUrlConfig: Optional[FunctionUrlConfig] = prop("FunctionUrlConfig")
Handler: Optional[Handler] = prop("Handler")
ImageConfig: Optional[PassThroughProp] = prop("ImageConfig")
Expand All @@ -545,7 +563,12 @@ class Properties(BaseModel):
RolePath: Optional[RolePath] = prop("RolePath")
PermissionsBoundary: Optional[PermissionsBoundary] = prop("PermissionsBoundary")
Policies: Optional[Union[str, DictStrAny, List[Union[str, DictStrAny]]]] = prop("Policies")
ProvisionedConcurrencyConfig: Optional[ProvisionedConcurrencyConfig] = prop("ProvisionedConcurrencyConfig")
ProvisionedConcurrencyConfig: Optional[ProvisionedConcurrencyConfig] = passthrough_prop(
PROPERTIES_STEM,
"ProvisionedConcurrencyConfig",
"AWS::Lambda::Alias",
"ProvisionedConcurrencyConfig",
)
ReservedConcurrentExecutions: Optional[ReservedConcurrentExecutions] = prop("ReservedConcurrentExecutions")
Role: Optional[SamIntrinsicable[str]] = prop("Role")
Runtime: Optional[Runtime] = prop("Runtime")
Expand All @@ -567,7 +590,12 @@ class Globals(BaseModel):
MemorySize: Optional[MemorySize] = prop("MemorySize")
Timeout: Optional[Timeout] = prop("Timeout")
VpcConfig: Optional[VpcConfig] = prop("VpcConfig")
Environment: Optional[Environment] = passthrough_prop("AWS::Lambda::Function", "Environment")
Environment: Optional[Environment] = passthrough_prop(
PROPERTIES_STEM,
"Environment",
"AWS::Lambda::Function",
"Environment",
)
Tags: Optional[Tags] = prop("Tags")
Tracing: Optional[Tracing] = prop("Tracing")
KmsKeyArn: Optional[KmsKeyArn] = prop("KmsKeyArn")
Expand All @@ -581,7 +609,12 @@ class Globals(BaseModel):
AssumeRolePolicyDocument: Optional[AssumeRolePolicyDocument] = prop("AssumeRolePolicyDocument")
EventInvokeConfig: Optional[EventInvokeConfig] = prop("EventInvokeConfig")
Architectures: Optional[Architectures] = prop("Architectures")
EphemeralStorage: Optional[EphemeralStorage] = passthrough_prop("AWS::Lambda::Function", "EphemeralStorage")
EphemeralStorage: Optional[EphemeralStorage] = passthrough_prop(
PROPERTIES_STEM,
"EphemeralStorage",
"AWS::Lambda::Function",
"EphemeralStorage",
)
SnapStart: Optional[SnapStart] = prop("SnapStart")
RuntimeManagementConfig: Optional[RuntimeManagementConfig] = prop("RuntimeManagementConfig")

Expand Down
12 changes: 9 additions & 3 deletions samtranslator/internal/schema_source/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,22 @@ def get_prop(stem: str) -> Any:
return partial(_get_prop, stem)


def passthrough_prop(resource_type: str, path: str) -> Any:
def passthrough_prop(sam_docs_stem: str, sam_docs_name: str, resource_type: str, prop_path: str) -> Any:
"""
Specifies a pass-through field, where resource_type is the CloudFormation
resource type, and path is a `.`-delimitated path to the property.
"""
prop_path = f"definitions.{resource_type}.properties.Properties.properties.{path}"
prop_path = f"definitions.{resource_type}.properties.Properties.properties.{prop_path}"
docs = _DOCS["properties"][sam_docs_stem][sam_docs_name]
return Field(
# We add a custom value to the schema containing the path to the pass-through
# documentation; the dict containing the value is replaced in the final schema
__samPassThroughPath=prop_path,
__samPassThrough={
# To know at schema build-time where to find the property schema
"schemaPath": prop_path,
# Use SAM docs at the top-level pass-through; it can include useful SAM-specific information
"markdownDescriptionOverride": docs,
},
)


Expand Down
11 changes: 9 additions & 2 deletions samtranslator/internal/schema_source/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import argparse
import json
from copy import deepcopy
from pathlib import Path
from typing import Any, Callable, Dict, Optional, Type, Union

Expand Down Expand Up @@ -149,10 +150,16 @@ def extend_with_cfn_schema(sam_schema: Dict[str, Any], cfn_schema: Dict[str, Any
_add_embedded_connectors(sam_schema)

# Inject CloudFormation documentation to SAM pass-through properties
def replace_passthrough(d: Dict[str, Any]) -> Dict[str, Any]:
passthrough = d["__samPassThrough"]
schema = deepcopy(_deep_get(cfn_schema, passthrough["schemaPath"]))
schema["markdownDescription"] = passthrough["markdownDescriptionOverride"]
return schema

_replace_in_dict(
sam_schema,
"__samPassThroughPath",
lambda d: _deep_get(cfn_schema, d["__samPassThroughPath"]),
"__samPassThrough",
replace_passthrough,
)

# The unified schema should include all supported properties
Expand Down
17 changes: 6 additions & 11 deletions samtranslator/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -200647,12 +200647,12 @@
},
"Environment": {
"$ref": "#/definitions/AWS::Lambda::Function.Environment",
"markdownDescription": "Environment variables that are accessible from function code during execution\\. \n*Required*: No \n*Type*: [Environment](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html) \n*Update requires*: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)",
"markdownDescription": "The configuration for the runtime environment\\. \n*Type*: [Environment](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`Environment`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html) property of an `AWS::Lambda::Function` resource\\.",
"title": "Environment"
},
"EphemeralStorage": {
"$ref": "#/definitions/AWS::Lambda::Function.EphemeralStorage",
"markdownDescription": "The size of the function's `/tmp` directory in MB\\. The default value is 512, but it can be any whole number between 512 and 10,240 MB\\. \n*Required*: No \n*Type*: [EphemeralStorage](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-ephemeralstorage.html) \n*Update requires*: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)",
"markdownDescription": "An object that specifies the disk space, in MB, available to your Lambda function in `/tmp`\\. \nFor more information about this property, see [Lambda execution environment](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-context.html) in the *AWS Lambda Developer Guide*\\. \n*Type*: [EphemeralStorage](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-ephemeralstorage) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`EphemeralStorage`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-ephemeralstorage) property of an `AWS::Lambda::Function` resource\\.",
"title": "EphemeralStorage"
},
"EventInvokeConfig": {
Expand Down Expand Up @@ -200934,12 +200934,12 @@
},
"Environment": {
"$ref": "#/definitions/AWS::Lambda::Function.Environment",
"markdownDescription": "Environment variables that are accessible from function code during execution\\. \n*Required*: No \n*Type*: [Environment](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html) \n*Update requires*: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)",
"markdownDescription": "The configuration for the runtime environment\\. \n*Type*: [Environment](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`Environment`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html) property of an `AWS::Lambda::Function` resource\\.",
"title": "Environment"
},
"EphemeralStorage": {
"$ref": "#/definitions/AWS::Lambda::Function.EphemeralStorage",
"markdownDescription": "The size of the function's `/tmp` directory in MB\\. The default value is 512, but it can be any whole number between 512 and 10,240 MB\\. \n*Required*: No \n*Type*: [EphemeralStorage](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-ephemeralstorage.html) \n*Update requires*: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)",
"markdownDescription": "An object that specifies the disk space, in MB, available to your Lambda function in `/tmp`\\. \nFor more information about this property, see [Lambda execution environment](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-context.html) in the *AWS Lambda Developer Guide*\\. \n*Type*: [EphemeralStorage](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-ephemeralstorage) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`EphemeralStorage`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-ephemeralstorage) property of an `AWS::Lambda::Function` resource\\.",
"title": "EphemeralStorage"
},
"EventInvokeConfig": {
Expand Down Expand Up @@ -201030,7 +201030,7 @@
"title": "FileSystemConfigs"
},
"FunctionName": {
"markdownDescription": "The name of the Lambda function, up to 64 characters in length\\. If you don't specify a name, AWS CloudFormation generates one\\. \nIf you specify a name, you cannot perform updates that require replacement of this resource\\. You can perform updates that require no or some interruption\\. If you must replace the resource, specify a new name\\. \n*Required*: No \n*Type*: String \n*Update requires*: [Replacement](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-replacement)",
"markdownDescription": "A name for the function\\. If you don't specify a name, a unique name is generated for you\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`FunctionName`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-functionname) property of an `AWS::Lambda::Function` resource\\.",
"title": "FunctionName",
"type": "string"
},
Expand Down Expand Up @@ -201161,12 +201161,7 @@
"title": "Policies"
},
"ProvisionedConcurrencyConfig": {
"allOf": [
{
"$ref": "#/definitions/PassThroughProp"
}
],
"description": "The provisioned concurrency configuration of a function's alias\\. \n`ProvisionedConcurrencyConfig` can be specified only if the `AutoPublishAlias` is set\\. Otherwise, an error results\\.\n*Type*: [ProvisionedConcurrencyConfig](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-alias.html#cfn-lambda-alias-provisionedconcurrencyconfig) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`ProvisionedConcurrencyConfig`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-alias.html#cfn-lambda-alias-provisionedconcurrencyconfig) property of an `AWS::Lambda::Alias` resource\\.",
"$ref": "#/definitions/AWS::Lambda::Alias.ProvisionedConcurrencyConfiguration",
"markdownDescription": "The provisioned concurrency configuration of a function's alias\\. \n`ProvisionedConcurrencyConfig` can be specified only if the `AutoPublishAlias` is set\\. Otherwise, an error results\\.\n*Type*: [ProvisionedConcurrencyConfig](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-alias.html#cfn-lambda-alias-provisionedconcurrencyconfig) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`ProvisionedConcurrencyConfig`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-alias.html#cfn-lambda-alias-provisionedconcurrencyconfig) property of an `AWS::Lambda::Alias` resource\\.",
"title": "ProvisionedConcurrencyConfig"
},
Expand Down
Loading

0 comments on commit a28afd4

Please sign in to comment.