Repository: smithy-lang/smithy
Pull request #2035 (2023-11-08 18:02:19)

Bump version to 1.41.0
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dfc18065f..ee1d33d31 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,37 @@
 # Smithy Changelog
 
+## 1.41.0 (2023-11-08)
+
+### Features
+
+* Added new member to `@aws.iam#iamResource` for disabling condition key inheritance. ([#2036](https://github.com/smithy-lang/smithy/pull/2036))
+* Added new trait for defining IAM actions, which consolidates and deprecates several older IAM traits. ([#2034](https://github.com/smithy-lang/smithy/pull/2034)) 
+* Added convenience method, `expectIntEnumShape`, to `GenerateIntEnumDirective` to get an `IntEnumShape` ([#2033](https://github.com/smithy-lang/smithy/pull/2033))
+* Added plugin to `NodeValidationVisitor` to ensure collections with `@uniqueItems` trait have unique-ness enforced. ([#2031](https://github.com/smithy-lang/smithy/pull/2031))
+* Added new member to `@aws.iam#iamResource` and `@aws.iam#defineConditionKeys` traits for defining a relative URL path of documentation. ([#2027](https://github.com/smithy-lang/smithy/pull/2027))
+* Migrated IAM traits JSON file to IDL file in `smithy-aws-iam-traits`. ([#2026](https://github.com/smithy-lang/smithy/pull/2026))
+* Added protocol test for verifying behavior when handling unknown union members in the `restJson1` protocol. ([#2022](https://github.com/smithy-lang/smithy/pull/2022))
+* Enabled `aws.iam#disableConditionKeyInference` trait to be applicable to service shapes. ([#2019](https://github.com/smithy-lang/smithy/pull/2019))
+* Updated `partitions.json` with two new entries, `aws-iso-e` and `aws-iso-f` to be consistent with SDKs. ([#2018](https://github.com/smithy-lang/smithy/pull/2018))
+* Added event-id subparts to `ClientEndpointDiscoveryValidator` to clarify validation events. ([#2017](https://github.com/smithy-lang/smithy/pull/2017))
+* Added configuration for plugin integrations in `smithy-build.json`. ([#2014](https://github.com/smithy-lang/smithy/pull/2014))
+* Added protocol tests for verifying behavior of default values in the `awsJson1_1` protocol. ([#2002](https://github.com/smithy-lang/smithy/pull/2002))
+* Added several new traits for modelling declarative endpoints. ([#1987](https://github.com/smithy-lang/smithy/pull/1987))
+
+### Documentation
+
+* Added basic website analytics so that engagement can be measured. ([#2025](https://github.com/smithy-lang/smithy/pull/2025))
+* Added documentation for new traits added for declarative endpoints. ([#2013](https://github.com/smithy-lang/smithy/pull/2013))
+
+### Bug Fixes
+
+* Fixed handling and deconflicting of duplicate apply statements targetting mixed-in members ([#2030](https://github.com/smithy-lang/smithy/pull/2030))
+* Fixed an NPE in the `PluginContext.toBuilder` method in `PluginContext`. ([#2028](https://github.com/smithy-lang/smithy/pull/2028))
+* Fixed a trait parse error for shape IDs. [#2023](https://github.com/smithy-lang/smithy/pull/2023))
+* Fixed several major issues with how neighbors and model graph traversal was implemented. ([#2020](https://github.com/smithy-lang/smithy/pull/2020))
+* Added expect-check to mitigate NSE exception in `PrivateAccessValidator`. ([#2015](https://github.com/smithy-lang/smithy/pull/2015))
+* Fixed equality of `@examples` traits by overriding the `equals` method in `ExampleTrait`. ([#2009](https://github.com/smithy-lang/smithy/pull/2009))
+
 ## 1.40.0 (2023-10-16)
 
 ### Features
diff --git a/VERSION b/VERSION
index 32b7211cb..7d47e5998 100644
--- a/VERSION
+++ b/VERSION
@@ -1,1 +1,1 @@
-1.40.0
+1.41.0
diff --git a/docs/source-2.0/aws/aws-iam.rst b/docs/source-2.0/aws/aws-iam.rst
index a7e2ae28e..ee39923db 100644
--- a/docs/source-2.0/aws/aws-iam.rst
+++ b/docs/source-2.0/aws/aws-iam.rst
@@ -100,6 +100,12 @@ members:
       - ``string``
       - A relative URL path that defines more information about the resource
         within a set of IAM-related documentation.
+    * - disableConditionKeyInheritance
+      - ``boolean``
+      - When set to ``true``, decouples this IAM resource's condition keys from
+        those of its parent resource(s). This can be used in combination with
+        the :ref:`aws.iam#conditionKeys-trait` trait to isolate a resource's
+        condition keys from those of its parent(s).
 
 The following example defines a simple resource with a name in AWS IAM that
 deviates from the :ref:`shape name of the shape ID <shape-id>` of the resource.
@@ -751,7 +757,7 @@ Given the following model,
     resource MyResource {
         identifiers: {foo: String}
         operations: [MyOperation]
-        resources: [MyInnerResource]
+        resources: [MyInnerResource, MyDetachedResource, MyCustomResource]
     }
 
     @iamResource(name: "InnerResource")
@@ -759,6 +765,19 @@ Given the following model,
         identifiers: {yum: String}
     }
 
+    @disableConditionKeyInference
+    @iamResource(disableConditionKeyInheritance: true)
+    resource MyDetachedResource {
+        identifiers: {yum: String}
+    }
+
+    @disableConditionKeyInference
+    @iamResource(disableConditionKeyInheritance: true)
+    @conditionKeys(["aws:region"])
+    resource MyCustomResource {
+        identifiers: {yum: String}
+    }
+
     @conditionKeys(["aws:region"])
     operation MyOperation {}
 
@@ -779,6 +798,11 @@ The computed condition keys for the service are:
           * ``myservice:MyResourceFoo``
           * ``otherservice:Bar``
           * ``myservice:InnerResourceYum``
+    * - ``MyDetachedResource``
+      - None
+    * - ``MyCustomResource``
+      -
+          * ``aws:region``
     * - ``MyOperation``
       -
           * ``aws:region``
diff --git a/smithy-aws-iam-traits/src/main/java/software/amazon/smithy/aws/iam/traits/ConditionKeysIndex.java b/smithy-aws-iam-traits/src/main/java/software/amazon/smithy/aws/iam/traits/ConditionKeysIndex.java
index af5c1ed4b..346616d51 100644
--- a/smithy-aws-iam-traits/src/main/java/software/amazon/smithy/aws/iam/traits/ConditionKeysIndex.java
+++ b/smithy-aws-iam-traits/src/main/java/software/amazon/smithy/aws/iam/traits/ConditionKeysIndex.java
@@ -169,7 +169,12 @@ public final class ConditionKeysIndex implements KnowledgeIndex {
             ResourceShape parent,
             Set<String> parentDefinitions
     ) {
-        Set<String> definitions = new HashSet<>(parentDefinitions);
+        Set<String> definitions = new HashSet<>();
+        if (!subject.hasTrait(IamResourceTrait.ID)
+                || !subject.expectTrait(IamResourceTrait.class).isDisableConditionKeyInheritance()
+        ) {
+            definitions.addAll(parentDefinitions);
+        }
         resourceConditionKeys.get(service.getId()).put(subject.getId(), definitions);
         subject.getTrait(ConditionKeysTrait.class).ifPresent(trait -> definitions.addAll(trait.getValues()));
 
diff --git a/smithy-aws-iam-traits/src/main/java/software/amazon/smithy/aws/iam/traits/IamResourceTrait.java b/smithy-aws-iam-traits/src/main/java/software/amazon/smithy/aws/iam/traits/IamResourceTrait.java
index 2e3bed2fb..1787b320d 100644
--- a/smithy-aws-iam-traits/src/main/java/software/amazon/smithy/aws/iam/traits/IamResourceTrait.java
+++ b/smithy-aws-iam-traits/src/main/java/software/amazon/smithy/aws/iam/traits/IamResourceTrait.java
@@ -32,13 +32,15 @@ public final class IamResourceTrait extends AbstractTrait
         implements ToSmithyBuilder<IamResourceTrait> {
     public static final ShapeId ID = ShapeId.from("aws.iam#iamResource");
 
-    public final String name;
-    public final String relativeDocumentation;
+    private final String name;
+    private final String relativeDocumentation;
+    private final boolean disableConditionKeyInheritance;
 
     private IamResourceTrait(Builder builder) {
         super(ID, builder.getSourceLocation());
         name = builder.name;
         relativeDocumentation = builder.relativeDocumentation;
+        disableConditionKeyInheritance = builder.disableConditionKeyInheritance;
     }
 
     /**
@@ -47,7 +49,7 @@ public final class IamResourceTrait extends AbstractTrait
      * @return Returns the name.
      */
     public Optional<String> getName() {
-        return Optional.of(name);
+        return Optional.ofNullable(name);
     }
 
     /**
@@ -60,6 +62,16 @@ public final class IamResourceTrait extends AbstractTrait
         return Optional.ofNullable(relativeDocumentation);
     }
 
+    /**
+     * Gets if this IAM resource's condition keys are decoupled from
+     * those of its parent resource(s).
+     *
+     * @return Returns true if condition key inheritance is disabled.
+     */
+    public boolean isDisableConditionKeyInheritance() {
+        return disableConditionKeyInheritance;
+    }
+
     public static Builder builder() {
         return new Builder();
     }
@@ -93,6 +105,7 @@ public final class IamResourceTrait extends AbstractTrait
     public static final class Builder extends AbstractTraitBuilder<IamResourceTrait, Builder> {
         private String name;
         private String relativeDocumentation;
+        private boolean disableConditionKeyInheritance;
 
         private Builder() {}
 
@@ -110,5 +123,10 @@ public final class IamResourceTrait extends AbstractTrait
             this.relativeDocumentation = relativeDocumentation;
             return this;
         }
+
+        public Builder disableConditionKeyInheritance(boolean disableConditionKeyInheritance) {
+            this.disableConditionKeyInheritance = disableConditionKeyInheritance;
+            return this;
+        }
     }
 }
diff --git a/smithy-aws-iam-traits/src/main/resources/META-INF/smithy/aws.iam.smithy b/smithy-aws-iam-traits/src/main/resources/META-INF/smithy/aws.iam.smithy
index 47fd14293..157028602 100644
--- a/smithy-aws-iam-traits/src/main/resources/META-INF/smithy/aws.iam.smithy
+++ b/smithy-aws-iam-traits/src/main/resources/META-INF/smithy/aws.iam.smithy
@@ -25,7 +25,7 @@ list conditionKeys {
 string conditionKeyValue
 
 /// Defines the set of condition keys that appear within a service in addition to
-///  inferred and global condition keys.
+/// inferred and global condition keys.
 @trait(selector: "service")
 map defineConditionKeys {
     key: IamIdentifier
@@ -65,9 +65,13 @@ structure iamResource {
     /// The name of the resource in AWS IAM.
     name: String
 
-    ///  A relative URL path that defines more information about the resource
-    ///  within a set of IAM-related documentation.
+    /// A relative URL path that defines more information about the resource
+    /// within a set of IAM-related documentation.
     relativeDocumentation: String
+
+    /// When set to `true`, decouples this IAM resource's condition keys from
+    /// those of its parent resource(s).
+    disableConditionKeyInheritance: Boolean
 }
 
 /// Other actions that the invoker must be authorized to perform when executing the targeted operation.
@@ -112,8 +116,8 @@ structure ConditionKeyDefinition {
     /// A valid URL that defines more information about the condition key.
     externalDocumentation: String
 
-    ///  A relative URL path that defines more information about the condition key
-    ///  within a set of IAM-related documentation.
+    /// A relative URL path that defines more information about the condition key
+    /// within a set of IAM-related documentation.
     relativeDocumentation: String
 }
 


Test patch:
diff --git a/smithy-aws-iam-traits/src/test/java/software/amazon/smithy/aws/iam/traits/ConditionKeysIndexTest.java b/smithy-aws-iam-traits/src/test/java/software/amazon/smithy/aws/iam/traits/ConditionKeysIndexTest.java
index e47054780..d5e7f9c8b 100644
--- a/smithy-aws-iam-traits/src/test/java/software/amazon/smithy/aws/iam/traits/ConditionKeysIndexTest.java
+++ b/smithy-aws-iam-traits/src/test/java/software/amazon/smithy/aws/iam/traits/ConditionKeysIndexTest.java
@@ -49,6 +49,11 @@ public class ConditionKeysIndexTest {
         assertThat(index.getConditionKeyNames(service, ShapeId.from("smithy.example#Resource2")),
                 containsInAnyOrder("aws:accountId", "foo:baz",
                         "myservice:Resource1Id1", "myservice:ResourceTwoId2"));
+        // This resource has inheritance disabled.
+        assertThat(index.getConditionKeyNames(service, ShapeId.from("smithy.example#Resource3")), empty());
+        // This resource has inheritance disabled and an explicit list provided.
+        assertThat(index.getConditionKeyNames(service, ShapeId.from("smithy.example#Resource4")),
+                contains("foo:baz"));
         // Note that while this operation binds identifiers, it contains no unique ConditionKeys to bind.
         assertThat(index.getConditionKeyNames(service, ShapeId.from("smithy.example#GetResource2")), is(empty()));
 
diff --git a/smithy-aws-iam-traits/src/test/java/software/amazon/smithy/aws/iam/traits/IamResourceTraitTest.java b/smithy-aws-iam-traits/src/test/java/software/amazon/smithy/aws/iam/traits/IamResourceTraitTest.java
index eb7bc1837..dc03eb967 100644
--- a/smithy-aws-iam-traits/src/test/java/software/amazon/smithy/aws/iam/traits/IamResourceTraitTest.java
+++ b/smithy-aws-iam-traits/src/test/java/software/amazon/smithy/aws/iam/traits/IamResourceTraitTest.java
@@ -16,6 +16,7 @@
 package software.amazon.smithy.aws.iam.traits;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.junit.jupiter.api.Test;
@@ -37,5 +38,6 @@ public class IamResourceTraitTest {
         assertTrue(superResource.hasTrait(IamResourceTrait.class));
         assertEquals(superResource.expectTrait(IamResourceTrait.class).getName().get(), "super");
         assertEquals(superResource.expectTrait(IamResourceTrait.class).getRelativeDocumentation().get(), "API-Super.html");
+        assertFalse(superResource.expectTrait(IamResourceTrait.class).isDisableConditionKeyInheritance());
     }
 }
diff --git a/smithy-aws-iam-traits/src/test/resources/software/amazon/smithy/aws/iam/traits/iam-resource.smithy b/smithy-aws-iam-traits/src/test/resources/software/amazon/smithy/aws/iam/traits/iam-resource.smithy
index 55fc02b9a..627e72602 100644
--- a/smithy-aws-iam-traits/src/test/resources/software/amazon/smithy/aws/iam/traits/iam-resource.smithy
+++ b/smithy-aws-iam-traits/src/test/resources/software/amazon/smithy/aws/iam/traits/iam-resource.smithy
@@ -1,31 +1,34 @@
-$version: "1.0"
+$version: "2.0"
 
 namespace smithy.example
 
 use aws.api#arn
+use aws.api#service
+use aws.iam#iamResource
 
-@aws.api#service(sdkId: "My")
+@service(sdkId: "My")
 service MyService {
-    version: "2020-07-02",
+    version: "2020-07-02"
     resources: [SuperResource]
 }
 
-@aws.iam#iamResource(
-    name: "super",
+@iamResource(
+    name: "super"
     relativeDocumentation: "API-Super.html"
+    disableConditionKeyInheritance: false
 )
 @arn(template: "super/{id1}")
 resource SuperResource {
     identifiers: {
-        id1: String,
-    },
+        id1: String
+    }
     read: GetResource
 }
 
 @readonly
 operation GetResource {
-    input: GetResourceInput,
-    output: GetResourceOutput,
+    input: GetResourceInput
+    output: GetResourceOutput
 }
 
 structure GetResourceInput {
@@ -34,9 +37,9 @@ structure GetResourceInput {
 }
 
 structure GetResourceOutput {
-    super: Super,
+    super: Super
 }
 
 structure Super {
-    id1: String,
+    id1: String
 }
diff --git a/smithy-aws-iam-traits/src/test/resources/software/amazon/smithy/aws/iam/traits/successful-condition-keys.smithy b/smithy-aws-iam-traits/src/test/resources/software/amazon/smithy/aws/iam/traits/successful-condition-keys.smithy
index a7c0999c0..f6a209a05 100644
--- a/smithy-aws-iam-traits/src/test/resources/software/amazon/smithy/aws/iam/traits/successful-condition-keys.smithy
+++ b/smithy-aws-iam-traits/src/test/resources/software/amazon/smithy/aws/iam/traits/successful-condition-keys.smithy
@@ -1,8 +1,15 @@
 $version: "1.0"
 namespace smithy.example
 
-@aws.api#service(sdkId: "My")
-@aws.iam#defineConditionKeys(
+use aws.api#arnReference
+use aws.api#service
+use aws.iam#conditionKeys
+use aws.iam#defineConditionKeys
+use aws.iam#disableConditionKeyInference
+use aws.iam#iamResource
+
+@service(sdkId: "My")
+@defineConditionKeys(
   "foo:baz": {
     type: "String",
     documentation: "Foo baz",
@@ -15,18 +22,18 @@ service MyService {
   resources: [Resource1]
 }
 
-@aws.iam#conditionKeys(["aws:accountId", "foo:baz"])
+@conditionKeys(["aws:accountId", "foo:baz"])
 operation Operation1 {}
 
-@aws.iam#conditionKeys(["aws:accountId", "foo:baz"])
+@conditionKeys(["aws:accountId", "foo:baz"])
 resource Resource1 {
   identifiers: {
     id1: ArnString,
   },
-  resources: [Resource2]
+  resources: [Resource2, Resource3, Resource4]
 }
 
-@aws.iam#iamResource(name: "ResourceTwo")
+@iamResource(name: "ResourceTwo")
 resource Resource2 {
   identifiers: {
     id1: ArnString,
@@ -36,6 +43,27 @@ resource Resource2 {
   list: ListResource2,
 }
 
+@disableConditionKeyInference
+@iamResource(disableConditionKeyInheritance: true)
+resource Resource3 {
+  identifiers: {
+    id1: ArnString
+    id2: FooString
+    id3: String
+  }
+}
+
+@disableConditionKeyInference
+@iamResource(disableConditionKeyInheritance: true)
+@conditionKeys(["foo:baz"])
+resource Resource4 {
+  identifiers: {
+    id1: ArnString
+    id2: FooString
+    id4: String
+  }
+}
+
 @readonly
 operation GetResource2 {
     input: GetResource2Input
@@ -65,5 +93,5 @@ structure ListResource2Input {
 
 structure ListResource2Output {}
 
-@aws.api#arnReference(type: "ec2:Instance")
+@arnReference(type: "ec2:Instance")
 string ArnString