From e89e3e391cdfbcc246e982ceb6509ec94f615996 Mon Sep 17 00:00:00 2001 From: Nick Aiello Date: Tue, 12 Mar 2024 23:47:21 -0500 Subject: [PATCH 1/9] feat(route53): allow specifying an STS region when creating a cross-account zone delegation --- .../index.ts | 7 +-- .../aws-cdk-lib/aws-route53/lib/record-set.ts | 7 +++ .../aws-route53/test/record-set.test.ts | 54 +++++++++++++++++++ 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/custom-resource-handlers/lib/aws-route53/cross-account-zone-delegation-handler/index.ts b/packages/@aws-cdk/custom-resource-handlers/lib/aws-route53/cross-account-zone-delegation-handler/index.ts index 833ec0cb5d3b9..bf92858f65000 100644 --- a/packages/@aws-cdk/custom-resource-handlers/lib/aws-route53/cross-account-zone-delegation-handler/index.ts +++ b/packages/@aws-cdk/custom-resource-handlers/lib/aws-route53/cross-account-zone-delegation-handler/index.ts @@ -15,6 +15,7 @@ interface ResourceProperties { DelegatedZoneName: string, DelegatedZoneNameServers: string[], TTL: number, + STSRegion?: string, } export async function handler(event: CrossAccountZoneDelegationEvent) { @@ -37,7 +38,7 @@ async function cfnUpdateEventHandler(props: ResourceProperties, oldProps: Resour } async function cfnEventHandler(props: ResourceProperties, isDeleteEvent: boolean) { - const { AssumeRoleArn, ParentZoneId, ParentZoneName, DelegatedZoneName, DelegatedZoneNameServers, TTL } = props; + const { AssumeRoleArn, ParentZoneId, ParentZoneName, DelegatedZoneName, DelegatedZoneNameServers, TTL, STSRegion } = props; if (!ParentZoneId && !ParentZoneName) { throw Error('One of ParentZoneId or ParentZoneName must be specified'); @@ -47,7 +48,7 @@ async function cfnEventHandler(props: ResourceProperties, isDeleteEvent: boolean const route53 = new Route53({ credentials: fromTemporaryCredentials({ clientConfig: { - region: route53Region(process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? ''), + region: STSRegion ?? route53Region(process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? ''), }, params: { RoleArn: AssumeRoleArn, @@ -123,4 +124,4 @@ function route53Region(region: string) { // Default for commercial partition return 'us-east-1'; -} \ No newline at end of file +} diff --git a/packages/aws-cdk-lib/aws-route53/lib/record-set.ts b/packages/aws-cdk-lib/aws-route53/lib/record-set.ts index 499b3ca12c5a3..1d5f6570acc83 100644 --- a/packages/aws-cdk-lib/aws-route53/lib/record-set.ts +++ b/packages/aws-cdk-lib/aws-route53/lib/record-set.ts @@ -859,6 +859,12 @@ export interface CrossAccountZoneDelegationRecordProps { * @default RemovalPolicy.DESTROY */ readonly removalPolicy?: RemovalPolicy; + + /** + * Region from which to obtain temporary credentials. + * @default - the Route53 signing region in the current partition + */ + readonly stsRegion?: string; } /** @@ -897,6 +903,7 @@ export class CrossAccountZoneDelegationRecord extends Construct { DelegatedZoneName: props.delegatedZone.zoneName, DelegatedZoneNameServers: props.delegatedZone.hostedZoneNameServers!, TTL: (props.ttl || Duration.days(2)).toSeconds(), + STSRegion: props.stsRegion, }, }); diff --git a/packages/aws-cdk-lib/aws-route53/test/record-set.test.ts b/packages/aws-cdk-lib/aws-route53/test/record-set.test.ts index 4f04cdea52eaf..65652feed3dd1 100644 --- a/packages/aws-cdk-lib/aws-route53/test/record-set.test.ts +++ b/packages/aws-cdk-lib/aws-route53/test/record-set.test.ts @@ -811,6 +811,60 @@ describe('record set', () => { }); }); + testDeprecated('Cross account zone delegation record with stsRegion', () => { + // GIVEN + const stack = new Stack(); + const parentZone = new route53.PublicHostedZone(stack, 'ParentHostedZone', { + zoneName: 'myzone.com', + crossAccountZoneDelegationPrincipal: new iam.AccountPrincipal('123456789012'), + }); + + // WHEN + const childZone = new route53.PublicHostedZone(stack, 'ChildHostedZone', { + zoneName: 'sub.myzone.com', + }); + new route53.CrossAccountZoneDelegationRecord(stack, 'Delegation', { + delegatedZone: childZone, + parentHostedZoneId: parentZone.hostedZoneId, + delegationRole: parentZone.crossAccountZoneDelegationRole!, + ttl: Duration.seconds(60), + removalPolicy: RemovalPolicy.RETAIN, + stsRegion: 'us-west-2', + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('Custom::CrossAccountZoneDelegation', { + ServiceToken: { + 'Fn::GetAtt': [ + 'CustomCrossAccountZoneDelegationCustomResourceProviderHandler44A84265', + 'Arn', + ], + }, + AssumeRoleArn: { + 'Fn::GetAtt': [ + 'ParentHostedZoneCrossAccountZoneDelegationRole95B1C36E', + 'Arn', + ], + }, + ParentZoneId: { + Ref: 'ParentHostedZoneC2BD86E1', + }, + DelegatedZoneName: 'sub.myzone.com', + DelegatedZoneNameServers: { + 'Fn::GetAtt': [ + 'ChildHostedZone4B14AC71', + 'NameServers', + ], + }, + TTL: 60, + STSRegion: 'us-west-2', + }); + Template.fromStack(stack).hasResource('Custom::CrossAccountZoneDelegation', { + DeletionPolicy: 'Retain', + UpdateReplacePolicy: 'Retain', + }); + }); + testDeprecated('Cross account zone delegation record with parentHostedZoneName', () => { // GIVEN const stack = new Stack(); From 4fb52cd5df608c0d083eff4bc9564e88d79cf297 Mon Sep 17 00:00:00 2001 From: Nick Aiello Date: Mon, 18 Mar 2024 22:33:03 -0500 Subject: [PATCH 2/9] chore: rename property --- .../index.ts | 6 +++--- packages/aws-cdk-lib/aws-route53/README.md | 15 +++++++++++++++ .../aws-cdk-lib/aws-route53/lib/record-set.ts | 4 ++-- .../aws-route53/test/record-set.test.ts | 6 +++--- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/@aws-cdk/custom-resource-handlers/lib/aws-route53/cross-account-zone-delegation-handler/index.ts b/packages/@aws-cdk/custom-resource-handlers/lib/aws-route53/cross-account-zone-delegation-handler/index.ts index bf92858f65000..a197af5751659 100644 --- a/packages/@aws-cdk/custom-resource-handlers/lib/aws-route53/cross-account-zone-delegation-handler/index.ts +++ b/packages/@aws-cdk/custom-resource-handlers/lib/aws-route53/cross-account-zone-delegation-handler/index.ts @@ -15,7 +15,7 @@ interface ResourceProperties { DelegatedZoneName: string, DelegatedZoneNameServers: string[], TTL: number, - STSRegion?: string, + AssumeRoleRegion?: string, } export async function handler(event: CrossAccountZoneDelegationEvent) { @@ -38,7 +38,7 @@ async function cfnUpdateEventHandler(props: ResourceProperties, oldProps: Resour } async function cfnEventHandler(props: ResourceProperties, isDeleteEvent: boolean) { - const { AssumeRoleArn, ParentZoneId, ParentZoneName, DelegatedZoneName, DelegatedZoneNameServers, TTL, STSRegion } = props; + const { AssumeRoleArn, ParentZoneId, ParentZoneName, DelegatedZoneName, DelegatedZoneNameServers, TTL, AssumeRoleRegion } = props; if (!ParentZoneId && !ParentZoneName) { throw Error('One of ParentZoneId or ParentZoneName must be specified'); @@ -48,7 +48,7 @@ async function cfnEventHandler(props: ResourceProperties, isDeleteEvent: boolean const route53 = new Route53({ credentials: fromTemporaryCredentials({ clientConfig: { - region: STSRegion ?? route53Region(process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? ''), + region: AssumeRoleRegion ?? route53Region(process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? ''), }, params: { RoleArn: AssumeRoleArn, diff --git a/packages/aws-cdk-lib/aws-route53/README.md b/packages/aws-cdk-lib/aws-route53/README.md index 2f7737d65a3b5..56fe5bcc9204b 100644 --- a/packages/aws-cdk-lib/aws-route53/README.md +++ b/packages/aws-cdk-lib/aws-route53/README.md @@ -305,6 +305,21 @@ new route53.CrossAccountZoneDelegationRecord(this, 'delegate', { }); ``` +Delegating the hosted zone requires assuming a role in the parent hosted zone's account. +In order for the assumed credentials to be valid, the resource must assume the role using +an STS endpoint in a region where both the subdomain's account and the parent's account +are opted-in. By default, this region is determined automatically, but if you need to +change the region used for the AssumeRole call, specify `assumeRoleRegion`: + +```ts +new route53.CrossAccountZoneDelegationRecord(this, 'delegate', { + delegatedZone: subZone, + parentHostedZoneName: 'someexample.com', // or you can use parentHostedZoneId + delegationRole, + assumeRoleRegion: "us-east-1", +}); +``` + ### Add Trailing Dot to Domain Names In order to continue managing existing domain names with trailing dots using CDK, you can set `addTrailingDot: false` to prevent the Construct from adding a dot at the end of the domain name. diff --git a/packages/aws-cdk-lib/aws-route53/lib/record-set.ts b/packages/aws-cdk-lib/aws-route53/lib/record-set.ts index 1d5f6570acc83..a4e3984100865 100644 --- a/packages/aws-cdk-lib/aws-route53/lib/record-set.ts +++ b/packages/aws-cdk-lib/aws-route53/lib/record-set.ts @@ -864,7 +864,7 @@ export interface CrossAccountZoneDelegationRecordProps { * Region from which to obtain temporary credentials. * @default - the Route53 signing region in the current partition */ - readonly stsRegion?: string; + readonly assumeRoleRegion?: string; } /** @@ -903,7 +903,7 @@ export class CrossAccountZoneDelegationRecord extends Construct { DelegatedZoneName: props.delegatedZone.zoneName, DelegatedZoneNameServers: props.delegatedZone.hostedZoneNameServers!, TTL: (props.ttl || Duration.days(2)).toSeconds(), - STSRegion: props.stsRegion, + AssumeRoleRegion: props.assumeRoleRegion, }, }); diff --git a/packages/aws-cdk-lib/aws-route53/test/record-set.test.ts b/packages/aws-cdk-lib/aws-route53/test/record-set.test.ts index 65652feed3dd1..b2d89c1f5fa54 100644 --- a/packages/aws-cdk-lib/aws-route53/test/record-set.test.ts +++ b/packages/aws-cdk-lib/aws-route53/test/record-set.test.ts @@ -811,7 +811,7 @@ describe('record set', () => { }); }); - testDeprecated('Cross account zone delegation record with stsRegion', () => { + test('Cross account zone delegation record with stsRegion', () => { // GIVEN const stack = new Stack(); const parentZone = new route53.PublicHostedZone(stack, 'ParentHostedZone', { @@ -829,7 +829,7 @@ describe('record set', () => { delegationRole: parentZone.crossAccountZoneDelegationRole!, ttl: Duration.seconds(60), removalPolicy: RemovalPolicy.RETAIN, - stsRegion: 'us-west-2', + assumeRoleRegion: 'fake-region-1', }); // THEN @@ -857,7 +857,7 @@ describe('record set', () => { ], }, TTL: 60, - STSRegion: 'us-west-2', + AssumeRoleRegion: 'fake-region-1', }); Template.fromStack(stack).hasResource('Custom::CrossAccountZoneDelegation', { DeletionPolicy: 'Retain', From 9aa4da747aa20d65ae54e061bf5dae4a96a72483 Mon Sep 17 00:00:00 2001 From: Nick Aiello Date: Tue, 19 Mar 2024 00:18:15 -0500 Subject: [PATCH 3/9] test: add tests --- .../__entrypoint__.js | 156 ++++++++++++++ .../index.js | 1 + ...-stack-with-assume-role-region.assets.json | 34 +++ ...tack-with-assume-role-region.template.json | 159 ++++++++++++++ .../child-opt-in-stack.assets.json | 18 ++ .../child-opt-in-stack.template.json | 8 +- .../child-stack.assets.json | 18 ++ .../child-stack.template.json | 4 + .../integ.json | 3 +- .../manifest.json | 92 +++++++- .../tree.json | 202 +++++++++++++++++- .../integ.cross-account-zone-delegation.ts | 27 ++- 12 files changed, 712 insertions(+), 10 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.template.json diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js new file mode 100644 index 0000000000000..9271364bb7e49 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js @@ -0,0 +1,156 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.withRetries = exports.handler = exports.external = void 0; +const https = require("https"); +const url = require("url"); +// for unit tests +exports.external = { + sendHttpRequest: defaultSendHttpRequest, + log: defaultLog, + includeStackTraces: true, + userHandlerIndex: './index', +}; +const CREATE_FAILED_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::CREATE_FAILED'; +const MISSING_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID'; +async function handler(event, context) { + const sanitizedEvent = { ...event, ResponseURL: '...' }; + exports.external.log(JSON.stringify(sanitizedEvent, undefined, 2)); + // ignore DELETE event when the physical resource ID is the marker that + // indicates that this DELETE is a subsequent DELETE to a failed CREATE + // operation. + if (event.RequestType === 'Delete' && event.PhysicalResourceId === CREATE_FAILED_PHYSICAL_ID_MARKER) { + exports.external.log('ignoring DELETE event caused by a failed CREATE event'); + await submitResponse('SUCCESS', event); + return; + } + try { + // invoke the user handler. this is intentionally inside the try-catch to + // ensure that if there is an error it's reported as a failure to + // cloudformation (otherwise cfn waits). + // eslint-disable-next-line @typescript-eslint/no-require-imports + const userHandler = require(exports.external.userHandlerIndex).handler; + const result = await userHandler(sanitizedEvent, context); + // validate user response and create the combined event + const responseEvent = renderResponse(event, result); + // submit to cfn as success + await submitResponse('SUCCESS', responseEvent); + } + catch (e) { + const resp = { + ...event, + Reason: exports.external.includeStackTraces ? e.stack : e.message, + }; + if (!resp.PhysicalResourceId) { + // special case: if CREATE fails, which usually implies, we usually don't + // have a physical resource id. in this case, the subsequent DELETE + // operation does not have any meaning, and will likely fail as well. to + // address this, we use a marker so the provider framework can simply + // ignore the subsequent DELETE. + if (event.RequestType === 'Create') { + exports.external.log('CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored'); + resp.PhysicalResourceId = CREATE_FAILED_PHYSICAL_ID_MARKER; + } + else { + // otherwise, if PhysicalResourceId is not specified, something is + // terribly wrong because all other events should have an ID. + exports.external.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(event)}`); + } + } + // this is an actual error, fail the activity altogether and exist. + await submitResponse('FAILED', resp); + } +} +exports.handler = handler; +function renderResponse(cfnRequest, handlerResponse = {}) { + // if physical ID is not returned, we have some defaults for you based + // on the request type. + const physicalResourceId = handlerResponse.PhysicalResourceId ?? cfnRequest.PhysicalResourceId ?? cfnRequest.RequestId; + // if we are in DELETE and physical ID was changed, it's an error. + if (cfnRequest.RequestType === 'Delete' && physicalResourceId !== cfnRequest.PhysicalResourceId) { + throw new Error(`DELETE: cannot change the physical resource ID from "${cfnRequest.PhysicalResourceId}" to "${handlerResponse.PhysicalResourceId}" during deletion`); + } + // merge request event and result event (result prevails). + return { + ...cfnRequest, + ...handlerResponse, + PhysicalResourceId: physicalResourceId, + }; +} +async function submitResponse(status, event) { + const json = { + Status: status, + Reason: event.Reason ?? status, + StackId: event.StackId, + RequestId: event.RequestId, + PhysicalResourceId: event.PhysicalResourceId || MISSING_PHYSICAL_ID_MARKER, + LogicalResourceId: event.LogicalResourceId, + NoEcho: event.NoEcho, + Data: event.Data, + }; + const parsedUrl = url.parse(event.ResponseURL); + const loggingSafeUrl = `${parsedUrl.protocol}//${parsedUrl.hostname}/${parsedUrl.pathname}?***`; + exports.external.log('submit response to cloudformation', loggingSafeUrl, json); + const responseBody = JSON.stringify(json); + const req = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: 'PUT', + headers: { + 'content-type': '', + 'content-length': Buffer.byteLength(responseBody, 'utf8'), + }, + }; + const retryOptions = { + attempts: 5, + sleep: 1000, + }; + await withRetries(retryOptions, exports.external.sendHttpRequest)(req, responseBody); +} +async function defaultSendHttpRequest(options, requestBody) { + return new Promise((resolve, reject) => { + try { + const request = https.request(options, (response) => { + response.resume(); // Consume the response but don't care about it + if (!response.statusCode || response.statusCode >= 400) { + reject(new Error(`Unsuccessful HTTP response: ${response.statusCode}`)); + } + else { + resolve(); + } + }); + request.on('error', reject); + request.write(requestBody); + request.end(); + } + catch (e) { + reject(e); + } + }); +} +function defaultLog(fmt, ...params) { + // eslint-disable-next-line no-console + console.log(fmt, ...params); +} +function withRetries(options, fn) { + return async (...xs) => { + let attempts = options.attempts; + let ms = options.sleep; + while (true) { + try { + return await fn(...xs); + } + catch (e) { + if (attempts-- <= 0) { + throw e; + } + await sleep(Math.floor(Math.random() * ms)); + ms *= 2; + } + } + }; +} +exports.withRetries = withRetries; +async function sleep(ms) { + return new Promise((ok) => setTimeout(ok, ms)); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsMkJBQTJCO0FBRTNCLGlCQUFpQjtBQUNKLFFBQUEsUUFBUSxHQUFHO0lBQ3RCLGVBQWUsRUFBRSxzQkFBc0I7SUFDdkMsR0FBRyxFQUFFLFVBQVU7SUFDZixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGdCQUFnQixFQUFFLFNBQVM7Q0FDNUIsQ0FBQztBQUVGLE1BQU0sZ0NBQWdDLEdBQUcsd0RBQXdELENBQUM7QUFDbEcsTUFBTSwwQkFBMEIsR0FBRyw4REFBOEQsQ0FBQztBQVczRixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDeEQsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFM0QsdUVBQXVFO0lBQ3ZFLHVFQUF1RTtJQUN2RSxhQUFhO0lBQ2IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEtBQUssZ0NBQWdDLEVBQUU7UUFDbkcsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN0RSxNQUFNLGNBQWMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkMsT0FBTztLQUNSO0lBRUQsSUFBSTtRQUNGLHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsd0NBQXdDO1FBQ3hDLGlFQUFpRTtRQUNqRSxNQUFNLFdBQVcsR0FBWSxPQUFPLENBQUMsZ0JBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4RSxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FB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bXBvcnQgKiBhcyBodHRwcyBmcm9tICdodHRwcyc7XG5pbXBvcnQgKiBhcyB1cmwgZnJvbSAndXJsJztcblxuLy8gZm9yIHVuaXQgdGVzdHNcbmV4cG9ydCBjb25zdCBleHRlcm5hbCA9IHtcbiAgc2VuZEh0dHBSZXF1ZXN0OiBkZWZhdWx0U2VuZEh0dHBSZXF1ZXN0LFxuICBsb2c6IGRlZmF1bHRMb2csXG4gIGluY2x1ZGVTdGFja1RyYWNlczogdHJ1ZSxcbiAgdXNlckhhbmRsZXJJbmRleDogJy4vaW5kZXgnLFxufTtcblxuY29uc3QgQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVIgPSAnQVdTQ0RLOjpDdXN0b21SZXNvdXJjZVByb3ZpZGVyRnJhbWV3b3JrOjpDUkVBVEVfRkFJTEVEJztcbmNvbnN0IE1JU1NJTkdfUEhZU0lDQUxfSURfTUFSS0VSID0gJ0FXU0NESzo6Q3VzdG9tUmVzb3VyY2VQcm92aWRlckZyYW1ld29yazo6TUlTU0lOR19QSFlTSUNBTF9JRCc7XG5cbmV4cG9ydCB0eXBlIFJlc3BvbnNlID0gQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIEhhbmRsZXJSZXNwb25zZTtcbmV4cG9ydCB0eXBlIEhhbmRsZXIgPSAoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSA9PiBQcm9taXNlPEhhbmRsZXJSZXNwb25zZSB8IHZvaWQ+O1xuZXhwb3J0IHR5cGUgSGFuZGxlclJlc3BvbnNlID0gdW5kZWZpbmVkIHwge1xuICBEYXRhPzogYW55O1xuICBQaHlzaWNhbFJlc291cmNlSWQ/OiBzdHJpbmc7XG4gIFJlYXNvbj86IHN0cmluZztcbiAgTm9FY2hvPzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50LCBjb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dCkge1xuICBjb25zdCBzYW5pdGl6ZWRFdmVudCA9IHsgLi4uZXZlbnQsIFJlc3BvbnNlVVJMOiAnLi4uJyB9O1xuICBleHRlcm5hbC5sb2coSlNPTi5zdHJpbmdpZnkoc2FuaXRpemVkRXZlbnQsIHVuZGVmaW5lZCwgMikpO1xuXG4gIC8vIGlnbm9yZSBERUxFVEUgZXZlbnQgd2hlbiB0aGUgcGh5c2ljYWwgcmVzb3VyY2UgSUQgaXMgdGhlIG1hcmtlciB0aGF0XG4gIC8vIGluZGljYXRlcyB0aGF0IHRoaXMgREVMRVRFIGlzIGEgc3Vic2VxdWVudCBERUxFVEUgdG8gYSBmYWlsZWQgQ1JFQVRFXG4gIC8vIG9wZXJhdGlvbi5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgPT09IENSRUFURV9GQUlMRURfUEhZU0lDQUxfSURfTUFSS0VSKSB7XG4gICAgZXh0ZXJuYWwubG9nKCdpZ25vcmluZyBERUxFVEUgZXZlbnQgY2F1c2VkIGJ5IGEgZmFpbGVkIENSRUFURSBldmVudCcpO1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgZXZlbnQpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgLy8gaW52b2tlIHRoZSB1c2VyIGhhbmRsZXIuIHRoaXMgaXMgaW50ZW50aW9uYWxseSBpbnNpZGUgdGhlIHRyeS1jYXRjaCB0b1xuICAgIC8vIGVuc3VyZSB0aGF0IGlmIHRoZXJlIGlzIGFuIGVycm9yIGl0J3MgcmVwb3J0ZWQgYXMgYSBmYWlsdXJlIHRvXG4gICAgLy8gY2xvdWRmb3JtYXRpb24gKG90aGVyd2lzZSBjZm4gd2FpdHMpLlxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3QgdXNlckhhbmRsZXI6IEhhbmRsZXIgPSByZXF1aXJlKGV4dGVybmFsLnVzZXJIYW5kbGVySW5kZXgpLmhhbmRsZXI7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdXNlckhhbmRsZXIoc2FuaXRpemVkRXZlbnQsIGNvbnRleHQpO1xuXG4gICAgLy8gdmFsaWRhdGUgdXNlciByZXNwb25zZSBhbmQgY3JlYXRlIHRoZSBjb21iaW5lZCBldmVudFxuICAgIGNvbnN0IHJlc3BvbnNlRXZlbnQgPSByZW5kZXJSZXNwb25zZShldmVudCwgcmVzdWx0KTtcblxuICAgIC8vIHN1Ym1pdCB0byBjZm4gYXMgc3VjY2Vzc1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgcmVzcG9uc2VFdmVudCk7XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGNvbnN0IHJlc3A6IFJlc3BvbnNlID0ge1xuICAgICAgLi4uZXZlbnQsXG4gICAgICBSZWFzb246IGV4dGVybmFsLmluY2x1ZGVTdGFja1RyYWNlcyA/IGUuc3RhY2sgOiBlLm1lc3NhZ2UsXG4gICAgfTtcblxuICAgIGlmICghcmVzcC5QaHlzaWNhbFJlc291cmNlSWQpIHtcbiAgICAgIC8vIHNwZWNpYWwgY2FzZTogaWYgQ1JFQVRFIGZhaWxzLCB3aGljaCB1c3VhbGx5IGltcGxpZXMsIHdlIHVzdWFsbHkgZG9uJ3RcbiAgICAgIC8vIGhhdmUgYSBwaHlzaWNhbCByZXNvdXJjZSBpZC4gaW4gdGhpcyBjYXNlLCB0aGUgc3Vic2VxdWVudCBERUxFVEVcbiAgICAgIC8vIG9wZXJhdGlvbiBkb2VzIG5vdCBoYXZlIGFueSBtZWFuaW5nLCBhbmQgd2lsbCBsaWtlbHkgZmFpbCBhcyB3ZWxsLiB0b1xuICAgICAgLy8gYWRkcmVzcyB0aGlzLCB3ZSB1c2UgYSBtYXJrZXIgc28gdGhlIHByb3ZpZGVyIGZyYW1ld29yayBjYW4gc2ltcGx5XG4gICAgICAvLyBpZ25vcmUgdGhlIHN1YnNlcXVlbnQgREVMRVRFLlxuICAgICAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnQ3JlYXRlJykge1xuICAgICAgICBleHRlcm5hbC5sb2coJ0NSRUFURSBmYWlsZWQsIHJlc3BvbmRpbmcgd2l0aCBhIG1hcmtlciBwaHlzaWNhbCByZXNvdXJjZSBpZCBzbyB0aGF0IHRoZSBzdWJzZXF1ZW50IERFTEVURSB3aWxsIGJlIGlnbm9yZWQnKTtcbiAgICAgICAgcmVzcC5QaHlzaWNhbFJlc291cmNlSWQgPSBDUkVBVEVfRkFJTEVEX1BIWVNJQ0FMX0lEX01BUktFUjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG90aGVyd2lzZSwgaWYgUGh5c2ljYWxSZXNvdXJjZUlkIGlzIG5vdCBzcGVjaWZpZWQsIHNvbWV0aGluZyBpc1xuICAgICAgICAvLyB0ZXJyaWJseSB3cm9uZyBiZWNhdXNlIGFsbCBvdGhlciBldmVudHMgc2hvdWxkIGhhdmUgYW4gSUQuXG4gICAgICAgIGV4dGVybmFsLmxvZyhgRVJST1I6IE1hbGZvcm1lZCBldmVudC4gXCJQaHlzaWNhbFJlc291cmNlSWRcIiBpcyByZXF1aXJlZDogJHtKU09OLnN0cmluZ2lmeShldmVudCl9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdGhpcyBpcyBhbiBhY3R1YWwgZXJyb3IsIGZhaWwgdGhlIGFjdGl2aXR5IGFsdG9nZXRoZXIgYW5kIGV4aXN0LlxuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdGQUlMRUQnLCByZXNwKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW5kZXJSZXNwb25zZShcbiAgY2ZuUmVxdWVzdDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIHsgUGh5c2ljYWxSZXNvdXJjZUlkPzogc3RyaW5nIH0sXG4gIGhhbmRsZXJSZXNwb25zZTogdm9pZCB8IEhhbmRsZXJSZXNwb25zZSA9IHsgfSk6IFJlc3BvbnNlIHtcblxuICAvLyBpZiBwaHlzaWNhbCBJRCBpcyBub3QgcmV0dXJuZWQsIHdlIGhhdmUgc29tZSBkZWZhdWx0cyBmb3IgeW91IGJhc2VkXG4gIC8vIG9uIHRoZSByZXF1ZXN0IHR5cGUuXG4gIGNvbnN0IHBoeXNpY2FsUmVzb3VyY2VJZCA9IGhhbmRsZXJSZXNwb25zZS5QaHlzaWNhbFJlc291cmNlSWQgPz8gY2ZuUmVxdWVzdC5QaHlzaWNhbFJlc291cmNlSWQgPz8gY2ZuUmVxdWVzdC5SZXF1ZXN0SWQ7XG5cbiAgLy8gaWYgd2UgYXJlIGluIERFTEVURSBhbmQgcGh5c2ljYWwgSUQgd2FzIGNoYW5nZWQsIGl0J3MgYW4gZXJyb3IuXG4gIGlmIChjZm5SZXF1ZXN0LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBwaHlzaWNhbFJlc291cmNlSWQgIT09IGNmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBERUxFVEU6IGNhbm5vdCBjaGFuZ2UgdGhlIHBoeXNpY2FsIHJlc291cmNlIElEIGZyb20gXCIke2NmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkfVwiIHRvIFwiJHtoYW5kbGVyUmVzcG9uc2UuUGh5c2ljYWxSZXNvdXJjZUlkfVwiIGR1cmluZyBkZWxldGlvbmApO1xuICB9XG5cbiAgLy8gbWVyZ2UgcmVxdWVzdCBldmVudCBhbmQgcmVzdWx0IGV2ZW50IChyZXN1bHQgcHJldmFpbHMpLlxuICByZXR1cm4ge1xuICAgIC4uLmNmblJlcXVlc3QsXG4gICAgLi4uaGFuZGxlclJlc3BvbnNlLFxuICAgIFBoeXNpY2FsUmVzb3VyY2VJZDogcGh5c2ljYWxSZXNvdXJjZUlkLFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzdWJtaXRSZXNwb25zZShzdGF0dXM6ICdTVUNDRVNTJyB8ICdGQUlMRUQnLCBldmVudDogUmVzcG9uc2UpIHtcbiAgY29uc3QganNvbjogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VSZXNwb25zZSA9IHtcbiAgICBTdGF0dXM6IHN0YXR1cyxcbiAgICBSZWFzb246IGV2ZW50LlJlYXNvbiA/PyBzdGF0dXMsXG4gICAgU3RhY2tJZDogZXZlbnQuU3RhY2tJZCxcbiAgICBSZXF1ZXN0SWQ6IGV2ZW50LlJlcXVlc3RJZCxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCB8fCBNSVNTSU5HX1BIWVNJQ0FMX0lEX01BUktFUixcbiAgICBMb2dpY2FsUmVzb3VyY2VJZDogZXZlbnQuTG9naWNhbFJlc291cmNlSWQsXG4gICAgTm9FY2hvOiBldmVudC5Ob0VjaG8sXG4gICAgRGF0YTogZXZlbnQuRGF0YSxcbiAgfTtcblxuICBjb25zdCBwYXJzZWRVcmwgPSB1cmwucGFyc2UoZXZlbnQuUmVzcG9uc2VVUkwpO1xuICBjb25zdCBsb2dnaW5nU2FmZVVybCA9IGAke3BhcnNlZFVybC5wcm90b2NvbH0vLyR7cGFyc2VkVXJsLmhvc3RuYW1lfS8ke3BhcnNlZFVybC5wYXRobmFtZX0/KioqYDtcbiAgZXh0ZXJuYWwubG9nKCdzdWJtaXQgcmVzcG9uc2UgdG8gY2xvdWRmb3JtYXRpb24nLCBsb2dnaW5nU2FmZVVybCwganNvbik7XG5cbiAgY29uc3QgcmVzcG9uc2VCb2R5ID0gSlNPTi5zdHJpbmdpZnkoanNvbik7XG4gIGNvbnN0IHJlcSA9IHtcbiAgICBob3N0bmFtZTogcGFyc2VkVXJsLmhvc3RuYW1lLFxuICAgIHBhdGg6IHBhcnNlZFVybC5wYXRoLFxuICAgIG1ldGhvZDogJ1BVVCcsXG4gICAgaGVhZGVyczoge1xuICAgICAgJ2NvbnRlbnQtdHlwZSc6ICcnLFxuICAgICAgJ2NvbnRlbnQtbGVuZ3RoJzogQnVmZmVyLmJ5dGVMZW5ndGgocmVzcG9uc2VCb2R5LCAndXRmOCcpLFxuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgcmV0cnlPcHRpb25zID0ge1xuICAgIGF0dGVtcHRzOiA1LFxuICAgIHNsZWVwOiAxMDAwLFxuICB9O1xuICBhd2FpdCB3aXRoUmV0cmllcyhyZXRyeU9wdGlvbnMsIGV4dGVybmFsLnNlbmRIdHRwUmVxdWVzdCkocmVxLCByZXNwb25zZUJvZHkpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBkZWZhdWx0U2VuZEh0dHBSZXF1ZXN0KG9wdGlvbnM6IGh0dHBzLlJlcXVlc3RPcHRpb25zLCByZXF1ZXN0Qm9keTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBodHRwcy5yZXF1ZXN0KG9wdGlvbnMsIChyZXNwb25zZSkgPT4ge1xuICAgICAgICByZXNwb25zZS5yZXN1bWUoKTsgLy8gQ29uc3VtZSB0aGUgcmVzcG9uc2UgYnV0IGRvbid0IGNhcmUgYWJvdXQgaXRcbiAgICAgICAgaWYgKCFyZXNwb25zZS5zdGF0dXNDb2RlIHx8IHJlc3BvbnNlLnN0YXR1c0NvZGUgPj0gNDAwKSB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgVW5zdWNjZXNzZnVsIEhUVFAgcmVzcG9uc2U6ICR7cmVzcG9uc2Uuc3RhdHVzQ29kZX1gKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJlcXVlc3Qub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgICAgIHJlcXVlc3Qud3JpdGUocmVxdWVzdEJvZHkpO1xuICAgICAgcmVxdWVzdC5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZSk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdExvZyhmbXQ6IHN0cmluZywgLi4ucGFyYW1zOiBhbnlbXSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLmxvZyhmbXQsIC4uLnBhcmFtcyk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmV0cnlPcHRpb25zIHtcbiAgLyoqIEhvdyBtYW55IHJldHJpZXMgKHdpbGwgYXQgbGVhc3QgdHJ5IG9uY2UpICovXG4gIHJlYWRvbmx5IGF0dGVtcHRzOiBudW1iZXI7XG4gIC8qKiBTbGVlcCBiYXNlLCBpbiBtcyAqL1xuICByZWFkb25seSBzbGVlcDogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aFJldHJpZXM8QSBleHRlbmRzIEFycmF5PGFueT4sIEI+KG9wdGlvbnM6IFJldHJ5T3B0aW9ucywgZm46ICguLi54czogQSkgPT4gUHJvbWlzZTxCPik6ICguLi54czogQSkgPT4gUHJvbWlzZTxCPiB7XG4gIHJldHVybiBhc3luYyAoLi4ueHM6IEEpID0+IHtcbiAgICBsZXQgYXR0ZW1wdHMgPSBvcHRpb25zLmF0dGVtcHRzO1xuICAgIGxldCBtcyA9IG9wdGlvbnMuc2xlZXA7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmbiguLi54cyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChhdHRlbXB0cy0tIDw9IDApIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHNsZWVwKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIG1zKSk7XG4gICAgICAgIG1zICo9IDI7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgob2spID0+IHNldFRpbWVvdXQob2ssIG1zKSk7XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js new file mode 100644 index 0000000000000..fc8189b0bbb1d --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js @@ -0,0 +1 @@ +"use strict";var a=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var h=(o,e)=>{for(var r in e)a(o,r,{get:e[r],enumerable:!0})},E=(o,e,r,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of N(e))!P.call(o,n)&&n!==r&&a(o,n,{get:()=>e[n],enumerable:!(t=Z(e,n))||t.enumerable});return o};var A=o=>E(a({},"__esModule",{value:!0}),o);var v={};h(v,{handler:()=>D});module.exports=A(v);var c=require("@aws-sdk/client-route-53"),u=require("@aws-sdk/credential-providers");async function D(o){let e=o.ResourceProperties;switch(o.RequestType){case"Create":return s(e,!1);case"Update":return w(e,o.OldResourceProperties);case"Delete":return s(e,!0)}}async function w(o,e){e&&o.DelegatedZoneName!==e.DelegatedZoneName&&await s(e,!0),await s(o,!1)}async function s(o,e){let{AssumeRoleArn:r,ParentZoneId:t,ParentZoneName:n,DelegatedZoneName:m,DelegatedZoneNameServers:d,TTL:g,AssumeRoleRegion:R}=o;if(!t&&!n)throw Error("One of ParentZoneId or ParentZoneName must be specified");let l=new Date().getTime(),i=new c.Route53({credentials:(0,u.fromTemporaryCredentials)({clientConfig:{region:R??T(process.env.AWS_REGION??process.env.AWS_DEFAULT_REGION??"")},params:{RoleArn:r,RoleSessionName:`cross-account-zone-delegation-${l}`}})}),p=t??await S(n,i);await i.changeResourceRecordSets({HostedZoneId:p,ChangeBatch:{Changes:[{Action:e?"DELETE":"UPSERT",ResourceRecordSet:{Name:m,Type:"NS",TTL:g,ResourceRecords:d.map(f=>({Value:f}))}}]}})}async function S(o,e){let t=(await e.listHostedZonesByName({DNSName:o})).HostedZones?.filter(n=>n.Name===`${o}.`)??[];if(t&&t.length!==1)throw Error(`Expected one hosted zone to match the given name but found ${t.length}`);return t[0].Id}function T(o){let e={cn:"cn-northwest-1","us-gov":"us-gov-west-1","us-iso":"us-iso-east-1","us-isob":"us-isob-east-1"};for(let[r,t]of Object.entries(e))if(o.startsWith(`${r}-`))return t;return"us-east-1"}0&&(module.exports={handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.assets.json new file mode 100644 index 0000000000000..7d4e310c38056 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.assets.json @@ -0,0 +1,34 @@ +{ + "version": "36.0.0", + "files": { + "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a": { + "source": { + "path": "asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a", + "packaging": "zip" + }, + "destinations": { + "234567890123-af-south-1": { + "bucketName": "cdk-hnb659fds-assets-234567890123-af-south-1", + "objectKey": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip", + "region": "af-south-1", + "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-af-south-1" + } + } + }, + "f623a975a6715de3e8cfcea1429aa4dd9a0a9d47f328849d3148a0859b45a9d6": { + "source": { + "path": "child-opt-in-stack-with-assume-role-region.template.json", + "packaging": "file" + }, + "destinations": { + "234567890123-af-south-1": { + "bucketName": "cdk-hnb659fds-assets-234567890123-af-south-1", + "objectKey": "f623a975a6715de3e8cfcea1429aa4dd9a0a9d47f328849d3148a0859b45a9d6.json", + "region": "af-south-1", + "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-af-south-1" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.template.json new file mode 100644 index 0000000000000..ab52c5ecd1378 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.template.json @@ -0,0 +1,159 @@ +{ + "Resources": { + "SubZoneF7955E1A": { + "Type": "AWS::Route53::HostedZone", + "Properties": { + "Name": "sub3.uniqueexample.com." + } + }, + "delegatecrossaccountzonedelegationhandlerrolePolicychildoptinstackwithassumeroleregiondelegatecrossaccountzonedelegationhandlerroleA822DAE1970772B0": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": "arn:aws:iam::12345678:role/MyUniqueDelegationRole" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PolicychildoptinstackwithassumeroleregiondelegatecrossaccountzonedelegationhandlerroleA822DAE1", + "Roles": [ + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "/", + { + "Fn::Select": [ + 5, + { + "Fn::Split": [ + ":", + { + "Fn::GetAtt": [ + "CustomCrossAccountZoneDelegationCustomResourceProviderRoleED64687B", + "Arn" + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + }, + "delegateCrossAccountZoneDelegationCustomResource23BD590B": { + "Type": "Custom::CrossAccountZoneDelegation", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "CustomCrossAccountZoneDelegationCustomResourceProviderHandler44A84265", + "Arn" + ] + }, + "AssumeRoleArn": "arn:aws:iam::12345678:role/MyUniqueDelegationRole", + "ParentZoneName": "uniqueexample.com", + "DelegatedZoneName": "sub3.uniqueexample.com", + "DelegatedZoneNameServers": { + "Fn::GetAtt": [ + "SubZoneF7955E1A", + "NameServers" + ] + }, + "TTL": 172800, + "AssumeRoleRegion": "eu-west-1" + }, + "DependsOn": [ + "delegatecrossaccountzonedelegationhandlerrolePolicychildoptinstackwithassumeroleregiondelegatecrossaccountzonedelegationhandlerroleA822DAE1970772B0" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "CustomCrossAccountZoneDelegationCustomResourceProviderRoleED64687B": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ] + } + }, + "CustomCrossAccountZoneDelegationCustomResourceProviderHandler44A84265": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "cdk-hnb659fds-assets-234567890123-af-south-1", + "S3Key": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip" + }, + "Timeout": 900, + "MemorySize": 128, + "Handler": "__entrypoint__.handler", + "Role": { + "Fn::GetAtt": [ + "CustomCrossAccountZoneDelegationCustomResourceProviderRoleED64687B", + "Arn" + ] + }, + "Runtime": "nodejs18.x" + }, + "DependsOn": [ + "CustomCrossAccountZoneDelegationCustomResourceProviderRoleED64687B" + ] + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.assets.json index 71e2bce9c16b6..24434b21f3d01 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.assets.json @@ -1,21 +1,35 @@ { "version": "36.0.0", "files": { +<<<<<<< HEAD "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a": { "source": { "path": "asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a", +======= + "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a": { + "source": { + "path": "asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a", +>>>>>>> 96239f83c0 (test: add tests) "packaging": "zip" }, "destinations": { "234567890123-af-south-1": { "bucketName": "cdk-hnb659fds-assets-234567890123-af-south-1", +<<<<<<< HEAD "objectKey": "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a.zip", +======= + "objectKey": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip", +>>>>>>> 96239f83c0 (test: add tests) "region": "af-south-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-af-south-1" } } }, +<<<<<<< HEAD "34da3610276ae2d635b15c43c511f47cbd7b4f6e3b7de7b82b980f76956011b1": { +======= + "18f2dbac091f9ac5d22a8c4ce4a05b8c6c31cdaf1f062f8d19cda274d27ccf3c": { +>>>>>>> 96239f83c0 (test: add tests) "source": { "path": "child-opt-in-stack.template.json", "packaging": "file" @@ -23,7 +37,11 @@ "destinations": { "234567890123-af-south-1": { "bucketName": "cdk-hnb659fds-assets-234567890123-af-south-1", +<<<<<<< HEAD "objectKey": "34da3610276ae2d635b15c43c511f47cbd7b4f6e3b7de7b82b980f76956011b1.json", +======= + "objectKey": "18f2dbac091f9ac5d22a8c4ce4a05b8c6c31cdaf1f062f8d19cda274d27ccf3c.json", +>>>>>>> 96239f83c0 (test: add tests) "region": "af-south-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-af-south-1" } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.template.json index fb9d627591fd9..e52f4bc9778c4 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.template.json @@ -3,7 +3,7 @@ "SubZoneF7955E1A": { "Type": "AWS::Route53::HostedZone", "Properties": { - "Name": "sub.uniqueexample.com." + "Name": "sub2.uniqueexample.com." } }, "delegatecrossaccountzonedelegationhandlerrolePolicychildoptinstackdelegatecrossaccountzonedelegationhandlerroleD1C6F26DE28FC01D": { @@ -61,7 +61,7 @@ }, "AssumeRoleArn": "arn:aws:iam::12345678:role/MyUniqueDelegationRole", "ParentZoneName": "uniqueexample.com", - "DelegatedZoneName": "sub.uniqueexample.com", + "DelegatedZoneName": "sub2.uniqueexample.com", "DelegatedZoneNameServers": { "Fn::GetAtt": [ "SubZoneF7955E1A", @@ -103,7 +103,11 @@ "Properties": { "Code": { "S3Bucket": "cdk-hnb659fds-assets-234567890123-af-south-1", +<<<<<<< HEAD "S3Key": "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a.zip" +======= + "S3Key": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip" +>>>>>>> 96239f83c0 (test: add tests) }, "Timeout": 900, "MemorySize": 128, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.assets.json index 3e9342b96558d..3b3bca57a2b8e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.assets.json @@ -1,21 +1,35 @@ { "version": "36.0.0", "files": { +<<<<<<< HEAD "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a": { "source": { "path": "asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a", +======= + "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a": { + "source": { + "path": "asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a", +>>>>>>> 96239f83c0 (test: add tests) "packaging": "zip" }, "destinations": { "234567890123-us-east-1": { "bucketName": "cdk-hnb659fds-assets-234567890123-us-east-1", +<<<<<<< HEAD "objectKey": "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a.zip", +======= + "objectKey": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip", +>>>>>>> 96239f83c0 (test: add tests) "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-us-east-1" } } }, +<<<<<<< HEAD "3e4b4f51ab2cf9d297070625300465aeacdc41af65e442818c5ef6c17e800728": { +======= + "8918292f4943f8879dc05122e8ad942ce9821941625fd7a4cc914db637b828b3": { +>>>>>>> 96239f83c0 (test: add tests) "source": { "path": "child-stack.template.json", "packaging": "file" @@ -23,7 +37,11 @@ "destinations": { "234567890123-us-east-1": { "bucketName": "cdk-hnb659fds-assets-234567890123-us-east-1", +<<<<<<< HEAD "objectKey": "3e4b4f51ab2cf9d297070625300465aeacdc41af65e442818c5ef6c17e800728.json", +======= + "objectKey": "8918292f4943f8879dc05122e8ad942ce9821941625fd7a4cc914db637b828b3.json", +>>>>>>> 96239f83c0 (test: add tests) "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-us-east-1" } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.template.json index 0e056b8c4a286..8f1b82c1944ac 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.template.json @@ -103,7 +103,11 @@ "Properties": { "Code": { "S3Bucket": "cdk-hnb659fds-assets-234567890123-us-east-1", +<<<<<<< HEAD "S3Key": "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a.zip" +======= + "S3Key": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip" +>>>>>>> 96239f83c0 (test: add tests) }, "Timeout": 900, "MemorySize": 128, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/integ.json index a1405d643a470..7a1037b90cdd7 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/integ.json @@ -4,7 +4,8 @@ "Route53CrossAccountInteg/DefaultTest": { "stacks": [ "child-stack", - "child-opt-in-stack" + "child-opt-in-stack", + "child-opt-in-stack-with-assume-role-region" ], "diffAssets": true, "assertionStack": "Route53CrossAccountInteg/DefaultTest/DeployAssert", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/manifest.json index e880c00afc438..16134f7243603 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/manifest.json @@ -84,7 +84,11 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-deploy-role-234567890123-us-east-1", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-cfn-exec-role-234567890123-us-east-1", +<<<<<<< HEAD "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-us-east-1/3e4b4f51ab2cf9d297070625300465aeacdc41af65e442818c5ef6c17e800728.json", +======= + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-us-east-1/8918292f4943f8879dc05122e8ad942ce9821941625fd7a4cc914db637b828b3.json", +>>>>>>> 96239f83c0 (test: add tests) "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -163,7 +167,11 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-deploy-role-234567890123-af-south-1", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-cfn-exec-role-234567890123-af-south-1", +<<<<<<< HEAD "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-af-south-1/34da3610276ae2d635b15c43c511f47cbd7b4f6e3b7de7b82b980f76956011b1.json", +======= + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-af-south-1/18f2dbac091f9ac5d22a8c4ce4a05b8c6c31cdaf1f062f8d19cda274d27ccf3c.json", +>>>>>>> 96239f83c0 (test: add tests) "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -183,7 +191,10 @@ "/child-opt-in-stack/SubZone/Resource": [ { "type": "aws:cdk:logicalId", - "data": "SubZoneF7955E1A" + "data": "SubZoneF7955E1A", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" + ] } ], "/child-opt-in-stack/delegate/cross-account-zone-delegation-handler-role/PolicychildoptinstackdelegatecrossaccountzonedelegationhandlerroleD1C6F26D/Resource": [ @@ -225,6 +236,85 @@ }, "displayName": "child-opt-in-stack" }, + "child-opt-in-stack-with-assume-role-region.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "child-opt-in-stack-with-assume-role-region.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "child-opt-in-stack-with-assume-role-region": { + "type": "aws:cloudformation:stack", + "environment": "aws://234567890123/af-south-1", + "properties": { + "templateFile": "child-opt-in-stack-with-assume-role-region.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-deploy-role-234567890123-af-south-1", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-cfn-exec-role-234567890123-af-south-1", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-af-south-1/f623a975a6715de3e8cfcea1429aa4dd9a0a9d47f328849d3148a0859b45a9d6.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "child-opt-in-stack-with-assume-role-region.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-lookup-role-234567890123-af-south-1", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "parent-stack", + "child-opt-in-stack-with-assume-role-region.assets" + ], + "metadata": { + "/child-opt-in-stack-with-assume-role-region/SubZone/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "SubZoneF7955E1A" + } + ], + "/child-opt-in-stack-with-assume-role-region/delegate/cross-account-zone-delegation-handler-role/PolicychildoptinstackwithassumeroleregiondelegatecrossaccountzonedelegationhandlerroleA822DAE1/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "delegatecrossaccountzonedelegationhandlerrolePolicychildoptinstackwithassumeroleregiondelegatecrossaccountzonedelegationhandlerroleA822DAE1970772B0" + } + ], + "/child-opt-in-stack-with-assume-role-region/delegate/CrossAccountZoneDelegationCustomResource/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "delegateCrossAccountZoneDelegationCustomResource23BD590B" + } + ], + "/child-opt-in-stack-with-assume-role-region/Custom::CrossAccountZoneDelegationCustomResourceProvider/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomCrossAccountZoneDelegationCustomResourceProviderRoleED64687B" + } + ], + "/child-opt-in-stack-with-assume-role-region/Custom::CrossAccountZoneDelegationCustomResourceProvider/Handler": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomCrossAccountZoneDelegationCustomResourceProviderHandler44A84265" + } + ], + "/child-opt-in-stack-with-assume-role-region/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/child-opt-in-stack-with-assume-role-region/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "child-opt-in-stack-with-assume-role-region" + }, "Route53CrossAccountIntegDefaultTestDeployAssertF1D808C9.assets": { "type": "cdk:asset-manifest", "properties": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/tree.json index af266b3859958..6ed5d16c08087 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/tree.json @@ -377,7 +377,7 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::Route53::HostedZone", "aws:cdk:cloudformation:props": { - "name": "sub.uniqueexample.com." + "name": "sub2.uniqueexample.com." } }, "constructInfo": { @@ -563,6 +563,206 @@ "version": "0.0.0" } }, + "child-opt-in-stack-with-assume-role-region": { + "id": "child-opt-in-stack-with-assume-role-region", + "path": "child-opt-in-stack-with-assume-role-region", + "children": { + "SubZone": { + "id": "SubZone", + "path": "child-opt-in-stack-with-assume-role-region/SubZone", + "children": { + "Resource": { + "id": "Resource", + "path": "child-opt-in-stack-with-assume-role-region/SubZone/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Route53::HostedZone", + "aws:cdk:cloudformation:props": { + "name": "sub3.uniqueexample.com." + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_route53.CfnHostedZone", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_route53.PublicHostedZone", + "version": "0.0.0" + } + }, + "MutableRoleDelegationRole": { + "id": "MutableRoleDelegationRole", + "path": "child-opt-in-stack-with-assume-role-region/MutableRoleDelegationRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "DelegationRole": { + "id": "DelegationRole", + "path": "child-opt-in-stack-with-assume-role-region/DelegationRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "delegate": { + "id": "delegate", + "path": "child-opt-in-stack-with-assume-role-region/delegate", + "children": { + "cross-account-zone-delegation-handler-role": { + "id": "cross-account-zone-delegation-handler-role", + "path": "child-opt-in-stack-with-assume-role-region/delegate/cross-account-zone-delegation-handler-role", + "children": { + "PolicychildoptinstackwithassumeroleregiondelegatecrossaccountzonedelegationhandlerroleA822DAE1": { + "id": "PolicychildoptinstackwithassumeroleregiondelegatecrossaccountzonedelegationhandlerroleA822DAE1", + "path": "child-opt-in-stack-with-assume-role-region/delegate/cross-account-zone-delegation-handler-role/PolicychildoptinstackwithassumeroleregiondelegatecrossaccountzonedelegationhandlerroleA822DAE1", + "children": { + "Resource": { + "id": "Resource", + "path": "child-opt-in-stack-with-assume-role-region/delegate/cross-account-zone-delegation-handler-role/PolicychildoptinstackwithassumeroleregiondelegatecrossaccountzonedelegationhandlerroleA822DAE1/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": "arn:aws:iam::12345678:role/MyUniqueDelegationRole" + } + ], + "Version": "2012-10-17" + }, + "policyName": "PolicychildoptinstackwithassumeroleregiondelegatecrossaccountzonedelegationhandlerroleA822DAE1", + "roles": [ + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "/", + { + "Fn::Select": [ + 5, + { + "Fn::Split": [ + ":", + { + "Fn::GetAtt": [ + "CustomCrossAccountZoneDelegationCustomResourceProviderRoleED64687B", + "Arn" + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "CrossAccountZoneDelegationCustomResource": { + "id": "CrossAccountZoneDelegationCustomResource", + "path": "child-opt-in-stack-with-assume-role-region/delegate/CrossAccountZoneDelegationCustomResource", + "children": { + "Default": { + "id": "Default", + "path": "child-opt-in-stack-with-assume-role-region/delegate/CrossAccountZoneDelegationCustomResource/Default", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.CustomResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_route53.CrossAccountZoneDelegationRecord", + "version": "0.0.0" + } + }, + "Custom::CrossAccountZoneDelegationCustomResourceProvider": { + "id": "Custom::CrossAccountZoneDelegationCustomResourceProvider", + "path": "child-opt-in-stack-with-assume-role-region/Custom::CrossAccountZoneDelegationCustomResourceProvider", + "children": { + "Staging": { + "id": "Staging", + "path": "child-opt-in-stack-with-assume-role-region/Custom::CrossAccountZoneDelegationCustomResourceProvider/Staging", + "constructInfo": { + "fqn": "aws-cdk-lib.AssetStaging", + "version": "0.0.0" + } + }, + "Role": { + "id": "Role", + "path": "child-opt-in-stack-with-assume-role-region/Custom::CrossAccountZoneDelegationCustomResourceProvider/Role", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnResource", + "version": "0.0.0" + } + }, + "Handler": { + "id": "Handler", + "path": "child-opt-in-stack-with-assume-role-region/Custom::CrossAccountZoneDelegationCustomResourceProvider/Handler", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.CustomResourceProviderBase", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "child-opt-in-stack-with-assume-role-region/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "child-opt-in-stack-with-assume-role-region/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, "Route53CrossAccountInteg": { "id": "Route53CrossAccountInteg", "path": "Route53CrossAccountInteg", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.ts index 54ac97f2df5ca..ba50d8afb8cd1 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.ts @@ -39,7 +39,6 @@ const crossAccount = process.env.CDK_INTEG_CROSS_ACCOUNT || '234567890123'; // t const delegationRoleName = 'MyUniqueDelegationRole'; const parentZoneName = 'uniqueexample.com'; -const subZoneName = 'sub.uniqueexample.com'; class ParentStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { @@ -56,12 +55,17 @@ class ParentStack extends cdk.Stack { } } +interface ChildStackProps extends cdk.StackProps { + readonly subZoneName: string; + readonly assumeRoleRegion?: string; +} + class ChildStack extends cdk.Stack { - constructor(scope: Construct, id: string, props?: cdk.StackProps) { + constructor(scope: Construct, id: string, props: ChildStackProps) { super(scope, id, props); const subZone = new route53.PublicHostedZone(this, 'SubZone', { - zoneName: subZoneName, + zoneName: props.subZoneName, }); const delegationRoleArn = cdk.Stack.of(this).formatArn({ @@ -77,6 +81,7 @@ class ChildStack extends cdk.Stack { delegatedZone: subZone, parentHostedZoneName: parentZoneName, delegationRole, + assumeRoleRegion: props.assumeRoleRegion, }); } } @@ -93,6 +98,7 @@ const childStack = new ChildStack(app, 'child-stack', { account: crossAccount, region: 'us-east-1', }, + subZoneName: 'sub.uniqueexample.com', }); const childOptInStack = new ChildStack(app, 'child-opt-in-stack', { @@ -100,12 +106,23 @@ const childOptInStack = new ChildStack(app, 'child-opt-in-stack', { account: crossAccount, region: 'af-south-1', }, + subZoneName: 'sub2.uniqueexample.com', +}); + +const childOptInStackWithAssumeRoleRegion = new ChildStack(app, 'child-opt-in-stack-with-assume-role-region', { + env: { + account: crossAccount, + region: 'af-south-1', + }, + assumeRoleRegion: 'eu-west-1', + subZoneName: 'sub3.uniqueexample.com', }); childStack.addDependency(parentStack); childOptInStack.addDependency(parentStack); +childOptInStackWithAssumeRoleRegion.addDependency(parentStack); new IntegTest(app, 'Route53CrossAccountInteg', { - testCases: [childStack, childOptInStack], + testCases: [childStack, childOptInStack, childOptInStackWithAssumeRoleRegion], diffAssets: true, -}); \ No newline at end of file +}); From 28a1f6b973348aefce3affaeb54a1fd116092a84 Mon Sep 17 00:00:00 2001 From: Nick Aiello Date: Tue, 19 Mar 2024 16:43:21 -0500 Subject: [PATCH 4/9] test: integ test snapshot updates --- .../manifest.json | 5 +- .../__entrypoint__.js | 156 ++++++++++++++++++ .../index.js | 1 + .../child-stack.assets.json | 10 +- .../child-stack.template.json | 2 +- .../manifest.json | 2 +- 6 files changed, 165 insertions(+), 11 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/manifest.json index 16134f7243603..81b6361157711 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/manifest.json @@ -191,10 +191,7 @@ "/child-opt-in-stack/SubZone/Resource": [ { "type": "aws:cdk:logicalId", - "data": "SubZoneF7955E1A", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" - ] + "data": "SubZoneF7955E1A" } ], "/child-opt-in-stack/delegate/cross-account-zone-delegation-handler-role/PolicychildoptinstackdelegatecrossaccountzonedelegationhandlerroleD1C6F26D/Resource": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js new file mode 100644 index 0000000000000..9271364bb7e49 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js @@ -0,0 +1,156 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.withRetries = exports.handler = exports.external = void 0; +const https = require("https"); +const url = require("url"); +// for unit tests +exports.external = { + sendHttpRequest: defaultSendHttpRequest, + log: defaultLog, + includeStackTraces: true, + userHandlerIndex: './index', +}; +const CREATE_FAILED_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::CREATE_FAILED'; +const MISSING_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID'; +async function handler(event, context) { + const sanitizedEvent = { ...event, ResponseURL: '...' }; + exports.external.log(JSON.stringify(sanitizedEvent, undefined, 2)); + // ignore DELETE event when the physical resource ID is the marker that + // indicates that this DELETE is a subsequent DELETE to a failed CREATE + // operation. + if (event.RequestType === 'Delete' && event.PhysicalResourceId === CREATE_FAILED_PHYSICAL_ID_MARKER) { + exports.external.log('ignoring DELETE event caused by a failed CREATE event'); + await submitResponse('SUCCESS', event); + return; + } + try { + // invoke the user handler. this is intentionally inside the try-catch to + // ensure that if there is an error it's reported as a failure to + // cloudformation (otherwise cfn waits). + // eslint-disable-next-line @typescript-eslint/no-require-imports + const userHandler = require(exports.external.userHandlerIndex).handler; + const result = await userHandler(sanitizedEvent, context); + // validate user response and create the combined event + const responseEvent = renderResponse(event, result); + // submit to cfn as success + await submitResponse('SUCCESS', responseEvent); + } + catch (e) { + const resp = { + ...event, + Reason: exports.external.includeStackTraces ? e.stack : e.message, + }; + if (!resp.PhysicalResourceId) { + // special case: if CREATE fails, which usually implies, we usually don't + // have a physical resource id. in this case, the subsequent DELETE + // operation does not have any meaning, and will likely fail as well. to + // address this, we use a marker so the provider framework can simply + // ignore the subsequent DELETE. + if (event.RequestType === 'Create') { + exports.external.log('CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored'); + resp.PhysicalResourceId = CREATE_FAILED_PHYSICAL_ID_MARKER; + } + else { + // otherwise, if PhysicalResourceId is not specified, something is + // terribly wrong because all other events should have an ID. + exports.external.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(event)}`); + } + } + // this is an actual error, fail the activity altogether and exist. + await submitResponse('FAILED', resp); + } +} +exports.handler = handler; +function renderResponse(cfnRequest, handlerResponse = {}) { + // if physical ID is not returned, we have some defaults for you based + // on the request type. + const physicalResourceId = handlerResponse.PhysicalResourceId ?? cfnRequest.PhysicalResourceId ?? cfnRequest.RequestId; + // if we are in DELETE and physical ID was changed, it's an error. + if (cfnRequest.RequestType === 'Delete' && physicalResourceId !== cfnRequest.PhysicalResourceId) { + throw new Error(`DELETE: cannot change the physical resource ID from "${cfnRequest.PhysicalResourceId}" to "${handlerResponse.PhysicalResourceId}" during deletion`); + } + // merge request event and result event (result prevails). + return { + ...cfnRequest, + ...handlerResponse, + PhysicalResourceId: physicalResourceId, + }; +} +async function submitResponse(status, event) { + const json = { + Status: status, + Reason: event.Reason ?? status, + StackId: event.StackId, + RequestId: event.RequestId, + PhysicalResourceId: event.PhysicalResourceId || MISSING_PHYSICAL_ID_MARKER, + LogicalResourceId: event.LogicalResourceId, + NoEcho: event.NoEcho, + Data: event.Data, + }; + const parsedUrl = url.parse(event.ResponseURL); + const loggingSafeUrl = `${parsedUrl.protocol}//${parsedUrl.hostname}/${parsedUrl.pathname}?***`; + exports.external.log('submit response to cloudformation', loggingSafeUrl, json); + const responseBody = JSON.stringify(json); + const req = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: 'PUT', + headers: { + 'content-type': '', + 'content-length': Buffer.byteLength(responseBody, 'utf8'), + }, + }; + const retryOptions = { + attempts: 5, + sleep: 1000, + }; + await withRetries(retryOptions, exports.external.sendHttpRequest)(req, responseBody); +} +async function defaultSendHttpRequest(options, requestBody) { + return new Promise((resolve, reject) => { + try { + const request = https.request(options, (response) => { + response.resume(); // Consume the response but don't care about it + if (!response.statusCode || response.statusCode >= 400) { + reject(new Error(`Unsuccessful HTTP response: ${response.statusCode}`)); + } + else { + resolve(); + } + }); + request.on('error', reject); + request.write(requestBody); + request.end(); + } + catch (e) { + reject(e); + } + }); +} +function defaultLog(fmt, ...params) { + // eslint-disable-next-line no-console + console.log(fmt, ...params); +} +function withRetries(options, fn) { + return async (...xs) => { + let attempts = options.attempts; + let ms = options.sleep; + while (true) { + try { + return await fn(...xs); + } + catch (e) { + if (attempts-- <= 0) { + throw e; + } + await sleep(Math.floor(Math.random() * ms)); + ms *= 2; + } + } + }; +} +exports.withRetries = withRetries; +async function sleep(ms) { + return new Promise((ok) => setTimeout(ok, ms)); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsMkJBQTJCO0FBRTNCLGlCQUFpQjtBQUNKLFFBQUEsUUFBUSxHQUFHO0lBQ3RCLGVBQWUsRUFBRSxzQkFBc0I7SUFDdkMsR0FBRyxFQUFFLFVBQVU7SUFDZixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGdCQUFnQixFQUFFLFNBQVM7Q0FDNUIsQ0FBQztBQUVGLE1BQU0sZ0NBQWdDLEdBQUcsd0RBQXdELENBQUM7QUFDbEcsTUFBTSwwQkFBMEIsR0FBRyw4REFBOEQsQ0FBQztBQVczRixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDeEQsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFM0QsdUVBQXVFO0lBQ3ZFLHVFQUF1RTtJQUN2RSxhQUFhO0lBQ2IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEtBQUssZ0NBQWdDLEVBQUU7UUFDbkcsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN0RSxNQUFNLGNBQWMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkMsT0FBTztLQUNSO0lBRUQsSUFBSTtRQUNGLHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsd0NBQXdDO1FBQ3hDLGlFQUFpRTtRQUNqRSxNQUFNLFdBQVcsR0FBWSxPQUFPLENBQUMsZ0JBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4RSxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FB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bXBvcnQgKiBhcyBodHRwcyBmcm9tICdodHRwcyc7XG5pbXBvcnQgKiBhcyB1cmwgZnJvbSAndXJsJztcblxuLy8gZm9yIHVuaXQgdGVzdHNcbmV4cG9ydCBjb25zdCBleHRlcm5hbCA9IHtcbiAgc2VuZEh0dHBSZXF1ZXN0OiBkZWZhdWx0U2VuZEh0dHBSZXF1ZXN0LFxuICBsb2c6IGRlZmF1bHRMb2csXG4gIGluY2x1ZGVTdGFja1RyYWNlczogdHJ1ZSxcbiAgdXNlckhhbmRsZXJJbmRleDogJy4vaW5kZXgnLFxufTtcblxuY29uc3QgQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVIgPSAnQVdTQ0RLOjpDdXN0b21SZXNvdXJjZVByb3ZpZGVyRnJhbWV3b3JrOjpDUkVBVEVfRkFJTEVEJztcbmNvbnN0IE1JU1NJTkdfUEhZU0lDQUxfSURfTUFSS0VSID0gJ0FXU0NESzo6Q3VzdG9tUmVzb3VyY2VQcm92aWRlckZyYW1ld29yazo6TUlTU0lOR19QSFlTSUNBTF9JRCc7XG5cbmV4cG9ydCB0eXBlIFJlc3BvbnNlID0gQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIEhhbmRsZXJSZXNwb25zZTtcbmV4cG9ydCB0eXBlIEhhbmRsZXIgPSAoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSA9PiBQcm9taXNlPEhhbmRsZXJSZXNwb25zZSB8IHZvaWQ+O1xuZXhwb3J0IHR5cGUgSGFuZGxlclJlc3BvbnNlID0gdW5kZWZpbmVkIHwge1xuICBEYXRhPzogYW55O1xuICBQaHlzaWNhbFJlc291cmNlSWQ/OiBzdHJpbmc7XG4gIFJlYXNvbj86IHN0cmluZztcbiAgTm9FY2hvPzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50LCBjb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dCkge1xuICBjb25zdCBzYW5pdGl6ZWRFdmVudCA9IHsgLi4uZXZlbnQsIFJlc3BvbnNlVVJMOiAnLi4uJyB9O1xuICBleHRlcm5hbC5sb2coSlNPTi5zdHJpbmdpZnkoc2FuaXRpemVkRXZlbnQsIHVuZGVmaW5lZCwgMikpO1xuXG4gIC8vIGlnbm9yZSBERUxFVEUgZXZlbnQgd2hlbiB0aGUgcGh5c2ljYWwgcmVzb3VyY2UgSUQgaXMgdGhlIG1hcmtlciB0aGF0XG4gIC8vIGluZGljYXRlcyB0aGF0IHRoaXMgREVMRVRFIGlzIGEgc3Vic2VxdWVudCBERUxFVEUgdG8gYSBmYWlsZWQgQ1JFQVRFXG4gIC8vIG9wZXJhdGlvbi5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgPT09IENSRUFURV9GQUlMRURfUEhZU0lDQUxfSURfTUFSS0VSKSB7XG4gICAgZXh0ZXJuYWwubG9nKCdpZ25vcmluZyBERUxFVEUgZXZlbnQgY2F1c2VkIGJ5IGEgZmFpbGVkIENSRUFURSBldmVudCcpO1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgZXZlbnQpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgLy8gaW52b2tlIHRoZSB1c2VyIGhhbmRsZXIuIHRoaXMgaXMgaW50ZW50aW9uYWxseSBpbnNpZGUgdGhlIHRyeS1jYXRjaCB0b1xuICAgIC8vIGVuc3VyZSB0aGF0IGlmIHRoZXJlIGlzIGFuIGVycm9yIGl0J3MgcmVwb3J0ZWQgYXMgYSBmYWlsdXJlIHRvXG4gICAgLy8gY2xvdWRmb3JtYXRpb24gKG90aGVyd2lzZSBjZm4gd2FpdHMpLlxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3QgdXNlckhhbmRsZXI6IEhhbmRsZXIgPSByZXF1aXJlKGV4dGVybmFsLnVzZXJIYW5kbGVySW5kZXgpLmhhbmRsZXI7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdXNlckhhbmRsZXIoc2FuaXRpemVkRXZlbnQsIGNvbnRleHQpO1xuXG4gICAgLy8gdmFsaWRhdGUgdXNlciByZXNwb25zZSBhbmQgY3JlYXRlIHRoZSBjb21iaW5lZCBldmVudFxuICAgIGNvbnN0IHJlc3BvbnNlRXZlbnQgPSByZW5kZXJSZXNwb25zZShldmVudCwgcmVzdWx0KTtcblxuICAgIC8vIHN1Ym1pdCB0byBjZm4gYXMgc3VjY2Vzc1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgcmVzcG9uc2VFdmVudCk7XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGNvbnN0IHJlc3A6IFJlc3BvbnNlID0ge1xuICAgICAgLi4uZXZlbnQsXG4gICAgICBSZWFzb246IGV4dGVybmFsLmluY2x1ZGVTdGFja1RyYWNlcyA/IGUuc3RhY2sgOiBlLm1lc3NhZ2UsXG4gICAgfTtcblxuICAgIGlmICghcmVzcC5QaHlzaWNhbFJlc291cmNlSWQpIHtcbiAgICAgIC8vIHNwZWNpYWwgY2FzZTogaWYgQ1JFQVRFIGZhaWxzLCB3aGljaCB1c3VhbGx5IGltcGxpZXMsIHdlIHVzdWFsbHkgZG9uJ3RcbiAgICAgIC8vIGhhdmUgYSBwaHlzaWNhbCByZXNvdXJjZSBpZC4gaW4gdGhpcyBjYXNlLCB0aGUgc3Vic2VxdWVudCBERUxFVEVcbiAgICAgIC8vIG9wZXJhdGlvbiBkb2VzIG5vdCBoYXZlIGFueSBtZWFuaW5nLCBhbmQgd2lsbCBsaWtlbHkgZmFpbCBhcyB3ZWxsLiB0b1xuICAgICAgLy8gYWRkcmVzcyB0aGlzLCB3ZSB1c2UgYSBtYXJrZXIgc28gdGhlIHByb3ZpZGVyIGZyYW1ld29yayBjYW4gc2ltcGx5XG4gICAgICAvLyBpZ25vcmUgdGhlIHN1YnNlcXVlbnQgREVMRVRFLlxuICAgICAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnQ3JlYXRlJykge1xuICAgICAgICBleHRlcm5hbC5sb2coJ0NSRUFURSBmYWlsZWQsIHJlc3BvbmRpbmcgd2l0aCBhIG1hcmtlciBwaHlzaWNhbCByZXNvdXJjZSBpZCBzbyB0aGF0IHRoZSBzdWJzZXF1ZW50IERFTEVURSB3aWxsIGJlIGlnbm9yZWQnKTtcbiAgICAgICAgcmVzcC5QaHlzaWNhbFJlc291cmNlSWQgPSBDUkVBVEVfRkFJTEVEX1BIWVNJQ0FMX0lEX01BUktFUjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG90aGVyd2lzZSwgaWYgUGh5c2ljYWxSZXNvdXJjZUlkIGlzIG5vdCBzcGVjaWZpZWQsIHNvbWV0aGluZyBpc1xuICAgICAgICAvLyB0ZXJyaWJseSB3cm9uZyBiZWNhdXNlIGFsbCBvdGhlciBldmVudHMgc2hvdWxkIGhhdmUgYW4gSUQuXG4gICAgICAgIGV4dGVybmFsLmxvZyhgRVJST1I6IE1hbGZvcm1lZCBldmVudC4gXCJQaHlzaWNhbFJlc291cmNlSWRcIiBpcyByZXF1aXJlZDogJHtKU09OLnN0cmluZ2lmeShldmVudCl9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdGhpcyBpcyBhbiBhY3R1YWwgZXJyb3IsIGZhaWwgdGhlIGFjdGl2aXR5IGFsdG9nZXRoZXIgYW5kIGV4aXN0LlxuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdGQUlMRUQnLCByZXNwKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW5kZXJSZXNwb25zZShcbiAgY2ZuUmVxdWVzdDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIHsgUGh5c2ljYWxSZXNvdXJjZUlkPzogc3RyaW5nIH0sXG4gIGhhbmRsZXJSZXNwb25zZTogdm9pZCB8IEhhbmRsZXJSZXNwb25zZSA9IHsgfSk6IFJlc3BvbnNlIHtcblxuICAvLyBpZiBwaHlzaWNhbCBJRCBpcyBub3QgcmV0dXJuZWQsIHdlIGhhdmUgc29tZSBkZWZhdWx0cyBmb3IgeW91IGJhc2VkXG4gIC8vIG9uIHRoZSByZXF1ZXN0IHR5cGUuXG4gIGNvbnN0IHBoeXNpY2FsUmVzb3VyY2VJZCA9IGhhbmRsZXJSZXNwb25zZS5QaHlzaWNhbFJlc291cmNlSWQgPz8gY2ZuUmVxdWVzdC5QaHlzaWNhbFJlc291cmNlSWQgPz8gY2ZuUmVxdWVzdC5SZXF1ZXN0SWQ7XG5cbiAgLy8gaWYgd2UgYXJlIGluIERFTEVURSBhbmQgcGh5c2ljYWwgSUQgd2FzIGNoYW5nZWQsIGl0J3MgYW4gZXJyb3IuXG4gIGlmIChjZm5SZXF1ZXN0LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBwaHlzaWNhbFJlc291cmNlSWQgIT09IGNmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBERUxFVEU6IGNhbm5vdCBjaGFuZ2UgdGhlIHBoeXNpY2FsIHJlc291cmNlIElEIGZyb20gXCIke2NmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkfVwiIHRvIFwiJHtoYW5kbGVyUmVzcG9uc2UuUGh5c2ljYWxSZXNvdXJjZUlkfVwiIGR1cmluZyBkZWxldGlvbmApO1xuICB9XG5cbiAgLy8gbWVyZ2UgcmVxdWVzdCBldmVudCBhbmQgcmVzdWx0IGV2ZW50IChyZXN1bHQgcHJldmFpbHMpLlxuICByZXR1cm4ge1xuICAgIC4uLmNmblJlcXVlc3QsXG4gICAgLi4uaGFuZGxlclJlc3BvbnNlLFxuICAgIFBoeXNpY2FsUmVzb3VyY2VJZDogcGh5c2ljYWxSZXNvdXJjZUlkLFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzdWJtaXRSZXNwb25zZShzdGF0dXM6ICdTVUNDRVNTJyB8ICdGQUlMRUQnLCBldmVudDogUmVzcG9uc2UpIHtcbiAgY29uc3QganNvbjogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VSZXNwb25zZSA9IHtcbiAgICBTdGF0dXM6IHN0YXR1cyxcbiAgICBSZWFzb246IGV2ZW50LlJlYXNvbiA/PyBzdGF0dXMsXG4gICAgU3RhY2tJZDogZXZlbnQuU3RhY2tJZCxcbiAgICBSZXF1ZXN0SWQ6IGV2ZW50LlJlcXVlc3RJZCxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCB8fCBNSVNTSU5HX1BIWVNJQ0FMX0lEX01BUktFUixcbiAgICBMb2dpY2FsUmVzb3VyY2VJZDogZXZlbnQuTG9naWNhbFJlc291cmNlSWQsXG4gICAgTm9FY2hvOiBldmVudC5Ob0VjaG8sXG4gICAgRGF0YTogZXZlbnQuRGF0YSxcbiAgfTtcblxuICBjb25zdCBwYXJzZWRVcmwgPSB1cmwucGFyc2UoZXZlbnQuUmVzcG9uc2VVUkwpO1xuICBjb25zdCBsb2dnaW5nU2FmZVVybCA9IGAke3BhcnNlZFVybC5wcm90b2NvbH0vLyR7cGFyc2VkVXJsLmhvc3RuYW1lfS8ke3BhcnNlZFVybC5wYXRobmFtZX0/KioqYDtcbiAgZXh0ZXJuYWwubG9nKCdzdWJtaXQgcmVzcG9uc2UgdG8gY2xvdWRmb3JtYXRpb24nLCBsb2dnaW5nU2FmZVVybCwganNvbik7XG5cbiAgY29uc3QgcmVzcG9uc2VCb2R5ID0gSlNPTi5zdHJpbmdpZnkoanNvbik7XG4gIGNvbnN0IHJlcSA9IHtcbiAgICBob3N0bmFtZTogcGFyc2VkVXJsLmhvc3RuYW1lLFxuICAgIHBhdGg6IHBhcnNlZFVybC5wYXRoLFxuICAgIG1ldGhvZDogJ1BVVCcsXG4gICAgaGVhZGVyczoge1xuICAgICAgJ2NvbnRlbnQtdHlwZSc6ICcnLFxuICAgICAgJ2NvbnRlbnQtbGVuZ3RoJzogQnVmZmVyLmJ5dGVMZW5ndGgocmVzcG9uc2VCb2R5LCAndXRmOCcpLFxuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgcmV0cnlPcHRpb25zID0ge1xuICAgIGF0dGVtcHRzOiA1LFxuICAgIHNsZWVwOiAxMDAwLFxuICB9O1xuICBhd2FpdCB3aXRoUmV0cmllcyhyZXRyeU9wdGlvbnMsIGV4dGVybmFsLnNlbmRIdHRwUmVxdWVzdCkocmVxLCByZXNwb25zZUJvZHkpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBkZWZhdWx0U2VuZEh0dHBSZXF1ZXN0KG9wdGlvbnM6IGh0dHBzLlJlcXVlc3RPcHRpb25zLCByZXF1ZXN0Qm9keTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBodHRwcy5yZXF1ZXN0KG9wdGlvbnMsIChyZXNwb25zZSkgPT4ge1xuICAgICAgICByZXNwb25zZS5yZXN1bWUoKTsgLy8gQ29uc3VtZSB0aGUgcmVzcG9uc2UgYnV0IGRvbid0IGNhcmUgYWJvdXQgaXRcbiAgICAgICAgaWYgKCFyZXNwb25zZS5zdGF0dXNDb2RlIHx8IHJlc3BvbnNlLnN0YXR1c0NvZGUgPj0gNDAwKSB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgVW5zdWNjZXNzZnVsIEhUVFAgcmVzcG9uc2U6ICR7cmVzcG9uc2Uuc3RhdHVzQ29kZX1gKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJlcXVlc3Qub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgICAgIHJlcXVlc3Qud3JpdGUocmVxdWVzdEJvZHkpO1xuICAgICAgcmVxdWVzdC5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZSk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdExvZyhmbXQ6IHN0cmluZywgLi4ucGFyYW1zOiBhbnlbXSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLmxvZyhmbXQsIC4uLnBhcmFtcyk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmV0cnlPcHRpb25zIHtcbiAgLyoqIEhvdyBtYW55IHJldHJpZXMgKHdpbGwgYXQgbGVhc3QgdHJ5IG9uY2UpICovXG4gIHJlYWRvbmx5IGF0dGVtcHRzOiBudW1iZXI7XG4gIC8qKiBTbGVlcCBiYXNlLCBpbiBtcyAqL1xuICByZWFkb25seSBzbGVlcDogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aFJldHJpZXM8QSBleHRlbmRzIEFycmF5PGFueT4sIEI+KG9wdGlvbnM6IFJldHJ5T3B0aW9ucywgZm46ICguLi54czogQSkgPT4gUHJvbWlzZTxCPik6ICguLi54czogQSkgPT4gUHJvbWlzZTxCPiB7XG4gIHJldHVybiBhc3luYyAoLi4ueHM6IEEpID0+IHtcbiAgICBsZXQgYXR0ZW1wdHMgPSBvcHRpb25zLmF0dGVtcHRzO1xuICAgIGxldCBtcyA9IG9wdGlvbnMuc2xlZXA7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmbiguLi54cyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChhdHRlbXB0cy0tIDw9IDApIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHNsZWVwKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIG1zKSk7XG4gICAgICAgIG1zICo9IDI7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgob2spID0+IHNldFRpbWVvdXQob2ssIG1zKSk7XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js new file mode 100644 index 0000000000000..fc8189b0bbb1d --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js @@ -0,0 +1 @@ +"use strict";var a=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var h=(o,e)=>{for(var r in e)a(o,r,{get:e[r],enumerable:!0})},E=(o,e,r,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of N(e))!P.call(o,n)&&n!==r&&a(o,n,{get:()=>e[n],enumerable:!(t=Z(e,n))||t.enumerable});return o};var A=o=>E(a({},"__esModule",{value:!0}),o);var v={};h(v,{handler:()=>D});module.exports=A(v);var c=require("@aws-sdk/client-route-53"),u=require("@aws-sdk/credential-providers");async function D(o){let e=o.ResourceProperties;switch(o.RequestType){case"Create":return s(e,!1);case"Update":return w(e,o.OldResourceProperties);case"Delete":return s(e,!0)}}async function w(o,e){e&&o.DelegatedZoneName!==e.DelegatedZoneName&&await s(e,!0),await s(o,!1)}async function s(o,e){let{AssumeRoleArn:r,ParentZoneId:t,ParentZoneName:n,DelegatedZoneName:m,DelegatedZoneNameServers:d,TTL:g,AssumeRoleRegion:R}=o;if(!t&&!n)throw Error("One of ParentZoneId or ParentZoneName must be specified");let l=new Date().getTime(),i=new c.Route53({credentials:(0,u.fromTemporaryCredentials)({clientConfig:{region:R??T(process.env.AWS_REGION??process.env.AWS_DEFAULT_REGION??"")},params:{RoleArn:r,RoleSessionName:`cross-account-zone-delegation-${l}`}})}),p=t??await S(n,i);await i.changeResourceRecordSets({HostedZoneId:p,ChangeBatch:{Changes:[{Action:e?"DELETE":"UPSERT",ResourceRecordSet:{Name:m,Type:"NS",TTL:g,ResourceRecords:d.map(f=>({Value:f}))}}]}})}async function S(o,e){let t=(await e.listHostedZonesByName({DNSName:o})).HostedZones?.filter(n=>n.Name===`${o}.`)??[];if(t&&t.length!==1)throw Error(`Expected one hosted zone to match the given name but found ${t.length}`);return t[0].Id}function T(o){let e={cn:"cn-northwest-1","us-gov":"us-gov-west-1","us-iso":"us-iso-east-1","us-isob":"us-isob-east-1"};for(let[r,t]of Object.entries(e))if(o.startsWith(`${r}-`))return t;return"us-east-1"}0&&(module.exports={handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.assets.json index 9f17e5a71f2d7..3e5377c0386c0 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.assets.json @@ -1,21 +1,21 @@ { "version": "36.0.0", "files": { - "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a": { + "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a": { "source": { - "path": "asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a", + "path": "asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a", "packaging": "zip" }, "destinations": { "234567890123-us-east-1": { "bucketName": "cdk-hnb659fds-assets-234567890123-us-east-1", - "objectKey": "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a.zip", + "objectKey": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip", "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-us-east-1" } } }, - "29bfebfb05b102586faa0f38d585a3aea3433366ba19f4b7f213dbc46a9e7544": { + "d402e439418fde6a5f1b138f07ab2b71e78ff60664359406393938a25d687253": { "source": { "path": "child-stack.template.json", "packaging": "file" @@ -23,7 +23,7 @@ "destinations": { "234567890123-us-east-1": { "bucketName": "cdk-hnb659fds-assets-234567890123-us-east-1", - "objectKey": "29bfebfb05b102586faa0f38d585a3aea3433366ba19f4b7f213dbc46a9e7544.json", + "objectKey": "d402e439418fde6a5f1b138f07ab2b71e78ff60664359406393938a25d687253.json", "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-us-east-1" } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.template.json index b510dd3a2b69f..5c601cd8c1aa4 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.template.json @@ -103,7 +103,7 @@ "Properties": { "Code": { "S3Bucket": "cdk-hnb659fds-assets-234567890123-us-east-1", - "S3Key": "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a.zip" + "S3Key": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/manifest.json index b5cc97c012268..a4e6019b060c7 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/manifest.json @@ -84,7 +84,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-deploy-role-234567890123-us-east-1", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-cfn-exec-role-234567890123-us-east-1", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-us-east-1/29bfebfb05b102586faa0f38d585a3aea3433366ba19f4b7f213dbc46a9e7544.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-us-east-1/d402e439418fde6a5f1b138f07ab2b71e78ff60664359406393938a25d687253.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ From b8f94d24e9862ebdd3336a076af439efed0736ab Mon Sep 17 00:00:00 2001 From: Nick Aiello Date: Tue, 19 Mar 2024 17:29:43 -0500 Subject: [PATCH 5/9] chore: update README --- packages/aws-cdk-lib/aws-route53/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/aws-cdk-lib/aws-route53/README.md b/packages/aws-cdk-lib/aws-route53/README.md index 56fe5bcc9204b..09298340c472d 100644 --- a/packages/aws-cdk-lib/aws-route53/README.md +++ b/packages/aws-cdk-lib/aws-route53/README.md @@ -312,6 +312,20 @@ are opted-in. By default, this region is determined automatically, but if you ne change the region used for the AssumeRole call, specify `assumeRoleRegion`: ```ts +const subZone = new route53.PublicHostedZone(this, 'SubZone', { + zoneName: 'sub.someexample.com', +}); + +// import the delegation role by constructing the roleArn +const delegationRoleArn = Stack.of(this).formatArn({ + region: '', // IAM is global in each partition + service: 'iam', + account: 'parent-account-id', + resource: 'role', + resourceName: 'MyDelegationRole', +}); +const delegationRole = iam.Role.fromRoleArn(this, 'DelegationRole', delegationRoleArn); + new route53.CrossAccountZoneDelegationRecord(this, 'delegate', { delegatedZone: subZone, parentHostedZoneName: 'someexample.com', // or you can use parentHostedZoneId From 3b55091a5f3f7c1448ee8cdafcd237a2e016b713 Mon Sep 17 00:00:00 2001 From: Nick Aiello Date: Fri, 22 Mar 2024 18:41:13 -0500 Subject: [PATCH 6/9] test: update cross-account-zone-delegation integ test --- .../index.js | 1 - .../__entrypoint__.js | 156 ------------------ .../index.js | 1 - .../__entrypoint__.js | 0 .../index.js | 1 + ...-stack-with-assume-role-region.assets.json | 10 +- ...tack-with-assume-role-region.template.json | 2 +- .../child-opt-in-stack.assets.json | 28 +--- .../child-opt-in-stack.template.json | 6 +- .../child-stack.assets.json | 28 +--- .../child-stack.template.json | 6 +- .../manifest.json | 14 +- 12 files changed, 22 insertions(+), 231 deletions(-) delete mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a/index.js delete mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js delete mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js rename packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/{asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a => asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458}/__entrypoint__.js (100%) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458/index.js diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a/index.js deleted file mode 100644 index d69c0934f88d4..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a/index.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var Z=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var h=(o,e)=>{for(var s in e)a(o,s,{get:e[s],enumerable:!0})},P=(o,e,s,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Z(e))!N.call(o,n)&&n!==s&&a(o,n,{get:()=>e[n],enumerable:!(t=p(e,n))||t.enumerable});return o};var E=o=>P(a({},"__esModule",{value:!0}),o);var T={};h(T,{handler:()=>w});module.exports=E(T);var c=require("@aws-sdk/client-route-53"),u=require("@aws-sdk/credential-providers");async function w(o){let e=o.ResourceProperties;switch(o.RequestType){case"Create":return r(e,!1);case"Update":return D(e,o.OldResourceProperties);case"Delete":return r(e,!0)}}async function D(o,e){e&&o.DelegatedZoneName!==e.DelegatedZoneName&&await r(e,!0),await r(o,!1)}async function r(o,e){let{AssumeRoleArn:s,ParentZoneId:t,ParentZoneName:n,DelegatedZoneName:d,DelegatedZoneNameServers:m,TTL:g}=o;if(!t&&!n)throw Error("One of ParentZoneId or ParentZoneName must be specified");let l=new Date().getTime(),i=new c.Route53({credentials:(0,u.fromTemporaryCredentials)({clientConfig:{region:S(process.env.AWS_REGION??process.env.AWS_DEFAULT_REGION??"")},params:{RoleArn:s,RoleSessionName:`cross-account-zone-delegation-${l}`}})}),R=t??await A(n,i);await i.changeResourceRecordSets({HostedZoneId:R,ChangeBatch:{Changes:[{Action:e?"DELETE":"UPSERT",ResourceRecordSet:{Name:d,Type:"NS",TTL:g,ResourceRecords:m.map(f=>({Value:f}))}}]}})}async function A(o,e){let t=(await e.listHostedZonesByName({DNSName:o})).HostedZones?.filter(n=>n.Name===`${o}.`)??[];if(t&&t.length!==1)throw Error(`Expected one hosted zone to match the given name but found ${t.length}`);return t[0].Id}function S(o){let e={cn:"cn-northwest-1","us-gov":"us-gov-west-1","us-iso":"us-iso-east-1","us-isob":"us-isob-east-1","eu-isoe":"eu-isoe-west-1","us-isof":"us-isof-south-1"};for(let[s,t]of Object.entries(e))if(o.startsWith(`${s}-`))return t;return"us-east-1"}0&&(module.exports={handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js deleted file mode 100644 index 9271364bb7e49..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js +++ /dev/null @@ -1,156 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.withRetries = exports.handler = exports.external = void 0; -const https = require("https"); -const url = require("url"); -// for unit tests -exports.external = { - sendHttpRequest: defaultSendHttpRequest, - log: defaultLog, - includeStackTraces: true, - userHandlerIndex: './index', -}; -const CREATE_FAILED_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::CREATE_FAILED'; -const MISSING_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID'; -async function handler(event, context) { - const sanitizedEvent = { ...event, ResponseURL: '...' }; - exports.external.log(JSON.stringify(sanitizedEvent, undefined, 2)); - // ignore DELETE event when the physical resource ID is the marker that - // indicates that this DELETE is a subsequent DELETE to a failed CREATE - // operation. - if (event.RequestType === 'Delete' && event.PhysicalResourceId === CREATE_FAILED_PHYSICAL_ID_MARKER) { - exports.external.log('ignoring DELETE event caused by a failed CREATE event'); - await submitResponse('SUCCESS', event); - return; - } - try { - // invoke the user handler. this is intentionally inside the try-catch to - // ensure that if there is an error it's reported as a failure to - // cloudformation (otherwise cfn waits). - // eslint-disable-next-line @typescript-eslint/no-require-imports - const userHandler = require(exports.external.userHandlerIndex).handler; - const result = await userHandler(sanitizedEvent, context); - // validate user response and create the combined event - const responseEvent = renderResponse(event, result); - // submit to cfn as success - await submitResponse('SUCCESS', responseEvent); - } - catch (e) { - const resp = { - ...event, - Reason: exports.external.includeStackTraces ? e.stack : e.message, - }; - if (!resp.PhysicalResourceId) { - // special case: if CREATE fails, which usually implies, we usually don't - // have a physical resource id. in this case, the subsequent DELETE - // operation does not have any meaning, and will likely fail as well. to - // address this, we use a marker so the provider framework can simply - // ignore the subsequent DELETE. - if (event.RequestType === 'Create') { - exports.external.log('CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored'); - resp.PhysicalResourceId = CREATE_FAILED_PHYSICAL_ID_MARKER; - } - else { - // otherwise, if PhysicalResourceId is not specified, something is - // terribly wrong because all other events should have an ID. - exports.external.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(event)}`); - } - } - // this is an actual error, fail the activity altogether and exist. - await submitResponse('FAILED', resp); - } -} -exports.handler = handler; -function renderResponse(cfnRequest, handlerResponse = {}) { - // if physical ID is not returned, we have some defaults for you based - // on the request type. - const physicalResourceId = handlerResponse.PhysicalResourceId ?? cfnRequest.PhysicalResourceId ?? cfnRequest.RequestId; - // if we are in DELETE and physical ID was changed, it's an error. - if (cfnRequest.RequestType === 'Delete' && physicalResourceId !== cfnRequest.PhysicalResourceId) { - throw new Error(`DELETE: cannot change the physical resource ID from "${cfnRequest.PhysicalResourceId}" to "${handlerResponse.PhysicalResourceId}" during deletion`); - } - // merge request event and result event (result prevails). - return { - ...cfnRequest, - ...handlerResponse, - PhysicalResourceId: physicalResourceId, - }; -} -async function submitResponse(status, event) { - const json = { - Status: status, - Reason: event.Reason ?? status, - StackId: event.StackId, - RequestId: event.RequestId, - PhysicalResourceId: event.PhysicalResourceId || MISSING_PHYSICAL_ID_MARKER, - LogicalResourceId: event.LogicalResourceId, - NoEcho: event.NoEcho, - Data: event.Data, - }; - const parsedUrl = url.parse(event.ResponseURL); - const loggingSafeUrl = `${parsedUrl.protocol}//${parsedUrl.hostname}/${parsedUrl.pathname}?***`; - exports.external.log('submit response to cloudformation', loggingSafeUrl, json); - const responseBody = JSON.stringify(json); - const req = { - hostname: parsedUrl.hostname, - path: parsedUrl.path, - method: 'PUT', - headers: { - 'content-type': '', - 'content-length': Buffer.byteLength(responseBody, 'utf8'), - }, - }; - const retryOptions = { - attempts: 5, - sleep: 1000, - }; - await withRetries(retryOptions, exports.external.sendHttpRequest)(req, responseBody); -} -async function defaultSendHttpRequest(options, requestBody) { - return new Promise((resolve, reject) => { - try { - const request = https.request(options, (response) => { - response.resume(); // Consume the response but don't care about it - if (!response.statusCode || response.statusCode >= 400) { - reject(new Error(`Unsuccessful HTTP response: ${response.statusCode}`)); - } - else { - resolve(); - } - }); - request.on('error', reject); - request.write(requestBody); - request.end(); - } - catch (e) { - reject(e); - } - }); -} -function defaultLog(fmt, ...params) { - // eslint-disable-next-line no-console - console.log(fmt, ...params); -} -function withRetries(options, fn) { - return async (...xs) => { - let attempts = options.attempts; - let ms = options.sleep; - while (true) { - try { - return await fn(...xs); - } - catch (e) { - if (attempts-- <= 0) { - throw e; - } - await sleep(Math.floor(Math.random() * ms)); - ms *= 2; - } - } - }; -} -exports.withRetries = withRetries; -async function sleep(ms) { - return new Promise((ok) => setTimeout(ok, ms)); -} -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsMkJBQTJCO0FBRTNCLGlCQUFpQjtBQUNKLFFBQUEsUUFBUSxHQUFHO0lBQ3RCLGVBQWUsRUFBRSxzQkFBc0I7SUFDdkMsR0FBRyxFQUFFLFVBQVU7SUFDZixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGdCQUFnQixFQUFFLFNBQVM7Q0FDNUIsQ0FBQztBQUVGLE1BQU0sZ0NBQWdDLEdBQUcsd0RBQXdELENBQUM7QUFDbEcsTUFBTSwwQkFBMEIsR0FBRyw4REFBOEQsQ0FBQztBQVczRixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDeEQsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFM0QsdUVBQXVFO0lBQ3ZFLHVFQUF1RTtJQUN2RSxhQUFhO0lBQ2IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEtBQUssZ0NBQWdDLEVBQUU7UUFDbkcsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN0RSxNQUFNLGNBQWMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkMsT0FBTztLQUNSO0lBRUQsSUFBSTtRQUNGLHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsd0NBQXdDO1FBQ3hDLGlFQUFpRTtRQUNqRSxNQUFNLFdBQVcsR0FBWSxPQUFPLENBQUMsZ0JBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4RSxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FB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bXBvcnQgKiBhcyBodHRwcyBmcm9tICdodHRwcyc7XG5pbXBvcnQgKiBhcyB1cmwgZnJvbSAndXJsJztcblxuLy8gZm9yIHVuaXQgdGVzdHNcbmV4cG9ydCBjb25zdCBleHRlcm5hbCA9IHtcbiAgc2VuZEh0dHBSZXF1ZXN0OiBkZWZhdWx0U2VuZEh0dHBSZXF1ZXN0LFxuICBsb2c6IGRlZmF1bHRMb2csXG4gIGluY2x1ZGVTdGFja1RyYWNlczogdHJ1ZSxcbiAgdXNlckhhbmRsZXJJbmRleDogJy4vaW5kZXgnLFxufTtcblxuY29uc3QgQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVIgPSAnQVdTQ0RLOjpDdXN0b21SZXNvdXJjZVByb3ZpZGVyRnJhbWV3b3JrOjpDUkVBVEVfRkFJTEVEJztcbmNvbnN0IE1JU1NJTkdfUEhZU0lDQUxfSURfTUFSS0VSID0gJ0FXU0NESzo6Q3VzdG9tUmVzb3VyY2VQcm92aWRlckZyYW1ld29yazo6TUlTU0lOR19QSFlTSUNBTF9JRCc7XG5cbmV4cG9ydCB0eXBlIFJlc3BvbnNlID0gQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIEhhbmRsZXJSZXNwb25zZTtcbmV4cG9ydCB0eXBlIEhhbmRsZXIgPSAoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSA9PiBQcm9taXNlPEhhbmRsZXJSZXNwb25zZSB8IHZvaWQ+O1xuZXhwb3J0IHR5cGUgSGFuZGxlclJlc3BvbnNlID0gdW5kZWZpbmVkIHwge1xuICBEYXRhPzogYW55O1xuICBQaHlzaWNhbFJlc291cmNlSWQ/OiBzdHJpbmc7XG4gIFJlYXNvbj86IHN0cmluZztcbiAgTm9FY2hvPzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50LCBjb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dCkge1xuICBjb25zdCBzYW5pdGl6ZWRFdmVudCA9IHsgLi4uZXZlbnQsIFJlc3BvbnNlVVJMOiAnLi4uJyB9O1xuICBleHRlcm5hbC5sb2coSlNPTi5zdHJpbmdpZnkoc2FuaXRpemVkRXZlbnQsIHVuZGVmaW5lZCwgMikpO1xuXG4gIC8vIGlnbm9yZSBERUxFVEUgZXZlbnQgd2hlbiB0aGUgcGh5c2ljYWwgcmVzb3VyY2UgSUQgaXMgdGhlIG1hcmtlciB0aGF0XG4gIC8vIGluZGljYXRlcyB0aGF0IHRoaXMgREVMRVRFIGlzIGEgc3Vic2VxdWVudCBERUxFVEUgdG8gYSBmYWlsZWQgQ1JFQVRFXG4gIC8vIG9wZXJhdGlvbi5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgPT09IENSRUFURV9GQUlMRURfUEhZU0lDQUxfSURfTUFSS0VSKSB7XG4gICAgZXh0ZXJuYWwubG9nKCdpZ25vcmluZyBERUxFVEUgZXZlbnQgY2F1c2VkIGJ5IGEgZmFpbGVkIENSRUFURSBldmVudCcpO1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgZXZlbnQpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgLy8gaW52b2tlIHRoZSB1c2VyIGhhbmRsZXIuIHRoaXMgaXMgaW50ZW50aW9uYWxseSBpbnNpZGUgdGhlIHRyeS1jYXRjaCB0b1xuICAgIC8vIGVuc3VyZSB0aGF0IGlmIHRoZXJlIGlzIGFuIGVycm9yIGl0J3MgcmVwb3J0ZWQgYXMgYSBmYWlsdXJlIHRvXG4gICAgLy8gY2xvdWRmb3JtYXRpb24gKG90aGVyd2lzZSBjZm4gd2FpdHMpLlxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3QgdXNlckhhbmRsZXI6IEhhbmRsZXIgPSByZXF1aXJlKGV4dGVybmFsLnVzZXJIYW5kbGVySW5kZXgpLmhhbmRsZXI7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdXNlckhhbmRsZXIoc2FuaXRpemVkRXZlbnQsIGNvbnRleHQpO1xuXG4gICAgLy8gdmFsaWRhdGUgdXNlciByZXNwb25zZSBhbmQgY3JlYXRlIHRoZSBjb21iaW5lZCBldmVudFxuICAgIGNvbnN0IHJlc3BvbnNlRXZlbnQgPSByZW5kZXJSZXNwb25zZShldmVudCwgcmVzdWx0KTtcblxuICAgIC8vIHN1Ym1pdCB0byBjZm4gYXMgc3VjY2Vzc1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgcmVzcG9uc2VFdmVudCk7XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGNvbnN0IHJlc3A6IFJlc3BvbnNlID0ge1xuICAgICAgLi4uZXZlbnQsXG4gICAgICBSZWFzb246IGV4dGVybmFsLmluY2x1ZGVTdGFja1RyYWNlcyA/IGUuc3RhY2sgOiBlLm1lc3NhZ2UsXG4gICAgfTtcblxuICAgIGlmICghcmVzcC5QaHlzaWNhbFJlc291cmNlSWQpIHtcbiAgICAgIC8vIHNwZWNpYWwgY2FzZTogaWYgQ1JFQVRFIGZhaWxzLCB3aGljaCB1c3VhbGx5IGltcGxpZXMsIHdlIHVzdWFsbHkgZG9uJ3RcbiAgICAgIC8vIGhhdmUgYSBwaHlzaWNhbCByZXNvdXJjZSBpZC4gaW4gdGhpcyBjYXNlLCB0aGUgc3Vic2VxdWVudCBERUxFVEVcbiAgICAgIC8vIG9wZXJhdGlvbiBkb2VzIG5vdCBoYXZlIGFueSBtZWFuaW5nLCBhbmQgd2lsbCBsaWtlbHkgZmFpbCBhcyB3ZWxsLiB0b1xuICAgICAgLy8gYWRkcmVzcyB0aGlzLCB3ZSB1c2UgYSBtYXJrZXIgc28gdGhlIHByb3ZpZGVyIGZyYW1ld29yayBjYW4gc2ltcGx5XG4gICAgICAvLyBpZ25vcmUgdGhlIHN1YnNlcXVlbnQgREVMRVRFLlxuICAgICAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnQ3JlYXRlJykge1xuICAgICAgICBleHRlcm5hbC5sb2coJ0NSRUFURSBmYWlsZWQsIHJlc3BvbmRpbmcgd2l0aCBhIG1hcmtlciBwaHlzaWNhbCByZXNvdXJjZSBpZCBzbyB0aGF0IHRoZSBzdWJzZXF1ZW50IERFTEVURSB3aWxsIGJlIGlnbm9yZWQnKTtcbiAgICAgICAgcmVzcC5QaHlzaWNhbFJlc291cmNlSWQgPSBDUkVBVEVfRkFJTEVEX1BIWVNJQ0FMX0lEX01BUktFUjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG90aGVyd2lzZSwgaWYgUGh5c2ljYWxSZXNvdXJjZUlkIGlzIG5vdCBzcGVjaWZpZWQsIHNvbWV0aGluZyBpc1xuICAgICAgICAvLyB0ZXJyaWJseSB3cm9uZyBiZWNhdXNlIGFsbCBvdGhlciBldmVudHMgc2hvdWxkIGhhdmUgYW4gSUQuXG4gICAgICAgIGV4dGVybmFsLmxvZyhgRVJST1I6IE1hbGZvcm1lZCBldmVudC4gXCJQaHlzaWNhbFJlc291cmNlSWRcIiBpcyByZXF1aXJlZDogJHtKU09OLnN0cmluZ2lmeShldmVudCl9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdGhpcyBpcyBhbiBhY3R1YWwgZXJyb3IsIGZhaWwgdGhlIGFjdGl2aXR5IGFsdG9nZXRoZXIgYW5kIGV4aXN0LlxuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdGQUlMRUQnLCByZXNwKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW5kZXJSZXNwb25zZShcbiAgY2ZuUmVxdWVzdDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIHsgUGh5c2ljYWxSZXNvdXJjZUlkPzogc3RyaW5nIH0sXG4gIGhhbmRsZXJSZXNwb25zZTogdm9pZCB8IEhhbmRsZXJSZXNwb25zZSA9IHsgfSk6IFJlc3BvbnNlIHtcblxuICAvLyBpZiBwaHlzaWNhbCBJRCBpcyBub3QgcmV0dXJuZWQsIHdlIGhhdmUgc29tZSBkZWZhdWx0cyBmb3IgeW91IGJhc2VkXG4gIC8vIG9uIHRoZSByZXF1ZXN0IHR5cGUuXG4gIGNvbnN0IHBoeXNpY2FsUmVzb3VyY2VJZCA9IGhhbmRsZXJSZXNwb25zZS5QaHlzaWNhbFJlc291cmNlSWQgPz8gY2ZuUmVxdWVzdC5QaHlzaWNhbFJlc291cmNlSWQgPz8gY2ZuUmVxdWVzdC5SZXF1ZXN0SWQ7XG5cbiAgLy8gaWYgd2UgYXJlIGluIERFTEVURSBhbmQgcGh5c2ljYWwgSUQgd2FzIGNoYW5nZWQsIGl0J3MgYW4gZXJyb3IuXG4gIGlmIChjZm5SZXF1ZXN0LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBwaHlzaWNhbFJlc291cmNlSWQgIT09IGNmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBERUxFVEU6IGNhbm5vdCBjaGFuZ2UgdGhlIHBoeXNpY2FsIHJlc291cmNlIElEIGZyb20gXCIke2NmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkfVwiIHRvIFwiJHtoYW5kbGVyUmVzcG9uc2UuUGh5c2ljYWxSZXNvdXJjZUlkfVwiIGR1cmluZyBkZWxldGlvbmApO1xuICB9XG5cbiAgLy8gbWVyZ2UgcmVxdWVzdCBldmVudCBhbmQgcmVzdWx0IGV2ZW50IChyZXN1bHQgcHJldmFpbHMpLlxuICByZXR1cm4ge1xuICAgIC4uLmNmblJlcXVlc3QsXG4gICAgLi4uaGFuZGxlclJlc3BvbnNlLFxuICAgIFBoeXNpY2FsUmVzb3VyY2VJZDogcGh5c2ljYWxSZXNvdXJjZUlkLFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzdWJtaXRSZXNwb25zZShzdGF0dXM6ICdTVUNDRVNTJyB8ICdGQUlMRUQnLCBldmVudDogUmVzcG9uc2UpIHtcbiAgY29uc3QganNvbjogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VSZXNwb25zZSA9IHtcbiAgICBTdGF0dXM6IHN0YXR1cyxcbiAgICBSZWFzb246IGV2ZW50LlJlYXNvbiA/PyBzdGF0dXMsXG4gICAgU3RhY2tJZDogZXZlbnQuU3RhY2tJZCxcbiAgICBSZXF1ZXN0SWQ6IGV2ZW50LlJlcXVlc3RJZCxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCB8fCBNSVNTSU5HX1BIWVNJQ0FMX0lEX01BUktFUixcbiAgICBMb2dpY2FsUmVzb3VyY2VJZDogZXZlbnQuTG9naWNhbFJlc291cmNlSWQsXG4gICAgTm9FY2hvOiBldmVudC5Ob0VjaG8sXG4gICAgRGF0YTogZXZlbnQuRGF0YSxcbiAgfTtcblxuICBjb25zdCBwYXJzZWRVcmwgPSB1cmwucGFyc2UoZXZlbnQuUmVzcG9uc2VVUkwpO1xuICBjb25zdCBsb2dnaW5nU2FmZVVybCA9IGAke3BhcnNlZFVybC5wcm90b2NvbH0vLyR7cGFyc2VkVXJsLmhvc3RuYW1lfS8ke3BhcnNlZFVybC5wYXRobmFtZX0/KioqYDtcbiAgZXh0ZXJuYWwubG9nKCdzdWJtaXQgcmVzcG9uc2UgdG8gY2xvdWRmb3JtYXRpb24nLCBsb2dnaW5nU2FmZVVybCwganNvbik7XG5cbiAgY29uc3QgcmVzcG9uc2VCb2R5ID0gSlNPTi5zdHJpbmdpZnkoanNvbik7XG4gIGNvbnN0IHJlcSA9IHtcbiAgICBob3N0bmFtZTogcGFyc2VkVXJsLmhvc3RuYW1lLFxuICAgIHBhdGg6IHBhcnNlZFVybC5wYXRoLFxuICAgIG1ldGhvZDogJ1BVVCcsXG4gICAgaGVhZGVyczoge1xuICAgICAgJ2NvbnRlbnQtdHlwZSc6ICcnLFxuICAgICAgJ2NvbnRlbnQtbGVuZ3RoJzogQnVmZmVyLmJ5dGVMZW5ndGgocmVzcG9uc2VCb2R5LCAndXRmOCcpLFxuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgcmV0cnlPcHRpb25zID0ge1xuICAgIGF0dGVtcHRzOiA1LFxuICAgIHNsZWVwOiAxMDAwLFxuICB9O1xuICBhd2FpdCB3aXRoUmV0cmllcyhyZXRyeU9wdGlvbnMsIGV4dGVybmFsLnNlbmRIdHRwUmVxdWVzdCkocmVxLCByZXNwb25zZUJvZHkpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBkZWZhdWx0U2VuZEh0dHBSZXF1ZXN0KG9wdGlvbnM6IGh0dHBzLlJlcXVlc3RPcHRpb25zLCByZXF1ZXN0Qm9keTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBodHRwcy5yZXF1ZXN0KG9wdGlvbnMsIChyZXNwb25zZSkgPT4ge1xuICAgICAgICByZXNwb25zZS5yZXN1bWUoKTsgLy8gQ29uc3VtZSB0aGUgcmVzcG9uc2UgYnV0IGRvbid0IGNhcmUgYWJvdXQgaXRcbiAgICAgICAgaWYgKCFyZXNwb25zZS5zdGF0dXNDb2RlIHx8IHJlc3BvbnNlLnN0YXR1c0NvZGUgPj0gNDAwKSB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgVW5zdWNjZXNzZnVsIEhUVFAgcmVzcG9uc2U6ICR7cmVzcG9uc2Uuc3RhdHVzQ29kZX1gKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJlcXVlc3Qub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgICAgIHJlcXVlc3Qud3JpdGUocmVxdWVzdEJvZHkpO1xuICAgICAgcmVxdWVzdC5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZSk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdExvZyhmbXQ6IHN0cmluZywgLi4ucGFyYW1zOiBhbnlbXSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLmxvZyhmbXQsIC4uLnBhcmFtcyk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmV0cnlPcHRpb25zIHtcbiAgLyoqIEhvdyBtYW55IHJldHJpZXMgKHdpbGwgYXQgbGVhc3QgdHJ5IG9uY2UpICovXG4gIHJlYWRvbmx5IGF0dGVtcHRzOiBudW1iZXI7XG4gIC8qKiBTbGVlcCBiYXNlLCBpbiBtcyAqL1xuICByZWFkb25seSBzbGVlcDogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aFJldHJpZXM8QSBleHRlbmRzIEFycmF5PGFueT4sIEI+KG9wdGlvbnM6IFJldHJ5T3B0aW9ucywgZm46ICguLi54czogQSkgPT4gUHJvbWlzZTxCPik6ICguLi54czogQSkgPT4gUHJvbWlzZTxCPiB7XG4gIHJldHVybiBhc3luYyAoLi4ueHM6IEEpID0+IHtcbiAgICBsZXQgYXR0ZW1wdHMgPSBvcHRpb25zLmF0dGVtcHRzO1xuICAgIGxldCBtcyA9IG9wdGlvbnMuc2xlZXA7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmbiguLi54cyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChhdHRlbXB0cy0tIDw9IDApIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHNsZWVwKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIG1zKSk7XG4gICAgICAgIG1zICo9IDI7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgob2spID0+IHNldFRpbWVvdXQob2ssIG1zKSk7XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js deleted file mode 100644 index fc8189b0bbb1d..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";var a=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var h=(o,e)=>{for(var r in e)a(o,r,{get:e[r],enumerable:!0})},E=(o,e,r,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of N(e))!P.call(o,n)&&n!==r&&a(o,n,{get:()=>e[n],enumerable:!(t=Z(e,n))||t.enumerable});return o};var A=o=>E(a({},"__esModule",{value:!0}),o);var v={};h(v,{handler:()=>D});module.exports=A(v);var c=require("@aws-sdk/client-route-53"),u=require("@aws-sdk/credential-providers");async function D(o){let e=o.ResourceProperties;switch(o.RequestType){case"Create":return s(e,!1);case"Update":return w(e,o.OldResourceProperties);case"Delete":return s(e,!0)}}async function w(o,e){e&&o.DelegatedZoneName!==e.DelegatedZoneName&&await s(e,!0),await s(o,!1)}async function s(o,e){let{AssumeRoleArn:r,ParentZoneId:t,ParentZoneName:n,DelegatedZoneName:m,DelegatedZoneNameServers:d,TTL:g,AssumeRoleRegion:R}=o;if(!t&&!n)throw Error("One of ParentZoneId or ParentZoneName must be specified");let l=new Date().getTime(),i=new c.Route53({credentials:(0,u.fromTemporaryCredentials)({clientConfig:{region:R??T(process.env.AWS_REGION??process.env.AWS_DEFAULT_REGION??"")},params:{RoleArn:r,RoleSessionName:`cross-account-zone-delegation-${l}`}})}),p=t??await S(n,i);await i.changeResourceRecordSets({HostedZoneId:p,ChangeBatch:{Changes:[{Action:e?"DELETE":"UPSERT",ResourceRecordSet:{Name:m,Type:"NS",TTL:g,ResourceRecords:d.map(f=>({Value:f}))}}]}})}async function S(o,e){let t=(await e.listHostedZonesByName({DNSName:o})).HostedZones?.filter(n=>n.Name===`${o}.`)??[];if(t&&t.length!==1)throw Error(`Expected one hosted zone to match the given name but found ${t.length}`);return t[0].Id}function T(o){let e={cn:"cn-northwest-1","us-gov":"us-gov-west-1","us-iso":"us-iso-east-1","us-isob":"us-isob-east-1"};for(let[r,t]of Object.entries(e))if(o.startsWith(`${r}-`))return t;return"us-east-1"}0&&(module.exports={handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a/__entrypoint__.js b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458/__entrypoint__.js similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a/__entrypoint__.js rename to packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458/__entrypoint__.js diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458/index.js new file mode 100644 index 0000000000000..3f0f1c7eede9c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458/index.js @@ -0,0 +1 @@ +"use strict";var a=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var P=(o,e)=>{for(var n in e)a(o,n,{get:e[n],enumerable:!0})},E=(o,e,n,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of N(e))!h.call(o,s)&&s!==n&&a(o,s,{get:()=>e[s],enumerable:!(t=Z(e,s))||t.enumerable});return o};var A=o=>E(a({},"__esModule",{value:!0}),o);var v={};P(v,{handler:()=>w});module.exports=A(v);var c=require("@aws-sdk/client-route-53"),u=require("@aws-sdk/credential-providers");async function w(o){let e=o.ResourceProperties;switch(o.RequestType){case"Create":return r(e,!1);case"Update":return D(e,o.OldResourceProperties);case"Delete":return r(e,!0)}}async function D(o,e){e&&o.DelegatedZoneName!==e.DelegatedZoneName&&await r(e,!0),await r(o,!1)}async function r(o,e){let{AssumeRoleArn:n,ParentZoneId:t,ParentZoneName:s,DelegatedZoneName:m,DelegatedZoneNameServers:d,TTL:g,AssumeRoleRegion:R}=o;if(!t&&!s)throw Error("One of ParentZoneId or ParentZoneName must be specified");let l=new Date().getTime(),i=new c.Route53({credentials:(0,u.fromTemporaryCredentials)({clientConfig:{region:R??T(process.env.AWS_REGION??process.env.AWS_DEFAULT_REGION??"")},params:{RoleArn:n,RoleSessionName:`cross-account-zone-delegation-${l}`}})}),f=t??await S(s,i);await i.changeResourceRecordSets({HostedZoneId:f,ChangeBatch:{Changes:[{Action:e?"DELETE":"UPSERT",ResourceRecordSet:{Name:m,Type:"NS",TTL:g,ResourceRecords:d.map(p=>({Value:p}))}}]}})}async function S(o,e){let t=(await e.listHostedZonesByName({DNSName:o})).HostedZones?.filter(s=>s.Name===`${o}.`)??[];if(t&&t.length!==1)throw Error(`Expected one hosted zone to match the given name but found ${t.length}`);return t[0].Id}function T(o){let e={cn:"cn-northwest-1","us-gov":"us-gov-west-1","us-iso":"us-iso-east-1","us-isob":"us-isob-east-1","eu-isoe":"eu-isoe-west-1","us-isof":"us-isof-south-1"};for(let[n,t]of Object.entries(e))if(o.startsWith(`${n}-`))return t;return"us-east-1"}0&&(module.exports={handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.assets.json index 7d4e310c38056..fcf8c9d9a0b2c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.assets.json @@ -1,21 +1,21 @@ { "version": "36.0.0", "files": { - "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a": { + "f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458": { "source": { - "path": "asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a", + "path": "asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458", "packaging": "zip" }, "destinations": { "234567890123-af-south-1": { "bucketName": "cdk-hnb659fds-assets-234567890123-af-south-1", - "objectKey": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip", + "objectKey": "f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458.zip", "region": "af-south-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-af-south-1" } } }, - "f623a975a6715de3e8cfcea1429aa4dd9a0a9d47f328849d3148a0859b45a9d6": { + "a78a3dc2d80e9c4da64e1535efeb43c779441835dfc427c092f0c61fed0c63c4": { "source": { "path": "child-opt-in-stack-with-assume-role-region.template.json", "packaging": "file" @@ -23,7 +23,7 @@ "destinations": { "234567890123-af-south-1": { "bucketName": "cdk-hnb659fds-assets-234567890123-af-south-1", - "objectKey": "f623a975a6715de3e8cfcea1429aa4dd9a0a9d47f328849d3148a0859b45a9d6.json", + "objectKey": "a78a3dc2d80e9c4da64e1535efeb43c779441835dfc427c092f0c61fed0c63c4.json", "region": "af-south-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-af-south-1" } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.template.json index ab52c5ecd1378..2355e36da150a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack-with-assume-role-region.template.json @@ -104,7 +104,7 @@ "Properties": { "Code": { "S3Bucket": "cdk-hnb659fds-assets-234567890123-af-south-1", - "S3Key": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip" + "S3Key": "f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.assets.json index 24434b21f3d01..09f4ec5c6b1ca 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.assets.json @@ -1,35 +1,21 @@ { "version": "36.0.0", "files": { -<<<<<<< HEAD - "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a": { + "f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458": { "source": { - "path": "asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a", -======= - "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a": { - "source": { - "path": "asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a", ->>>>>>> 96239f83c0 (test: add tests) + "path": "asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458", "packaging": "zip" }, "destinations": { "234567890123-af-south-1": { "bucketName": "cdk-hnb659fds-assets-234567890123-af-south-1", -<<<<<<< HEAD - "objectKey": "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a.zip", -======= - "objectKey": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip", ->>>>>>> 96239f83c0 (test: add tests) + "objectKey": "f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458.zip", "region": "af-south-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-af-south-1" } } }, -<<<<<<< HEAD - "34da3610276ae2d635b15c43c511f47cbd7b4f6e3b7de7b82b980f76956011b1": { -======= - "18f2dbac091f9ac5d22a8c4ce4a05b8c6c31cdaf1f062f8d19cda274d27ccf3c": { ->>>>>>> 96239f83c0 (test: add tests) + "c1eff1c52ef11d0e701efdf0a44fa41b7e08915b74b284a3d6dd71f1ff90a6cf": { "source": { "path": "child-opt-in-stack.template.json", "packaging": "file" @@ -37,11 +23,7 @@ "destinations": { "234567890123-af-south-1": { "bucketName": "cdk-hnb659fds-assets-234567890123-af-south-1", -<<<<<<< HEAD - "objectKey": "34da3610276ae2d635b15c43c511f47cbd7b4f6e3b7de7b82b980f76956011b1.json", -======= - "objectKey": "18f2dbac091f9ac5d22a8c4ce4a05b8c6c31cdaf1f062f8d19cda274d27ccf3c.json", ->>>>>>> 96239f83c0 (test: add tests) + "objectKey": "c1eff1c52ef11d0e701efdf0a44fa41b7e08915b74b284a3d6dd71f1ff90a6cf.json", "region": "af-south-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-af-south-1" } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.template.json index e52f4bc9778c4..bd87415d2baed 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-opt-in-stack.template.json @@ -103,11 +103,7 @@ "Properties": { "Code": { "S3Bucket": "cdk-hnb659fds-assets-234567890123-af-south-1", -<<<<<<< HEAD - "S3Key": "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a.zip" -======= - "S3Key": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip" ->>>>>>> 96239f83c0 (test: add tests) + "S3Key": "f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.assets.json index 3b3bca57a2b8e..735331fee4937 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.assets.json @@ -1,35 +1,21 @@ { "version": "36.0.0", "files": { -<<<<<<< HEAD - "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a": { + "f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458": { "source": { - "path": "asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a", -======= - "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a": { - "source": { - "path": "asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a", ->>>>>>> 96239f83c0 (test: add tests) + "path": "asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458", "packaging": "zip" }, "destinations": { "234567890123-us-east-1": { "bucketName": "cdk-hnb659fds-assets-234567890123-us-east-1", -<<<<<<< HEAD - "objectKey": "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a.zip", -======= - "objectKey": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip", ->>>>>>> 96239f83c0 (test: add tests) + "objectKey": "f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458.zip", "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-us-east-1" } } }, -<<<<<<< HEAD - "3e4b4f51ab2cf9d297070625300465aeacdc41af65e442818c5ef6c17e800728": { -======= - "8918292f4943f8879dc05122e8ad942ce9821941625fd7a4cc914db637b828b3": { ->>>>>>> 96239f83c0 (test: add tests) + "842851077ae4d9217e979ac9b947e1aba7d8ee848ad1606c64fd070f2d09a426": { "source": { "path": "child-stack.template.json", "packaging": "file" @@ -37,11 +23,7 @@ "destinations": { "234567890123-us-east-1": { "bucketName": "cdk-hnb659fds-assets-234567890123-us-east-1", -<<<<<<< HEAD - "objectKey": "3e4b4f51ab2cf9d297070625300465aeacdc41af65e442818c5ef6c17e800728.json", -======= - "objectKey": "8918292f4943f8879dc05122e8ad942ce9821941625fd7a4cc914db637b828b3.json", ->>>>>>> 96239f83c0 (test: add tests) + "objectKey": "842851077ae4d9217e979ac9b947e1aba7d8ee848ad1606c64fd070f2d09a426.json", "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-us-east-1" } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.template.json index 8f1b82c1944ac..55d04123d6a51 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/child-stack.template.json @@ -103,11 +103,7 @@ "Properties": { "Code": { "S3Bucket": "cdk-hnb659fds-assets-234567890123-us-east-1", -<<<<<<< HEAD - "S3Key": "aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a.zip" -======= - "S3Key": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip" ->>>>>>> 96239f83c0 (test: add tests) + "S3Key": "f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/manifest.json index 81b6361157711..d9097fab077c7 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.js.snapshot/manifest.json @@ -84,11 +84,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-deploy-role-234567890123-us-east-1", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-cfn-exec-role-234567890123-us-east-1", -<<<<<<< HEAD - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-us-east-1/3e4b4f51ab2cf9d297070625300465aeacdc41af65e442818c5ef6c17e800728.json", -======= - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-us-east-1/8918292f4943f8879dc05122e8ad942ce9821941625fd7a4cc914db637b828b3.json", ->>>>>>> 96239f83c0 (test: add tests) + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-us-east-1/842851077ae4d9217e979ac9b947e1aba7d8ee848ad1606c64fd070f2d09a426.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -167,11 +163,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-deploy-role-234567890123-af-south-1", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-cfn-exec-role-234567890123-af-south-1", -<<<<<<< HEAD - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-af-south-1/34da3610276ae2d635b15c43c511f47cbd7b4f6e3b7de7b82b980f76956011b1.json", -======= - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-af-south-1/18f2dbac091f9ac5d22a8c4ce4a05b8c6c31cdaf1f062f8d19cda274d27ccf3c.json", ->>>>>>> 96239f83c0 (test: add tests) + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-af-south-1/c1eff1c52ef11d0e701efdf0a44fa41b7e08915b74b284a3d6dd71f1ff90a6cf.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -250,7 +242,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-deploy-role-234567890123-af-south-1", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-cfn-exec-role-234567890123-af-south-1", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-af-south-1/f623a975a6715de3e8cfcea1429aa4dd9a0a9d47f328849d3148a0859b45a9d6.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-af-south-1/a78a3dc2d80e9c4da64e1535efeb43c779441835dfc427c092f0c61fed0c63c4.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ From 68d38964cdbc5a6d0c0945f4e886a3d643a04051 Mon Sep 17 00:00:00 2001 From: Nick Aiello Date: Fri, 22 Mar 2024 18:49:16 -0500 Subject: [PATCH 7/9] test: update rename-cross-account-zone-delegation --- .../index.js | 1 - .../__entrypoint__.js | 156 ------------------ .../index.js | 1 - .../__entrypoint__.js | 0 .../index.js | 1 + .../child-stack.assets.json | 10 +- .../child-stack.template.json | 2 +- .../manifest.json | 2 +- 8 files changed, 8 insertions(+), 165 deletions(-) delete mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a/index.js delete mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js delete mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js rename packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/{asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a => asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458}/__entrypoint__.js (100%) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458/index.js diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a/index.js deleted file mode 100644 index d69c0934f88d4..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a/index.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var Z=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var h=(o,e)=>{for(var s in e)a(o,s,{get:e[s],enumerable:!0})},P=(o,e,s,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Z(e))!N.call(o,n)&&n!==s&&a(o,n,{get:()=>e[n],enumerable:!(t=p(e,n))||t.enumerable});return o};var E=o=>P(a({},"__esModule",{value:!0}),o);var T={};h(T,{handler:()=>w});module.exports=E(T);var c=require("@aws-sdk/client-route-53"),u=require("@aws-sdk/credential-providers");async function w(o){let e=o.ResourceProperties;switch(o.RequestType){case"Create":return r(e,!1);case"Update":return D(e,o.OldResourceProperties);case"Delete":return r(e,!0)}}async function D(o,e){e&&o.DelegatedZoneName!==e.DelegatedZoneName&&await r(e,!0),await r(o,!1)}async function r(o,e){let{AssumeRoleArn:s,ParentZoneId:t,ParentZoneName:n,DelegatedZoneName:d,DelegatedZoneNameServers:m,TTL:g}=o;if(!t&&!n)throw Error("One of ParentZoneId or ParentZoneName must be specified");let l=new Date().getTime(),i=new c.Route53({credentials:(0,u.fromTemporaryCredentials)({clientConfig:{region:S(process.env.AWS_REGION??process.env.AWS_DEFAULT_REGION??"")},params:{RoleArn:s,RoleSessionName:`cross-account-zone-delegation-${l}`}})}),R=t??await A(n,i);await i.changeResourceRecordSets({HostedZoneId:R,ChangeBatch:{Changes:[{Action:e?"DELETE":"UPSERT",ResourceRecordSet:{Name:d,Type:"NS",TTL:g,ResourceRecords:m.map(f=>({Value:f}))}}]}})}async function A(o,e){let t=(await e.listHostedZonesByName({DNSName:o})).HostedZones?.filter(n=>n.Name===`${o}.`)??[];if(t&&t.length!==1)throw Error(`Expected one hosted zone to match the given name but found ${t.length}`);return t[0].Id}function S(o){let e={cn:"cn-northwest-1","us-gov":"us-gov-west-1","us-iso":"us-iso-east-1","us-isob":"us-isob-east-1","eu-isoe":"eu-isoe-west-1","us-isof":"us-isof-south-1"};for(let[s,t]of Object.entries(e))if(o.startsWith(`${s}-`))return t;return"us-east-1"}0&&(module.exports={handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js deleted file mode 100644 index 9271364bb7e49..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/__entrypoint__.js +++ /dev/null @@ -1,156 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.withRetries = exports.handler = exports.external = void 0; -const https = require("https"); -const url = require("url"); -// for unit tests -exports.external = { - sendHttpRequest: defaultSendHttpRequest, - log: defaultLog, - includeStackTraces: true, - userHandlerIndex: './index', -}; -const CREATE_FAILED_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::CREATE_FAILED'; -const MISSING_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID'; -async function handler(event, context) { - const sanitizedEvent = { ...event, ResponseURL: '...' }; - exports.external.log(JSON.stringify(sanitizedEvent, undefined, 2)); - // ignore DELETE event when the physical resource ID is the marker that - // indicates that this DELETE is a subsequent DELETE to a failed CREATE - // operation. - if (event.RequestType === 'Delete' && event.PhysicalResourceId === CREATE_FAILED_PHYSICAL_ID_MARKER) { - exports.external.log('ignoring DELETE event caused by a failed CREATE event'); - await submitResponse('SUCCESS', event); - return; - } - try { - // invoke the user handler. this is intentionally inside the try-catch to - // ensure that if there is an error it's reported as a failure to - // cloudformation (otherwise cfn waits). - // eslint-disable-next-line @typescript-eslint/no-require-imports - const userHandler = require(exports.external.userHandlerIndex).handler; - const result = await userHandler(sanitizedEvent, context); - // validate user response and create the combined event - const responseEvent = renderResponse(event, result); - // submit to cfn as success - await submitResponse('SUCCESS', responseEvent); - } - catch (e) { - const resp = { - ...event, - Reason: exports.external.includeStackTraces ? e.stack : e.message, - }; - if (!resp.PhysicalResourceId) { - // special case: if CREATE fails, which usually implies, we usually don't - // have a physical resource id. in this case, the subsequent DELETE - // operation does not have any meaning, and will likely fail as well. to - // address this, we use a marker so the provider framework can simply - // ignore the subsequent DELETE. - if (event.RequestType === 'Create') { - exports.external.log('CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored'); - resp.PhysicalResourceId = CREATE_FAILED_PHYSICAL_ID_MARKER; - } - else { - // otherwise, if PhysicalResourceId is not specified, something is - // terribly wrong because all other events should have an ID. - exports.external.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(event)}`); - } - } - // this is an actual error, fail the activity altogether and exist. - await submitResponse('FAILED', resp); - } -} -exports.handler = handler; -function renderResponse(cfnRequest, handlerResponse = {}) { - // if physical ID is not returned, we have some defaults for you based - // on the request type. - const physicalResourceId = handlerResponse.PhysicalResourceId ?? cfnRequest.PhysicalResourceId ?? cfnRequest.RequestId; - // if we are in DELETE and physical ID was changed, it's an error. - if (cfnRequest.RequestType === 'Delete' && physicalResourceId !== cfnRequest.PhysicalResourceId) { - throw new Error(`DELETE: cannot change the physical resource ID from "${cfnRequest.PhysicalResourceId}" to "${handlerResponse.PhysicalResourceId}" during deletion`); - } - // merge request event and result event (result prevails). - return { - ...cfnRequest, - ...handlerResponse, - PhysicalResourceId: physicalResourceId, - }; -} -async function submitResponse(status, event) { - const json = { - Status: status, - Reason: event.Reason ?? status, - StackId: event.StackId, - RequestId: event.RequestId, - PhysicalResourceId: event.PhysicalResourceId || MISSING_PHYSICAL_ID_MARKER, - LogicalResourceId: event.LogicalResourceId, - NoEcho: event.NoEcho, - Data: event.Data, - }; - const parsedUrl = url.parse(event.ResponseURL); - const loggingSafeUrl = `${parsedUrl.protocol}//${parsedUrl.hostname}/${parsedUrl.pathname}?***`; - exports.external.log('submit response to cloudformation', loggingSafeUrl, json); - const responseBody = JSON.stringify(json); - const req = { - hostname: parsedUrl.hostname, - path: parsedUrl.path, - method: 'PUT', - headers: { - 'content-type': '', - 'content-length': Buffer.byteLength(responseBody, 'utf8'), - }, - }; - const retryOptions = { - attempts: 5, - sleep: 1000, - }; - await withRetries(retryOptions, exports.external.sendHttpRequest)(req, responseBody); -} -async function defaultSendHttpRequest(options, requestBody) { - return new Promise((resolve, reject) => { - try { - const request = https.request(options, (response) => { - response.resume(); // Consume the response but don't care about it - if (!response.statusCode || response.statusCode >= 400) { - reject(new Error(`Unsuccessful HTTP response: ${response.statusCode}`)); - } - else { - resolve(); - } - }); - request.on('error', reject); - request.write(requestBody); - request.end(); - } - catch (e) { - reject(e); - } - }); -} -function defaultLog(fmt, ...params) { - // eslint-disable-next-line no-console - console.log(fmt, ...params); -} -function withRetries(options, fn) { - return async (...xs) => { - let attempts = options.attempts; - let ms = options.sleep; - while (true) { - try { - return await fn(...xs); - } - catch (e) { - if (attempts-- <= 0) { - throw e; - } - await sleep(Math.floor(Math.random() * ms)); - ms *= 2; - } - } - }; -} -exports.withRetries = withRetries; -async function sleep(ms) { - return new Promise((ok) => setTimeout(ok, ms)); -} -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsMkJBQTJCO0FBRTNCLGlCQUFpQjtBQUNKLFFBQUEsUUFBUSxHQUFHO0lBQ3RCLGVBQWUsRUFBRSxzQkFBc0I7SUFDdkMsR0FBRyxFQUFFLFVBQVU7SUFDZixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGdCQUFnQixFQUFFLFNBQVM7Q0FDNUIsQ0FBQztBQUVGLE1BQU0sZ0NBQWdDLEdBQUcsd0RBQXdELENBQUM7QUFDbEcsTUFBTSwwQkFBMEIsR0FBRyw4REFBOEQsQ0FBQztBQVczRixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDeEQsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFM0QsdUVBQXVFO0lBQ3ZFLHVFQUF1RTtJQUN2RSxhQUFhO0lBQ2IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEtBQUssZ0NBQWdDLEVBQUU7UUFDbkcsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN0RSxNQUFNLGNBQWMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkMsT0FBTztLQUNSO0lBRUQsSUFBSTtRQUNGLHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsd0NBQXdDO1FBQ3hDLGlFQUFpRTtRQUNqRSxNQUFNLFdBQVcsR0FBWSxPQUFPLENBQUMsZ0JBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4RSxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FB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bXBvcnQgKiBhcyBodHRwcyBmcm9tICdodHRwcyc7XG5pbXBvcnQgKiBhcyB1cmwgZnJvbSAndXJsJztcblxuLy8gZm9yIHVuaXQgdGVzdHNcbmV4cG9ydCBjb25zdCBleHRlcm5hbCA9IHtcbiAgc2VuZEh0dHBSZXF1ZXN0OiBkZWZhdWx0U2VuZEh0dHBSZXF1ZXN0LFxuICBsb2c6IGRlZmF1bHRMb2csXG4gIGluY2x1ZGVTdGFja1RyYWNlczogdHJ1ZSxcbiAgdXNlckhhbmRsZXJJbmRleDogJy4vaW5kZXgnLFxufTtcblxuY29uc3QgQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVIgPSAnQVdTQ0RLOjpDdXN0b21SZXNvdXJjZVByb3ZpZGVyRnJhbWV3b3JrOjpDUkVBVEVfRkFJTEVEJztcbmNvbnN0IE1JU1NJTkdfUEhZU0lDQUxfSURfTUFSS0VSID0gJ0FXU0NESzo6Q3VzdG9tUmVzb3VyY2VQcm92aWRlckZyYW1ld29yazo6TUlTU0lOR19QSFlTSUNBTF9JRCc7XG5cbmV4cG9ydCB0eXBlIFJlc3BvbnNlID0gQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIEhhbmRsZXJSZXNwb25zZTtcbmV4cG9ydCB0eXBlIEhhbmRsZXIgPSAoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSA9PiBQcm9taXNlPEhhbmRsZXJSZXNwb25zZSB8IHZvaWQ+O1xuZXhwb3J0IHR5cGUgSGFuZGxlclJlc3BvbnNlID0gdW5kZWZpbmVkIHwge1xuICBEYXRhPzogYW55O1xuICBQaHlzaWNhbFJlc291cmNlSWQ/OiBzdHJpbmc7XG4gIFJlYXNvbj86IHN0cmluZztcbiAgTm9FY2hvPzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50LCBjb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dCkge1xuICBjb25zdCBzYW5pdGl6ZWRFdmVudCA9IHsgLi4uZXZlbnQsIFJlc3BvbnNlVVJMOiAnLi4uJyB9O1xuICBleHRlcm5hbC5sb2coSlNPTi5zdHJpbmdpZnkoc2FuaXRpemVkRXZlbnQsIHVuZGVmaW5lZCwgMikpO1xuXG4gIC8vIGlnbm9yZSBERUxFVEUgZXZlbnQgd2hlbiB0aGUgcGh5c2ljYWwgcmVzb3VyY2UgSUQgaXMgdGhlIG1hcmtlciB0aGF0XG4gIC8vIGluZGljYXRlcyB0aGF0IHRoaXMgREVMRVRFIGlzIGEgc3Vic2VxdWVudCBERUxFVEUgdG8gYSBmYWlsZWQgQ1JFQVRFXG4gIC8vIG9wZXJhdGlvbi5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgPT09IENSRUFURV9GQUlMRURfUEhZU0lDQUxfSURfTUFSS0VSKSB7XG4gICAgZXh0ZXJuYWwubG9nKCdpZ25vcmluZyBERUxFVEUgZXZlbnQgY2F1c2VkIGJ5IGEgZmFpbGVkIENSRUFURSBldmVudCcpO1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgZXZlbnQpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgLy8gaW52b2tlIHRoZSB1c2VyIGhhbmRsZXIuIHRoaXMgaXMgaW50ZW50aW9uYWxseSBpbnNpZGUgdGhlIHRyeS1jYXRjaCB0b1xuICAgIC8vIGVuc3VyZSB0aGF0IGlmIHRoZXJlIGlzIGFuIGVycm9yIGl0J3MgcmVwb3J0ZWQgYXMgYSBmYWlsdXJlIHRvXG4gICAgLy8gY2xvdWRmb3JtYXRpb24gKG90aGVyd2lzZSBjZm4gd2FpdHMpLlxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3QgdXNlckhhbmRsZXI6IEhhbmRsZXIgPSByZXF1aXJlKGV4dGVybmFsLnVzZXJIYW5kbGVySW5kZXgpLmhhbmRsZXI7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdXNlckhhbmRsZXIoc2FuaXRpemVkRXZlbnQsIGNvbnRleHQpO1xuXG4gICAgLy8gdmFsaWRhdGUgdXNlciByZXNwb25zZSBhbmQgY3JlYXRlIHRoZSBjb21iaW5lZCBldmVudFxuICAgIGNvbnN0IHJlc3BvbnNlRXZlbnQgPSByZW5kZXJSZXNwb25zZShldmVudCwgcmVzdWx0KTtcblxuICAgIC8vIHN1Ym1pdCB0byBjZm4gYXMgc3VjY2Vzc1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgcmVzcG9uc2VFdmVudCk7XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGNvbnN0IHJlc3A6IFJlc3BvbnNlID0ge1xuICAgICAgLi4uZXZlbnQsXG4gICAgICBSZWFzb246IGV4dGVybmFsLmluY2x1ZGVTdGFja1RyYWNlcyA/IGUuc3RhY2sgOiBlLm1lc3NhZ2UsXG4gICAgfTtcblxuICAgIGlmICghcmVzcC5QaHlzaWNhbFJlc291cmNlSWQpIHtcbiAgICAgIC8vIHNwZWNpYWwgY2FzZTogaWYgQ1JFQVRFIGZhaWxzLCB3aGljaCB1c3VhbGx5IGltcGxpZXMsIHdlIHVzdWFsbHkgZG9uJ3RcbiAgICAgIC8vIGhhdmUgYSBwaHlzaWNhbCByZXNvdXJjZSBpZC4gaW4gdGhpcyBjYXNlLCB0aGUgc3Vic2VxdWVudCBERUxFVEVcbiAgICAgIC8vIG9wZXJhdGlvbiBkb2VzIG5vdCBoYXZlIGFueSBtZWFuaW5nLCBhbmQgd2lsbCBsaWtlbHkgZmFpbCBhcyB3ZWxsLiB0b1xuICAgICAgLy8gYWRkcmVzcyB0aGlzLCB3ZSB1c2UgYSBtYXJrZXIgc28gdGhlIHByb3ZpZGVyIGZyYW1ld29yayBjYW4gc2ltcGx5XG4gICAgICAvLyBpZ25vcmUgdGhlIHN1YnNlcXVlbnQgREVMRVRFLlxuICAgICAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnQ3JlYXRlJykge1xuICAgICAgICBleHRlcm5hbC5sb2coJ0NSRUFURSBmYWlsZWQsIHJlc3BvbmRpbmcgd2l0aCBhIG1hcmtlciBwaHlzaWNhbCByZXNvdXJjZSBpZCBzbyB0aGF0IHRoZSBzdWJzZXF1ZW50IERFTEVURSB3aWxsIGJlIGlnbm9yZWQnKTtcbiAgICAgICAgcmVzcC5QaHlzaWNhbFJlc291cmNlSWQgPSBDUkVBVEVfRkFJTEVEX1BIWVNJQ0FMX0lEX01BUktFUjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG90aGVyd2lzZSwgaWYgUGh5c2ljYWxSZXNvdXJjZUlkIGlzIG5vdCBzcGVjaWZpZWQsIHNvbWV0aGluZyBpc1xuICAgICAgICAvLyB0ZXJyaWJseSB3cm9uZyBiZWNhdXNlIGFsbCBvdGhlciBldmVudHMgc2hvdWxkIGhhdmUgYW4gSUQuXG4gICAgICAgIGV4dGVybmFsLmxvZyhgRVJST1I6IE1hbGZvcm1lZCBldmVudC4gXCJQaHlzaWNhbFJlc291cmNlSWRcIiBpcyByZXF1aXJlZDogJHtKU09OLnN0cmluZ2lmeShldmVudCl9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdGhpcyBpcyBhbiBhY3R1YWwgZXJyb3IsIGZhaWwgdGhlIGFjdGl2aXR5IGFsdG9nZXRoZXIgYW5kIGV4aXN0LlxuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdGQUlMRUQnLCByZXNwKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW5kZXJSZXNwb25zZShcbiAgY2ZuUmVxdWVzdDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIHsgUGh5c2ljYWxSZXNvdXJjZUlkPzogc3RyaW5nIH0sXG4gIGhhbmRsZXJSZXNwb25zZTogdm9pZCB8IEhhbmRsZXJSZXNwb25zZSA9IHsgfSk6IFJlc3BvbnNlIHtcblxuICAvLyBpZiBwaHlzaWNhbCBJRCBpcyBub3QgcmV0dXJuZWQsIHdlIGhhdmUgc29tZSBkZWZhdWx0cyBmb3IgeW91IGJhc2VkXG4gIC8vIG9uIHRoZSByZXF1ZXN0IHR5cGUuXG4gIGNvbnN0IHBoeXNpY2FsUmVzb3VyY2VJZCA9IGhhbmRsZXJSZXNwb25zZS5QaHlzaWNhbFJlc291cmNlSWQgPz8gY2ZuUmVxdWVzdC5QaHlzaWNhbFJlc291cmNlSWQgPz8gY2ZuUmVxdWVzdC5SZXF1ZXN0SWQ7XG5cbiAgLy8gaWYgd2UgYXJlIGluIERFTEVURSBhbmQgcGh5c2ljYWwgSUQgd2FzIGNoYW5nZWQsIGl0J3MgYW4gZXJyb3IuXG4gIGlmIChjZm5SZXF1ZXN0LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBwaHlzaWNhbFJlc291cmNlSWQgIT09IGNmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBERUxFVEU6IGNhbm5vdCBjaGFuZ2UgdGhlIHBoeXNpY2FsIHJlc291cmNlIElEIGZyb20gXCIke2NmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkfVwiIHRvIFwiJHtoYW5kbGVyUmVzcG9uc2UuUGh5c2ljYWxSZXNvdXJjZUlkfVwiIGR1cmluZyBkZWxldGlvbmApO1xuICB9XG5cbiAgLy8gbWVyZ2UgcmVxdWVzdCBldmVudCBhbmQgcmVzdWx0IGV2ZW50IChyZXN1bHQgcHJldmFpbHMpLlxuICByZXR1cm4ge1xuICAgIC4uLmNmblJlcXVlc3QsXG4gICAgLi4uaGFuZGxlclJlc3BvbnNlLFxuICAgIFBoeXNpY2FsUmVzb3VyY2VJZDogcGh5c2ljYWxSZXNvdXJjZUlkLFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzdWJtaXRSZXNwb25zZShzdGF0dXM6ICdTVUNDRVNTJyB8ICdGQUlMRUQnLCBldmVudDogUmVzcG9uc2UpIHtcbiAgY29uc3QganNvbjogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VSZXNwb25zZSA9IHtcbiAgICBTdGF0dXM6IHN0YXR1cyxcbiAgICBSZWFzb246IGV2ZW50LlJlYXNvbiA/PyBzdGF0dXMsXG4gICAgU3RhY2tJZDogZXZlbnQuU3RhY2tJZCxcbiAgICBSZXF1ZXN0SWQ6IGV2ZW50LlJlcXVlc3RJZCxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCB8fCBNSVNTSU5HX1BIWVNJQ0FMX0lEX01BUktFUixcbiAgICBMb2dpY2FsUmVzb3VyY2VJZDogZXZlbnQuTG9naWNhbFJlc291cmNlSWQsXG4gICAgTm9FY2hvOiBldmVudC5Ob0VjaG8sXG4gICAgRGF0YTogZXZlbnQuRGF0YSxcbiAgfTtcblxuICBjb25zdCBwYXJzZWRVcmwgPSB1cmwucGFyc2UoZXZlbnQuUmVzcG9uc2VVUkwpO1xuICBjb25zdCBsb2dnaW5nU2FmZVVybCA9IGAke3BhcnNlZFVybC5wcm90b2NvbH0vLyR7cGFyc2VkVXJsLmhvc3RuYW1lfS8ke3BhcnNlZFVybC5wYXRobmFtZX0/KioqYDtcbiAgZXh0ZXJuYWwubG9nKCdzdWJtaXQgcmVzcG9uc2UgdG8gY2xvdWRmb3JtYXRpb24nLCBsb2dnaW5nU2FmZVVybCwganNvbik7XG5cbiAgY29uc3QgcmVzcG9uc2VCb2R5ID0gSlNPTi5zdHJpbmdpZnkoanNvbik7XG4gIGNvbnN0IHJlcSA9IHtcbiAgICBob3N0bmFtZTogcGFyc2VkVXJsLmhvc3RuYW1lLFxuICAgIHBhdGg6IHBhcnNlZFVybC5wYXRoLFxuICAgIG1ldGhvZDogJ1BVVCcsXG4gICAgaGVhZGVyczoge1xuICAgICAgJ2NvbnRlbnQtdHlwZSc6ICcnLFxuICAgICAgJ2NvbnRlbnQtbGVuZ3RoJzogQnVmZmVyLmJ5dGVMZW5ndGgocmVzcG9uc2VCb2R5LCAndXRmOCcpLFxuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgcmV0cnlPcHRpb25zID0ge1xuICAgIGF0dGVtcHRzOiA1LFxuICAgIHNsZWVwOiAxMDAwLFxuICB9O1xuICBhd2FpdCB3aXRoUmV0cmllcyhyZXRyeU9wdGlvbnMsIGV4dGVybmFsLnNlbmRIdHRwUmVxdWVzdCkocmVxLCByZXNwb25zZUJvZHkpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBkZWZhdWx0U2VuZEh0dHBSZXF1ZXN0KG9wdGlvbnM6IGh0dHBzLlJlcXVlc3RPcHRpb25zLCByZXF1ZXN0Qm9keTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBodHRwcy5yZXF1ZXN0KG9wdGlvbnMsIChyZXNwb25zZSkgPT4ge1xuICAgICAgICByZXNwb25zZS5yZXN1bWUoKTsgLy8gQ29uc3VtZSB0aGUgcmVzcG9uc2UgYnV0IGRvbid0IGNhcmUgYWJvdXQgaXRcbiAgICAgICAgaWYgKCFyZXNwb25zZS5zdGF0dXNDb2RlIHx8IHJlc3BvbnNlLnN0YXR1c0NvZGUgPj0gNDAwKSB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgVW5zdWNjZXNzZnVsIEhUVFAgcmVzcG9uc2U6ICR7cmVzcG9uc2Uuc3RhdHVzQ29kZX1gKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJlcXVlc3Qub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgICAgIHJlcXVlc3Qud3JpdGUocmVxdWVzdEJvZHkpO1xuICAgICAgcmVxdWVzdC5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZSk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdExvZyhmbXQ6IHN0cmluZywgLi4ucGFyYW1zOiBhbnlbXSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLmxvZyhmbXQsIC4uLnBhcmFtcyk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmV0cnlPcHRpb25zIHtcbiAgLyoqIEhvdyBtYW55IHJldHJpZXMgKHdpbGwgYXQgbGVhc3QgdHJ5IG9uY2UpICovXG4gIHJlYWRvbmx5IGF0dGVtcHRzOiBudW1iZXI7XG4gIC8qKiBTbGVlcCBiYXNlLCBpbiBtcyAqL1xuICByZWFkb25seSBzbGVlcDogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aFJldHJpZXM8QSBleHRlbmRzIEFycmF5PGFueT4sIEI+KG9wdGlvbnM6IFJldHJ5T3B0aW9ucywgZm46ICguLi54czogQSkgPT4gUHJvbWlzZTxCPik6ICguLi54czogQSkgPT4gUHJvbWlzZTxCPiB7XG4gIHJldHVybiBhc3luYyAoLi4ueHM6IEEpID0+IHtcbiAgICBsZXQgYXR0ZW1wdHMgPSBvcHRpb25zLmF0dGVtcHRzO1xuICAgIGxldCBtcyA9IG9wdGlvbnMuc2xlZXA7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmbiguLi54cyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChhdHRlbXB0cy0tIDw9IDApIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHNsZWVwKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIG1zKSk7XG4gICAgICAgIG1zICo9IDI7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgob2spID0+IHNldFRpbWVvdXQob2ssIG1zKSk7XG59XG4iXX0= \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js deleted file mode 100644 index fc8189b0bbb1d..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a/index.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";var a=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var h=(o,e)=>{for(var r in e)a(o,r,{get:e[r],enumerable:!0})},E=(o,e,r,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of N(e))!P.call(o,n)&&n!==r&&a(o,n,{get:()=>e[n],enumerable:!(t=Z(e,n))||t.enumerable});return o};var A=o=>E(a({},"__esModule",{value:!0}),o);var v={};h(v,{handler:()=>D});module.exports=A(v);var c=require("@aws-sdk/client-route-53"),u=require("@aws-sdk/credential-providers");async function D(o){let e=o.ResourceProperties;switch(o.RequestType){case"Create":return s(e,!1);case"Update":return w(e,o.OldResourceProperties);case"Delete":return s(e,!0)}}async function w(o,e){e&&o.DelegatedZoneName!==e.DelegatedZoneName&&await s(e,!0),await s(o,!1)}async function s(o,e){let{AssumeRoleArn:r,ParentZoneId:t,ParentZoneName:n,DelegatedZoneName:m,DelegatedZoneNameServers:d,TTL:g,AssumeRoleRegion:R}=o;if(!t&&!n)throw Error("One of ParentZoneId or ParentZoneName must be specified");let l=new Date().getTime(),i=new c.Route53({credentials:(0,u.fromTemporaryCredentials)({clientConfig:{region:R??T(process.env.AWS_REGION??process.env.AWS_DEFAULT_REGION??"")},params:{RoleArn:r,RoleSessionName:`cross-account-zone-delegation-${l}`}})}),p=t??await S(n,i);await i.changeResourceRecordSets({HostedZoneId:p,ChangeBatch:{Changes:[{Action:e?"DELETE":"UPSERT",ResourceRecordSet:{Name:m,Type:"NS",TTL:g,ResourceRecords:d.map(f=>({Value:f}))}}]}})}async function S(o,e){let t=(await e.listHostedZonesByName({DNSName:o})).HostedZones?.filter(n=>n.Name===`${o}.`)??[];if(t&&t.length!==1)throw Error(`Expected one hosted zone to match the given name but found ${t.length}`);return t[0].Id}function T(o){let e={cn:"cn-northwest-1","us-gov":"us-gov-west-1","us-iso":"us-iso-east-1","us-isob":"us-isob-east-1"};for(let[r,t]of Object.entries(e))if(o.startsWith(`${r}-`))return t;return"us-east-1"}0&&(module.exports={handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a/__entrypoint__.js b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458/__entrypoint__.js similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.aca4a134bf7ace6088b21213be7ab4357e3705f714362b690d76376b8f1df53a/__entrypoint__.js rename to packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458/__entrypoint__.js diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458/index.js new file mode 100644 index 0000000000000..3f0f1c7eede9c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458/index.js @@ -0,0 +1 @@ +"use strict";var a=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var P=(o,e)=>{for(var n in e)a(o,n,{get:e[n],enumerable:!0})},E=(o,e,n,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of N(e))!h.call(o,s)&&s!==n&&a(o,s,{get:()=>e[s],enumerable:!(t=Z(e,s))||t.enumerable});return o};var A=o=>E(a({},"__esModule",{value:!0}),o);var v={};P(v,{handler:()=>w});module.exports=A(v);var c=require("@aws-sdk/client-route-53"),u=require("@aws-sdk/credential-providers");async function w(o){let e=o.ResourceProperties;switch(o.RequestType){case"Create":return r(e,!1);case"Update":return D(e,o.OldResourceProperties);case"Delete":return r(e,!0)}}async function D(o,e){e&&o.DelegatedZoneName!==e.DelegatedZoneName&&await r(e,!0),await r(o,!1)}async function r(o,e){let{AssumeRoleArn:n,ParentZoneId:t,ParentZoneName:s,DelegatedZoneName:m,DelegatedZoneNameServers:d,TTL:g,AssumeRoleRegion:R}=o;if(!t&&!s)throw Error("One of ParentZoneId or ParentZoneName must be specified");let l=new Date().getTime(),i=new c.Route53({credentials:(0,u.fromTemporaryCredentials)({clientConfig:{region:R??T(process.env.AWS_REGION??process.env.AWS_DEFAULT_REGION??"")},params:{RoleArn:n,RoleSessionName:`cross-account-zone-delegation-${l}`}})}),f=t??await S(s,i);await i.changeResourceRecordSets({HostedZoneId:f,ChangeBatch:{Changes:[{Action:e?"DELETE":"UPSERT",ResourceRecordSet:{Name:m,Type:"NS",TTL:g,ResourceRecords:d.map(p=>({Value:p}))}}]}})}async function S(o,e){let t=(await e.listHostedZonesByName({DNSName:o})).HostedZones?.filter(s=>s.Name===`${o}.`)??[];if(t&&t.length!==1)throw Error(`Expected one hosted zone to match the given name but found ${t.length}`);return t[0].Id}function T(o){let e={cn:"cn-northwest-1","us-gov":"us-gov-west-1","us-iso":"us-iso-east-1","us-isob":"us-isob-east-1","eu-isoe":"eu-isoe-west-1","us-isof":"us-isof-south-1"};for(let[n,t]of Object.entries(e))if(o.startsWith(`${n}-`))return t;return"us-east-1"}0&&(module.exports={handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.assets.json index 3e5377c0386c0..098461f91e808 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.assets.json @@ -1,21 +1,21 @@ { "version": "36.0.0", "files": { - "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a": { + "f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458": { "source": { - "path": "asset.df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a", + "path": "asset.f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458", "packaging": "zip" }, "destinations": { "234567890123-us-east-1": { "bucketName": "cdk-hnb659fds-assets-234567890123-us-east-1", - "objectKey": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip", + "objectKey": "f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458.zip", "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-us-east-1" } } }, - "d402e439418fde6a5f1b138f07ab2b71e78ff60664359406393938a25d687253": { + "14800d68ec4a699ef7ee95b17c76e0eba3badf933bf2e67a6880e082a148bfca": { "source": { "path": "child-stack.template.json", "packaging": "file" @@ -23,7 +23,7 @@ "destinations": { "234567890123-us-east-1": { "bucketName": "cdk-hnb659fds-assets-234567890123-us-east-1", - "objectKey": "d402e439418fde6a5f1b138f07ab2b71e78ff60664359406393938a25d687253.json", + "objectKey": "14800d68ec4a699ef7ee95b17c76e0eba3badf933bf2e67a6880e082a148bfca.json", "region": "us-east-1", "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-file-publishing-role-234567890123-us-east-1" } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.template.json index 5c601cd8c1aa4..dadf35d9f1ecd 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/child-stack.template.json @@ -103,7 +103,7 @@ "Properties": { "Code": { "S3Bucket": "cdk-hnb659fds-assets-234567890123-us-east-1", - "S3Key": "df95834e6926d4afc6bfce2bc88b586e43b0ca9a3abb57b43754f174ff07828a.zip" + "S3Key": "f43e5ef82b45e2e3ecb60cd54aa4a3599da7bb4c85d10cfe133dc43f54705458.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/manifest.json index a4e6019b060c7..fcb1f39df7be0 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.rename-cross-account-zone-delegation.js.snapshot/manifest.json @@ -84,7 +84,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-deploy-role-234567890123-us-east-1", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::234567890123:role/cdk-hnb659fds-cfn-exec-role-234567890123-us-east-1", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-us-east-1/d402e439418fde6a5f1b138f07ab2b71e78ff60664359406393938a25d687253.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-234567890123-us-east-1/14800d68ec4a699ef7ee95b17c76e0eba3badf933bf2e67a6880e082a148bfca.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ From 106380414d7bcb9e606fe5efd735e48d51e9c736 Mon Sep 17 00:00:00 2001 From: Nick Aiello Date: Fri, 22 Mar 2024 18:51:00 -0500 Subject: [PATCH 8/9] chore: update spacing --- packages/aws-cdk-lib/aws-route53/lib/record-set.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/aws-cdk-lib/aws-route53/lib/record-set.ts b/packages/aws-cdk-lib/aws-route53/lib/record-set.ts index a4e3984100865..35bee5b5a9ee9 100644 --- a/packages/aws-cdk-lib/aws-route53/lib/record-set.ts +++ b/packages/aws-cdk-lib/aws-route53/lib/record-set.ts @@ -862,6 +862,7 @@ export interface CrossAccountZoneDelegationRecordProps { /** * Region from which to obtain temporary credentials. + * * @default - the Route53 signing region in the current partition */ readonly assumeRoleRegion?: string; From a89ddf1be4da350c049289414d411962f0da98a1 Mon Sep 17 00:00:00 2001 From: Nick Aiello Date: Thu, 28 Mar 2024 13:48:03 -0500 Subject: [PATCH 9/9] chore: update spacing --- .../aws-route53/test/integ.cross-account-zone-delegation.ts | 2 +- .../aws-route53/cross-account-zone-delegation-handler/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.ts index ba50d8afb8cd1..5ceb81c95f453 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.cross-account-zone-delegation.ts @@ -125,4 +125,4 @@ childOptInStackWithAssumeRoleRegion.addDependency(parentStack); new IntegTest(app, 'Route53CrossAccountInteg', { testCases: [childStack, childOptInStack, childOptInStackWithAssumeRoleRegion], diffAssets: true, -}); +}); \ No newline at end of file diff --git a/packages/@aws-cdk/custom-resource-handlers/lib/aws-route53/cross-account-zone-delegation-handler/index.ts b/packages/@aws-cdk/custom-resource-handlers/lib/aws-route53/cross-account-zone-delegation-handler/index.ts index a197af5751659..092b6aad9b27a 100644 --- a/packages/@aws-cdk/custom-resource-handlers/lib/aws-route53/cross-account-zone-delegation-handler/index.ts +++ b/packages/@aws-cdk/custom-resource-handlers/lib/aws-route53/cross-account-zone-delegation-handler/index.ts @@ -124,4 +124,4 @@ function route53Region(region: string) { // Default for commercial partition return 'us-east-1'; -} +} \ No newline at end of file