Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

06/23/2023 AWS CloudFormation Resource Provider Definition Schema #52

Merged
merged 4 commits into from
Jun 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## v0.21.0 (Unreleased)

Support [`handlers.handlerSchema`](https://github.com/aws-cloudformation/cloudformation-resource-schema#handlers).

## v0.20.0 (December 19, 2022)

Support [`arrayType`](https://github.com/aws-cloudformation/cloudformation-resource-schema#arraytype).
Expand Down
5 changes: 3 additions & 2 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const (
)

type Handler struct {
Permissions []string `json:"permissions,omitempty"`
TimeoutInMinutes int `json:"timeoutInMinutes,omitempty"`
HandlerSchema *HandlerSchema `json:"handlerSchema,omitempty"`
Permissions []string `json:"permissions,omitempty"`
TimeoutInMinutes int `json:"timeoutInMinutes,omitempty"`
}
12 changes: 12 additions & 0 deletions handler_schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package cfschema

type HandlerSchema struct {
AllOf []*PropertySubschema `json:"allOf,omitempty"`
AnyOf []*PropertySubschema `json:"anyOf,omitempty"`
OneOf []*PropertySubschema `json:"oneOf,omitempty"`
Properties map[string]*Property `json:"properties,omitempty"`
Required []string `json:"required,omitempty"`
}
75 changes: 75 additions & 0 deletions handler_schema_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package cfschema_test

import (
"path/filepath"
"testing"

cfschema "github.com/hashicorp/aws-cloudformation-resource-schema-sdk-go"
)

func TestHandlerSchema(t *testing.T) {
testCases := []struct {
TestDescription string
MetaSchemaPath string
ResourceSchemaPath string
ExpectError bool
ExpectedHandlerSchema int
}{
{
TestDescription: "no handlerSchema",
MetaSchemaPath: "provider.definition.schema.v1.json",
ResourceSchemaPath: "AWS_CloudWatch_MetricStream.json",
},
{
TestDescription: "list handlerSchema",
MetaSchemaPath: "provider.definition.schema.v1.json",
ResourceSchemaPath: "AWS_NetworkManager_TransitGatewayRegistration.json",
ExpectedHandlerSchema: 1,
},
}

for _, testCase := range testCases {
testCase := testCase

t.Run(testCase.TestDescription, func(t *testing.T) {
metaSchema, err := cfschema.NewMetaJsonSchemaPath(filepath.Join("testdata", testCase.MetaSchemaPath))

if err != nil {
t.Fatalf("unexpected NewMetaJsonSchemaPath() error: %s", err)
}

resourceSchema, err := cfschema.NewResourceJsonSchemaPath(filepath.Join("testdata", testCase.ResourceSchemaPath))

if err != nil {
t.Fatalf("unexpected NewResourceJsonSchemaPath() error: %s", err)
}

err = metaSchema.ValidateResourceJsonSchema(resourceSchema)

if err != nil {
t.Fatalf("unexpected ValidateResourceJsonSchema() error: %s", err)
}

resource, err := resourceSchema.Resource()

if err != nil {
t.Fatalf("unexpected Resource() error: %s", err)
}

got := 0

for _, handler := range resource.Handlers {
if handler.HandlerSchema != nil {
got++
}
}

if actual, expected := got, testCase.ExpectedHandlerSchema; actual != expected {
t.Errorf("expected %d handlerSchema elements, got: %d", expected, actual)
}
})
}
}
2 changes: 2 additions & 0 deletions resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ type Resource struct {
DeprecatedProperties PropertyJsonPointers `json:"deprecatedProperties,omitempty"`
Description *string `json:"description,omitempty"`
Handlers map[string]*Handler `json:"handlers,omitempty"`
NonPublicDefinitions PropertyJsonPointers `json:"nonPublicDefinitions,omitempty"`
NonPublicProperties PropertyJsonPointers `json:"nonPublicProperties,omitempty"`
OneOf []*PropertySubschema `json:"oneOf,omitempty"`
PrimaryIdentifier PropertyJsonPointers `json:"primaryIdentifier,omitempty"`
Properties map[string]*Property `json:"properties,omitempty"`
Expand Down
1 change: 1 addition & 0 deletions tagging.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ type Tagging struct {
TagUpdatable *bool `json:"tagUpdatable,omitempty"`
CloudFormationSystemTags *bool `json:"cloudFormationSystemTags,omitempty"`
TagProperty *PropertyJsonPointer `json:"tagProperty,omitempty"`
Permissions []string `json:"permissions,omitempty"`
}
62 changes: 62 additions & 0 deletions testdata/AWS_NetworkManager_TransitGatewayRegistration.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"typeName": "AWS::NetworkManager::TransitGatewayRegistration",
"description": "The AWS::NetworkManager::TransitGatewayRegistration type registers a transit gateway in your global network. The transit gateway can be in any AWS Region, but it must be owned by the same AWS account that owns the global network. You cannot register a transit gateway in more than one global network.",
"sourceUrl": "https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-networkmanager.git",
"properties": {
"GlobalNetworkId": {
"description": "The ID of the global network.",
"type": "string"
},
"TransitGatewayArn": {
"description": "The Amazon Resource Name (ARN) of the transit gateway.",
"type": "string"
}
},
"taggable": false,
"additionalProperties": false,
"required": [
"GlobalNetworkId",
"TransitGatewayArn"
],
"createOnlyProperties": [
"/properties/GlobalNetworkId",
"/properties/TransitGatewayArn"
],
"primaryIdentifier": [
"/properties/GlobalNetworkId",
"/properties/TransitGatewayArn"
],
"handlers": {
"create": {
"permissions": [
"networkmanager:RegisterTransitGateway"
],
"timeoutInMinutes": 30
},
"read": {
"permissions": [
"networkmanager:GetTransitGatewayRegistrations"
]
},
"list": {
"handlerSchema": {
"properties": {
"GlobalNetworkId": {
"$ref": "resource-schema.json#/properties/GlobalNetworkId"
}
},
"required": ["GlobalNetworkId"]
},
"permissions": [
"networkmanager:GetTransitGatewayRegistrations"
]
},
"delete": {
"permissions": [
"networkmanager:DeregisterTransitGateway"
],
"timeoutInMinutes": 30
}
}
}

68 changes: 67 additions & 1 deletion testdata/provider.definition.schema.v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,57 @@
"title": "CloudFormation Resource Provider Definition MetaSchema",
"description": "This schema validates a CloudFormation resource provider definition.",
"definitions": {
"handlerSchema": {
"type": "object",
"properties": {
"properties": {
"$ref": "file://./base.definition.schema.v1.json#/properties/properties"
},
"required": {
"$ref": "file://./base.definition.schema.v1.json#/properties/required"
},
"allOf": {
"$ref": "file://./base.definition.schema.v1.json#/definitions/schemaArray"
},
"anyOf": {
"$ref": "file://./base.definition.schema.v1.json#/definitions/schemaArray"
},
"oneOf": {
"$ref": "file://./base.definition.schema.v1.json#/definitions/schemaArray"
}
},
"required": [
"properties"
],
"additionalProperties": false
},
"handlerDefinitionWithSchemaOverride": {
"description": "Defines any execution operations which can be performed on this resource provider",
"type": "object",
"properties": {
"handlerSchema": {
"$ref": "#/definitions/handlerSchema"
},
"permissions": {
"type": "array",
"items": {
"type": "string"
},
"additionalItems": false
},
"timeoutInMinutes": {
"description": "Defines the timeout for the entire operation to be interpreted by the invoker of the handler. The default is 120 (2 hours).",
"type": "integer",
"minimum": 2,
"maximum": 2160,
"default": 120
}
},
"additionalProperties": false,
"required": [
"permissions"
]
},
"handlerDefinition": {
"description": "Defines any execution operations which can be performed on this resource provider",
"type": "object",
Expand Down Expand Up @@ -145,6 +196,13 @@
"description": "A reference to the Tags property in the schema.",
"$ref": "http://json-schema.org/draft-07/schema#/properties/$ref",
"default": "/properties/Tags"
},
"permissions": {
"type": "array",
"items": {
"type": "string"
},
"additionalItems": false
}
},
"required": [
Expand Down Expand Up @@ -183,7 +241,7 @@
"$ref": "#/definitions/handlerDefinition"
},
"list": {
"$ref": "#/definitions/handlerDefinition"
"$ref": "#/definitions/handlerDefinitionWithSchemaOverride"
}
},
"additionalProperties": false
Expand All @@ -204,6 +262,14 @@
"description": "A list of JSON pointers for properties that can only be updated under certain conditions. For example, you can upgrade the engine version of an RDS DBInstance but you cannot downgrade it. When updating this property for a resource in a CloudFormation stack, the resource will be replaced if it cannot be updated.",
"$ref": "file://./base.definition.schema.v1.json#/definitions/jsonPointerArray"
},
"nonPublicProperties": {
"description": "A list of JSON pointers for properties that are hidden. These properties will still be used but will not be visible",
"$ref": "file://./base.definition.schema.v1.json#/definitions/jsonPointerArray"
},
"nonPublicDefinitions": {
"description": "A list of JSON pointers for definitions that are hidden. These definitions will still be used but will not be visible",
"$ref": "file://./base.definition.schema.v1.json#/definitions/jsonPointerArray"
},
"createOnlyProperties": {
"description": "A list of JSON pointers to properties that are only able to be specified by the customer when creating a resource. Conversely, any property *not* in this list can be applied to an Update request.",
"$ref": "file://./base.definition.schema.v1.json#/definitions/jsonPointerArray"
Expand Down