diff --git a/.github/workflows/github-merit-badger.yml b/.github/workflows/github-merit-badger.yml index 6952ee7c1e2e4..75f641c9383c8 100644 --- a/.github/workflows/github-merit-badger.yml +++ b/.github/workflows/github-merit-badger.yml @@ -17,4 +17,4 @@ jobs: badges: '[beginning-contributor,repeat-contributor,valued-contributor,admired-contributor,star-contributor,distinguished-contributor]' thresholds: '[0,3,6,13,25,50]' badge-type: 'achievement' - ignore-usernames: '[rix0rrr,iliapolo,otaviomacedo,kaizencc,comcalvi,TheRealAmazonKendra,vinayak-kukreja,mrgrain,pahud,cgarvis,kellertk,ashishdhingra,HBobertz,sumupitchayan,SankyRed,udaypant,colifran,khushail,scanlonp,mikewrighton,moelasmar,paulhcsun,awsmjs,evgenyka,GavinZZ,aaythapa,xazhao,ConnorRobertson,ssenchenko,gracelu0,jfuss,SimonCMoore,shikha372,kirtishrinkhala,godwingrs22,bergjaak,IanKonlog,Leo10Gama,samson-keung,scorbiere,michelle-wangg,aws-cdk-automation,dependabot[bot],mergify[bot]]' + ignore-usernames: '[rix0rrr,iliapolo,otaviomacedo,kaizencc,comcalvi,TheRealAmazonKendra,vinayak-kukreja,mrgrain,pahud,cgarvis,kellertk,ashishdhingra,HBobertz,sumupitchayan,SankyRed,udaypant,colifran,khushail,scanlonp,mikewrighton,moelasmar,paulhcsun,awsmjs,evgenyka,GavinZZ,aaythapa,xazhao,ConnorRobertson,ssenchenko,gracelu0,jfuss,SimonCMoore,shikha372,kirtishrinkhala,godwingrs22,bergjaak,IanKonlog,Leo10Gama,samson-keung,scorbiere,michelle-wangg,jiayiwang7,aws-cdk-automation,dependabot[bot],mergify[bot]]' diff --git a/.mergify.yml b/.mergify.yml index 6533eae54d22b..d895d5ee87938 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -11,7 +11,7 @@ pull_request_rules: label: add: [ contribution/core ] conditions: - - author~=^(rix0rrr|iliapolo|otaviomacedo|kaizencc|comcalvi|TheRealAmazonKendra|vinayak-kukreja|mrgrain|pahud|ashishdhingra|cgarvis|kellertk|HBobertz|sumupitchayan|SankyRed|udaypant|colifran|scanlonp|mikewrighton|moelasmar|paulhcsun|awsmjs|evgenyka|GavinZZ|aaythapa|xazhao|ConnorRobertson|ssenchenko|gracelu0|jfuss|SimonCMoore|shikha372|kirtishrinkhala|godwingrs22|bergjaak|samson-keung|IanKonlog|Leo10Gama|scorbiere|michelle-wangg)$ + - author~=^(rix0rrr|iliapolo|otaviomacedo|kaizencc|comcalvi|TheRealAmazonKendra|vinayak-kukreja|mrgrain|pahud|ashishdhingra|cgarvis|kellertk|HBobertz|sumupitchayan|SankyRed|udaypant|colifran|scanlonp|mikewrighton|moelasmar|paulhcsun|awsmjs|evgenyka|GavinZZ|aaythapa|xazhao|ConnorRobertson|ssenchenko|gracelu0|jfuss|SimonCMoore|shikha372|kirtishrinkhala|godwingrs22|bergjaak|samson-keung|IanKonlog|Leo10Gama|scorbiere|michelle-wangg|jiayiwang7)$ - -label~="contribution/core" - name: automatic merge actions: diff --git a/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js b/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js index 8c3a4b4f20e20..37b09e7789c79 100755 --- a/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js +++ b/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js @@ -13,6 +13,7 @@ if (process.env.PACKAGE_LAYOUT_VERSION === '1') { var lambda = require('@aws-cdk/aws-lambda'); var sso = require('@aws-cdk/aws-sso'); var docker = require('@aws-cdk/aws-ecr-assets'); + var appsync = require('@aws-cdk/aws-appsync'); } else { var cdk = require('aws-cdk-lib'); var { @@ -28,6 +29,7 @@ if (process.env.PACKAGE_LAYOUT_VERSION === '1') { aws_sqs: sqs, aws_lambda: lambda, aws_ecr_assets: docker, + aws_appsync: appsync, Stack } = require('aws-cdk-lib'); } @@ -698,6 +700,34 @@ class BuiltinLambdaStack extends cdk.Stack { } } +class AppSyncHotswapStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + const api = new appsync.GraphqlApi(this, "Api", { + name: "appsync-hotswap", + definition: appsync.Definition.fromFile(path.join(__dirname, 'appsync.hotswap.graphql')), + authorizationConfig: { + defaultAuthorization: { + authorizationType: appsync.AuthorizationType.IAM, + }, + }, + }); + + const noneDataSource = api.addNoneDataSource("none"); + // create 50 appsync functions to hotswap + for (const i of Array(50).keys()) { + const appsyncFunction = new appsync.AppsyncFunction(this, `Function${i}`, { + name: `appsync_function${i}`, + api, + dataSource: noneDataSource, + requestMappingTemplate: appsync.MappingTemplate.fromString(process.env.DYNAMIC_APPSYNC_PROPERTY_VALUE ?? "$util.toJson({})"), + responseMappingTemplate: appsync.MappingTemplate.fromString('$util.toJson({})'), + }); + } + } +} + const app = new cdk.App({ context: { '@aws-cdk/core:assetHashSalt': process.env.CODEBUILD_BUILD_ID, // Force all assets to be unique, but consistent in one build @@ -743,6 +773,7 @@ switch (stackSet) { new SessionTagsWithNoExecutionRoleCustomSynthesizerStack(app, `${stackPrefix}-session-tags-with-custom-synthesizer`); new LambdaHotswapStack(app, `${stackPrefix}-lambda-hotswap`); new EcsHotswapStack(app, `${stackPrefix}-ecs-hotswap`); + new AppSyncHotswapStack(app, `${stackPrefix}-appsync-hotswap`); new DockerStack(app, `${stackPrefix}-docker`); new DockerStackWithCustomFile(app, `${stackPrefix}-docker-with-custom-file`); diff --git a/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/appsync.hotswap.graphql b/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/appsync.hotswap.graphql new file mode 100644 index 0000000000000..808e3421471ab --- /dev/null +++ b/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/appsync.hotswap.graphql @@ -0,0 +1,3 @@ +type Query { + listString: [String] +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/cli.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/cli.integtest.ts index 8ebfcc0752716..4f62c15d62482 100644 --- a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/cli.integtest.ts +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/cli.integtest.ts @@ -2176,6 +2176,37 @@ integTest( }), ); +integTest('hotswap deployment supports AppSync APIs with many functions', + withDefaultFixture(async (fixture) => { + // GIVEN + const stackArn = await fixture.cdkDeploy('appsync-hotswap', { + captureStderr: false, + }); + + // WHEN + const deployOutput = await fixture.cdkDeploy('appsync-hotswap', { + options: ['--hotswap'], + captureStderr: true, + onlyStderr: true, + modEnv: { + DYNAMIC_APPSYNC_PROPERTY_VALUE: '$util.qr($ctx.stash.put("newTemplate", []))\n$util.toJson({})', + }, + }); + + const response = await fixture.aws.cloudFormation.send( + new DescribeStacksCommand({ + StackName: stackArn, + }), + ); + + expect(response.Stacks?.[0].StackStatus).toEqual('CREATE_COMPLETE'); + // assert all 50 functions were hotswapped + for (const i of Array(50).keys()) { + expect(deployOutput).toContain(`AWS::AppSync::FunctionConfiguration 'appsync_function${i}' hotswapped!`); + } + }), +); + async function listChildren(parent: string, pred: (x: string) => Promise) { const ret = new Array(); for (const child of await fs.readdir(parent, { encoding: 'utf-8' })) { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk-integ-opensearch.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk-integ-opensearch-min.assets.json similarity index 62% rename from packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk-integ-opensearch.assets.json rename to packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk-integ-opensearch-min.assets.json index f81b264dc54ab..1cec4f1cb8e0b 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk-integ-opensearch.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk-integ-opensearch-min.assets.json @@ -1,15 +1,15 @@ { - "version": "35.0.0", + "version": "36.0.5", "files": { - "ec8121bfd58ee4336b54eadf549ef20f883de211e6e775d5465a52ea693d70bb": { + "1255c7b5b61b498b41414039e46e2ac24d67f3f62d55fc817ef805f24fb4cccd": { "source": { - "path": "cdk-integ-opensearch.template.json", + "path": "cdk-integ-opensearch-min.template.json", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "ec8121bfd58ee4336b54eadf549ef20f883de211e6e775d5465a52ea693d70bb.json", + "objectKey": "1255c7b5b61b498b41414039e46e2ac24d67f3f62d55fc817ef805f24fb4cccd.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk-integ-opensearch.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk-integ-opensearch-min.template.json similarity index 65% rename from packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk-integ-opensearch.template.json rename to packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk-integ-opensearch-min.template.json index f54bc8f909197..d432e084b1001 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk-integ-opensearch.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk-integ-opensearch-min.template.json @@ -1,6 +1,6 @@ { "Resources": { - "Domain66AC69E0": { + "OpenSearch213B37A164B": { "Type": "AWS::OpenSearchService::Domain", "Properties": { "ClusterConfig": { @@ -30,6 +30,37 @@ }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" + }, + "OpenSearch21566632C3A": { + "Type": "AWS::OpenSearchService::Domain", + "Properties": { + "ClusterConfig": { + "DedicatedMasterEnabled": false, + "InstanceCount": 1, + "InstanceType": "r5.large.search", + "MultiAZWithStandbyEnabled": false, + "ZoneAwarenessEnabled": false + }, + "DomainEndpointOptions": { + "EnforceHTTPS": false, + "TLSSecurityPolicy": "Policy-Min-TLS-1-0-2019-07" + }, + "EBSOptions": { + "EBSEnabled": true, + "VolumeSize": 10, + "VolumeType": "gp2" + }, + "EncryptionAtRestOptions": { + "Enabled": false + }, + "EngineVersion": "OpenSearch_2.15", + "LogPublishingOptions": {}, + "NodeToNodeEncryptionOptions": { + "Enabled": false + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" } }, "Parameters": { @@ -66,4 +97,4 @@ ] } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk.out index c5cb2e5de6344..bd5311dc372de 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"35.0.0"} \ No newline at end of file +{"version":"36.0.5"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/integ.json index 213aa21a0fa35..dd0a795a8eeac 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/integ.json @@ -1,12 +1,12 @@ { - "version": "35.0.0", + "version": "36.0.5", "testCases": { - "Integ/DefaultTest": { + "integ-openseach-min/DefaultTest": { "stacks": [ - "cdk-integ-opensearch" + "cdk-integ-opensearch-min" ], - "assertionStack": "Integ/DefaultTest/DeployAssert", - "assertionStackName": "IntegDefaultTestDeployAssert4E6713E1" + "assertionStack": "integ-openseach-min/DefaultTest/DeployAssert", + "assertionStackName": "integopenseachminDefaultTestDeployAssert0EB58658" } } } \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/integopenseachminDefaultTestDeployAssert0EB58658.assets.json similarity index 84% rename from packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json rename to packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/integopenseachminDefaultTestDeployAssert0EB58658.assets.json index 23e5a2ce21170..400ae1dfbb9cc 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/integopenseachminDefaultTestDeployAssert0EB58658.assets.json @@ -1,9 +1,9 @@ { - "version": "35.0.0", + "version": "36.0.5", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { - "path": "IntegDefaultTestDeployAssert4E6713E1.template.json", + "path": "integopenseachminDefaultTestDeployAssert0EB58658.template.json", "packaging": "file" }, "destinations": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/integopenseachminDefaultTestDeployAssert0EB58658.template.json similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.template.json rename to packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/integopenseachminDefaultTestDeployAssert0EB58658.template.json diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/manifest.json index 8e68657360f52..afd7651b2df69 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/manifest.json @@ -1,28 +1,28 @@ { - "version": "35.0.0", + "version": "36.0.5", "artifacts": { - "cdk-integ-opensearch.assets": { + "cdk-integ-opensearch-min.assets": { "type": "cdk:asset-manifest", "properties": { - "file": "cdk-integ-opensearch.assets.json", + "file": "cdk-integ-opensearch-min.assets.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" } }, - "cdk-integ-opensearch": { + "cdk-integ-opensearch-min": { "type": "aws:cloudformation:stack", "environment": "aws://unknown-account/unknown-region", "properties": { - "templateFile": "cdk-integ-opensearch.template.json", + "templateFile": "cdk-integ-opensearch-min.template.json", "terminationProtection": false, "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/ec8121bfd58ee4336b54eadf549ef20f883de211e6e775d5465a52ea693d70bb.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/1255c7b5b61b498b41414039e46e2ac24d67f3f62d55fc817ef805f24fb4cccd.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ - "cdk-integ-opensearch.assets" + "cdk-integ-opensearch-min.assets" ], "lookupRole": { "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", @@ -31,43 +31,49 @@ } }, "dependencies": [ - "cdk-integ-opensearch.assets" + "cdk-integ-opensearch-min.assets" ], "metadata": { - "/cdk-integ-opensearch/Domain/Resource": [ + "/cdk-integ-opensearch-min/OpenSearch_2.13/Resource": [ { "type": "aws:cdk:logicalId", - "data": "Domain66AC69E0" + "data": "OpenSearch213B37A164B" } ], - "/cdk-integ-opensearch/BootstrapVersion": [ + "/cdk-integ-opensearch-min/OpenSearch_2.15/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "OpenSearch21566632C3A" + } + ], + "/cdk-integ-opensearch-min/BootstrapVersion": [ { "type": "aws:cdk:logicalId", "data": "BootstrapVersion" } ], - "/cdk-integ-opensearch/CheckBootstrapVersion": [ + "/cdk-integ-opensearch-min/CheckBootstrapVersion": [ { "type": "aws:cdk:logicalId", "data": "CheckBootstrapVersion" } ] }, - "displayName": "cdk-integ-opensearch" + "displayName": "cdk-integ-opensearch-min" }, - "IntegDefaultTestDeployAssert4E6713E1.assets": { + "integopenseachminDefaultTestDeployAssert0EB58658.assets": { "type": "cdk:asset-manifest", "properties": { - "file": "IntegDefaultTestDeployAssert4E6713E1.assets.json", + "file": "integopenseachminDefaultTestDeployAssert0EB58658.assets.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" } }, - "IntegDefaultTestDeployAssert4E6713E1": { + "integopenseachminDefaultTestDeployAssert0EB58658": { "type": "aws:cloudformation:stack", "environment": "aws://unknown-account/unknown-region", "properties": { - "templateFile": "IntegDefaultTestDeployAssert4E6713E1.template.json", + "templateFile": "integopenseachminDefaultTestDeployAssert0EB58658.template.json", "terminationProtection": false, "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", @@ -76,7 +82,7 @@ "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ - "IntegDefaultTestDeployAssert4E6713E1.assets" + "integopenseachminDefaultTestDeployAssert0EB58658.assets" ], "lookupRole": { "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", @@ -85,23 +91,23 @@ } }, "dependencies": [ - "IntegDefaultTestDeployAssert4E6713E1.assets" + "integopenseachminDefaultTestDeployAssert0EB58658.assets" ], "metadata": { - "/Integ/DefaultTest/DeployAssert/BootstrapVersion": [ + "/integ-openseach-min/DefaultTest/DeployAssert/BootstrapVersion": [ { "type": "aws:cdk:logicalId", "data": "BootstrapVersion" } ], - "/Integ/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + "/integ-openseach-min/DefaultTest/DeployAssert/CheckBootstrapVersion": [ { "type": "aws:cdk:logicalId", "data": "CheckBootstrapVersion" } ] }, - "displayName": "Integ/DefaultTest/DeployAssert" + "displayName": "integ-openseach-min/DefaultTest/DeployAssert" }, "Tree": { "type": "cdk:tree", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/tree.json index deef8bfd8e7ed..7e6411c8151b4 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.js.snapshot/tree.json @@ -4,17 +4,17 @@ "id": "App", "path": "", "children": { - "cdk-integ-opensearch": { - "id": "cdk-integ-opensearch", - "path": "cdk-integ-opensearch", + "cdk-integ-opensearch-min": { + "id": "cdk-integ-opensearch-min", + "path": "cdk-integ-opensearch-min", "children": { - "Domain": { - "id": "Domain", - "path": "cdk-integ-opensearch/Domain", + "OpenSearch_2.13": { + "id": "OpenSearch_2.13", + "path": "cdk-integ-opensearch-min/OpenSearch_2.13", "children": { "Resource": { "id": "Resource", - "path": "cdk-integ-opensearch/Domain/Resource", + "path": "cdk-integ-opensearch-min/OpenSearch_2.13/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::OpenSearchService::Domain", "aws:cdk:cloudformation:props": { @@ -55,9 +55,56 @@ "version": "0.0.0" } }, + "OpenSearch_2.15": { + "id": "OpenSearch_2.15", + "path": "cdk-integ-opensearch-min/OpenSearch_2.15", + "children": { + "Resource": { + "id": "Resource", + "path": "cdk-integ-opensearch-min/OpenSearch_2.15/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::OpenSearchService::Domain", + "aws:cdk:cloudformation:props": { + "clusterConfig": { + "dedicatedMasterEnabled": false, + "instanceCount": 1, + "instanceType": "r5.large.search", + "multiAzWithStandbyEnabled": false, + "zoneAwarenessEnabled": false + }, + "domainEndpointOptions": { + "enforceHttps": false, + "tlsSecurityPolicy": "Policy-Min-TLS-1-0-2019-07" + }, + "ebsOptions": { + "ebsEnabled": true, + "volumeSize": 10, + "volumeType": "gp2" + }, + "encryptionAtRestOptions": { + "enabled": false + }, + "engineVersion": "OpenSearch_2.15", + "logPublishingOptions": {}, + "nodeToNodeEncryptionOptions": { + "enabled": false + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_opensearchservice.CfnDomain", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_opensearchservice.Domain", + "version": "0.0.0" + } + }, "BootstrapVersion": { "id": "BootstrapVersion", - "path": "cdk-integ-opensearch/BootstrapVersion", + "path": "cdk-integ-opensearch-min/BootstrapVersion", "constructInfo": { "fqn": "aws-cdk-lib.CfnParameter", "version": "0.0.0" @@ -65,7 +112,7 @@ }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", - "path": "cdk-integ-opensearch/CheckBootstrapVersion", + "path": "cdk-integ-opensearch-min/CheckBootstrapVersion", "constructInfo": { "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" @@ -77,17 +124,17 @@ "version": "0.0.0" } }, - "Integ": { - "id": "Integ", - "path": "Integ", + "integ-openseach-min": { + "id": "integ-openseach-min", + "path": "integ-openseach-min", "children": { "DefaultTest": { "id": "DefaultTest", - "path": "Integ/DefaultTest", + "path": "integ-openseach-min/DefaultTest", "children": { "Default": { "id": "Default", - "path": "Integ/DefaultTest/Default", + "path": "integ-openseach-min/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0" @@ -95,11 +142,11 @@ }, "DeployAssert": { "id": "DeployAssert", - "path": "Integ/DefaultTest/DeployAssert", + "path": "integ-openseach-min/DefaultTest/DeployAssert", "children": { "BootstrapVersion": { "id": "BootstrapVersion", - "path": "Integ/DefaultTest/DeployAssert/BootstrapVersion", + "path": "integ-openseach-min/DefaultTest/DeployAssert/BootstrapVersion", "constructInfo": { "fqn": "aws-cdk-lib.CfnParameter", "version": "0.0.0" @@ -107,7 +154,7 @@ }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", - "path": "Integ/DefaultTest/DeployAssert/CheckBootstrapVersion", + "path": "integ-openseach-min/DefaultTest/DeployAssert/CheckBootstrapVersion", "constructInfo": { "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" @@ -145,4 +192,4 @@ "version": "0.0.0" } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.ts index b0cd6aa86e523..79813d35d5d75 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-opensearchservice/test/integ.opensearch.min.ts @@ -7,20 +7,27 @@ class TestStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); - // deploy the latest opensearch domain with minimal configuration - const domainProps: opensearch.DomainProps = { - version: opensearch.EngineVersion.OPENSEARCH_2_13, - removalPolicy: RemovalPolicy.DESTROY, - capacity: { - multiAzWithStandbyEnabled: false, - }, - }; + const versions = [ + opensearch.EngineVersion.OPENSEARCH_2_13, + opensearch.EngineVersion.OPENSEARCH_2_15, + ]; - new opensearch.Domain(this, 'Domain', domainProps); + // deploy opensearch domain with minimal configuration + versions.forEach((version) => { + const domainProps: opensearch.DomainProps = { + version, + removalPolicy: RemovalPolicy.DESTROY, + capacity: { + multiAzWithStandbyEnabled: false, + }, + }; + + new opensearch.Domain(this, version.version, domainProps); + }); } } const app = new App(); -const stack = new TestStack(app, 'cdk-integ-opensearch'); +const stack = new TestStack(app, 'cdk-integ-opensearch-min'); -new IntegTest(app, 'Integ', { testCases: [stack] }); +new IntegTest(app, 'integ-openseach-min', { testCases: [stack] }); diff --git a/packages/aws-cdk-lib/aws-ec2/lib/vpc-endpoint.ts b/packages/aws-cdk-lib/aws-ec2/lib/vpc-endpoint.ts index d186d00987317..7e3cedf219e09 100644 --- a/packages/aws-cdk-lib/aws-ec2/lib/vpc-endpoint.ts +++ b/packages/aws-cdk-lib/aws-ec2/lib/vpc-endpoint.ts @@ -9,6 +9,7 @@ import { ISubnet, IVpc, SubnetSelection } from './vpc'; import * as iam from '../../aws-iam'; import * as cxschema from '../../cloud-assembly-schema'; import { Aws, ContextProvider, IResource, Lazy, Resource, Stack, Token } from '../../core'; +import { PARTITION_MAP } from '../../region-info/build-tools/fact-tables'; /** * A VPC endpoint. @@ -666,8 +667,21 @@ export class InterfaceVpcEndpointAwsService implements IInterfaceVpcEndpointServ 'redshift', 'redshift-data', 's3', 'sagemaker.api', 'sagemaker.featurestore-runtime', 'sagemaker.runtime', 'securityhub', 'servicecatalog', 'sms', 'sqs', 'states', 'sts', 'sync-states', 'synthetics', 'transcribe', 'transcribestreaming', 'transfer', 'workspaces', 'xray'], + 'us-isof-': ['ecr.api', 'ecr.dkr'], + 'eu-isoe-': ['ecr.api', 'ecr.dkr'], }; - if (VPC_ENDPOINT_SERVICE_EXCEPTIONS[region]?.includes(name)) { + + const regionPartition = region.split('-').slice(0, 2).join('-'); + const partitionDetails = PARTITION_MAP[`${regionPartition}-`]; + + // Check for specific service name under isolated region prefix + const serviceInExceptions = VPC_ENDPOINT_SERVICE_EXCEPTIONS[`${regionPartition}-`]?.includes(name); + + if (serviceInExceptions) { + // Endpoints generated in reverse of domain suffix for the services mentioned in map + const reverseString = partitionDetails.domainSuffix.split('.').reverse().join('.'); + return reverseString; + } else if (VPC_ENDPOINT_SERVICE_EXCEPTIONS[region]?.includes(name)) { return 'cn.com.amazonaws'; } else { return 'com.amazonaws'; diff --git a/packages/aws-cdk-lib/aws-ec2/test/vpc-endpoint.test.ts b/packages/aws-cdk-lib/aws-ec2/test/vpc-endpoint.test.ts index 3c1c05ba8dfa8..2e9ae880d7147 100644 --- a/packages/aws-cdk-lib/aws-ec2/test/vpc-endpoint.test.ts +++ b/packages/aws-cdk-lib/aws-ec2/test/vpc-endpoint.test.ts @@ -694,6 +694,37 @@ describe('vpc endpoint', () => { }); }); + + test.each([ + ['us-isof-test-1', 'gov.ic.hci.csp'], + ['eu-isoe-test-1', 'uk.adc-e.cloud'], + ['us-east-1', 'com.amazonaws'], + ['us-gov-west-1', 'com.amazonaws'], + ['cn-northwest-1', 'cn.com.amazonaws'], + ['cn-north-1', 'cn.com.amazonaws'], + ])('test vpc interface endpoint for ECR can be created correctly in all regions', (region : string, domain: string) => { + //GIVEN + const stack = new Stack(undefined, 'TestStack', { env: { account: '123456789012', region: region } }); + const vpc = new Vpc(stack, 'VPC'); + + //WHEN + vpc.addInterfaceEndpoint('ECR Endpoint', { + service: InterfaceVpcEndpointAwsService.ECR, + }); + + vpc.addInterfaceEndpoint('ECR Docker Endpoint', { + service: InterfaceVpcEndpointAwsService.ECR_DOCKER, + }); + + //THEN + Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCEndpoint', { + ServiceName: `${domain}.${region}.ecr.api`, + }); + Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCEndpoint', { + ServiceName: `${domain}.${region}.ecr.dkr`, + }); + }); + test.each([ ['transcribe', InterfaceVpcEndpointAwsService.TRANSCRIBE], ])('test vpc interface endpoint with .cn suffix for %s can be created correctly in China regions', (name: string, given: InterfaceVpcEndpointAwsService) => { diff --git a/packages/aws-cdk-lib/aws-opensearchservice/lib/version.ts b/packages/aws-cdk-lib/aws-opensearchservice/lib/version.ts index 513aae1b950cf..68b508559daa7 100644 --- a/packages/aws-cdk-lib/aws-opensearchservice/lib/version.ts +++ b/packages/aws-cdk-lib/aws-opensearchservice/lib/version.ts @@ -102,6 +102,9 @@ export class EngineVersion { /** AWS OpenSearch 2.13 */ public static readonly OPENSEARCH_2_13 = EngineVersion.openSearch('2.13'); + /** AWS OpenSearch 2.15 */ + public static readonly OPENSEARCH_2_15 = EngineVersion.openSearch('2.15'); + /** * Custom ElasticSearch version * @param version custom version number diff --git a/packages/aws-cdk-lib/aws-opensearchservice/test/domain.test.ts b/packages/aws-cdk-lib/aws-opensearchservice/test/domain.test.ts index abde6c1fb499c..55d6e7f325eef 100644 --- a/packages/aws-cdk-lib/aws-opensearchservice/test/domain.test.ts +++ b/packages/aws-cdk-lib/aws-opensearchservice/test/domain.test.ts @@ -43,6 +43,7 @@ const testedOpenSearchVersions = [ EngineVersion.OPENSEARCH_2_10, EngineVersion.OPENSEARCH_2_11, EngineVersion.OPENSEARCH_2_13, + EngineVersion.OPENSEARCH_2_15, ]; each(testedOpenSearchVersions).test('connections throws if domain is not placed inside a vpc', (engineVersion) => { @@ -209,6 +210,7 @@ each([ [EngineVersion.OPENSEARCH_2_10, 'OpenSearch_2.10'], [EngineVersion.OPENSEARCH_2_11, 'OpenSearch_2.11'], [EngineVersion.OPENSEARCH_2_13, 'OpenSearch_2.13'], + [EngineVersion.OPENSEARCH_2_15, 'OpenSearch_2.15'], ]).test('minimal example renders correctly', (engineVersion, expectedCfVersion) => { new Domain(stack, 'Domain', { version: engineVersion }); diff --git a/packages/aws-cdk-lib/aws-s3/lib/bucket-policy.ts b/packages/aws-cdk-lib/aws-s3/lib/bucket-policy.ts index f9875c7a48ae9..72aaaedf9191f 100644 --- a/packages/aws-cdk-lib/aws-s3/lib/bucket-policy.ts +++ b/packages/aws-cdk-lib/aws-s3/lib/bucket-policy.ts @@ -31,7 +31,20 @@ export interface BucketPolicyProps { * policy if one doesn't exist yet, otherwise it will add to the existing * policy. * - * Prefer to use `addToResourcePolicy()` instead. + * The bucket policy method is implemented differently than `addToResourcePolicy()` + * as `BucketPolicy()` creates a new policy without knowing one earlier existed. + * e.g. if during Bucket creation, if `autoDeleteObject:true`, these policies are + * added to the bucket policy: + * ["s3:DeleteObject*", "s3:GetBucket*", "s3:List*", "s3:PutBucketPolicy"], + * and when you add a new BucketPolicy with ["s3:GetObject", "s3:ListBucket"] on + * this existing bucket, invoking `BucketPolicy()` will create a new Policy + * without knowing one earlier exists already, so it creates a new one. + * In this case, the custom resource handler will not have access to + * `s3:GetBucketTagging` action which will cause failure during deletion of stack. + * + * Hence its strongly recommended to use `addToResourcePolicy()` method to add + * new permissions to existing policy. + * */ export class BucketPolicy extends Resource { /** diff --git a/packages/aws-cdk/lib/api/bootstrap/bootstrap-props.ts b/packages/aws-cdk/lib/api/bootstrap/bootstrap-props.ts index 95661a0bd96b0..b575acb50fc78 100644 --- a/packages/aws-cdk/lib/api/bootstrap/bootstrap-props.ts +++ b/packages/aws-cdk/lib/api/bootstrap/bootstrap-props.ts @@ -129,5 +129,4 @@ export interface BootstrappingParameters { * @default - No value, optional argument */ readonly customPermissionsBoundary?: string; - } diff --git a/packages/aws-cdk/lib/api/cxapp/exec.ts b/packages/aws-cdk/lib/api/cxapp/exec.ts index 4069d7a660143..31f2fca029dd9 100644 --- a/packages/aws-cdk/lib/api/cxapp/exec.ts +++ b/packages/aws-cdk/lib/api/cxapp/exec.ts @@ -58,37 +58,42 @@ export async function execProgram(aws: SdkProvider, config: Configuration): Prom debug('outdir:', outdir); env[cxapi.OUTDIR_ENV] = outdir; - // Acquire a read lock on the output directory + // Acquire a lock on the output directory const writerLock = await new RWLock(outdir).acquireWrite(); - // Send version information - env[cxapi.CLI_ASM_VERSION_ENV] = cxschema.Manifest.version(); - env[cxapi.CLI_VERSION_ENV] = versionNumber(); + try { + // Send version information + env[cxapi.CLI_ASM_VERSION_ENV] = cxschema.Manifest.version(); + env[cxapi.CLI_VERSION_ENV] = versionNumber(); - debug('env:', env); + debug('env:', env); - const envVariableSizeLimit = os.platform() === 'win32' ? 32760 : 131072; - const [smallContext, overflow] = splitBySize(context, spaceAvailableForContext(env, envVariableSizeLimit)); + const envVariableSizeLimit = os.platform() === 'win32' ? 32760 : 131072; + const [smallContext, overflow] = splitBySize(context, spaceAvailableForContext(env, envVariableSizeLimit)); - // Store the safe part in the environment variable - env[cxapi.CONTEXT_ENV] = JSON.stringify(smallContext); + // Store the safe part in the environment variable + env[cxapi.CONTEXT_ENV] = JSON.stringify(smallContext); - // If there was any overflow, write it to a temporary file - let contextOverflowLocation; - if (Object.keys(overflow ?? {}).length > 0) { - const contextDir = await fs.mkdtemp(path.join(os.tmpdir(), 'cdk-context')); - contextOverflowLocation = path.join(contextDir, 'context-overflow.json'); - fs.writeJSONSync(contextOverflowLocation, overflow); - env[cxapi.CONTEXT_OVERFLOW_LOCATION_ENV] = contextOverflowLocation; - } + // If there was any overflow, write it to a temporary file + let contextOverflowLocation; + if (Object.keys(overflow ?? {}).length > 0) { + const contextDir = await fs.mkdtemp(path.join(os.tmpdir(), 'cdk-context')); + contextOverflowLocation = path.join(contextDir, 'context-overflow.json'); + fs.writeJSONSync(contextOverflowLocation, overflow); + env[cxapi.CONTEXT_OVERFLOW_LOCATION_ENV] = contextOverflowLocation; + } - await exec(commandLine.join(' ')); + await exec(commandLine.join(' ')); - const assembly = createAssembly(outdir); + const assembly = createAssembly(outdir); - contextOverflowCleanup(contextOverflowLocation, assembly); + contextOverflowCleanup(contextOverflowLocation, assembly); - return { assembly, lock: await writerLock.convertToReaderLock() }; + return { assembly, lock: await writerLock.convertToReaderLock() }; + } catch (e) { + await writerLock.release(); + throw e; + } async function exec(commandAndArgs: string) { return new Promise((ok, fail) => { diff --git a/packages/aws-cdk/lib/api/hotswap/appsync-mapping-templates.ts b/packages/aws-cdk/lib/api/hotswap/appsync-mapping-templates.ts index a5a2156409458..91dcba4461f78 100644 --- a/packages/aws-cdk/lib/api/hotswap/appsync-mapping-templates.ts +++ b/packages/aws-cdk/lib/api/hotswap/appsync-mapping-templates.ts @@ -1,4 +1,4 @@ -import { GetSchemaCreationStatusRequest, GetSchemaCreationStatusResponse } from 'aws-sdk/clients/appsync'; +import { GetSchemaCreationStatusRequest, GetSchemaCreationStatusResponse, ListFunctionsResponse, FunctionConfiguration } from 'aws-sdk/clients/appsync'; import { ChangeHotswapResult, classifyChanges, HotswappableChangeCandidate, lowerCaseFirstCharacter, transformObjectKeys } from './common'; import { ISDK } from '../aws-auth'; @@ -96,7 +96,7 @@ export async function isHotswappableAppSyncChange( delete sdkRequestObject.runtime; } - const { functions } = await sdk.appsync().listFunctions({ apiId: sdkRequestObject.apiId }).promise(); + const functions = await getAppSyncFunctions(sdk, sdkRequestObject.apiId); const { functionId } = functions?.find(fn => fn.name === physicalName) ?? {}; // Updating multiple functions at the same time or along with graphql schema results in `ConcurrentModificationException` await simpleRetry( @@ -155,3 +155,18 @@ async function simpleRetry(fn: () => Promise, numOfRetries: number, errorCo async function sleep(ms: number) { return new Promise(ok => setTimeout(ok, ms)); } + +/** + * Get all functions for a given AppSync API by iterating through the paginated list of functions + */ +async function getAppSyncFunctions(sdk: ISDK, apiId: string, nextToken?: string): Promise { + const ret = new Array(); + return sdk.appsync().listFunctions({ apiId, nextToken }).promise() + .then(async (listFunctionsResponse: ListFunctionsResponse) => { + ret.push(...(listFunctionsResponse.functions ?? [])); + if (listFunctionsResponse.nextToken) { + ret.push(...await getAppSyncFunctions(sdk, apiId, listFunctionsResponse.nextToken)); + } + return ret; + }); +} diff --git a/packages/aws-cdk/lib/cli.ts b/packages/aws-cdk/lib/cli.ts index ac7be73f2f019..f63c7cbf21eef 100644 --- a/packages/aws-cdk/lib/cli.ts +++ b/packages/aws-cdk/lib/cli.ts @@ -547,7 +547,7 @@ export async function exec(args: string[], synthesizer?: Synthesizer): Promise { await lock.release(); }, TEN_SECOND_TIMEOUT); +test('cli releases the outdir lock when execProgram throws', async () => { + // GIVEN + config.settings.set(['app'], 'cloud-executable'); + mockSpawn({ + commandLine: 'fake-command', + exitCode: 127, + }); + + // WHEN + await expect(execProgram(sdkProvider, config)).rejects.toThrow(); + + const output = config.settings.get(['output']); + expect(output).toBeDefined(); + + // check that the lock is released + const lock = await new RWLock(output).acquireWrite(); + await lock.release(); +}); + function writeOutputAssembly() { const asm = testAssembly({ stacks: [], diff --git a/packages/aws-cdk/test/api/hotswap/appsync-mapping-templates-hotswap-deployments.test.ts b/packages/aws-cdk/test/api/hotswap/appsync-mapping-templates-hotswap-deployments.test.ts index ca45a75f031f1..700924c69f906 100644 --- a/packages/aws-cdk/test/api/hotswap/appsync-mapping-templates-hotswap-deployments.test.ts +++ b/packages/aws-cdk/test/api/hotswap/appsync-mapping-templates-hotswap-deployments.test.ts @@ -871,6 +871,89 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot } }); + silentTest('calls the updateFunction() API with functionId when function is listed on second page', async () => { + // GIVEN + const mockListFunctions = jest + .fn() + .mockReturnValueOnce({ + functions: [{ name: 'other-function', functionId: 'other-functionId' }], + nextToken: 'nexttoken', + }) + .mockReturnValueOnce({ + functions: [{ name: 'my-function', functionId: 'functionId' }], + }); + hotswapMockSdkProvider.stubAppSync({ + listFunctions: mockListFunctions, + updateFunction: mockUpdateFunction, + }); + + setup.setCurrentCfnStackTemplate({ + Resources: { + AppSyncFunction: { + Type: 'AWS::AppSync::FunctionConfiguration', + Properties: { + Name: 'my-function', + ApiId: 'apiId', + DataSourceName: 'my-datasource', + FunctionVersion: '2018-05-29', + Runtime: 'APPSYNC_JS', + Code: 'old test code', + }, + Metadata: { + 'aws:asset:path': 'old-path', + }, + }, + }, + }); + const cdkStackArtifact = setup.cdkStackArtifactOf({ + template: { + Resources: { + AppSyncFunction: { + Type: 'AWS::AppSync::FunctionConfiguration', + Properties: { + Name: 'my-function', + ApiId: 'apiId', + DataSourceName: 'my-datasource', + FunctionVersion: '2018-05-29', + Runtime: 'APPSYNC_JS', + Code: 'new test code', + }, + Metadata: { + 'aws:asset:path': 'new-path', + }, + }, + }, + }, + }); + + // WHEN + const deployStackResult = + await hotswapMockSdkProvider.tryHotswapDeployment( + hotswapMode, + cdkStackArtifact, + ); + + // THEN + expect(deployStackResult).not.toBeUndefined(); + expect(mockListFunctions).toHaveBeenCalledTimes(2); + expect(mockListFunctions).toHaveBeenCalledWith({ + apiId: 'apiId', + nextToken: undefined, + }); + expect(mockListFunctions).toHaveBeenCalledWith({ + apiId: 'apiId', + nextToken: 'nexttoken', + }); + expect(mockUpdateFunction).toHaveBeenCalledWith({ + apiId: 'apiId', + dataSourceName: 'my-datasource', + functionId: 'functionId', + runtime: 'APPSYNC_JS', + name: 'my-function', + code: 'new test code', + }); + }); + silentTest('calls the startSchemaCreation() API when it receives only a definition difference in a graphql schema', async () => { // GIVEN mockStartSchemaCreation = jest.fn().mockReturnValueOnce({ status: 'SUCCESS' }); diff --git a/packages/aws-cdk/test/cdk-toolkit.test.ts b/packages/aws-cdk/test/cdk-toolkit.test.ts index 7f70bbc8434de..9a1cc7f493886 100644 --- a/packages/aws-cdk/test/cdk-toolkit.test.ts +++ b/packages/aws-cdk/test/cdk-toolkit.test.ts @@ -69,6 +69,7 @@ import { HotswapMode } from '../lib/api/hotswap/common'; import { Template } from '../lib/api/util/cloudformation'; import { CdkToolkit, Tag } from '../lib/cdk-toolkit'; import { RequireApproval } from '../lib/diff'; +import { Configuration } from '../lib/settings'; import { flatten } from '../lib/util'; let cloudExecutable: MockCloudExecutable; @@ -115,7 +116,6 @@ describe('readCurrentTemplate', () => { let mockForEnvironment = jest.fn(); let mockCloudExecutable: MockCloudExecutable; beforeEach(() => { - template = { Resources: { Func: { @@ -394,6 +394,29 @@ describe('readCurrentTemplate', () => { }); }); +describe('bootstrap', () => { + test('accepts qualifier from context', async () => { + // GIVEN + const toolkit = defaultToolkitSetup(); + const configuration = new Configuration(); + configuration.context.set('@aws-cdk/core:bootstrapQualifier', 'abcde'); + + // WHEN + await toolkit.bootstrap(['aws://56789/south-pole'], bootstrapper, { + parameters: { + qualifier: configuration.context.get('@aws-cdk/core:bootstrapQualifier'), + }, + }); + + // THEN + expect(bootstrapper.bootstrapEnvironment).toHaveBeenCalledWith(expect.anything(), expect.anything(), { + parameters: { + qualifier: 'abcde', + }, + }); + }); +}); + describe('deploy', () => { test('fails when no valid stack names are given', async () => { // GIVEN diff --git a/yarn.lock b/yarn.lock index 373d697e86766..ec85df378061c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16563,7 +16563,16 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0", string-width@*, string-width@^1.0.1, "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3, string-width@^5.0.1, string-width@^5.1.2: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@*, string-width@^1.0.1, "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3, string-width@^5.0.1, string-width@^5.1.2: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -16628,7 +16637,7 @@ stringify-package@^1.0.1: resolved "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz#e5aa3643e7f74d0f28628b72f3dad5cecfc3ba85" integrity sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg== -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -16642,6 +16651,13 @@ strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -17639,7 +17655,7 @@ workerpool@^6.5.1: resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -17657,6 +17673,15 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"