diff --git a/docs/source/1.0/guides/generating-cloudformation-resources.rst b/docs/source/1.0/guides/generating-cloudformation-resources.rst index c4cf3431377..0ac9cc4702d 100644 --- a/docs/source/1.0/guides/generating-cloudformation-resources.rst +++ b/docs/source/1.0/guides/generating-cloudformation-resources.rst @@ -289,12 +289,79 @@ jsonAdd (``Map>``) } } +.. _generate-cloudformation-setting-disableHandlerPermissionGeneration: + +disableHandlerPermissionGeneration (``boolean``) + Sets whether to disable generating ``handler`` ``permission`` lists for + Resource Schemas. By default, handler permissions lists are automatically + added to schemas based on :ref:`lifecycle-operations` and permissions + listed in the :ref:`aws.iam#requiredActions-trait` on the operation. See + `the handlers section`_ in the CloudFormation Resource Schemas + documentation for more information. + + .. code-block:: json + + { + "version": "1.0", + "plugins": { + "cloudformation": { + "service": "smithy.example#Queues", + "organizationName": "Smithy", + "disableHandlerPermissionGeneration": true + } + } + } + + CloudFormation Resource Schema handlers determine what provisioning actions + can be performed for the resource. The handlers utilized by CloudFormation + align with some :ref:`lifecycle-operations`. These operations can also + define other permission actions required to invoke them with the :ref:`aws.iam#requiredActions-trait`. + + When handler permission generation is enabled, all the actions required to + invoke the operations related to the handler, including the actions for the + operations themselves, are used to populate permission lists: + + .. code-block:: json + + + "handlers": { + "create": { + "permissions": [ + "dependency:GetDependencyComponent", + "queues:CreateQueue" + ] + }, + "read": { + "permissions": [ + "queues:GetQueue" + ] + }, + "update": { + "permissions": [ + "dependency:GetDependencyComponent", + "queues:UpdateQueue" + ] + }, + "delete": { + "permissions": [ + "queues:DeleteQueue" + ] + }, + "list": { + "permissions": [ + "queues:ListQueues" + ] + } + }, + .. _generate-cloudformation-setting-disableDeprecatedPropertyGeneration: disableDeprecatedPropertyGeneration (``boolean``) Sets whether to disable generating ``deprecatedProperties`` for Resource Schemas. By default, deprecated members are automatically added to the - ``deprecatedProperties`` schema property. + ``deprecatedProperties`` schema property. See `the deprecatedProperties + section`_ in the CloudFormation Resource Schemas documentation for more + information. .. code-block:: json @@ -314,7 +381,8 @@ disableDeprecatedPropertyGeneration (``boolean``) disableRequiredPropertyGeneration (``boolean``) Sets whether to disable generating ``required`` for Resource Schemas. By default, required members are automatically added to the ``required`` - schema property. + schema property. See `the required property section`_ in the CloudFormation + Resource Schemas documentation for more information. .. code-block:: json @@ -500,3 +568,6 @@ service providers. See the `Javadocs`_ for more information. .. _Smithy Gradle plugin: https://github.com/awslabs/smithy-gradle-plugin .. _type name: https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/resource-type-schema.html#schema-properties-typeName .. _Javadocs: https://awslabs.github.io/smithy/javadoc/__smithy_version__/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/Smithy2CfnExtension.html +.. _the handlers section: https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/resource-type-schema.html#schema-properties-handlers +.. _the deprecatedProperties section: https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/resource-type-schema.html#schema-properties-deprecatedproperties +.. _the required property section: https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/resource-type-schema.html#schema-properties-required diff --git a/smithy-aws-cloudformation/build.gradle b/smithy-aws-cloudformation/build.gradle index 19bfb96fe64..927f066bc87 100644 --- a/smithy-aws-cloudformation/build.gradle +++ b/smithy-aws-cloudformation/build.gradle @@ -29,6 +29,7 @@ dependencies { api project(":smithy-build") api project(":smithy-jsonschema") api project(":smithy-aws-cloudformation-traits") + api project(":smithy-aws-iam-traits") api project(":smithy-aws-traits") // For use in validating schemas used in tests against the supplied diff --git a/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/CfnConfig.java b/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/CfnConfig.java index ba029b20e59..72c72de5333 100644 --- a/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/CfnConfig.java +++ b/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/CfnConfig.java @@ -36,6 +36,7 @@ public final class CfnConfig extends JsonSchemaConfig { /** The JSON pointer to where CloudFormation schema shared resource properties should be written. */ public static final String SCHEMA_COMPONENTS_POINTER = "#/definitions"; + private boolean disableHandlerPermissionGeneration = false; private boolean disableDeprecatedPropertyGeneration = false; private boolean disableRequiredPropertyGeneration = false; private boolean disableCapitalizedProperties = false; @@ -89,6 +90,25 @@ public void setAlphanumericOnlyRefs(boolean alphanumericOnlyRefs) { } } + public boolean getDisableHandlerPermissionGeneration() { + return disableHandlerPermissionGeneration; + } + + /** + * Set to true to disable generating {@code handler} property's {@code permissions} + * lists for Resource Schemas. + * + *

By default, handler permissions are automatically added to the {@code handler} + * property's {@code permissions} list. This includes the lifecycle operation used + * and any permissions listed in the {@code aws.iam#requiredActions} trait. + * + * @param disableHandlerPermissionGeneration True to disable handler {@code permissions} + * generation + */ + public void setDisableHandlerPermissionGeneration(boolean disableHandlerPermissionGeneration) { + this.disableHandlerPermissionGeneration = disableHandlerPermissionGeneration; + } + public boolean getDisableDeprecatedPropertyGeneration() { return disableDeprecatedPropertyGeneration; } diff --git a/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/mappers/CoreExtension.java b/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/mappers/CoreExtension.java index 7531c3dec7d..4b75d220dbd 100644 --- a/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/mappers/CoreExtension.java +++ b/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/mappers/CoreExtension.java @@ -30,6 +30,7 @@ public List getCfnMappers() { new AdditionalPropertiesMapper(), new DeprecatedMapper(), new DocumentationMapper(), + new HandlerPermissionMapper(), new IdentifierMapper(), new JsonAddMapper(), new MutabilityMapper(), diff --git a/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/mappers/HandlerPermissionMapper.java b/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/mappers/HandlerPermissionMapper.java new file mode 100644 index 00000000000..97106725859 --- /dev/null +++ b/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/mappers/HandlerPermissionMapper.java @@ -0,0 +1,120 @@ +/* + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.aws.cloudformation.schema.fromsmithy.mappers; + +import java.util.Locale; +import java.util.Set; +import java.util.TreeSet; +import software.amazon.smithy.aws.cloudformation.schema.fromsmithy.CfnMapper; +import software.amazon.smithy.aws.cloudformation.schema.fromsmithy.Context; +import software.amazon.smithy.aws.cloudformation.schema.model.Handler; +import software.amazon.smithy.aws.cloudformation.schema.model.ResourceSchema; +import software.amazon.smithy.aws.iam.traits.RequiredActionsTrait; +import software.amazon.smithy.aws.traits.ServiceTrait; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.OperationShape; +import software.amazon.smithy.model.shapes.ResourceShape; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.ShapeId; +import software.amazon.smithy.model.traits.NoReplaceTrait; +import software.amazon.smithy.utils.SetUtils; +import software.amazon.smithy.utils.SmithyInternalApi; + +/** + * Generates the resource's handler permissions list based on the lifecycle operation + * used and any permissions listed in the {@code aws.iam#requiredActions} trait. + * + * @see handlers Docs + */ +@SmithyInternalApi +public final class HandlerPermissionMapper implements CfnMapper { + @Override + public void before(Context context, ResourceSchema.Builder resourceSchema) { + if (context.getConfig().getDisableHandlerPermissionGeneration()) { + return; + } + + Model model = context.getModel(); + ServiceShape service = context.getService(); + ResourceShape resource = context.getResource(); + + // Start the create and update handler permission gathering. + // TODO Break this out to its own knowledge index if it becomes useful in more contexts. + Set createPermissions = resource.getCreate() + .map(operation -> getPermissionsEntriesForOperation(model, service, operation)) + .orElseGet(TreeSet::new); + Set updatePermissions = resource.getUpdate() + .map(operation -> getPermissionsEntriesForOperation(model, service, operation)) + .orElseGet(TreeSet::new); + + // Add the permissions from the resource's put lifecycle operation + // to the relevant handlers. + Set putPermissions = resource.getPut() + .map(operation -> getPermissionsEntriesForOperation(model, service, operation)) + .orElse(SetUtils.of()); + createPermissions.addAll(putPermissions); + // Put operations without the noReplace trait are used for updates. + resource.getPut() + .map(model::expectShape) + .filter(shape -> !shape.hasTrait(NoReplaceTrait.class)) + .ifPresent(shape -> updatePermissions.addAll(putPermissions)); + + // Set the create and update handlers, if they have permissions, now that they're complete. + if (!createPermissions.isEmpty()) { + resourceSchema.addHandler("create", Handler.builder().permissions(createPermissions).build()); + } + if (!updatePermissions.isEmpty()) { + resourceSchema.addHandler("update", Handler.builder().permissions(updatePermissions).build()); + } + + // Add the handler permission sets that don't need operation + // permissions to be combined. + resource.getRead() + .map(operation -> getPermissionsEntriesForOperation(model, service, operation)) + .ifPresent(permissions -> resourceSchema.addHandler("read", Handler.builder() + .permissions(permissions).build())); + + resource.getDelete() + .map(operation -> getPermissionsEntriesForOperation(model, service, operation)) + .ifPresent(permissions -> resourceSchema.addHandler("delete", Handler.builder() + .permissions(permissions).build())); + + resource.getList() + .map(operation -> getPermissionsEntriesForOperation(model, service, operation)) + .ifPresent(permissions -> resourceSchema.addHandler("list", Handler.builder() + .permissions(permissions).build())); + } + + private Set getPermissionsEntriesForOperation(Model model, ServiceShape service, ShapeId operationId) { + OperationShape operation = model.expectShape(operationId, OperationShape.class); + Set permissionsEntries = new TreeSet<>(); + + // Add the operation's permission name itself. + String operationActionName = + service.getTrait(ServiceTrait.class) + .map(ServiceTrait::getArnNamespace) + .orElse(service.getId().getName()) + .toLowerCase(Locale.US); + operationActionName += ":" + operationId.getName(service); + permissionsEntries.add(operationActionName); + + // Add all the other required actions for the operation. + operation.getTrait(RequiredActionsTrait.class) + .map(RequiredActionsTrait::getValues) + .map(permissionsEntries::addAll); + return permissionsEntries; + } +} diff --git a/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/model/Handler.java b/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/model/Handler.java index 53bf516ead6..e6262733fb8 100644 --- a/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/model/Handler.java +++ b/smithy-aws-cloudformation/src/main/java/software/amazon/smithy/aws/cloudformation/schema/model/Handler.java @@ -15,14 +15,15 @@ package software.amazon.smithy.aws.cloudformation.schema.model; -import java.util.ArrayList; -import java.util.List; +import java.util.Collection; import java.util.Map; +import java.util.Set; +import java.util.TreeSet; import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.node.NodeMapper; import software.amazon.smithy.model.node.ToNode; -import software.amazon.smithy.utils.ListUtils; import software.amazon.smithy.utils.MapUtils; +import software.amazon.smithy.utils.SetUtils; import software.amazon.smithy.utils.SmithyBuilder; import software.amazon.smithy.utils.ToSmithyBuilder; @@ -45,10 +46,10 @@ public final class Handler implements ToNode, ToSmithyBuilder { DELETE, 3, LIST, 4); - private final List permissions; + private final Set permissions; private Handler(Builder builder) { - this.permissions = ListUtils.copyOf(builder.permissions); + this.permissions = SetUtils.orderedCopyOf(builder.permissions); } @Override @@ -69,7 +70,7 @@ public static Builder builder() { return new Builder(); } - public List getPermissions() { + public Set getPermissions() { return permissions; } @@ -78,7 +79,7 @@ public static Integer getHandlerNameOrder(String name) { } public static final class Builder implements SmithyBuilder { - private final List permissions = new ArrayList<>(); + private final Set permissions = new TreeSet<>(); private Builder() {} @@ -87,7 +88,7 @@ public Handler build() { return new Handler(this); } - public Builder permissions(List permissions) { + public Builder permissions(Collection permissions) { this.permissions.clear(); this.permissions.addAll(permissions); return this; diff --git a/smithy-aws-cloudformation/src/test/java/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/mappers/HandlerPermissionMapperTest.java b/smithy-aws-cloudformation/src/test/java/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/mappers/HandlerPermissionMapperTest.java new file mode 100644 index 00000000000..410b00ec279 --- /dev/null +++ b/smithy-aws-cloudformation/src/test/java/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/mappers/HandlerPermissionMapperTest.java @@ -0,0 +1,86 @@ +/* + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.smithy.aws.cloudformation.schema.fromsmithy.mappers; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import java.util.Map; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import software.amazon.smithy.aws.cloudformation.schema.CfnConfig; +import software.amazon.smithy.aws.cloudformation.schema.fromsmithy.CfnConverter; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.node.Node; +import software.amazon.smithy.model.node.ObjectNode; +import software.amazon.smithy.model.node.StringNode; +import software.amazon.smithy.model.shapes.ShapeId; + +public final class HandlerPermissionMapperTest { + @Test + public void addsHandlerPermissionsByDefault() { + Model model = Model.assembler() + .addImport(HandlerPermissionMapperTest.class.getResource("simple.smithy")) + .discoverModels() + .assemble() + .unwrap(); + + CfnConfig config = new CfnConfig(); + config.setOrganizationName("Smithy"); + config.setService(ShapeId.from("smithy.example#TestService")); + + ObjectNode resourceNode = CfnConverter.create() + .config(config) + .convertToNodes(model) + .get("Smithy::TestService::FooResource"); + + Map handlersDefined = resourceNode.expectObjectMember("handlers").getStringMap(); + Assertions.assertEquals(3, handlersDefined.size()); + assertThat(handlersDefined.keySet(), containsInAnyOrder("create", "read", "update")); + + assertThat(handlersDefined.get("create").expectObjectNode() + .expectArrayMember("permissions").getElementsAs(StringNode::getValue), + containsInAnyOrder("testservice:CreateFooOperation", "otherservice:DescribeDependencyComponent")); + assertThat(handlersDefined.get("read").expectObjectNode() + .expectArrayMember("permissions").getElementsAs(StringNode::getValue), + contains("testservice:GetFooOperation")); + assertThat(handlersDefined.get("update").expectObjectNode() + .expectArrayMember("permissions").getElementsAs(StringNode::getValue), + contains("testservice:UpdateFooOperation")); + } + @Test + public void canDisableHandlerPermissionsGeneration() { + Model model = Model.assembler() + .addImport(HandlerPermissionMapperTest.class.getResource("simple.smithy")) + .discoverModels() + .assemble() + .unwrap(); + + CfnConfig config = new CfnConfig(); + config.setOrganizationName("Smithy"); + config.setService(ShapeId.from("smithy.example#TestService")); + config.setDisableHandlerPermissionGeneration(true); + + ObjectNode resourceNode = CfnConverter.create() + .config(config) + .convertToNodes(model) + .get("Smithy::TestService::FooResource"); + + assertFalse(resourceNode.getMember("handlers").isPresent()); + } +} diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/disable-caps-fooresource.cfn.json b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/disable-caps-fooresource.cfn.json index c425ae9bc1c..ec7496c7c51 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/disable-caps-fooresource.cfn.json +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/disable-caps-fooresource.cfn.json @@ -92,5 +92,22 @@ "primaryIdentifier": [ "/properties/fooId" ], + "handlers": { + "create": { + "permissions": [ + "testservice:CreateFooOperation" + ] + }, + "read": { + "permissions": [ + "testservice:GetFooOperation" + ] + }, + "update": { + "permissions": [ + "testservice:UpdateFooOperation" + ] + } + }, "additionalProperties": false } diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/complex-resource.cfn.json b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/complex-resource.cfn.json index abfaaf1b0a0..86442086fa5 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/complex-resource.cfn.json +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/complex-resource.cfn.json @@ -98,5 +98,22 @@ "/properties/FooAlias" ] ], + "handlers": { + "create": { + "permissions": [ + "testservice:CreateFoo" + ] + }, + "read": { + "permissions": [ + "testservice:GetFoo" + ] + }, + "update": { + "permissions": [ + "testservice:UpdateFoo" + ] + } + }, "additionalProperties": false } diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/create-write-mutability.cfn.json b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/create-write-mutability.cfn.json index 5532e4b926a..eaba35b64c4 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/create-write-mutability.cfn.json +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/create-write-mutability.cfn.json @@ -21,5 +21,12 @@ "primaryIdentifier": [ "/properties/FooId" ], + "handlers": { + "create": { + "permissions": [ + "testservice:CreateFoo" + ] + } + }, "additionalProperties": false } diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/full-mutability.cfn.json b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/full-mutability.cfn.json index 628e29f8c7f..c09f40aa47f 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/full-mutability.cfn.json +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/full-mutability.cfn.json @@ -21,5 +21,12 @@ "primaryIdentifier": [ "/properties/FooId" ], + "handlers": { + "create": { + "permissions": [ + "testservice:CreateFoo" + ] + } + }, "additionalProperties": false } diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/put-lifecycle.cfn.json b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/put-lifecycle.cfn.json index 6486dfb0bdc..ef9f5ce3a2c 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/put-lifecycle.cfn.json +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/put-lifecycle.cfn.json @@ -21,5 +21,17 @@ "primaryIdentifier": [ "/properties/FooId" ], + "handlers": { + "create": { + "permissions": [ + "testservice:PutFoo" + ] + }, + "update": { + "permissions": [ + "testservice:PutFoo" + ] + } + }, "additionalProperties": false } diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/queue-example.cfn.json b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/queue-example.cfn.json index 6abe986793d..d99ab4d9feb 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/queue-example.cfn.json +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/queue-example.cfn.json @@ -99,5 +99,17 @@ "/properties/Arn" ] ], + "handlers": { + "create": { + "permissions": [ + "testservice:CreateQueue" + ] + }, + "update": { + "permissions": [ + "testservice:CreateQueue" + ] + } + }, "additionalProperties": false } diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/read-mutability.cfn.json b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/read-mutability.cfn.json index 3f9b660568a..8c54212e6db 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/read-mutability.cfn.json +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/read-mutability.cfn.json @@ -22,5 +22,12 @@ "primaryIdentifier": [ "/properties/FooId" ], + "handlers": { + "read": { + "permissions": [ + "testservice:GetFoo" + ] + } + }, "additionalProperties": false } diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/write-mutability.cfn.json b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/write-mutability.cfn.json index 14cbd0be71c..56bde360d9a 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/write-mutability.cfn.json +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/integ/write-mutability.cfn.json @@ -22,5 +22,12 @@ "primaryIdentifier": [ "/properties/FooId" ], + "handlers": { + "create": { + "permissions": [ + "testservice:CreateFoo" + ] + } + }, "additionalProperties": false } diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/mappers/simple.smithy b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/mappers/simple.smithy index d0655277c86..706681e99bb 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/mappers/simple.smithy +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/mappers/simple.smithy @@ -28,6 +28,7 @@ resource FooResource { update: UpdateFooOperation, } +@aws.iam#requiredActions(["otherservice:DescribeDependencyComponent"]) operation CreateFooOperation { input: CreateFooRequest, output: CreateFooResponse, diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/simple-service-aws.cfn.json b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/simple-service-aws.cfn.json index 9e023fec7f0..2c61b7979ed 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/simple-service-aws.cfn.json +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/simple-service-aws.cfn.json @@ -54,5 +54,33 @@ "primaryIdentifier": [ "/properties/FooId" ], + "handlers": { + "create": { + "permissions": [ + "otherservice:DescribeDependencyComponent", + "something:CreateFooOperation" + ] + }, + "read": { + "permissions": [ + "something:GetFooOperation" + ] + }, + "update": { + "permissions": [ + "something:UpdateFooOperation" + ] + }, + "delete": { + "permissions": [ + "something:DeleteFooOperation" + ] + }, + "list": { + "permissions": [ + "something:ListFoosOperation" + ] + } + }, "additionalProperties": false } diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/simple-service-aws.smithy b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/simple-service-aws.smithy index d758c384e87..26a59aa8df7 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/simple-service-aws.smithy +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/simple-service-aws.smithy @@ -5,7 +5,7 @@ namespace smithy.example use aws.api#service use aws.cloudformation#cfnResource -@service(sdkId: "Some Thing", cloudFormationName: "SomeThing") +@service(sdkId: "Some Thing", cloudFormationName: "SomeThing", arnNamespace: "something") service TestService { version: "2020-07-02", resources: [ @@ -28,8 +28,11 @@ resource FooResource { create: CreateFooOperation, read: GetFooOperation, update: UpdateFooOperation, + delete: DeleteFooOperation, + list: ListFoosOperation } +@aws.iam#requiredActions(["otherservice:DescribeDependencyComponent"]) operation CreateFooOperation { input: CreateFooRequest, output: CreateFooResponse, @@ -101,6 +104,40 @@ structure UpdateFooResponse { fooValidFullyMutableProperty: ComplexProperty, } +@idempotent +operation DeleteFooOperation { + input: DeleteFooRequest, + output: DeleteFooResponse, +} + +structure DeleteFooRequest { + @required + fooId: FooId, +} + +structure DeleteFooResponse {} + +@readonly +operation ListFoosOperation { + input: ListFoosRequest, + output: ListFoosResult, +} + +structure ListFoosRequest {} + +structure ListFoosResult { + foos: FooSummaryList, +} + +list FooSummaryList { + member: FooSummary +} + +structure FooSummary { + fooId: FooId, + fooValidFullyMutableProperty: ComplexProperty, +} + string FooId structure ComplexProperty { diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/smithy-testservice-bar.cfn.json b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/smithy-testservice-bar.cfn.json index 109d6a2beb6..7eb4c55c3b0 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/smithy-testservice-bar.cfn.json +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/smithy-testservice-bar.cfn.json @@ -36,5 +36,24 @@ "/properties/Arn" ] ], + "handlers": { + "create": { + "permissions": [ + "otherservice:DescribeDependencyComponent", + "testservice:PutBarOperation" + ] + }, + "read": { + "permissions": [ + "testservice:GetBarOperation" + ] + }, + "update": { + "permissions": [ + "otherservice:DescribeDependencyComponent", + "testservice:PutBarOperation" + ] + } + }, "additionalProperties": false } diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/smithy-testservice-basil.cfn.json b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/smithy-testservice-basil.cfn.json index 3cd4aa91f06..66ba45b2073 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/smithy-testservice-basil.cfn.json +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/smithy-testservice-basil.cfn.json @@ -39,5 +39,22 @@ "/properties/BarId", "/properties/BazId" ], + "handlers": { + "create": { + "permissions": [ + "testservice:CreateBazOperation" + ] + }, + "read": { + "permissions": [ + "testservice:GetBazOperation" + ] + }, + "update": { + "permissions": [ + "testservice:UpdateBazOperation" + ] + } + }, "additionalProperties": false } diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/smithy-testservice-fooresource.cfn.json b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/smithy-testservice-fooresource.cfn.json index ac8a713361d..1a2dc78dd60 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/smithy-testservice-fooresource.cfn.json +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/smithy-testservice-fooresource.cfn.json @@ -92,5 +92,22 @@ "primaryIdentifier": [ "/properties/FooId" ], + "handlers": { + "create": { + "permissions": [ + "testservice:CreateFooOperation" + ] + }, + "read": { + "permissions": [ + "testservice:GetFooOperation" + ] + }, + "update": { + "permissions": [ + "testservice:UpdateFooOperation" + ] + } + }, "additionalProperties": false } diff --git a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/test-service.smithy b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/test-service.smithy index 80a80c65feb..394c0ef5949 100644 --- a/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/test-service.smithy +++ b/smithy-aws-cloudformation/src/test/resources/software/amazon/smithy/aws/cloudformation/schema/fromsmithy/test-service.smithy @@ -108,6 +108,7 @@ resource BarResource { } @idempotent +@aws.iam#requiredActions(["otherservice:DescribeDependencyComponent"]) operation PutBarOperation { input: PutBarRequest, }