diff --git a/smithy-aws-endpoints/build.gradle b/smithy-aws-endpoints/build.gradle index 7eda2cdcdbb..2fdbcadaec0 100644 --- a/smithy-aws-endpoints/build.gradle +++ b/smithy-aws-endpoints/build.gradle @@ -11,6 +11,8 @@ ext { } dependencies { + api project(":smithy-aws-traits") + api project(":smithy-diff") api project(":smithy-rules-engine") api project(":smithy-model") api project(":smithy-utils") diff --git a/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/diff/EndpointSigV4Migration.java b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/diff/EndpointSigV4Migration.java new file mode 100644 index 00000000000..1c12b24efd0 --- /dev/null +++ b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/diff/EndpointSigV4Migration.java @@ -0,0 +1,249 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.rulesengine.aws.diff; + +import static software.amazon.smithy.rulesengine.aws.language.functions.EndpointAuthUtils.isSigV4AEquivalentAuthScheme; +import static software.amazon.smithy.rulesengine.aws.language.functions.EndpointAuthUtils.isSigV4EquivalentAuthScheme; +import static software.amazon.smithy.rulesengine.language.EndpointRuleSet.EndpointPathCollector; + +import java.util.AbstractMap.SimpleEntry; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import software.amazon.smithy.diff.ChangedShape; +import software.amazon.smithy.diff.Differences; +import software.amazon.smithy.diff.evaluators.AbstractDiffEvaluator; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.knowledge.ServiceIndex; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.ShapeId; +import software.amazon.smithy.model.traits.AuthTrait; +import software.amazon.smithy.model.validation.ValidationEvent; +import software.amazon.smithy.rulesengine.aws.language.functions.EndpointAuthUtils; +import software.amazon.smithy.rulesengine.language.Endpoint; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait; +import software.amazon.smithy.utils.Pair; +import software.amazon.smithy.utils.SmithyInternalApi; + +/** + * Emit diff validation for SigV4 migration in the {@code @smithy.rules#endpointRuleSet} trait. + * + * Specifically, SigV4 ({@code aws.auth#sigv4}) to SigV4A ({@code aws.auth#sigv4a}) due to a subset of credentials + * usable with SigV4 that are not usable with SigV4A. + * + * @see AWS Authentication Traits + * @see Endpoint {@code authSchemes} list property + */ +@SmithyInternalApi +public final class EndpointSigV4Migration extends AbstractDiffEvaluator { + private static final Identifier ID_NAME = Identifier.of("name"); + + @Override + public List evaluate(Differences differences) { + List events = new ArrayList<>(); + + Model oldModel = differences.getOldModel(); + ServiceIndex oldServiceIndex = ServiceIndex.of(oldModel); + Model newModel = differences.getNewModel(); + ServiceIndex newServiceIndex = ServiceIndex.of(newModel); + + // Validate Service effective auth schemes + List> serviceChanges = differences + .changedShapes(ServiceShape.class) + .collect(Collectors.toList()); + for (ChangedShape change : serviceChanges) { + ServiceShape oldServiceShape = change.getOldShape(); + ServiceShape newServiceShape = change.getNewShape(); + + if (!oldServiceShape.hasTrait(EndpointRuleSetTrait.ID) + || !newServiceShape.hasTrait(EndpointRuleSetTrait.ID)) { + continue; + } + + Optional> endpointRuleSetOpt = + change.getChangedTrait(EndpointRuleSetTrait.class); + Optional> authOpt = + change.getChangedTrait(AuthTrait.class); + List oldModeledAuthSchemes = getModeledAuthSchemes(oldServiceIndex, oldServiceShape); + List newModeledAuthSchemes = getModeledAuthSchemes(newServiceIndex, newServiceShape); + // Validate diffs for changes to `@smithy.rules#endpointRuleSet` and `@auth` and effective auth schemes + if (!endpointRuleSetOpt.isPresent() + && !authOpt.isPresent() + // Check modeled auth schemes since they could change without the `@auth` trait present + && oldModeledAuthSchemes.equals(newModeledAuthSchemes)) { + continue; + } + + EndpointRuleSetTrait oldErs = oldServiceShape.expectTrait(EndpointRuleSetTrait.class); + Map oldEndpoints = EndpointPathCollector.from(oldErs).collect(); + + EndpointRuleSetTrait newErs = newServiceShape.expectTrait(EndpointRuleSetTrait.class); + Map newEndpoints = EndpointPathCollector.from(newErs).collect(); + + // JSON path -> Endpoint entries that exist in both the old and new model and are changed + Map> changedEndpoints = newEndpoints.entrySet().stream() + .filter(e -> oldEndpoints.containsKey(e.getKey())) + .map(e -> new SimpleEntry>( + e.getKey(), + Pair.of(oldEndpoints.get(e.getKey()), e.getValue()))) + .filter(e -> !e.getValue().getLeft().equals(e.getValue().getRight())) + .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); + for (Entry> entry : changedEndpoints.entrySet()) { + String jsonPath = entry.getKey(); + Endpoint oldEndpoint = entry.getValue().getLeft(); + Endpoint newEndpoint = entry.getValue().getRight(); + List oldAuthSchemes = getAuthSchemes(oldEndpoint, oldModeledAuthSchemes); + List newAuthSchemes = getAuthSchemes(newEndpoint, newModeledAuthSchemes); + + boolean isOldSigV4Present = containsSigV4EquivalentAuthScheme(oldAuthSchemes); + boolean isOldSigV4APresent = containsSigV4AEquivalentAuthScheme(oldAuthSchemes); + boolean isNewSigV4Present = containsSigV4EquivalentAuthScheme(newAuthSchemes); + boolean isNewSigV4APresent = containsSigV4AEquivalentAuthScheme(newAuthSchemes); + + boolean isSigV4Replaced = isOldSigV4Present && !isNewSigV4Present + && !isOldSigV4APresent && isNewSigV4APresent; + boolean isSigV4AReplaced = !isOldSigV4Present && isNewSigV4Present + && isOldSigV4APresent && !isNewSigV4APresent; + boolean noSigV4XRemoved = isOldSigV4Present && isNewSigV4Present + && isOldSigV4APresent && isNewSigV4APresent; + boolean isSigV4Added = !isOldSigV4Present && isNewSigV4Present + && isOldSigV4APresent && isNewSigV4APresent; + boolean isSigV4AAdded = isOldSigV4Present && isNewSigV4Present + && !isOldSigV4APresent && isNewSigV4APresent; + if (isSigV4Replaced) { + events.add(danger( + newServiceShape, + "The `aws.auth#sigv4` authentication scheme was replaced by the `aws.auth#sigv4a` " + + "authentication scheme in the effective auth schemes for an endpoint in the " + + "`@smithy.rules#endpointRuleSet` trait applied to `" + newServiceShape.getId() + "` at: `" + + jsonPath + "`. " + + "Replacing the `aws.auth#sigv4` authentication scheme with the `aws.auth#sigv4a` " + + "authentication scheme directly is not backward compatible since not all credentials usable " + + "by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' " + + "authentication.")); + } else if (isSigV4AReplaced) { + events.add(danger( + newServiceShape, + "The `aws.auth#sigv4a` authentication scheme was replaced by the `aws.auth#sigv4` " + + "authentication scheme in the effective auth schemes for an endpoint in the " + + "`@smithy.rules#endpointRuleSet` trait applied to `" + newServiceShape.getId() + "` at: `" + + jsonPath + "`. " + + "Replacing the `aws.auth#sigv4` authentication scheme with the `aws.auth#sigv4a` " + + "authentication scheme directly may not be backward compatible if the signing scope was " + + "narrowed (typically from `*`).")); + } else if (noSigV4XRemoved) { + int oldSigV4Index = getIndexOfSigV4AuthScheme(oldAuthSchemes); + int oldSigV4aIndex = getIndexOfSigV4AAuthScheme(oldAuthSchemes); + int sigV4Index = getIndexOfSigV4AuthScheme(newAuthSchemes); + int sigV4aIndex = getIndexOfSigV4AAuthScheme(newAuthSchemes); + boolean isOldSigV4BeforeSigV4A = oldSigV4Index < oldSigV4aIndex; + boolean isSigV4BeforeSigV4A = sigV4Index < sigV4aIndex; + if (isOldSigV4BeforeSigV4A && !isSigV4BeforeSigV4A) { + events.add(danger( + newServiceShape, + "The `aws.auth#sigv4a` authentication scheme was moved before the `aws.auth#sigv4` " + + "authentication scheme in the effective auth schemes for an endpoint in the " + + "`@smithy.rules#endpointRuleSet` trait applied to `" + newServiceShape.getId() + + "` at: `" + jsonPath + "`. " + + "Moving the `aws.auth#sigv4a` authentication scheme before the `aws.auth#sigv4` " + + "authentication scheme is not backward compatible since not all credentials usable by " + + "`aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing " + + "clients' authentication.")); + } + if (!isOldSigV4BeforeSigV4A && isSigV4BeforeSigV4A) { + events.add(danger( + newServiceShape, + "The `aws.auth#sigv4` authentication scheme was moved before the `aws.auth#sigv4a` " + + "authentication scheme in the effective auth schemes for an endpoint in the " + + "`@smithy.rules#endpointRuleSet` trait applied to `" + newServiceShape.getId() + + "` at: `" + jsonPath + "`. " + + "Moving the `aws.auth#sigv4` authentication scheme before the `aws.auth#sigv4a` " + + "authentication scheme may not be backward compatible if the signing scope was narrowed " + + "(typically from `*`).")); + } + } else if (isSigV4Added) { + int sigV4Index = getIndexOfSigV4AuthScheme(newAuthSchemes); + int sigV4aIndex = getIndexOfSigV4AAuthScheme(newAuthSchemes); + boolean isSigV4AddedBeforeSigV4A = sigV4Index < sigV4aIndex; + if (isSigV4AddedBeforeSigV4A) { + events.add(danger( + newServiceShape, + "The `aws.auth#sigv4` authentication scheme was added before the `aws.auth#sigv4a` " + + "authentication scheme in the effective auth schemes for an endpoint in the " + + "`@smithy.rules#endpointRuleSet` trait applied to `" + newServiceShape.getId() + + "` at: `" + jsonPath + "`. " + + "Adding the `aws.auth#sigv4` authentication scheme before an existing `aws.auth#sigv4a` " + + "authentication scheme may not be backward compatible if the signing scope was narrowed " + + "(typically from `*`).")); + } + } else if (isSigV4AAdded) { + int sigV4Index = getIndexOfSigV4AuthScheme(newAuthSchemes); + int sigV4aIndex = getIndexOfSigV4AAuthScheme(newAuthSchemes); + boolean isSigV4AAddedBeforeSigV4 = sigV4aIndex < sigV4Index; + if (isSigV4AAddedBeforeSigV4) { + events.add(danger( + newServiceShape, + "The `aws.auth#sigv4a` authentication scheme was added before the `aws.auth#sigv4` " + + "authentication scheme in the effective auth schemes for an endpoint in the " + + "`@smithy.rules#endpointRuleSet` trait applied to `" + newServiceShape.getId() + + "` at: `" + jsonPath + "`. " + + "Adding the `aws.auth#sigv4a` authentication scheme before an existing `aws.auth#sigv4` " + + "authentication scheme is not backward compatible since not all credentials usable by " + + "`aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' " + + "authentication.")); + } + } + } + } + + return events; + } + + private static List getAuthSchemes(Endpoint endpoint, List modeledAuthSchemes) { + List endpointAuthSchemes = endpoint.getEndpointAuthSchemes().stream() + .map(a -> a.get(ID_NAME).asStringLiteral().get().expectLiteral()) + .collect(Collectors.toList()); + return endpointAuthSchemes.size() == 0 + ? modeledAuthSchemes + : endpointAuthSchemes; + } + + private static List getModeledAuthSchemes(ServiceIndex serviceIndex, ServiceShape serviceShape) { + return serviceIndex.getEffectiveAuthSchemes(serviceShape).keySet().stream() + .map(ShapeId::toString) + .collect(Collectors.toList()); + } + + private static boolean containsSigV4EquivalentAuthScheme(List authSchemes) { + return getIndexOfSigV4AuthScheme(authSchemes) != -1; + } + + private static boolean containsSigV4AEquivalentAuthScheme(List authSchemes) { + return getIndexOfSigV4AAuthScheme(authSchemes) != -1; + } + + private static int getIndexOfSigV4AuthScheme(List authSchemes) { + return getIndexOfAuthScheme(authSchemes, EndpointAuthUtils::isSigV4EquivalentAuthScheme); + } + + private static int getIndexOfSigV4AAuthScheme(List authSchemes) { + return getIndexOfAuthScheme(authSchemes, EndpointAuthUtils::isSigV4AEquivalentAuthScheme); + } + + private static int getIndexOfAuthScheme(List authSchemes, Predicate identifier) { + for (int i = 0; i < authSchemes.size(); i++) { + if (identifier.test(authSchemes.get(i))) { + return i; + } + } + return -1; + } +} diff --git a/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/EndpointAuthUtils.java b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/EndpointAuthUtils.java index 1c25ea94bcc..32544ee4aa5 100644 --- a/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/EndpointAuthUtils.java +++ b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/language/functions/EndpointAuthUtils.java @@ -11,6 +11,8 @@ import java.util.Optional; import java.util.function.BiFunction; import java.util.function.Function; +import software.amazon.smithy.aws.traits.auth.SigV4ATrait; +import software.amazon.smithy.aws.traits.auth.SigV4Trait; import software.amazon.smithy.model.FromSourceLocation; import software.amazon.smithy.model.validation.Severity; import software.amazon.smithy.model.validation.ValidationEvent; @@ -26,15 +28,19 @@ * Utilities for constructing and validating AWS-specific authentication components for rule-sets. */ public final class EndpointAuthUtils { - private static final String SIGV_4 = "sigv4"; - private static final String SIG_V4A = "sigv4a"; + private static final String SIGV4 = "sigv4"; + private static final String SIGV4_SHAPE_ID = SigV4Trait.ID.toString(); + private static final String SIGV4_SUB = "sigv4-"; + private static final String SIGV4_S3EXPRESS = "sigv4-s3express"; + private static final String SIGV4A = "sigv4a"; + private static final String SIGV4A_SHAPE_ID = SigV4ATrait.ID.toString(); private static final String SIGNING_NAME = "signingName"; private static final String SIGNING_REGION = "signingRegion"; private static final String SIGNING_REGION_SET = "signingRegionSet"; - private static final Identifier ID_SIGNING_NAME = Identifier.of("signingName"); - private static final Identifier ID_SIGNING_REGION = Identifier.of("signingRegion"); - private static final Identifier ID_SIGNING_REGION_SET = Identifier.of("signingRegionSet"); + private static final Identifier ID_SIGNING_NAME = Identifier.of(SIGNING_NAME); + private static final Identifier ID_SIGNING_REGION = Identifier.of(SIGNING_REGION); + private static final Identifier ID_SIGNING_REGION_SET = Identifier.of(SIGNING_REGION_SET); private static final Identifier ID_DISABLE_DOUBLE_ENCODING = Identifier.of("disableDoubleEncoding"); private static final Identifier ID_DISABLE_NORMALIZE_PATH = Identifier.of("disableNormalizePath"); @@ -49,7 +55,7 @@ private EndpointAuthUtils() {} * @return the updated endpoint builder. */ public static Endpoint.Builder sigv4(Endpoint.Builder builder, Literal signingRegion, Literal signingService) { - return builder.addAuthScheme(SIGV_4, MapUtils.of( + return builder.addAuthScheme(SIGV4, MapUtils.of( SIGNING_NAME, signingService, SIGNING_REGION, signingRegion)); } @@ -67,17 +73,49 @@ public static Endpoint.Builder sigv4a( List signingRegionSet, Literal signingService ) { - return builder.addAuthScheme(SIG_V4A, MapUtils.of( + return builder.addAuthScheme(SIGV4A, MapUtils.of( SIGNING_NAME, signingService, SIGNING_REGION_SET, Literal.tupleLiteral(signingRegionSet))); } + /** + * Returns if a given auth scheme is equivalent to {@code aws.auth#sigv4}. + * + * @param authScheme name of the auth scheme. + * @return whether the auth scheme is equivalent to {@code aws.auth#sigv4}. + */ + public static boolean isSigV4EquivalentAuthScheme(String authScheme) { + if (authScheme.equals(SIGV4) || authScheme.equals(SIGV4_SHAPE_ID)) { + return true; + } + if (authScheme.startsWith(SIGV4_SUB) && !authScheme.equals(SIGV4_S3EXPRESS)) { + return true; + } + return false; + } + + /** + * Returns if a given auth scheme is equivalent to {@code aws.auth#sigv4a}. + * + * @param authScheme name of the auth scheme. + * @return whether the auth scheme is equivalent to {@code aws.auth#sigv4a}. + */ + public static boolean isSigV4AEquivalentAuthScheme(String authScheme) { + if (authScheme.equals(SIGV4A) || authScheme.equals(SIGV4A_SHAPE_ID)) { + return true; + } + if (authScheme.equals(SIGV4_S3EXPRESS)) { + return true; + } + return false; + } + static final class SigV4SchemeValidator implements AuthSchemeValidator { SigV4SchemeValidator() {} @Override public boolean test(String name) { - return name.equals("sigv4"); + return name.equals(SIGV4); } @Override @@ -126,7 +164,7 @@ static final class SigV4aSchemeValidator implements AuthSchemeValidator { @Override public boolean test(String name) { - return name.equals("sigv4a"); + return name.equals(SIGV4A); } @Override @@ -173,7 +211,7 @@ static final class SigV4SubSchemeValidator implements AuthSchemeValidator { @Override public boolean test(String name) { - return name.startsWith("sigv4-"); + return name.startsWith(SIGV4_SUB); } @Override diff --git a/smithy-aws-endpoints/src/main/resources/META-INF/services/software.amazon.smithy.diff.DiffEvaluator b/smithy-aws-endpoints/src/main/resources/META-INF/services/software.amazon.smithy.diff.DiffEvaluator new file mode 100644 index 00000000000..e16810eea84 --- /dev/null +++ b/smithy-aws-endpoints/src/main/resources/META-INF/services/software.amazon.smithy.diff.DiffEvaluator @@ -0,0 +1 @@ +software.amazon.smithy.rulesengine.aws.diff.EndpointSigV4Migration diff --git a/smithy-aws-endpoints/src/test/java/software/amazon/smithy/rulesengine/aws/DiffTest.java b/smithy-aws-endpoints/src/test/java/software/amazon/smithy/rulesengine/aws/DiffTest.java new file mode 100644 index 00000000000..36a0a1d6bd8 --- /dev/null +++ b/smithy-aws-endpoints/src/test/java/software/amazon/smithy/rulesengine/aws/DiffTest.java @@ -0,0 +1,47 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.rulesengine.aws; + +import static java.lang.String.format; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.Callable; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import software.amazon.smithy.diff.ModelDiff; +import software.amazon.smithy.diff.testrunner.SmithyDiffTestCase; +import software.amazon.smithy.diff.testrunner.SmithyDiffTestSuite; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.SourceLocation; +import software.amazon.smithy.model.shapes.ShapeId; +import software.amazon.smithy.model.validation.Severity; +import software.amazon.smithy.model.validation.ValidationEvent; +import software.amazon.smithy.utils.IoUtils; +import software.amazon.smithy.utils.Pair; + +public class DiffTest { + @ParameterizedTest(name = "{0}") + @MethodSource("source") + public void testRunner(String filename, Callable callable) throws Exception { + callable.call(); + } + + public static Stream source() { + return SmithyDiffTestSuite.defaultParameterizedTestSource(DiffTest.class); + } +} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/either-or-both-no-endpointRuleSet.a.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/either-or-both-no-endpointRuleSet.a.smithy new file mode 100644 index 00000000000..ca42804e545 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/either-or-both-no-endpointRuleSet.a.smithy @@ -0,0 +1,28 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Add.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Remove.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use smithy.rules#endpointRuleSet + +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [] +) +service Service2 {} + +service Service3 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/either-or-both-no-endpointRuleSet.b.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/either-or-both-no-endpointRuleSet.b.smithy new file mode 100644 index 00000000000..cf6f413d0d1 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/either-or-both-no-endpointRuleSet.b.smithy @@ -0,0 +1,28 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Add.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Remove.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use smithy.rules#endpointRuleSet + +service Service1 {} + +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [] +) +service Service3 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/either-or-both-no-endpointRuleSet.events b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/either-or-both-no-endpointRuleSet.events new file mode 100644 index 00000000000..e69de29bb2d diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/no-old-sigv4.a.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/no-old-sigv4.a.smithy new file mode 100644 index 00000000000..dbec9b9d77a --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/no-old-sigv4.a.smithy @@ -0,0 +1,74 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Add.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Remove.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "example" + } + ] + } + } + } + ] +) +@auth([httpBearerAuth]) +@httpBearerAuth +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "example" + } + ] + } + } + } + ] +) +@auth([httpBearerAuth]) +@httpBearerAuth +service Service2 {} + +@auth([httpBearerAuth]) +@httpBearerAuth +service Service3 {} + +@auth([httpBearerAuth]) +@httpBearerAuth +service Service4 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/no-old-sigv4.b.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/no-old-sigv4.b.smithy new file mode 100644 index 00000000000..71844773b7a --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/no-old-sigv4.b.smithy @@ -0,0 +1,74 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Add.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Remove.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "example" + } + ] + } + } + } + ] +) +@auth([httpBearerAuth]) +@httpBearerAuth +service Service1 {} + +@auth([httpBearerAuth]) +@httpBearerAuth +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "example" + } + ] + } + } + } + ] +) +@auth([httpBearerAuth]) +@httpBearerAuth +service Service3 {} + +@auth([httpBearerAuth]) +@httpBearerAuth +service Service4 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/no-old-sigv4.events b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/no-old-sigv4.events new file mode 100644 index 00000000000..e69de29bb2d diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-after-sigv4a-migration.a.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-after-sigv4a-migration.a.smithy new file mode 100644 index 00000000000..0cca3ba92c8 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-after-sigv4a-migration.a.smithy @@ -0,0 +1,159 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service5") +@sigv4a(name: "service5") +service Service5 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service6") +@sigv4a(name: "service6") +service Service6 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-after-sigv4a-migration.b.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-after-sigv4a-migration.b.smithy new file mode 100644 index 00000000000..226fa83a059 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-after-sigv4a-migration.b.smithy @@ -0,0 +1,178 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service5") +@sigv4a(name: "service5") +service Service5 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service6") +@sigv4a(name: "service6") +service Service6 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-after-sigv4a-migration.events b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-after-sigv4a-migration.events new file mode 100644 index 00000000000..e69de29bb2d diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-before-sigv4a-migration.a.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-before-sigv4a-migration.a.smithy new file mode 100644 index 00000000000..26184bb539a --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-before-sigv4a-migration.a.smithy @@ -0,0 +1,183 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "SigV4Migration" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service5") +@sigv4a(name: "service5") +service Service5 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service6") +@sigv4a(name: "service6") +service Service6 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service7") +@sigv4a(name: "service7") +service Service7 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-before-sigv4a-migration.b.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-before-sigv4a-migration.b.smithy new file mode 100644 index 00000000000..ea80dd82fd8 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-before-sigv4a-migration.b.smithy @@ -0,0 +1,202 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "SigV4Migration" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service5") +@sigv4a(name: "service5") +service Service5 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service6") +@sigv4a(name: "service6") +service Service6 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { hello: "world" } + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service7") +@sigv4a(name: "service7") +service Service7 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-before-sigv4a-migration.events b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-before-sigv4a-migration.events new file mode 100644 index 00000000000..70b9b43e194 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-before-sigv4a-migration.events @@ -0,0 +1,11 @@ +[DANGER] ns.foo#Service1: The `aws.auth#sigv4` authentication scheme was added before the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service1` at: `/rules/0/endpoint`. Adding the `aws.auth#sigv4` authentication scheme before an existing `aws.auth#sigv4a` authentication scheme may not be backward compatible if the signing scope was narrowed (typically from `*`). | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service2: The `aws.auth#sigv4` authentication scheme was added before the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service2` at: `/rules/0/endpoint`. Adding the `aws.auth#sigv4` authentication scheme before an existing `aws.auth#sigv4a` authentication scheme may not be backward compatible if the signing scope was narrowed (typically from `*`). | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service3: The `aws.auth#sigv4` authentication scheme was added before the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service3` at: `/rules/0/endpoint`. Adding the `aws.auth#sigv4` authentication scheme before an existing `aws.auth#sigv4a` authentication scheme may not be backward compatible if the signing scope was narrowed (typically from `*`). | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service4: The `aws.auth#sigv4` authentication scheme was added before the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service4` at: `/rules/0/endpoint`. Adding the `aws.auth#sigv4` authentication scheme before an existing `aws.auth#sigv4a` authentication scheme may not be backward compatible if the signing scope was narrowed (typically from `*`). | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service5: The `aws.auth#sigv4` authentication scheme was added before the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service5` at: `/rules/0/endpoint`. Adding the `aws.auth#sigv4` authentication scheme before an existing `aws.auth#sigv4a` authentication scheme may not be backward compatible if the signing scope was narrowed (typically from `*`). | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service7: The `aws.auth#sigv4` authentication scheme was added before the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service7` at: `/rules/0/endpoint`. Adding the `aws.auth#sigv4` authentication scheme before an existing `aws.auth#sigv4a` authentication scheme may not be backward compatible if the signing scope was narrowed (typically from `*`). | EndpointSigV4Migration diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-replace-sigv4a-migration.a.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-replace-sigv4a-migration.a.smithy new file mode 100644 index 00000000000..3b2b090c028 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-replace-sigv4a-migration.a.smithy @@ -0,0 +1,116 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "SigV4Migration" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-replace-sigv4a-migration.b.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-replace-sigv4a-migration.b.smithy new file mode 100644 index 00000000000..0eb05adcd90 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-replace-sigv4a-migration.b.smithy @@ -0,0 +1,114 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "SigV4Migration" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-replace-sigv4a-migration.events b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-replace-sigv4a-migration.events new file mode 100644 index 00000000000..81f3a779daa --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-replace-sigv4a-migration.events @@ -0,0 +1,5 @@ +[DANGER] ns.foo#Service1: The `aws.auth#sigv4a` authentication scheme was replaced by the `aws.auth#sigv4` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service1` at: `/rules/0/endpoint`. Replacing the `aws.auth#sigv4` authentication scheme with the `aws.auth#sigv4a` authentication scheme directly may not be backward compatible if the signing scope was narrowed (typically from `*`). | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service2: The `aws.auth#sigv4a` authentication scheme was replaced by the `aws.auth#sigv4` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service2` at: `/rules/0/endpoint`. Replacing the `aws.auth#sigv4` authentication scheme with the `aws.auth#sigv4a` authentication scheme directly may not be backward compatible if the signing scope was narrowed (typically from `*`). | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service3: The `aws.auth#sigv4a` authentication scheme was replaced by the `aws.auth#sigv4` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service3` at: `/rules/0/endpoint`. Replacing the `aws.auth#sigv4` authentication scheme with the `aws.auth#sigv4a` authentication scheme directly may not be backward compatible if the signing scope was narrowed (typically from `*`). | EndpointSigV4Migration diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-in-order.a.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-in-order.a.smithy new file mode 100644 index 00000000000..ac3a78168b7 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-in-order.a.smithy @@ -0,0 +1,210 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4]) +@httpBearerAuth +@sigv4(name: "service5") +@sigv4a(name: "service5") +service Service5 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4, sigv4a]) +@httpBearerAuth +@sigv4(name: "service6") +@sigv4a(name: "service6") +service Service6 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service7") +@sigv4a(name: "service7") +service Service7 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-in-order.b.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-in-order.b.smithy new file mode 100644 index 00000000000..29f88f1a4be --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-in-order.b.smithy @@ -0,0 +1,212 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "example" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "example" + } + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + { + name: "example" + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4, httpBearerAuth, sigv4a]) +@httpBearerAuth +@sigv4(name: "service5") +@sigv4a(name: "service5") +service Service5 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { hello: "world" } + } + } + ] +) +@auth([sigv4, httpBearerAuth, sigv4a]) +@httpBearerAuth +@sigv4(name: "service6") +@sigv4a(name: "service6") +service Service6 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "example" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service7") +@sigv4a(name: "service7") +service Service7 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-in-order.events b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-in-order.events new file mode 100644 index 00000000000..e69de29bb2d diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-swap-order.a.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-swap-order.a.smithy new file mode 100644 index 00000000000..daa9b730bb3 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-swap-order.a.smithy @@ -0,0 +1,226 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Add.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "SigV4Migration" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service5") +@sigv4a(name: "service5") +service Service5 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service6") +@sigv4a(name: "service6") +service Service6 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service7") +@sigv4a(name: "service7") +service Service7 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service8") +@sigv4a(name: "service8") +service Service8 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-swap-order.b.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-swap-order.b.smithy new file mode 100644 index 00000000000..4cad3982b97 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-swap-order.b.smithy @@ -0,0 +1,226 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Add.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "SigV4Migration" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service5") +@sigv4a(name: "service5") +service Service5 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service6") +@sigv4a(name: "service6") +service Service6 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service7") +@sigv4a(name: "service7") +service Service7 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service8") +@sigv4a(name: "service8") +service Service8 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-swap-order.events b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-swap-order.events new file mode 100644 index 00000000000..b7bac41d2c7 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4-sigv4a-swap-order.events @@ -0,0 +1,11 @@ +[DANGER] ns.foo#Service1: The `aws.auth#sigv4a` authentication scheme was moved before the `aws.auth#sigv4` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service1` at: `/rules/0/endpoint`. Moving the `aws.auth#sigv4a` authentication scheme before the `aws.auth#sigv4` authentication scheme is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service2: The `aws.auth#sigv4a` authentication scheme was moved before the `aws.auth#sigv4` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service2` at: `/rules/0/endpoint`. Moving the `aws.auth#sigv4a` authentication scheme before the `aws.auth#sigv4` authentication scheme is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service3: The `aws.auth#sigv4a` authentication scheme was moved before the `aws.auth#sigv4` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service3` at: `/rules/0/endpoint`. Moving the `aws.auth#sigv4a` authentication scheme before the `aws.auth#sigv4` authentication scheme is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service5: The `aws.auth#sigv4` authentication scheme was moved before the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service5` at: `/rules/0/endpoint`. Moving the `aws.auth#sigv4` authentication scheme before the `aws.auth#sigv4a` authentication scheme may not be backward compatible if the signing scope was narrowed (typically from `*`). | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service6: The `aws.auth#sigv4` authentication scheme was moved before the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service6` at: `/rules/0/endpoint`. Moving the `aws.auth#sigv4` authentication scheme before the `aws.auth#sigv4a` authentication scheme may not be backward compatible if the signing scope was narrowed (typically from `*`). | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service7: The `aws.auth#sigv4` authentication scheme was moved before the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service7` at: `/rules/0/endpoint`. Moving the `aws.auth#sigv4` authentication scheme before the `aws.auth#sigv4a` authentication scheme may not be backward compatible if the signing scope was narrowed (typically from `*`). | EndpointSigV4Migration diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-after-sigv4-migration.a.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-after-sigv4-migration.a.smithy new file mode 100644 index 00000000000..4c2b91b2249 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-after-sigv4-migration.a.smithy @@ -0,0 +1,156 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service5") +@sigv4a(name: "service5") +service Service5 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service6") +@sigv4a(name: "service6") +service Service6 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-after-sigv4-migration.b.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-after-sigv4-migration.b.smithy new file mode 100644 index 00000000000..fc289c1c289 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-after-sigv4-migration.b.smithy @@ -0,0 +1,178 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service5") +@sigv4a(name: "service5") +service Service5 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4, sigv4a]) +@sigv4(name: "service6") +@sigv4a(name: "service6") +service Service6 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-after-sigv4-migration.events b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-after-sigv4-migration.events new file mode 100644 index 00000000000..e69de29bb2d diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-before-sigv4-migration.a.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-before-sigv4-migration.a.smithy new file mode 100644 index 00000000000..cffe9fd9ef1 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-before-sigv4-migration.a.smithy @@ -0,0 +1,180 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "SigV4Migration" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service5") +@sigv4a(name: "service5") +service Service5 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service6") +@sigv4a(name: "service6") +service Service6 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service7") +@sigv4a(name: "service7") +service Service7 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-before-sigv4-migration.b.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-before-sigv4-migration.b.smithy new file mode 100644 index 00000000000..f6288ff77d1 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-before-sigv4-migration.b.smithy @@ -0,0 +1,202 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "SigV4Migration" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service5") +@sigv4a(name: "service5") +service Service5 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service6") +@sigv4a(name: "service6") +service Service6 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { hello: "world" } + } + } + ] +) +@auth([sigv4a, sigv4]) +@sigv4(name: "service7") +@sigv4a(name: "service7") +service Service7 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-before-sigv4-migration.events b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-before-sigv4-migration.events new file mode 100644 index 00000000000..cafd3b9f587 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-before-sigv4-migration.events @@ -0,0 +1,11 @@ +[DANGER] ns.foo#Service1: The `aws.auth#sigv4a` authentication scheme was added before the `aws.auth#sigv4` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service1` at: `/rules/0/endpoint`. Adding the `aws.auth#sigv4a` authentication scheme before an existing `aws.auth#sigv4` authentication scheme is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service2: The `aws.auth#sigv4a` authentication scheme was added before the `aws.auth#sigv4` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service2` at: `/rules/0/endpoint`. Adding the `aws.auth#sigv4a` authentication scheme before an existing `aws.auth#sigv4` authentication scheme is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service3: The `aws.auth#sigv4a` authentication scheme was added before the `aws.auth#sigv4` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service3` at: `/rules/0/endpoint`. Adding the `aws.auth#sigv4a` authentication scheme before an existing `aws.auth#sigv4` authentication scheme is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service4: The `aws.auth#sigv4a` authentication scheme was added before the `aws.auth#sigv4` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service4` at: `/rules/0/endpoint`. Adding the `aws.auth#sigv4a` authentication scheme before an existing `aws.auth#sigv4` authentication scheme is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service5: The `aws.auth#sigv4a` authentication scheme was added before the `aws.auth#sigv4` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service5` at: `/rules/0/endpoint`. Adding the `aws.auth#sigv4a` authentication scheme before an existing `aws.auth#sigv4` authentication scheme is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service7: The `aws.auth#sigv4a` authentication scheme was added before the `aws.auth#sigv4` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service7` at: `/rules/0/endpoint`. Adding the `aws.auth#sigv4a` authentication scheme before an existing `aws.auth#sigv4` authentication scheme is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | EndpointSigV4Migration diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-replace-sigv4-migration.a.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-replace-sigv4-migration.a.smithy new file mode 100644 index 00000000000..6ebc522285d --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-replace-sigv4-migration.a.smithy @@ -0,0 +1,114 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "SigV4Migration" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-replace-sigv4-migration.b.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-replace-sigv4-migration.b.smithy new file mode 100644 index 00000000000..b221414978e --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-replace-sigv4-migration.b.smithy @@ -0,0 +1,116 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } + { + id: "SigV4Migration" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4a" + signingRegionSet: ["*"] + } + ] + } + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: {} + } + } + ] +) +@auth([sigv4a]) +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-replace-sigv4-migration.events b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-replace-sigv4-migration.events new file mode 100644 index 00000000000..2b31c4e0afa --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/sigv4a-replace-sigv4-migration.events @@ -0,0 +1,5 @@ +[DANGER] ns.foo#Service1: The `aws.auth#sigv4` authentication scheme was replaced by the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service1` at: `/rules/0/endpoint`. Replacing the `aws.auth#sigv4` authentication scheme with the `aws.auth#sigv4a` authentication scheme directly is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service2: The `aws.auth#sigv4` authentication scheme was replaced by the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service2` at: `/rules/0/endpoint`. Replacing the `aws.auth#sigv4` authentication scheme with the `aws.auth#sigv4a` authentication scheme directly is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | EndpointSigV4Migration +----- +[DANGER] ns.foo#Service3: The `aws.auth#sigv4` authentication scheme was replaced by the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for an endpoint in the `@smithy.rules#endpointRuleSet` trait applied to `ns.foo#Service3` at: `/rules/0/endpoint`. Replacing the `aws.auth#sigv4` authentication scheme with the `aws.auth#sigv4a` authentication scheme directly is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | EndpointSigV4Migration diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/with-sigv4-no-migration.a.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/with-sigv4-no-migration.a.smithy new file mode 100644 index 00000000000..0ec0391bc30 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/with-sigv4-no-migration.a.smithy @@ -0,0 +1,84 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4]) +@httpBearerAuth +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4]) +@httpBearerAuth +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@auth([sigv4]) +@httpBearerAuth +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@auth([sigv4]) +@httpBearerAuth +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/with-sigv4-no-migration.b.smithy b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/with-sigv4-no-migration.b.smithy new file mode 100644 index 00000000000..f89b193fdf2 --- /dev/null +++ b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/with-sigv4-no-migration.b.smithy @@ -0,0 +1,90 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } + { + id: "ModifiedTrait.Update.smithy.rules#endpointRuleSet" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a +use smithy.rules#endpointRuleSet + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "example" + } + { + name: "sigv4" + } + ] + } + } + } + ] +) +@auth([sigv4, httpBearerAuth]) +@httpBearerAuth +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 {} + +@endpointRuleSet( + version: "1.0" + serviceId: "service" + parameters: {} + rules: [ + { + type: "endpoint" + conditions: [] + endpoint: { + url: "https://abc.service.com" + properties: { + authSchemes: [ + { + name: "sigv4" + } + { + name: "example" + } + ] + } + } + } + ] +) +@auth([sigv4, httpBearerAuth]) +@httpBearerAuth +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 {} + +@auth([sigv4, httpBearerAuth]) +@httpBearerAuth +@sigv4(name: "service3") +@sigv4a(name: "service3") +service Service3 {} + +@auth([httpBearerAuth, sigv4]) +@httpBearerAuth +@sigv4(name: "service4") +@sigv4a(name: "service4") +service Service4 {} diff --git a/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/with-sigv4-no-migration.events b/smithy-aws-endpoints/src/test/resources/software/amazon/smithy/rulesengine/aws/diffs/with-sigv4-no-migration.events new file mode 100644 index 00000000000..e69de29bb2d diff --git a/smithy-aws-traits/build.gradle b/smithy-aws-traits/build.gradle index 151dd98dbcc..af2ac03b00e 100644 --- a/smithy-aws-traits/build.gradle +++ b/smithy-aws-traits/build.gradle @@ -21,5 +21,6 @@ ext { } dependencies { + api project(":smithy-diff") api project(":smithy-model") } diff --git a/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/auth/diff/SigV4Migration.java b/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/auth/diff/SigV4Migration.java new file mode 100644 index 00000000000..890c9fda867 --- /dev/null +++ b/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/auth/diff/SigV4Migration.java @@ -0,0 +1,210 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.aws.traits.auth.diff; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import software.amazon.smithy.aws.traits.auth.SigV4ATrait; +import software.amazon.smithy.aws.traits.auth.SigV4Trait; +import software.amazon.smithy.diff.ChangedShape; +import software.amazon.smithy.diff.Differences; +import software.amazon.smithy.diff.evaluators.AbstractDiffEvaluator; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.knowledge.ServiceIndex; +import software.amazon.smithy.model.knowledge.TopDownIndex; +import software.amazon.smithy.model.shapes.OperationShape; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.model.shapes.ShapeId; +import software.amazon.smithy.model.validation.ValidationEvent; +import software.amazon.smithy.utils.SmithyInternalApi; + +/** + * Emit diff validation for SigV4 migration in the {@code @auth} trait. + * + * Specifically, SigV4 ({@code aws.auth#sigv4}) to SigV4A ({@code aws.auth#sigv4a}) due to a subset of credentials + * usable with SigV4 that are not usable with SigV4A. + * + * @see AWS Authentication Traits + */ +@SmithyInternalApi +public final class SigV4Migration extends AbstractDiffEvaluator { + @Override + public List evaluate(Differences differences) { + List events = new ArrayList<>(); + + Model oldModel = differences.getOldModel(); + ServiceIndex oldServiceIndex = ServiceIndex.of(oldModel); + Model newModel = differences.getNewModel(); + ServiceIndex newServiceIndex = ServiceIndex.of(newModel); + + // Validate Service effective auth schemes + List> serviceChanges = differences + .changedShapes(ServiceShape.class) + .collect(Collectors.toList()); + for (ChangedShape change : serviceChanges) { + ServiceShape oldServiceShape = change.getOldShape(); + List oldAuthSchemes = oldServiceIndex + .getEffectiveAuthSchemes(oldServiceShape) + .keySet() + .stream() + .collect(Collectors.toList()); + ServiceShape newServiceShape = change.getNewShape(); + List newAuthSchemes = newServiceIndex + .getEffectiveAuthSchemes(newServiceShape) + .keySet() + .stream() + .collect(Collectors.toList()); + validateMigration( + newServiceShape, + oldAuthSchemes, + newAuthSchemes, + events); + } + + Map> operationToContainedServiceBindings = + computeOperationToContainedServiceBindings(newModel); + List> operationChanges = differences + .changedShapes(OperationShape.class) + .collect(Collectors.toList()); + for (ChangedShape change : operationChanges) { + OperationShape newOperationShape = change.getNewShape(); + Set newOperationServiceBindings = operationToContainedServiceBindings.get(newOperationShape); + if (newOperationServiceBindings == null) { + continue; + } + // Validate Operation effective auth schemes + for (ServiceShape newServiceShape : newOperationServiceBindings) { + ServiceShape oldServiceShape = oldModel.expectShape(newServiceShape.getId(), ServiceShape.class); + OperationShape oldOperationShape = change.getOldShape(); + List oldAuthSchemes = oldServiceIndex + .getEffectiveAuthSchemes(oldServiceShape, oldOperationShape) + .keySet() + .stream() + .collect(Collectors.toList()); + List newAuthSchemes = newServiceIndex + .getEffectiveAuthSchemes(newServiceShape, newOperationShape) + .keySet() + .stream() + .collect(Collectors.toList()); + validateMigration( + newOperationShape, + oldAuthSchemes, + newAuthSchemes, + events); + } + } + + return events; + } + + private void validateMigration( + Shape shape, + List oldAuthSchemes, + List newAuthSchemes, + List events + ) { + boolean isOldSigV4Present = oldAuthSchemes.contains(SigV4Trait.ID); + boolean isOldSigV4APresent = oldAuthSchemes.contains(SigV4ATrait.ID); + boolean isNewSigV4Present = newAuthSchemes.contains(SigV4Trait.ID); + boolean isNewSigV4APresent = newAuthSchemes.contains(SigV4ATrait.ID); + + boolean isSigV4Replaced = isOldSigV4Present && !isNewSigV4Present && !isOldSigV4APresent && isNewSigV4APresent; + boolean isSigV4AReplaced = !isOldSigV4Present && isNewSigV4Present && isOldSigV4APresent && !isNewSigV4APresent; + boolean noSigV4XRemoved = isOldSigV4Present && isNewSigV4Present && isOldSigV4APresent && isNewSigV4APresent; + boolean isSigV4Added = !isOldSigV4Present && isNewSigV4Present && isOldSigV4APresent && isNewSigV4APresent; + boolean isSigV4AAdded = isOldSigV4Present && isNewSigV4Present && !isOldSigV4APresent && isNewSigV4APresent; + if (isSigV4Replaced) { + events.add(danger( + shape, + "The `aws.auth#sigv4` authentication scheme was replaced by the `aws.auth#sigv4a` authentication " + + "scheme in the effective auth schemes for `" + shape.getId() + "`. " + + "Replacing the `aws.auth#sigv4` authentication scheme with the `aws.auth#sigv4a` authentication " + + "scheme directly is not backward compatible since not all credentials usable by `aws.auth#sigv4` are " + + "compatible with `aws.auth#sigv4a`, and can break existing clients' authentication.")); + } else if (isSigV4AReplaced) { + events.add(danger( + shape, + "The `aws.auth#sigv4a` authentication scheme was replaced by the `aws.auth#sigv4` authentication " + + "scheme in the effective auth schemes for `" + shape.getId() + "`. " + + "Replacing the `aws.auth#sigv4` authentication scheme with the `aws.auth#sigv4a` authentication " + + "scheme directly may not be backward compatible if the signing scope was narrowed (typically from " + + "`*`).")); + } else if (noSigV4XRemoved) { + int oldSigV4Index = oldAuthSchemes.indexOf(SigV4Trait.ID); + int oldSigV4aIndex = oldAuthSchemes.indexOf(SigV4ATrait.ID); + int sigV4Index = newAuthSchemes.indexOf(SigV4Trait.ID); + int sigV4aIndex = newAuthSchemes.indexOf(SigV4ATrait.ID); + boolean isOldSigV4BeforeSigV4A = oldSigV4Index < oldSigV4aIndex; + boolean isSigV4BeforeSigV4A = sigV4Index < sigV4aIndex; + if (isOldSigV4BeforeSigV4A && !isSigV4BeforeSigV4A) { + events.add(danger( + shape, + "The `aws.auth#sigv4a` authentication scheme was moved before the `aws.auth#sigv4` authentication " + + "scheme in the effective auth schemes for `" + shape.getId() + "`. " + + "Moving the `aws.auth#sigv4a` authentication scheme before the `aws.auth#sigv4` authentication " + + "scheme is not backward compatible since not all credentials usable by `aws.auth#sigv4` are " + + "compatible with `aws.auth#sigv4a`, and can break existing clients' authentication.")); + } + if (!isOldSigV4BeforeSigV4A && isSigV4BeforeSigV4A) { + events.add(danger( + shape, + "The `aws.auth#sigv4` authentication scheme was moved before the `aws.auth#sigv4a` authentication " + + "scheme in the effective auth schemes for `" + shape.getId() + "`. " + + "Moving the `aws.auth#sigv4` authentication scheme before the `aws.auth#sigv4a` authentication " + + "scheme may not be backward compatible if the signing scope was narrowed (typically from `*`).")); + } + } else if (isSigV4Added) { + int sigV4Index = newAuthSchemes.indexOf(SigV4Trait.ID); + int sigV4aIndex = newAuthSchemes.indexOf(SigV4ATrait.ID); + boolean isSigV4AddedBeforeSigV4A = sigV4Index < sigV4aIndex; + if (isSigV4AddedBeforeSigV4A) { + events.add(danger( + shape, + "The `aws.auth#sigv4` authentication scheme was added before the `aws.auth#sigv4a` authentication " + + "scheme in the effective auth schemes for `" + shape.getId() + "`. " + + "Adding the `aws.auth#sigv4` authentication scheme before an existing `aws.auth#sigv4a` " + + "authentication scheme may not be backward compatible if the signing scope was narrowed " + + "(typically from `*`).")); + } + } else if (isSigV4AAdded) { + int sigV4Index = newAuthSchemes.indexOf(SigV4Trait.ID); + int sigV4aIndex = newAuthSchemes.indexOf(SigV4ATrait.ID); + boolean isSigV4AAddedBeforeSigV4 = sigV4aIndex < sigV4Index; + if (isSigV4AAddedBeforeSigV4) { + events.add(danger( + shape, + "The `aws.auth#sigv4a` authentication scheme was added before the `aws.auth#sigv4` authentication " + + "scheme in the effective auth schemes for `" + shape.getId() + "`. " + + "Adding the `aws.auth#sigv4a` authentication scheme before an existing `aws.auth#sigv4` " + + "authentication scheme is not backward compatible since not all credentials usable by " + + "`aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' " + + "authentication.")); + } + } + } + + private static Map> computeOperationToContainedServiceBindings(Model model) { + Map> operationToContainedServiceBindings = new HashMap<>(); + TopDownIndex topDownIndex = TopDownIndex.of(model); + for (OperationShape operationShape : model.getOperationShapes()) { + Set operationEntry = operationToContainedServiceBindings + .getOrDefault(operationShape, new HashSet()); + for (ServiceShape serviceShape : model.getServiceShapes()) { + if (topDownIndex.getContainedOperations(serviceShape).contains(operationShape)) { + operationEntry.add(serviceShape); + } + } + operationToContainedServiceBindings.put(operationShape, operationEntry); + } + return operationToContainedServiceBindings; + } +} diff --git a/smithy-aws-traits/src/main/resources/META-INF/services/software.amazon.smithy.diff.DiffEvaluator b/smithy-aws-traits/src/main/resources/META-INF/services/software.amazon.smithy.diff.DiffEvaluator new file mode 100644 index 00000000000..5bbacbffb26 --- /dev/null +++ b/smithy-aws-traits/src/main/resources/META-INF/services/software.amazon.smithy.diff.DiffEvaluator @@ -0,0 +1 @@ +software.amazon.smithy.aws.traits.auth.diff.SigV4Migration diff --git a/smithy-aws-traits/src/test/java/software/amazon/smithy/aws/traits/DiffTest.java b/smithy-aws-traits/src/test/java/software/amazon/smithy/aws/traits/DiffTest.java new file mode 100644 index 00000000000..e001bff254c --- /dev/null +++ b/smithy-aws-traits/src/test/java/software/amazon/smithy/aws/traits/DiffTest.java @@ -0,0 +1,47 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.aws.traits; + +import static java.lang.String.format; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.Callable; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import software.amazon.smithy.diff.ModelDiff; +import software.amazon.smithy.diff.testrunner.SmithyDiffTestCase; +import software.amazon.smithy.diff.testrunner.SmithyDiffTestSuite; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.SourceLocation; +import software.amazon.smithy.model.shapes.ShapeId; +import software.amazon.smithy.model.validation.Severity; +import software.amazon.smithy.model.validation.ValidationEvent; +import software.amazon.smithy.utils.IoUtils; +import software.amazon.smithy.utils.Pair; + +public class DiffTest { + @ParameterizedTest(name = "{0}") + @MethodSource("source") + public void testRunner(String filename, Callable callable) throws Exception { + callable.call(); + } + + public static Stream source() { + return SmithyDiffTestSuite.defaultParameterizedTestSource(DiffTest.class); + } +} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/no-old-sigv4.a.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/no-old-sigv4.a.smithy new file mode 100644 index 00000000000..e75d0177d05 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/no-old-sigv4.a.smithy @@ -0,0 +1,21 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +@auth([]) +@httpBearerAuth +service Service { + operations: [ + Operation + ] +} + +@auth([]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/no-old-sigv4.b.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/no-old-sigv4.b.smithy new file mode 100644 index 00000000000..a2815d8d157 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/no-old-sigv4.b.smithy @@ -0,0 +1,21 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +@auth([httpBearerAuth]) +@httpBearerAuth +service Service { + operations: [ + Operation + ] +} + +@auth([httpBearerAuth]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/no-old-sigv4.events b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/no-old-sigv4.events new file mode 100644 index 00000000000..e69de29bb2d diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-after-sigv4a-migration.a.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-after-sigv4a-migration.a.smithy new file mode 100644 index 00000000000..8514baee527 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-after-sigv4a-migration.a.smithy @@ -0,0 +1,25 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4a]) +@sigv4(name: "service") +@sigv4a(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([sigv4a]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-after-sigv4a-migration.b.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-after-sigv4a-migration.b.smithy new file mode 100644 index 00000000000..028d92375db --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-after-sigv4a-migration.b.smithy @@ -0,0 +1,25 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4a, sigv4]) +@sigv4(name: "service") +@sigv4a(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([sigv4a, sigv4]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-after-sigv4a-migration.events b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-after-sigv4a-migration.events new file mode 100644 index 00000000000..e69de29bb2d diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-before-sigv4a-migration.a.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-before-sigv4a-migration.a.smithy new file mode 100644 index 00000000000..8514baee527 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-before-sigv4a-migration.a.smithy @@ -0,0 +1,25 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4a]) +@sigv4(name: "service") +@sigv4a(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([sigv4a]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-before-sigv4a-migration.b.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-before-sigv4a-migration.b.smithy new file mode 100644 index 00000000000..d6ad5d01fa1 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-before-sigv4a-migration.b.smithy @@ -0,0 +1,25 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4, sigv4a]) +@sigv4(name: "service") +@sigv4a(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([sigv4, sigv4a]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-before-sigv4a-migration.events b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-before-sigv4a-migration.events new file mode 100644 index 00000000000..ed584854cfb --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-before-sigv4a-migration.events @@ -0,0 +1,3 @@ +[DANGER] ns.foo#Service: The `aws.auth#sigv4` authentication scheme was added before the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for `ns.foo#Service`. Adding the `aws.auth#sigv4` authentication scheme before an existing `aws.auth#sigv4a` authentication scheme may not be backward compatible if the signing scope was narrowed (typically from `*`). | SigV4Migration +----- +[DANGER] ns.foo#Operation: The `aws.auth#sigv4` authentication scheme was added before the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for `ns.foo#Operation`. Adding the `aws.auth#sigv4` authentication scheme before an existing `aws.auth#sigv4a` authentication scheme may not be backward compatible if the signing scope was narrowed (typically from `*`). | SigV4Migration diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-replace-sigv4a-migration.a.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-replace-sigv4a-migration.a.smithy new file mode 100644 index 00000000000..8514baee527 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-replace-sigv4a-migration.a.smithy @@ -0,0 +1,25 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4a]) +@sigv4(name: "service") +@sigv4a(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([sigv4a]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-replace-sigv4a-migration.b.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-replace-sigv4a-migration.b.smithy new file mode 100644 index 00000000000..84b82e83db9 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-replace-sigv4a-migration.b.smithy @@ -0,0 +1,25 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4]) +@sigv4(name: "service") +@sigv4a(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([sigv4]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-replace-sigv4a-migration.events b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-replace-sigv4a-migration.events new file mode 100644 index 00000000000..6340e3e5437 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-replace-sigv4a-migration.events @@ -0,0 +1,3 @@ +[DANGER] ns.foo#Service: The `aws.auth#sigv4a` authentication scheme was replaced by the `aws.auth#sigv4` authentication scheme in the effective auth schemes for `ns.foo#Service`. Replacing the `aws.auth#sigv4` authentication scheme with the `aws.auth#sigv4a` authentication scheme directly may not be backward compatible if the signing scope was narrowed (typically from `*`). | SigV4Migration +----- +[DANGER] ns.foo#Operation: The `aws.auth#sigv4a` authentication scheme was replaced by the `aws.auth#sigv4` authentication scheme in the effective auth schemes for `ns.foo#Operation`. Replacing the `aws.auth#sigv4` authentication scheme with the `aws.auth#sigv4a` authentication scheme directly may not be backward compatible if the signing scope was narrowed (typically from `*`). | SigV4Migration diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-in-order.a.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-in-order.a.smithy new file mode 100644 index 00000000000..5c797829d9a --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-in-order.a.smithy @@ -0,0 +1,26 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([httpBearerAuth, sigv4, sigv4a]) +@httpBearerAuth +@sigv4(name: "service") +@sigv4a(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([httpBearerAuth, sigv4, sigv4a]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-in-order.b.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-in-order.b.smithy new file mode 100644 index 00000000000..6b7dca49d53 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-in-order.b.smithy @@ -0,0 +1,26 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4, httpBearerAuth, sigv4a]) +@httpBearerAuth +@sigv4(name: "service") +@sigv4a(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([sigv4, httpBearerAuth, sigv4a]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-in-order.events b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-in-order.events new file mode 100644 index 00000000000..e69de29bb2d diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-swap-order.a.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-swap-order.a.smithy new file mode 100644 index 00000000000..200a2690afb --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-swap-order.a.smithy @@ -0,0 +1,37 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4, sigv4a]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 { + operations: [ + Operation1 + ] +} + +@auth([sigv4, sigv4a]) +operation Operation1 {} + +@auth([sigv4a, sigv4]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 { + operations: [ + Operation2 + ] +} + +@auth([sigv4a, sigv4]) +operation Operation2 {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-swap-order.b.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-swap-order.b.smithy new file mode 100644 index 00000000000..ec607fa19db --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-swap-order.b.smithy @@ -0,0 +1,37 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4a, sigv4]) +@sigv4(name: "service1") +@sigv4a(name: "service1") +service Service1 { + operations: [ + Operation1 + ] +} + +@auth([sigv4a, sigv4]) +operation Operation1 {} + +@auth([sigv4, sigv4a]) +@sigv4(name: "service2") +@sigv4a(name: "service2") +service Service2 { + operations: [ + Operation2 + ] +} + +@auth([sigv4, sigv4a]) +operation Operation2 {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-swap-order.events b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-swap-order.events new file mode 100644 index 00000000000..57888ae1188 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4-sigv4a-swap-order.events @@ -0,0 +1,7 @@ +[DANGER] ns.foo#Service1: The `aws.auth#sigv4a` authentication scheme was moved before the `aws.auth#sigv4` authentication scheme in the effective auth schemes for `ns.foo#Service1`. Moving the `aws.auth#sigv4a` authentication scheme before the `aws.auth#sigv4` authentication scheme is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | SigV4Migration +----- +[DANGER] ns.foo#Operation1: The `aws.auth#sigv4a` authentication scheme was moved before the `aws.auth#sigv4` authentication scheme in the effective auth schemes for `ns.foo#Operation1`. Moving the `aws.auth#sigv4a` authentication scheme before the `aws.auth#sigv4` authentication scheme is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | SigV4Migration +----- +[DANGER] ns.foo#Service2: The `aws.auth#sigv4` authentication scheme was moved before the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for `ns.foo#Service2`. Moving the `aws.auth#sigv4` authentication scheme before the `aws.auth#sigv4a` authentication scheme may not be backward compatible if the signing scope was narrowed (typically from `*`). | SigV4Migration +----- +[DANGER] ns.foo#Operation2: The `aws.auth#sigv4` authentication scheme was moved before the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for `ns.foo#Operation2`. Moving the `aws.auth#sigv4` authentication scheme before the `aws.auth#sigv4a` authentication scheme may not be backward compatible if the signing scope was narrowed (typically from `*`). | SigV4Migration diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-after-sigv4-migration.a.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-after-sigv4-migration.a.smithy new file mode 100644 index 00000000000..84b82e83db9 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-after-sigv4-migration.a.smithy @@ -0,0 +1,25 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4]) +@sigv4(name: "service") +@sigv4a(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([sigv4]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-after-sigv4-migration.b.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-after-sigv4-migration.b.smithy new file mode 100644 index 00000000000..d6ad5d01fa1 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-after-sigv4-migration.b.smithy @@ -0,0 +1,25 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4, sigv4a]) +@sigv4(name: "service") +@sigv4a(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([sigv4, sigv4a]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-after-sigv4-migration.events b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-after-sigv4-migration.events new file mode 100644 index 00000000000..e69de29bb2d diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-before-sigv4-migration.a.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-before-sigv4-migration.a.smithy new file mode 100644 index 00000000000..84b82e83db9 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-before-sigv4-migration.a.smithy @@ -0,0 +1,25 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4]) +@sigv4(name: "service") +@sigv4a(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([sigv4]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-before-sigv4-migration.b.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-before-sigv4-migration.b.smithy new file mode 100644 index 00000000000..028d92375db --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-before-sigv4-migration.b.smithy @@ -0,0 +1,25 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4a, sigv4]) +@sigv4(name: "service") +@sigv4a(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([sigv4a, sigv4]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-before-sigv4-migration.events b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-before-sigv4-migration.events new file mode 100644 index 00000000000..dab1a613028 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-before-sigv4-migration.events @@ -0,0 +1,3 @@ +[DANGER] ns.foo#Service: The `aws.auth#sigv4a` authentication scheme was added before the `aws.auth#sigv4` authentication scheme in the effective auth schemes for `ns.foo#Service`. Adding the `aws.auth#sigv4a` authentication scheme before an existing `aws.auth#sigv4` authentication scheme is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | SigV4Migration +----- +[DANGER] ns.foo#Operation: The `aws.auth#sigv4a` authentication scheme was added before the `aws.auth#sigv4` authentication scheme in the effective auth schemes for `ns.foo#Operation`. Adding the `aws.auth#sigv4a` authentication scheme before an existing `aws.auth#sigv4` authentication scheme is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | SigV4Migration diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-replace-sigv4-migration.a.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-replace-sigv4-migration.a.smithy new file mode 100644 index 00000000000..84b82e83db9 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-replace-sigv4-migration.a.smithy @@ -0,0 +1,25 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4]) +@sigv4(name: "service") +@sigv4a(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([sigv4]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-replace-sigv4-migration.b.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-replace-sigv4-migration.b.smithy new file mode 100644 index 00000000000..8514baee527 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-replace-sigv4-migration.b.smithy @@ -0,0 +1,25 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 +use aws.auth#sigv4a + +@auth([sigv4a]) +@sigv4(name: "service") +@sigv4a(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([sigv4a]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-replace-sigv4-migration.events b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-replace-sigv4-migration.events new file mode 100644 index 00000000000..9b81ece18a8 --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/sigv4a-replace-sigv4-migration.events @@ -0,0 +1,3 @@ +[DANGER] ns.foo#Service: The `aws.auth#sigv4` authentication scheme was replaced by the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for `ns.foo#Service`. Replacing the `aws.auth#sigv4` authentication scheme with the `aws.auth#sigv4a` authentication scheme directly is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | SigV4Migration +----- +[DANGER] ns.foo#Operation: The `aws.auth#sigv4` authentication scheme was replaced by the `aws.auth#sigv4a` authentication scheme in the effective auth schemes for `ns.foo#Operation`. Replacing the `aws.auth#sigv4` authentication scheme with the `aws.auth#sigv4a` authentication scheme directly is not backward compatible since not all credentials usable by `aws.auth#sigv4` are compatible with `aws.auth#sigv4a`, and can break existing clients' authentication. | SigV4Migration diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/with-sigv4-no-migration.a.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/with-sigv4-no-migration.a.smithy new file mode 100644 index 00000000000..df9bb9120ad --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/with-sigv4-no-migration.a.smithy @@ -0,0 +1,24 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 + +@auth([sigv4]) +@httpBearerAuth +@sigv4(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([sigv4]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/with-sigv4-no-migration.b.smithy b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/with-sigv4-no-migration.b.smithy new file mode 100644 index 00000000000..31d687fc96b --- /dev/null +++ b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/with-sigv4-no-migration.b.smithy @@ -0,0 +1,24 @@ +$version: "2.0" + +metadata suppressions = [ + { + id: "ModifiedTrait.Update.smithy.api#auth" + namespace: "ns.foo" + } +] + +namespace ns.foo + +use aws.auth#sigv4 + +@auth([httpBearerAuth, sigv4]) +@httpBearerAuth +@sigv4(name: "service") +service Service { + operations: [ + Operation + ] +} + +@auth([httpBearerAuth, sigv4]) +operation Operation {} diff --git a/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/with-sigv4-no-migration.events b/smithy-aws-traits/src/test/resources/software/amazon/smithy/aws/traits/diffs/with-sigv4-no-migration.events new file mode 100644 index 00000000000..e69de29bb2d diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/Endpoint.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/Endpoint.java index dbaa282119b..0f0d3010fda 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/Endpoint.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/Endpoint.java @@ -12,8 +12,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; +import java.util.Optional; import java.util.TreeMap; +import java.util.stream.Collectors; import software.amazon.smithy.model.FromSourceLocation; import software.amazon.smithy.model.SourceLocation; import software.amazon.smithy.model.node.ArrayNode; @@ -42,6 +45,8 @@ public final class Endpoint implements FromSourceLocation, ToNode, ToSmithyBuild private static final String URL = "url"; private static final String PROPERTIES = "properties"; private static final String HEADERS = "headers"; + private static final Identifier ID_AUTH_SCHEMES = Identifier.of("authSchemes"); + private static final Identifier ID_NAME = Identifier.of("name"); private final Map> headers; private final Map properties; @@ -57,12 +62,12 @@ private Endpoint(Builder builder) { List authSchemes = new ArrayList<>(); for (Map.Entry> authScheme : builder.authSchemes.get().entrySet()) { Map base = new TreeMap<>(Comparator.comparing(Identifier::toString)); - base.put(Identifier.of("name"), Literal.of(authScheme.getKey().toString())); + base.put(ID_NAME, Literal.of(authScheme.getKey().toString())); base.putAll(authScheme.getValue()); authSchemes.add(Literal.recordLiteral(base)); } if (!authSchemes.isEmpty()) { - builder.putProperty(Identifier.of("authSchemes"), Literal.tupleLiteral(authSchemes)); + builder.putProperty(ID_AUTH_SCHEMES, Literal.tupleLiteral(authSchemes)); } this.properties = builder.properties.copy(); @@ -139,6 +144,19 @@ public Map getProperties() { return properties; } + /** + * Get the endpoint {@code authSchemes} property as a map of {@link Identifier} to {@link Literal} values. + * + * @return the list of endpoint {@code authSchemes}. + */ + public List> getEndpointAuthSchemes() { + return Optional.ofNullable(getProperties().get(ID_AUTH_SCHEMES)) + .map(a -> a.asTupleLiteral().get().stream() + .map(l -> l.asRecordLiteral().get()) + .collect(Collectors.toList())) + .orElse(Collections.emptyList()); + } + @Override public Builder toBuilder() { return builder().sourceLocation(sourceLocation).url(url).headers(headers).properties(properties); diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/EndpointRuleSet.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/EndpointRuleSet.java index fb97cd836dc..860c3e52b1a 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/EndpointRuleSet.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/language/EndpointRuleSet.java @@ -8,7 +8,10 @@ import static software.amazon.smithy.rulesengine.language.error.RuleError.context; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import java.util.function.Function; @@ -17,6 +20,7 @@ import software.amazon.smithy.model.node.ArrayNode; 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.node.ToNode; import software.amazon.smithy.rulesengine.language.error.RuleError; import software.amazon.smithy.rulesengine.language.evaluation.Scope; @@ -27,6 +31,7 @@ import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameters; import software.amazon.smithy.rulesengine.language.syntax.rule.EndpointRule; import software.amazon.smithy.rulesengine.language.syntax.rule.Rule; +import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait; import software.amazon.smithy.rulesengine.validators.AuthSchemeValidator; import software.amazon.smithy.utils.BuilderRef; import software.amazon.smithy.utils.SmithyBuilder; @@ -57,10 +62,10 @@ private static final class LazyEndpointComponentFactoryHolder { private EndpointRuleSet(Builder builder) { super(); - parameters = SmithyBuilder.requiredState("parameters", builder.parameters); + parameters = SmithyBuilder.requiredState(PARAMETERS, builder.parameters); rules = builder.rules.copy(); sourceLocation = SmithyBuilder.requiredState("source", builder.getSourceLocation()); - version = SmithyBuilder.requiredState("version", builder.version); + version = SmithyBuilder.requiredState(VERSION, builder.version); } /** @@ -313,4 +318,89 @@ public EndpointRuleSet build() { return ruleSet; } } + + /** + * {@link EndpointRuleSet} visitor that collects a map of JSON pointer paths to {@link Endpoint}s. + */ + @SmithyInternalApi + public static final class EndpointPathCollector { + private static final String ENDPOINT = "endpoint"; + private static final String TYPE = "type"; + private final Map visitedEndpoints = new HashMap(); + private final ObjectNode endpointRuleSet; + + private EndpointPathCollector(EndpointRuleSetTrait endpointRuleSetTrait) { + this.endpointRuleSet = endpointRuleSetTrait.getRuleSet().expectObjectNode(); + } + + /** + * Creates a collector from an {@link EndpointRuleSetTrait}. + * + * @param endpointRuleSetTrait EndpointRuleSet trait instance. + */ + @SmithyInternalApi + public static EndpointPathCollector from(EndpointRuleSetTrait endpointRuleSetTrait) { + return new EndpointPathCollector(endpointRuleSetTrait); + } + + /** + * Collects the mapped JSON pointer paths to {@link Endpoint}s. + * + * @return a map of JSON pointer paths to {@link Endpoint}s. + */ + @SmithyInternalApi + public Map collect() { + arrayNode(endpointRuleSet.expectArrayMember(RULES), "/" + RULES); + return visitedEndpoints; + } + + private void objectNode(ObjectNode node, String parentPath) { + boolean isEndpointRuleObject = node + .getMember(TYPE) + .map(n -> n.asStringNode() + .map(s -> s.getValue().equals(ENDPOINT)) + .orElse(false)) + .orElse(false); + if (isEndpointRuleObject) { + Endpoint endpoint = Endpoint.fromNode(node.expectMember(ENDPOINT)); + visitedEndpoints.put(parentPath + "/" + ENDPOINT, endpoint); + return; + } + for (Entry member : node.getMembers().entrySet()) { + String key = member.getKey().getValue(); + Node value = member.getValue(); + switch (value.getType()) { + case OBJECT: { + objectNode(value.expectObjectNode(), parentPath + "/" + key); + break; + } + case ARRAY: { + arrayNode(value.expectArrayNode(), parentPath + "/" + key); + break; + } + default: + break; + } + } + } + + private void arrayNode(ArrayNode node, String parentPath) { + List elements = node.getElements(); + for (int i = 0; i < elements.size(); i++) { + Node element = elements.get(i); + switch (element.getType()) { + case OBJECT: { + objectNode(element.expectObjectNode(), parentPath + "/" + i); + break; + } + case ARRAY: { + arrayNode(element.expectArrayNode(), parentPath + "/" + i); + break; + } + default: + break; + } + } + } + } } diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/EndpointRuleSetTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/EndpointRuleSetTest.java index db87a0630b9..623573d1356 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/EndpointRuleSetTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/EndpointRuleSetTest.java @@ -1,8 +1,14 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + package software.amazon.smithy.rulesengine.language; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Collections; +import java.util.Map; import org.junit.jupiter.api.Test; import software.amazon.smithy.model.SourceLocation; import software.amazon.smithy.model.node.Node; @@ -10,15 +16,25 @@ import software.amazon.smithy.rulesengine.language.evaluation.value.EndpointValue; import software.amazon.smithy.rulesengine.language.evaluation.value.Value; import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expressions.Reference; import software.amazon.smithy.rulesengine.language.syntax.expressions.literal.Literal; import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameter; import software.amazon.smithy.rulesengine.language.syntax.parameters.ParameterType; import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameters; import software.amazon.smithy.rulesengine.language.syntax.rule.Rule; +import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait; import software.amazon.smithy.utils.IoUtils; import software.amazon.smithy.utils.MapUtils; public class EndpointRuleSetTest { + private static final Endpoint MINIMAL_ENDPOINT = Endpoint.builder() + .sourceLocation(SourceLocation.none()) + .url(Literal.of("https://{Region}.amazonaws.com")) + .addAuthScheme(Identifier.of("sigv4"), MapUtils.of( + Identifier.of("signingRegion"), Literal.of("{Region}"), + Identifier.of("signingName"), Literal.of("serviceName"))) + .build(); + @Test public void testRuleEval() { EndpointRuleSet actual = TestRunnerTest.getMinimalEndpointRuleSet(); @@ -61,13 +77,62 @@ public void testMinimalRuleset() { .addRule(Rule .builder() .description("base rule") - .endpoint(Endpoint.builder() - .sourceLocation(SourceLocation.none()) - .url(Literal.of("https://{Region}.amazonaws.com")) - .addAuthScheme(Identifier.of("sigv4"), MapUtils.of( - Identifier.of("signingRegion"), Literal.of("{Region}"), - Identifier.of("signingName"), Literal.of("serviceName"))) - .build())) + .endpoint(MINIMAL_ENDPOINT)) .build(), actual); } + + @Test + public void testEndpointCollectorMinimalRuleset() { + EndpointRuleSet ers = TestRunnerTest.getMinimalEndpointRuleSet(); + Map actual = EndpointRuleSet.EndpointPathCollector + .from(EndpointRuleSetTrait.builder() + .ruleSet(ers.toNode()) + .build()) + .collect(); + Map expected = MapUtils.of("/rules/0/endpoint", MINIMAL_ENDPOINT); + assertEquals(expected, actual); + } + + @Test + public void testEndpointCollectorEmptyRuleset() { + EndpointRuleSet ers = EndpointRuleSet.builder() + .parameters(Parameters.builder().build()) + .build(); + Map actual = EndpointRuleSet.EndpointPathCollector + .from(EndpointRuleSetTrait.builder() + .ruleSet(ers.toNode()) + .build()) + .collect(); + Map expected = Collections.emptyMap(); + assertEquals(expected, actual); + } + + @Test + public void testEndpointCollectorComplexRuleset() { + EndpointRuleSet ers = TestRunnerTest.getEndpointRuleSet( + EndpointRuleSetTest.class, "example-complex-ruleset.json"); + Map actual = EndpointRuleSet.EndpointPathCollector + .from(EndpointRuleSetTrait.builder() + .ruleSet(ers.toNode()) + .build()) + .collect(); + Map expected = MapUtils.of( + "/rules/1/rules/0/rules/0/rules/1/endpoint", Endpoint.builder() + .url(Literal.of("https://example.{Region}.dual-stack-dns-suffix.com")) + .build(), + "/rules/1/rules/0/rules/1/rules/0/rules/0/endpoint", Endpoint.builder() + .url(Literal.of("https://example-fips.{Region}.dual-stack-dns-suffix.com")) + .build(), + "/rules/1/rules/0/rules/2/endpoint", Endpoint.builder() + .url(Literal.of("https://example.{Region}.dual-stack-dns-suffix.com")) + .build(), + "/rules/0/rules/1/endpoint", Endpoint.builder() + .url(new Reference(Identifier.of("Endpoint"), SourceLocation.NONE)) + .build(), + "/rules/1/rules/0/rules/0/rules/0/rules/0/rules/0/endpoint", Endpoint.builder() + .url(Literal.of("https://example-fips.{Region}.dual-stack-dns-suffix.com")) + .build() + ); + assertEquals(expected, actual); + } } diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/EndpointTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/EndpointTest.java new file mode 100644 index 00000000000..24f24d6b462 --- /dev/null +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/EndpointTest.java @@ -0,0 +1,62 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.rulesengine.language; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import org.junit.jupiter.api.Test; +import software.amazon.smithy.rulesengine.language.syntax.Identifier; +import software.amazon.smithy.rulesengine.language.syntax.expressions.literal.Literal; +import software.amazon.smithy.utils.ListUtils; +import software.amazon.smithy.utils.MapUtils; +import software.amazon.smithy.utils.Pair; + +public class EndpointTest { + private static final Pair> SIGV4_AUTH_SCHEME = Pair.of( + "sigv4", + Collections.emptyMap()); + private static final Pair> SIGV4A_AUTH_SCHEME = Pair.of( + "sigv4a", + MapUtils.of( + Identifier.of("signingRegionSet"), + Literal.tupleLiteral(ListUtils.of(Literal.of("*"))))); + + @Test + public void testGetEndpointAuthSchemes() { + Endpoint endpoint = Endpoint.builder() + .url(Literal.of("https://abc.service.com")) + .addAuthScheme(Identifier.of(SIGV4A_AUTH_SCHEME.getLeft()), SIGV4A_AUTH_SCHEME.getRight()) + .addAuthScheme(Identifier.of(SIGV4_AUTH_SCHEME.getLeft()), SIGV4_AUTH_SCHEME.getRight()) + .build(); + List> actual = endpoint.getEndpointAuthSchemes(); + List> expected = ListUtils.of( + convertAuthSchemeToMap(SIGV4A_AUTH_SCHEME), + convertAuthSchemeToMap(SIGV4_AUTH_SCHEME)); + assertEquals(expected, actual); + } + + @Test + public void testEmptyGetEndpointAuthSchemes() { + Endpoint endpoint = Endpoint.builder() + .url(Literal.of("https://abc.service.com")) + .build(); + List> actual = endpoint.getEndpointAuthSchemes(); + List> expected = Collections.emptyList(); + assertEquals(expected, actual); + } + + private static Map convertAuthSchemeToMap(Pair> authScheme) { + Map base = new TreeMap<>(Comparator.comparing(Identifier::toString)); + base.put(Identifier.of("name"), Literal.of(authScheme.getLeft())); + base.putAll(authScheme.getRight()); + return base; + } +} diff --git a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/TestRunnerTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/TestRunnerTest.java index a216a1fb118..553f9c62b9b 100644 --- a/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/TestRunnerTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/language/TestRunnerTest.java @@ -15,8 +15,11 @@ public static Stream source() { } public static EndpointRuleSet getMinimalEndpointRuleSet() { - return EndpointRuleSet.fromNode(Node.parse(IoUtils.readUtf8Resource( - TestRunnerTest.class, "minimal-ruleset.json"))); + return getEndpointRuleSet(TestRunnerTest.class, "minimal-ruleset.json"); + } + + public static EndpointRuleSet getEndpointRuleSet(Class klass, String file) { + return EndpointRuleSet.fromNode(Node.parseJsonWithComments(IoUtils.readUtf8Resource(klass, file))); } @ParameterizedTest(name = "{0}") diff --git a/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/example-complex-ruleset.json b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/example-complex-ruleset.json new file mode 100644 index 00000000000..c08bdb3144a --- /dev/null +++ b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/language/example-complex-ruleset.json @@ -0,0 +1,243 @@ +// Modified AWS service ruleset (may not actually resolve any endpoints correctly) +{ + "version": "1.0", + "parameters": { + "Region": { + "required": false, + "type": "String" + }, + "UseFIPS": { + "required": true, + "type": "Boolean" + }, + "Endpoint": { + "builtIn": "SDK::Endpoint", + "required": false, + "documentation": "Override the endpoint used to send this request", + "type": "String" + } + }, + "rules": [ + { + "conditions": [ + { + "fn": "isSet", + "argv": [ + { + "ref": "Endpoint" + } + ] + } + ], + "rules": [ + { + "conditions": [ + { + "fn": "booleanEquals", + "argv": [ + { + "ref": "UseFIPS" + }, + true + ] + } + ], + "error": "Invalid Configuration: FIPS and custom endpoint are not supported", + "type": "error" + }, + { + "conditions": [], + "endpoint": { + "url": { + "ref": "Endpoint" + }, + "properties": {}, + "headers": {} + }, + "type": "endpoint" + } + ], + "type": "tree" + }, + { + "conditions": [ + { + "fn": "isSet", + "argv": [ + { + "ref": "Region" + } + ] + } + ], + "rules": [ + { + "conditions": [ + { + "fn": "parseURL", + "argv": [ + { + "ref": "Region" + } + ], + "assign": "PartitionResult" + } + ], + "rules": [ + { + "conditions": [ + { + "fn": "booleanEquals", + "argv": [ + true, + { + "fn": "getAttr", + "argv": [ + { + "ref": "PartitionResult" + }, + "isIp" + ] + } + ] + } + ], + "rules": [ + { + "conditions": [ + { + "fn": "booleanEquals", + "argv": [ + { + "ref": "UseFIPS" + }, + true + ] + } + ], + "rules": [ + { + "conditions": [ + { + "fn": "booleanEquals", + "argv": [ + { + "fn": "getAttr", + "argv": [ + { + "ref": "PartitionResult" + }, + "isIp" + ] + }, + true + ] + } + ], + "rules": [ + { + "conditions": [], + "endpoint": { + "url": "https://example-fips.{Region}.dual-stack-dns-suffix.com", + "properties": {}, + "headers": {} + }, + "type": "endpoint" + } + ], + "type": "tree" + }, + { + "conditions": [], + "error": "FIPS is enabled but this partition does not support FIPS", + "type": "error" + } + ], + "type": "tree" + }, + { + "conditions": [], + "endpoint": { + "url": "https://example.{Region}.dual-stack-dns-suffix.com", + "properties": {}, + "headers": {} + }, + "type": "endpoint" + } + ], + "type": "tree" + }, + { + "conditions": [ + { + "fn": "booleanEquals", + "argv": [ + { + "ref": "UseFIPS" + }, + true + ] + } + ], + "rules": [ + { + "conditions": [ + { + "fn": "booleanEquals", + "argv": [ + { + "fn": "getAttr", + "argv": [ + { + "ref": "PartitionResult" + }, + "isIp" + ] + }, + true + ] + } + ], + "rules": [ + { + "conditions": [], + "endpoint": { + "url": "https://example-fips.{Region}.dual-stack-dns-suffix.com", + "properties": {}, + "headers": {} + }, + "type": "endpoint" + } + ], + "type": "tree" + }, + { + "conditions": [], + "error": "FIPS is enabled but this partition does not support FIPS", + "type": "error" + } + ], + "type": "tree" + }, + { + "conditions": [], + "endpoint": { + "url": "https://example.{Region}.dual-stack-dns-suffix.com", + "properties": {}, + "headers": {} + }, + "type": "endpoint" + } + ], + "type": "tree" + } + ], + "type": "tree" + }, + { + "conditions": [], + "error": "Invalid Configuration: Missing Region", + "type": "error" + } + ] +}