From d2f6a0119d53735485162c9c3c0574b4a9776ebe Mon Sep 17 00:00:00 2001 From: watany <76135106+watany-dev@users.noreply.github.com> Date: Sat, 26 Nov 2022 08:25:42 +0000 Subject: [PATCH 1/4] feat(cloudtrail): enable trail insight --- packages/@aws-cdk/aws-cloudtrail/README.md | 18 + .../@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts | 38 ++ packages/@aws-cdk/aws-cloudtrail/package.json | 3 +- .../aws-cloudtrail/test/cloudtrail.test.ts | 91 +++- .../__entrypoint__.js | 144 ++++++ .../index.js | 78 ++++ ...-cdk-cloudtrail-inshights-test.assets.json | 32 ++ ...dk-cloudtrail-inshights-test.template.json | 246 +++++++++++ ...efaultTestDeployAssertF7B86FF0.assets.json | 19 + ...aultTestDeployAssertF7B86FF0.template.json | 36 ++ .../cdk.out | 1 + .../integ-cloudtrail.assets.json | 32 ++ .../integ-cloudtrail.template.json | 418 ++++++++++++++++++ .../integ.json | 12 + .../manifest.json | 141 ++++++ .../tree.json | 333 ++++++++++++++ .../test/integ.cloudtrail-insight.lit.ts | 54 +++ 17 files changed, 1693 insertions(+), 3 deletions(-) create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/aws-cdk-cloudtrail-inshights-test.assets.json create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/aws-cdk-cloudtrail-inshights-test.template.json create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets.json create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.template.json create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.assets.json create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.template.json create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ.json create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/tree.json create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts diff --git a/packages/@aws-cdk/aws-cloudtrail/README.md b/packages/@aws-cdk/aws-cloudtrail/README.md index 4a750517d60bd..47443a6dc24ea 100644 --- a/packages/@aws-cdk/aws-cloudtrail/README.md +++ b/packages/@aws-cdk/aws-cloudtrail/README.md @@ -197,3 +197,21 @@ new cloudtrail.Trail(this, 'OrganizationTrail', { isOrganizationTrail: true, }); ``` + +## CloudTrail Insights + +Set `InsightSelector` to enable Insight. +Insights selector values can be `ApiCallRateInsight`, `ApiErrorRateInsight`, or both. + +```ts +new Trail(stack, 'Insights', { + insightSelectors: [ + { + insightType: Insight.TYPE_API_CALL_RATE, + }, + { + insightType: Insight.TYPE_API_ERROR_RATE, + }, + ], +}); +``` diff --git a/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts b/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts index 73cb247821560..7c81bcb218fd1 100644 --- a/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts +++ b/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts @@ -127,6 +127,13 @@ export interface TrailProps { * @default - false */ readonly isOrganizationTrail?: boolean + + /** + * A JSON string that contains the insight types you want to log on a trail. + * + * @default - No Value. + */ + readonly insightSelectors?: InsightSelector[] } /** @@ -158,6 +165,24 @@ export enum ReadWriteType { NONE = 'None', } +/** + * Util element for InsightSelector + */ +export class Insight { + + /** + * The type of insights to log on a trail. (API Call Rate) + */ + public static readonly TYPE_API_CALL_RATE = 'ApiCallRateInsight' + + /** + * The type of insights to log on a trail. (API Error Rate) + */ + public static readonly TYPE_API_ERROR_RATE = 'ApiErrorRateInsight' + + protected constructor(public readonly value: string) {} +} + /** * Cloud trail allows you to log events that happen in your AWS account * For example: @@ -298,6 +323,7 @@ export class Trail extends Resource { snsTopicName: this.topic?.topicName, eventSelectors: this.eventSelectors, isOrganizationTrail: props.isOrganizationTrail, + insightSelectors: props.insightSelectors, }); this.trailArn = this.getResourceArnAttribute(trail.attrArn, { @@ -502,3 +528,15 @@ interface EventSelectorData { readonly type: string; readonly values: string[]; } + +/** + * A JSON string that contains a list of insight types that are logged on a trail. + */ +export interface InsightSelector { + /** + * The type of insights to log on a trail. + * + * @default - No Value. + */ + readonly insightType?: string; +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/package.json b/packages/@aws-cdk/aws-cloudtrail/package.json index 17df9eddd0812..c6ca701fe34b9 100644 --- a/packages/@aws-cdk/aws-cloudtrail/package.json +++ b/packages/@aws-cdk/aws-cloudtrail/package.json @@ -115,7 +115,8 @@ }, "awslint": { "exclude": [ - "events-method-signature:@aws-cdk/aws-cloudtrail.Trail.onEvent" + "events-method-signature:@aws-cdk/aws-cloudtrail.Trail.onEvent", + "docs-public-apis:@aws-cdk/aws-cloudtrail.Insight.value" ] }, "engines": { diff --git a/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts b/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts index 9cb6149775fb1..dc5db15a8863c 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts +++ b/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts @@ -7,7 +7,7 @@ import * as s3 from '@aws-cdk/aws-s3'; import * as sns from '@aws-cdk/aws-sns'; import { testDeprecated } from '@aws-cdk/cdk-build-tools'; import { Stack } from '@aws-cdk/core'; -import { ManagementEventSources, ReadWriteType, Trail } from '../lib'; +import { ManagementEventSources, ReadWriteType, Trail, Insight } from '../lib'; const ExpectedBucketPolicyProperties = { PolicyDocument: { @@ -702,4 +702,91 @@ describe('cloudtrail', () => { }); }); }); -}); + describe('insights ', () => { + test('no properties', () => { + const stack = getTestStack(); + new Trail(stack, 'MyAmazingCloudTrail', { + insightSelectors: [], + }); + Template.fromStack(stack).hasResourceProperties('AWS::CloudTrail::Trail', { + InsightSelectors: [], + }); + }); + test('API Call Rate properties', () => { + const stack = getTestStack(); + new Trail(stack, 'MyAmazingCloudTrail', { + insightSelectors: [ + { + insightType: Insight.TYPE_API_CALL_RATE, + }, + ], + }); + Template.fromStack(stack).hasResourceProperties('AWS::CloudTrail::Trail', { + InsightSelectors: [{ + InsightType: 'ApiCallRateInsight', + }], + }); + }); + test('API Call Rate properties', () => { + const stack = getTestStack(); + new Trail(stack, 'MyAmazingCloudTrail', { + insightSelectors: [ + { + insightType: Insight.TYPE_API_ERROR_RATE, + }, + ], + }); + Template.fromStack(stack).hasResourceProperties('AWS::CloudTrail::Trail', { + InsightSelectors: [{ + InsightType: 'ApiErrorRateInsight', + }], + }); + }); + test('duplicate properties', () => { + const stack = getTestStack(); + new Trail(stack, 'MyAmazingCloudTrail', { + insightSelectors: [ + { + insightType: Insight.TYPE_API_CALL_RATE, + }, + { + insightType: Insight.TYPE_API_CALL_RATE, + }, + ], + }); + Template.fromStack(stack).hasResourceProperties('AWS::CloudTrail::Trail', { + InsightSelectors: [ + { + InsightType: 'ApiCallRateInsight', + }, + { + InsightType: 'ApiCallRateInsight', + }, + ], + }); + }); + test('ALL properties', () => { + const stack = getTestStack(); + new Trail(stack, 'MyAmazingCloudTrail', { + insightSelectors: [ + { + insightType: Insight.TYPE_API_CALL_RATE, + }, + { + insightType: Insight.TYPE_API_ERROR_RATE, + }, + ], + }); + Template.fromStack(stack).hasResourceProperties('AWS::CloudTrail::Trail', { + InsightSelectors: [ + { + InsightType: 'ApiCallRateInsight', + }, + { + InsightType: 'ApiErrorRateInsight', + }, + ], + }); + }); + }); +}); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js new file mode 100644 index 0000000000000..1e3a3093c1706 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js @@ -0,0 +1,144 @@ +"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, + }; + exports.external.log('submit response to cloudformation', json); + const responseBody = JSON.stringify(json); + const parsedUrl = url.parse(event.ResponseURL); + const req = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: 'PUT', + headers: { 'content-type': '', 'content-length': responseBody.length }, + }; + const retryOptions = { + attempts: 5, + sleep: 1000, + }; + await withRetries(retryOptions, exports.external.sendHttpRequest)(req, responseBody); +} +async function defaultSendHttpRequest(options, responseBody) { + return new Promise((resolve, reject) => { + try { + const request = https.request(options, _ => resolve()); + request.on('error', reject); + request.write(responseBody); + 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZWpzLWVudHJ5cG9pbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJub2RlanMtZW50cnlwb2ludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQkFBK0I7QUFDL0IsMkJBQTJCO0FBRTNCLGlCQUFpQjtBQUNKLFFBQUEsUUFBUSxHQUFHO0lBQ3RCLGVBQWUsRUFBRSxzQkFBc0I7SUFDdkMsR0FBRyxFQUFFLFVBQVU7SUFDZixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGdCQUFnQixFQUFFLFNBQVM7Q0FDNUIsQ0FBQztBQUVGLE1BQU0sZ0NBQWdDLEdBQUcsd0RBQXdELENBQUM7QUFDbEcsTUFBTSwwQkFBMEIsR0FBRyw4REFBOEQsQ0FBQztBQVczRixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDeEQsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFM0QsdUVBQXVFO0lBQ3ZFLHVFQUF1RTtJQUN2RSxhQUFhO0lBQ2IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEtBQUssZ0NBQWdDLEVBQUU7UUFDbkcsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN0RSxNQUFNLGNBQWMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkMsT0FBTztLQUNSO0lBRUQsSUFBSTtRQUNGLHlFQUF5RTtRQUN6RSxpRUFBaUU7UUFDakUsd0NBQXdDO1FBQ3hDLGlFQUFpRTtRQUNqRSxNQUFNLFdBQVcsR0FBWSxPQUFPLENBQUMsZ0JBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4RSxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFMUQsdURBQXVEO1FBQ3ZELE1BQU0sYUFBYSxHQUFHLGNBQWMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFcEQsMkJBQTJCO1FBQzNCLE1BQU0sY0FBYyxDQUFDLFNBQVMsRUFBRSxhQUFhLENBQUMsQ0FBQztLQUNoRDtJQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQ1YsTUFBTSxJQUFJLEdBQWE7WUFDckIsR0FBRyxLQUFLO1lBQ1IsTUFBTSxFQUFFLGdCQUFRLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPO1NBQzFELENBQUM7UUFFRixJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQzVCLHlFQUF5RTtZQUN6RSxtRUFBbUU7WUFDbkUsd0VBQXdFO1lBQ3hFLHFFQUFxRTtZQUNyRSxnQ0FBZ0M7WUFDaEMsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtnQkFDbEMsZ0JBQVEsQ0FBQyxHQUFHLENBQUMsNEdBQTRHLENBQUMsQ0FBQztnQkFDM0gsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGdDQUFnQyxDQUFDO2FBQzVEO2lCQUFNO2dCQUNMLGtFQUFrRTtnQkFDbEUsNkRBQTZEO2dCQUM3RCxnQkFBUSxDQUFDLEdBQUcsQ0FBQyw2REFBNkQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDcEc7U0FDRjtRQUVELG1FQUFtRTtRQUNuRSxNQUFNLGNBQWMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7S0FDdEM7QUFDSCxDQUFDO0FBbkRELDBCQW1EQztBQUVELFNBQVMsY0FBYyxDQUNyQixVQUF5RixFQUN6RixrQkFBMEMsRUFBRztJQUU3QyxzRUFBc0U7SUFDdEUsdUJBQXVCO0lBQ3ZCLE1BQU0sa0JBQWtCLEdBQUcsZUFBZSxDQUFDLGtCQUFrQixJQUFJLFVBQVUsQ0FBQyxrQkFBa0IsSUFBSSxVQUFVLENBQUMsU0FBUyxDQUFDO0lBRXZILGtFQUFrRTtJQUNsRSxJQUFJLFVBQVUsQ0FBQyxXQUFXLEtBQUssUUFBUSxJQUFJLGtCQUFrQixLQUFLLFVBQVUsQ0FBQyxrQkFBa0IsRUFBRTtRQUMvRixNQUFNLElBQUksS0FBSyxDQUFDLHdEQUF3RCxVQUFVLENBQUMsa0JBQWtCLFNBQVMsZUFBZSxDQUFDLGtCQUFrQixtQkFBbUIsQ0FBQyxDQUFDO0tBQ3RLO0lBRUQsMERBQTBEO0lBQzFELE9BQU87UUFDTCxHQUFHLFVBQVU7UUFDYixHQUFHLGVBQWU7UUFDbEIsa0JBQWtCLEVBQUUsa0JBQWtCO0tBQ3ZDLENBQUM7QUFDSixDQUFDO0FBRUQsS0FBSyxVQUFVLGNBQWMsQ0FBQyxNQUE0QixFQUFFLEtBQWU7SUFDekUsTUFBTSxJQUFJLEdBQW1EO1FBQzNELE1BQU0sRUFBRSxNQUFNO1FBQ2QsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLElBQUksTUFBTTtRQUM5QixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87UUFDdEIsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO1FBQzFCLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxrQkFBa0IsSUFBSSwwQkFBMEI7UUFDMUUsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLGlCQUFpQjtRQUMxQyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU07UUFDcEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO0tBQ2pCLENBQUM7SUFFRixnQkFBUSxDQUFDLEdBQUcsQ0FBQyxtQ0FBbUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUV4RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFDLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQy9DLE1BQU0sR0FBRyxHQUFHO1FBQ1YsUUFBUSxFQUFFLFNBQVMsQ0FBQyxRQUFRO1FBQzVCLElBQUksRUFBRSxTQUFTLENBQUMsSUFBSTtRQUNwQixNQUFNLEVBQUUsS0FBSztRQUNiLE9BQU8sRUFBRSxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxDQUFDLE1BQU0sRUFBRTtLQUN2RSxDQUFDO0lBRUYsTUFBTSxZQUFZLEdBQUc7UUFDbkIsUUFBUSxFQUFFLENBQUM7UUFDWCxLQUFLLEVBQUUsSUFBSTtLQUNaLENBQUM7SUFDRixNQUFNLFdBQVcsQ0FBQyxZQUFZLEVBQUUsZ0JBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7QUFDL0UsQ0FBQztBQUVELEtBQUssVUFBVSxzQkFBc0IsQ0FBQyxPQUE2QixFQUFFLFlBQW9CO0lBQ3ZGLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDckMsSUFBSTtZQUNGLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUN2RCxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1QixPQUFPLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzVCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztTQUNmO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDVixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDWDtJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLEdBQVcsRUFBRSxHQUFHLE1BQWE7SUFDL0Msc0NBQXNDO0lBQ3RDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUM7QUFDOUIsQ0FBQztBQVNELFNBQWdCLFdBQVcsQ0FBMEIsT0FBcUIsRUFBRSxFQUE0QjtJQUN0RyxPQUFPLEtBQUssRUFBRSxHQUFHLEVBQUssRUFBRSxFQUFFO1FBQ3hCLElBQUksUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFDaEMsSUFBSSxFQUFFLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztRQUN2QixPQUFPLElBQUksRUFBRTtZQUNYLElBQUk7Z0JBQ0YsT0FBTyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO2FBQ3hCO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1YsSUFBSSxRQUFRLEVBQUUsSUFBSSxDQUFDLEVBQUU7b0JBQ25CLE1BQU0sQ0FBQyxDQUFDO2lCQUNUO2dCQUNELE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzVDLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDVDtTQUNGO0lBQ0gsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQWhCRCxrQ0FnQkM7QUFFRCxLQUFLLFVBQVUsS0FBSyxDQUFDLEVBQVU7SUFDN0IsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2pELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBodHRwcyBmcm9tICdodHRwcyc7XG5pbXBvcnQgKiBhcyB1cmwgZnJvbSAndXJsJztcblxuLy8gZm9yIHVuaXQgdGVzdHNcbmV4cG9ydCBjb25zdCBleHRlcm5hbCA9IHtcbiAgc2VuZEh0dHBSZXF1ZXN0OiBkZWZhdWx0U2VuZEh0dHBSZXF1ZXN0LFxuICBsb2c6IGRlZmF1bHRMb2csXG4gIGluY2x1ZGVTdGFja1RyYWNlczogdHJ1ZSxcbiAgdXNlckhhbmRsZXJJbmRleDogJy4vaW5kZXgnLFxufTtcblxuY29uc3QgQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVIgPSAnQVdTQ0RLOjpDdXN0b21SZXNvdXJjZVByb3ZpZGVyRnJhbWV3b3JrOjpDUkVBVEVfRkFJTEVEJztcbmNvbnN0IE1JU1NJTkdfUEhZU0lDQUxfSURfTUFSS0VSID0gJ0FXU0NESzo6Q3VzdG9tUmVzb3VyY2VQcm92aWRlckZyYW1ld29yazo6TUlTU0lOR19QSFlTSUNBTF9JRCc7XG5cbmV4cG9ydCB0eXBlIFJlc3BvbnNlID0gQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCAmIEhhbmRsZXJSZXNwb25zZTtcbmV4cG9ydCB0eXBlIEhhbmRsZXIgPSAoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSA9PiBQcm9taXNlPEhhbmRsZXJSZXNwb25zZSB8IHZvaWQ+O1xuZXhwb3J0IHR5cGUgSGFuZGxlclJlc3BvbnNlID0gdW5kZWZpbmVkIHwge1xuICBEYXRhPzogYW55O1xuICBQaHlzaWNhbFJlc291cmNlSWQ/OiBzdHJpbmc7XG4gIFJlYXNvbj86IHN0cmluZztcbiAgTm9FY2hvPzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50LCBjb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dCkge1xuICBjb25zdCBzYW5pdGl6ZWRFdmVudCA9IHsgLi4uZXZlbnQsIFJlc3BvbnNlVVJMOiAnLi4uJyB9O1xuICBleHRlcm5hbC5sb2coSlNPTi5zdHJpbmdpZnkoc2FuaXRpemVkRXZlbnQsIHVuZGVmaW5lZCwgMikpO1xuXG4gIC8vIGlnbm9yZSBERUxFVEUgZXZlbnQgd2hlbiB0aGUgcGh5c2ljYWwgcmVzb3VyY2UgSUQgaXMgdGhlIG1hcmtlciB0aGF0XG4gIC8vIGluZGljYXRlcyB0aGF0IHRoaXMgREVMRVRFIGlzIGEgc3Vic2VxdWVudCBERUxFVEUgdG8gYSBmYWlsZWQgQ1JFQVRFXG4gIC8vIG9wZXJhdGlvbi5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJyAmJiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgPT09IENSRUFURV9GQUlMRURfUEhZU0lDQUxfSURfTUFSS0VSKSB7XG4gICAgZXh0ZXJuYWwubG9nKCdpZ25vcmluZyBERUxFVEUgZXZlbnQgY2F1c2VkIGJ5IGEgZmFpbGVkIENSRUFURSBldmVudCcpO1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgZXZlbnQpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgLy8gaW52b2tlIHRoZSB1c2VyIGhhbmRsZXIuIHRoaXMgaXMgaW50ZW50aW9uYWxseSBpbnNpZGUgdGhlIHRyeS1jYXRjaCB0b1xuICAgIC8vIGVuc3VyZSB0aGF0IGlmIHRoZXJlIGlzIGFuIGVycm9yIGl0J3MgcmVwb3J0ZWQgYXMgYSBmYWlsdXJlIHRvXG4gICAgLy8gY2xvdWRmb3JtYXRpb24gKG90aGVyd2lzZSBjZm4gd2FpdHMpLlxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgY29uc3QgdXNlckhhbmRsZXI6IEhhbmRsZXIgPSByZXF1aXJlKGV4dGVybmFsLnVzZXJIYW5kbGVySW5kZXgpLmhhbmRsZXI7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdXNlckhhbmRsZXIoc2FuaXRpemVkRXZlbnQsIGNvbnRleHQpO1xuXG4gICAgLy8gdmFsaWRhdGUgdXNlciByZXNwb25zZSBhbmQgY3JlYXRlIHRoZSBjb21iaW5lZCBldmVudFxuICAgIGNvbnN0IHJlc3BvbnNlRXZlbnQgPSByZW5kZXJSZXNwb25zZShldmVudCwgcmVzdWx0KTtcblxuICAgIC8vIHN1Ym1pdCB0byBjZm4gYXMgc3VjY2Vzc1xuICAgIGF3YWl0IHN1Ym1pdFJlc3BvbnNlKCdTVUNDRVNTJywgcmVzcG9uc2VFdmVudCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zdCByZXNwOiBSZXNwb25zZSA9IHtcbiAgICAgIC4uLmV2ZW50LFxuICAgICAgUmVhc29uOiBleHRlcm5hbC5pbmNsdWRlU3RhY2tUcmFjZXMgPyBlLnN0YWNrIDogZS5tZXNzYWdlLFxuICAgIH07XG5cbiAgICBpZiAoIXJlc3AuUGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgICAvLyBzcGVjaWFsIGNhc2U6IGlmIENSRUFURSBmYWlscywgd2hpY2ggdXN1YWxseSBpbXBsaWVzLCB3ZSB1c3VhbGx5IGRvbid0XG4gICAgICAvLyBoYXZlIGEgcGh5c2ljYWwgcmVzb3VyY2UgaWQuIGluIHRoaXMgY2FzZSwgdGhlIHN1YnNlcXVlbnQgREVMRVRFXG4gICAgICAvLyBvcGVyYXRpb24gZG9lcyBub3QgaGF2ZSBhbnkgbWVhbmluZywgYW5kIHdpbGwgbGlrZWx5IGZhaWwgYXMgd2VsbC4gdG9cbiAgICAgIC8vIGFkZHJlc3MgdGhpcywgd2UgdXNlIGEgbWFya2VyIHNvIHRoZSBwcm92aWRlciBmcmFtZXdvcmsgY2FuIHNpbXBseVxuICAgICAgLy8gaWdub3JlIHRoZSBzdWJzZXF1ZW50IERFTEVURS5cbiAgICAgIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ0NyZWF0ZScpIHtcbiAgICAgICAgZXh0ZXJuYWwubG9nKCdDUkVBVEUgZmFpbGVkLCByZXNwb25kaW5nIHdpdGggYSBtYXJrZXIgcGh5c2ljYWwgcmVzb3VyY2UgaWQgc28gdGhhdCB0aGUgc3Vic2VxdWVudCBERUxFVEUgd2lsbCBiZSBpZ25vcmVkJyk7XG4gICAgICAgIHJlc3AuUGh5c2ljYWxSZXNvdXJjZUlkID0gQ1JFQVRFX0ZBSUxFRF9QSFlTSUNBTF9JRF9NQVJLRVI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBvdGhlcndpc2UsIGlmIFBoeXNpY2FsUmVzb3VyY2VJZCBpcyBub3Qgc3BlY2lmaWVkLCBzb21ldGhpbmcgaXNcbiAgICAgICAgLy8gdGVycmlibHkgd3JvbmcgYmVjYXVzZSBhbGwgb3RoZXIgZXZlbnRzIHNob3VsZCBoYXZlIGFuIElELlxuICAgICAgICBleHRlcm5hbC5sb2coYEVSUk9SOiBNYWxmb3JtZWQgZXZlbnQuIFwiUGh5c2ljYWxSZXNvdXJjZUlkXCIgaXMgcmVxdWlyZWQ6ICR7SlNPTi5zdHJpbmdpZnkoZXZlbnQpfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHRoaXMgaXMgYW4gYWN0dWFsIGVycm9yLCBmYWlsIHRoZSBhY3Rpdml0eSBhbHRvZ2V0aGVyIGFuZCBleGlzdC5cbiAgICBhd2FpdCBzdWJtaXRSZXNwb25zZSgnRkFJTEVEJywgcmVzcCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVuZGVyUmVzcG9uc2UoXG4gIGNmblJlcXVlc3Q6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQgJiB7IFBoeXNpY2FsUmVzb3VyY2VJZD86IHN0cmluZyB9LFxuICBoYW5kbGVyUmVzcG9uc2U6IHZvaWQgfCBIYW5kbGVyUmVzcG9uc2UgPSB7IH0pOiBSZXNwb25zZSB7XG5cbiAgLy8gaWYgcGh5c2ljYWwgSUQgaXMgbm90IHJldHVybmVkLCB3ZSBoYXZlIHNvbWUgZGVmYXVsdHMgZm9yIHlvdSBiYXNlZFxuICAvLyBvbiB0aGUgcmVxdWVzdCB0eXBlLlxuICBjb25zdCBwaHlzaWNhbFJlc291cmNlSWQgPSBoYW5kbGVyUmVzcG9uc2UuUGh5c2ljYWxSZXNvdXJjZUlkID8/IGNmblJlcXVlc3QuUGh5c2ljYWxSZXNvdXJjZUlkID8/IGNmblJlcXVlc3QuUmVxdWVzdElkO1xuXG4gIC8vIGlmIHdlIGFyZSBpbiBERUxFVEUgYW5kIHBoeXNpY2FsIElEIHdhcyBjaGFuZ2VkLCBpdCdzIGFuIGVycm9yLlxuICBpZiAoY2ZuUmVxdWVzdC5SZXF1ZXN0VHlwZSA9PT0gJ0RlbGV0ZScgJiYgcGh5c2ljYWxSZXNvdXJjZUlkICE9PSBjZm5SZXF1ZXN0LlBoeXNpY2FsUmVzb3VyY2VJZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgREVMRVRFOiBjYW5ub3QgY2hhbmdlIHRoZSBwaHlzaWNhbCByZXNvdXJjZSBJRCBmcm9tIFwiJHtjZm5SZXF1ZXN0LlBoeXNpY2FsUmVzb3VyY2VJZH1cIiB0byBcIiR7aGFuZGxlclJlc3BvbnNlLlBoeXNpY2FsUmVzb3VyY2VJZH1cIiBkdXJpbmcgZGVsZXRpb25gKTtcbiAgfVxuXG4gIC8vIG1lcmdlIHJlcXVlc3QgZXZlbnQgYW5kIHJlc3VsdCBldmVudCAocmVzdWx0IHByZXZhaWxzKS5cbiAgcmV0dXJuIHtcbiAgICAuLi5jZm5SZXF1ZXN0LFxuICAgIC4uLmhhbmRsZXJSZXNwb25zZSxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IHBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc3VibWl0UmVzcG9uc2Uoc3RhdHVzOiAnU1VDQ0VTUycgfCAnRkFJTEVEJywgZXZlbnQ6IFJlc3BvbnNlKSB7XG4gIGNvbnN0IGpzb246IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlUmVzcG9uc2UgPSB7XG4gICAgU3RhdHVzOiBzdGF0dXMsXG4gICAgUmVhc29uOiBldmVudC5SZWFzb24gPz8gc3RhdHVzLFxuICAgIFN0YWNrSWQ6IGV2ZW50LlN0YWNrSWQsXG4gICAgUmVxdWVzdElkOiBldmVudC5SZXF1ZXN0SWQsXG4gICAgUGh5c2ljYWxSZXNvdXJjZUlkOiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgfHwgTUlTU0lOR19QSFlTSUNBTF9JRF9NQVJLRVIsXG4gICAgTG9naWNhbFJlc291cmNlSWQ6IGV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkLFxuICAgIE5vRWNobzogZXZlbnQuTm9FY2hvLFxuICAgIERhdGE6IGV2ZW50LkRhdGEsXG4gIH07XG5cbiAgZXh0ZXJuYWwubG9nKCdzdWJtaXQgcmVzcG9uc2UgdG8gY2xvdWRmb3JtYXRpb24nLCBqc29uKTtcblxuICBjb25zdCByZXNwb25zZUJvZHkgPSBKU09OLnN0cmluZ2lmeShqc29uKTtcbiAgY29uc3QgcGFyc2VkVXJsID0gdXJsLnBhcnNlKGV2ZW50LlJlc3BvbnNlVVJMKTtcbiAgY29uc3QgcmVxID0ge1xuICAgIGhvc3RuYW1lOiBwYXJzZWRVcmwuaG9zdG5hbWUsXG4gICAgcGF0aDogcGFyc2VkVXJsLnBhdGgsXG4gICAgbWV0aG9kOiAnUFVUJyxcbiAgICBoZWFkZXJzOiB7ICdjb250ZW50LXR5cGUnOiAnJywgJ2NvbnRlbnQtbGVuZ3RoJzogcmVzcG9uc2VCb2R5Lmxlbmd0aCB9LFxuICB9O1xuXG4gIGNvbnN0IHJldHJ5T3B0aW9ucyA9IHtcbiAgICBhdHRlbXB0czogNSxcbiAgICBzbGVlcDogMTAwMCxcbiAgfTtcbiAgYXdhaXQgd2l0aFJldHJpZXMocmV0cnlPcHRpb25zLCBleHRlcm5hbC5zZW5kSHR0cFJlcXVlc3QpKHJlcSwgcmVzcG9uc2VCb2R5KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZGVmYXVsdFNlbmRIdHRwUmVxdWVzdChvcHRpb25zOiBodHRwcy5SZXF1ZXN0T3B0aW9ucywgcmVzcG9uc2VCb2R5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IGh0dHBzLnJlcXVlc3Qob3B0aW9ucywgXyA9PiByZXNvbHZlKCkpO1xuICAgICAgcmVxdWVzdC5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgcmVxdWVzdC53cml0ZShyZXNwb25zZUJvZHkpO1xuICAgICAgcmVxdWVzdC5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZSk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdExvZyhmbXQ6IHN0cmluZywgLi4ucGFyYW1zOiBhbnlbXSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLmxvZyhmbXQsIC4uLnBhcmFtcyk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmV0cnlPcHRpb25zIHtcbiAgLyoqIEhvdyBtYW55IHJldHJpZXMgKHdpbGwgYXQgbGVhc3QgdHJ5IG9uY2UpICovXG4gIHJlYWRvbmx5IGF0dGVtcHRzOiBudW1iZXI7XG4gIC8qKiBTbGVlcCBiYXNlLCBpbiBtcyAqL1xuICByZWFkb25seSBzbGVlcDogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aFJldHJpZXM8QSBleHRlbmRzIEFycmF5PGFueT4sIEI+KG9wdGlvbnM6IFJldHJ5T3B0aW9ucywgZm46ICguLi54czogQSkgPT4gUHJvbWlzZTxCPik6ICguLi54czogQSkgPT4gUHJvbWlzZTxCPiB7XG4gIHJldHVybiBhc3luYyAoLi4ueHM6IEEpID0+IHtcbiAgICBsZXQgYXR0ZW1wdHMgPSBvcHRpb25zLmF0dGVtcHRzO1xuICAgIGxldCBtcyA9IG9wdGlvbnMuc2xlZXA7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmbiguLi54cyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChhdHRlbXB0cy0tIDw9IDApIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHNsZWVwKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIG1zKSk7XG4gICAgICAgIG1zICo9IDI7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgob2spID0+IHNldFRpbWVvdXQob2ssIG1zKSk7XG59Il19 \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js new file mode 100644 index 0000000000000..7ce4156d4ba41 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js @@ -0,0 +1,78 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.handler = void 0; +// eslint-disable-next-line import/no-extraneous-dependencies +const aws_sdk_1 = require("aws-sdk"); +const AUTO_DELETE_OBJECTS_TAG = 'aws-cdk:auto-delete-objects'; +const s3 = new aws_sdk_1.S3(); +async function handler(event) { + switch (event.RequestType) { + case 'Create': + return; + case 'Update': + return onUpdate(event); + case 'Delete': + return onDelete(event.ResourceProperties?.BucketName); + } +} +exports.handler = handler; +async function onUpdate(event) { + const updateEvent = event; + const oldBucketName = updateEvent.OldResourceProperties?.BucketName; + const newBucketName = updateEvent.ResourceProperties?.BucketName; + const bucketNameHasChanged = newBucketName != null && oldBucketName != null && newBucketName !== oldBucketName; + /* If the name of the bucket has changed, CloudFormation will try to delete the bucket + and create a new one with the new name. So we have to delete the contents of the + bucket so that this operation does not fail. */ + if (bucketNameHasChanged) { + return onDelete(oldBucketName); + } +} +/** + * Recursively delete all items in the bucket + * + * @param bucketName the bucket name + */ +async function emptyBucket(bucketName) { + const listedObjects = await s3.listObjectVersions({ Bucket: bucketName }).promise(); + const contents = [...listedObjects.Versions ?? [], ...listedObjects.DeleteMarkers ?? []]; + if (contents.length === 0) { + return; + } + const records = contents.map((record) => ({ Key: record.Key, VersionId: record.VersionId })); + await s3.deleteObjects({ Bucket: bucketName, Delete: { Objects: records } }).promise(); + if (listedObjects?.IsTruncated) { + await emptyBucket(bucketName); + } +} +async function onDelete(bucketName) { + if (!bucketName) { + throw new Error('No BucketName was provided.'); + } + if (!await isBucketTaggedForDeletion(bucketName)) { + process.stdout.write(`Bucket does not have '${AUTO_DELETE_OBJECTS_TAG}' tag, skipping cleaning.\n`); + return; + } + try { + await emptyBucket(bucketName); + } + catch (e) { + if (e.code !== 'NoSuchBucket') { + throw e; + } + // Bucket doesn't exist. Ignoring + } +} +/** + * The bucket will only be tagged for deletion if it's being deleted in the same + * deployment as this Custom Resource. + * + * If the Custom Resource is every deleted before the bucket, it must be because + * `autoDeleteObjects` has been switched to false, in which case the tag would have + * been removed before we get to this Delete event. + */ +async function isBucketTaggedForDeletion(bucketName) { + const response = await s3.getBucketTagging({ Bucket: bucketName }).promise(); + return response.TagSet.some(tag => tag.Key === AUTO_DELETE_OBJECTS_TAG && tag.Value === 'true'); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2REFBNkQ7QUFDN0QscUNBQTZCO0FBRTdCLE1BQU0sdUJBQXVCLEdBQUcsNkJBQTZCLENBQUM7QUFFOUQsTUFBTSxFQUFFLEdBQUcsSUFBSSxZQUFFLEVBQUUsQ0FBQztBQUViLEtBQUssVUFBVSxPQUFPLENBQUMsS0FBa0Q7SUFDOUUsUUFBUSxLQUFLLENBQUMsV0FBVyxFQUFFO1FBQ3pCLEtBQUssUUFBUTtZQUNYLE9BQU87UUFDVCxLQUFLLFFBQVE7WUFDWCxPQUFPLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QixLQUFLLFFBQVE7WUFDWCxPQUFPLFFBQVEsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEVBQUUsVUFBVSxDQUFDLENBQUM7S0FDekQ7QUFDSCxDQUFDO0FBVEQsMEJBU0M7QUFFRCxLQUFLLFVBQVUsUUFBUSxDQUFDLEtBQWtEO0lBQ3hFLE1BQU0sV0FBVyxHQUFHLEtBQTBELENBQUM7SUFDL0UsTUFBTSxhQUFhLEdBQUcsV0FBVyxDQUFDLHFCQUFxQixFQUFFLFVBQVUsQ0FBQztJQUNwRSxNQUFNLGFBQWEsR0FBRyxXQUFXLENBQUMsa0JBQWtCLEVBQUUsVUFBVSxDQUFDO0lBQ2pFLE1BQU0sb0JBQW9CLEdBQUcsYUFBYSxJQUFJLElBQUksSUFBSSxhQUFhLElBQUksSUFBSSxJQUFJLGFBQWEsS0FBSyxhQUFhLENBQUM7SUFFL0c7O3NEQUVrRDtJQUNsRCxJQUFJLG9CQUFvQixFQUFFO1FBQ3hCLE9BQU8sUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0tBQ2hDO0FBQ0gsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxLQUFLLFVBQVUsV0FBVyxDQUFDLFVBQWtCO0lBQzNDLE1BQU0sYUFBYSxHQUFHLE1BQU0sRUFBRSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDcEYsTUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxRQUFRLElBQUksRUFBRSxFQUFFLEdBQUcsYUFBYSxDQUFDLGFBQWEsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN6RixJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1FBQ3pCLE9BQU87S0FDUjtJQUVELE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFXLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLEdBQUcsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNsRyxNQUFNLEVBQUUsQ0FBQyxhQUFhLENBQUMsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFFdkYsSUFBSSxhQUFhLEVBQUUsV0FBVyxFQUFFO1FBQzlCLE1BQU0sV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0tBQy9CO0FBQ0gsQ0FBQztBQUVELEtBQUssVUFBVSxRQUFRLENBQUMsVUFBbUI7SUFDekMsSUFBSSxDQUFDLFVBQVUsRUFBRTtRQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLENBQUMsQ0FBQztLQUNoRDtJQUNELElBQUksQ0FBQyxNQUFNLHlCQUF5QixDQUFDLFVBQVUsQ0FBQyxFQUFFO1FBQ2hELE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5Qix1QkFBdUIsNkJBQTZCLENBQUMsQ0FBQztRQUNwRyxPQUFPO0tBQ1I7SUFDRCxJQUFJO1FBQ0YsTUFBTSxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUM7S0FDL0I7SUFBQyxPQUFPLENBQUMsRUFBRTtRQUNWLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxjQUFjLEVBQUU7WUFDN0IsTUFBTSxDQUFDLENBQUM7U0FDVDtRQUNELGlDQUFpQztLQUNsQztBQUNILENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsS0FBSyxVQUFVLHlCQUF5QixDQUFDLFVBQWtCO0lBQ3pELE1BQU0sUUFBUSxHQUFHLE1BQU0sRUFBRSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDN0UsT0FBTyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssdUJBQXVCLElBQUksR0FBRyxDQUFDLEtBQUssS0FBSyxNQUFNLENBQUMsQ0FBQztBQUNsRyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llc1xuaW1wb3J0IHsgUzMgfSBmcm9tICdhd3Mtc2RrJztcblxuY29uc3QgQVVUT19ERUxFVEVfT0JKRUNUU19UQUcgPSAnYXdzLWNkazphdXRvLWRlbGV0ZS1vYmplY3RzJztcblxuY29uc3QgczMgPSBuZXcgUzMoKTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQpIHtcbiAgc3dpdGNoIChldmVudC5SZXF1ZXN0VHlwZSkge1xuICAgIGNhc2UgJ0NyZWF0ZSc6XG4gICAgICByZXR1cm47XG4gICAgY2FzZSAnVXBkYXRlJzpcbiAgICAgIHJldHVybiBvblVwZGF0ZShldmVudCk7XG4gICAgY2FzZSAnRGVsZXRlJzpcbiAgICAgIHJldHVybiBvbkRlbGV0ZShldmVudC5SZXNvdXJjZVByb3BlcnRpZXM/LkJ1Y2tldE5hbWUpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG9uVXBkYXRlKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50KSB7XG4gIGNvbnN0IHVwZGF0ZUV2ZW50ID0gZXZlbnQgYXMgQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VVcGRhdGVFdmVudDtcbiAgY29uc3Qgb2xkQnVja2V0TmFtZSA9IHVwZGF0ZUV2ZW50Lk9sZFJlc291cmNlUHJvcGVydGllcz8uQnVja2V0TmFtZTtcbiAgY29uc3QgbmV3QnVja2V0TmFtZSA9IHVwZGF0ZUV2ZW50LlJlc291cmNlUHJvcGVydGllcz8uQnVja2V0TmFtZTtcbiAgY29uc3QgYnVja2V0TmFtZUhhc0NoYW5nZWQgPSBuZXdCdWNrZXROYW1lICE9IG51bGwgJiYgb2xkQnVja2V0TmFtZSAhPSBudWxsICYmIG5ld0J1Y2tldE5hbWUgIT09IG9sZEJ1Y2tldE5hbWU7XG5cbiAgLyogSWYgdGhlIG5hbWUgb2YgdGhlIGJ1Y2tldCBoYXMgY2hhbmdlZCwgQ2xvdWRGb3JtYXRpb24gd2lsbCB0cnkgdG8gZGVsZXRlIHRoZSBidWNrZXRcbiAgICAgYW5kIGNyZWF0ZSBhIG5ldyBvbmUgd2l0aCB0aGUgbmV3IG5hbWUuIFNvIHdlIGhhdmUgdG8gZGVsZXRlIHRoZSBjb250ZW50cyBvZiB0aGVcbiAgICAgYnVja2V0IHNvIHRoYXQgdGhpcyBvcGVyYXRpb24gZG9lcyBub3QgZmFpbC4gKi9cbiAgaWYgKGJ1Y2tldE5hbWVIYXNDaGFuZ2VkKSB7XG4gICAgcmV0dXJuIG9uRGVsZXRlKG9sZEJ1Y2tldE5hbWUpO1xuICB9XG59XG5cbi8qKlxuICogUmVjdXJzaXZlbHkgZGVsZXRlIGFsbCBpdGVtcyBpbiB0aGUgYnVja2V0XG4gKlxuICogQHBhcmFtIGJ1Y2tldE5hbWUgdGhlIGJ1Y2tldCBuYW1lXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGVtcHR5QnVja2V0KGJ1Y2tldE5hbWU6IHN0cmluZykge1xuICBjb25zdCBsaXN0ZWRPYmplY3RzID0gYXdhaXQgczMubGlzdE9iamVjdFZlcnNpb25zKHsgQnVja2V0OiBidWNrZXROYW1lIH0pLnByb21pc2UoKTtcbiAgY29uc3QgY29udGVudHMgPSBbLi4ubGlzdGVkT2JqZWN0cy5WZXJzaW9ucyA/PyBbXSwgLi4ubGlzdGVkT2JqZWN0cy5EZWxldGVNYXJrZXJzID8/IFtdXTtcbiAgaWYgKGNvbnRlbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHJlY29yZHMgPSBjb250ZW50cy5tYXAoKHJlY29yZDogYW55KSA9PiAoeyBLZXk6IHJlY29yZC5LZXksIFZlcnNpb25JZDogcmVjb3JkLlZlcnNpb25JZCB9KSk7XG4gIGF3YWl0IHMzLmRlbGV0ZU9iamVjdHMoeyBCdWNrZXQ6IGJ1Y2tldE5hbWUsIERlbGV0ZTogeyBPYmplY3RzOiByZWNvcmRzIH0gfSkucHJvbWlzZSgpO1xuXG4gIGlmIChsaXN0ZWRPYmplY3RzPy5Jc1RydW5jYXRlZCkge1xuICAgIGF3YWl0IGVtcHR5QnVja2V0KGJ1Y2tldE5hbWUpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG9uRGVsZXRlKGJ1Y2tldE5hbWU/OiBzdHJpbmcpIHtcbiAgaWYgKCFidWNrZXROYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdObyBCdWNrZXROYW1lIHdhcyBwcm92aWRlZC4nKTtcbiAgfVxuICBpZiAoIWF3YWl0IGlzQnVja2V0VGFnZ2VkRm9yRGVsZXRpb24oYnVja2V0TmFtZSkpIHtcbiAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShgQnVja2V0IGRvZXMgbm90IGhhdmUgJyR7QVVUT19ERUxFVEVfT0JKRUNUU19UQUd9JyB0YWcsIHNraXBwaW5nIGNsZWFuaW5nLlxcbmApO1xuICAgIHJldHVybjtcbiAgfVxuICB0cnkge1xuICAgIGF3YWl0IGVtcHR5QnVja2V0KGJ1Y2tldE5hbWUpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKGUuY29kZSAhPT0gJ05vU3VjaEJ1Y2tldCcpIHtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICAgIC8vIEJ1Y2tldCBkb2Vzbid0IGV4aXN0LiBJZ25vcmluZ1xuICB9XG59XG5cbi8qKlxuICogVGhlIGJ1Y2tldCB3aWxsIG9ubHkgYmUgdGFnZ2VkIGZvciBkZWxldGlvbiBpZiBpdCdzIGJlaW5nIGRlbGV0ZWQgaW4gdGhlIHNhbWVcbiAqIGRlcGxveW1lbnQgYXMgdGhpcyBDdXN0b20gUmVzb3VyY2UuXG4gKlxuICogSWYgdGhlIEN1c3RvbSBSZXNvdXJjZSBpcyBldmVyeSBkZWxldGVkIGJlZm9yZSB0aGUgYnVja2V0LCBpdCBtdXN0IGJlIGJlY2F1c2VcbiAqIGBhdXRvRGVsZXRlT2JqZWN0c2AgaGFzIGJlZW4gc3dpdGNoZWQgdG8gZmFsc2UsIGluIHdoaWNoIGNhc2UgdGhlIHRhZyB3b3VsZCBoYXZlXG4gKiBiZWVuIHJlbW92ZWQgYmVmb3JlIHdlIGdldCB0byB0aGlzIERlbGV0ZSBldmVudC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gaXNCdWNrZXRUYWdnZWRGb3JEZWxldGlvbihidWNrZXROYW1lOiBzdHJpbmcpIHtcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzMy5nZXRCdWNrZXRUYWdnaW5nKHsgQnVja2V0OiBidWNrZXROYW1lIH0pLnByb21pc2UoKTtcbiAgcmV0dXJuIHJlc3BvbnNlLlRhZ1NldC5zb21lKHRhZyA9PiB0YWcuS2V5ID09PSBBVVRPX0RFTEVURV9PQkpFQ1RTX1RBRyAmJiB0YWcuVmFsdWUgPT09ICd0cnVlJyk7XG59Il19 \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/aws-cdk-cloudtrail-inshights-test.assets.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/aws-cdk-cloudtrail-inshights-test.assets.json new file mode 100644 index 0000000000000..411d02d2fa1ef --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/aws-cdk-cloudtrail-inshights-test.assets.json @@ -0,0 +1,32 @@ +{ + "version": "21.0.0", + "files": { + "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c": { + "source": { + "path": "asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "9e54867c184c79374c51ba171db494a5736a30294e618efa94e199b94e58868e": { + "source": { + "path": "aws-cdk-cloudtrail-inshights-test.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "9e54867c184c79374c51ba171db494a5736a30294e618efa94e199b94e58868e.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/aws-cdk-cloudtrail-inshights-test.template.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/aws-cdk-cloudtrail-inshights-test.template.json new file mode 100644 index 0000000000000..fd514eb5cee35 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/aws-cdk-cloudtrail-inshights-test.template.json @@ -0,0 +1,246 @@ +{ + "Resources": { + "S3486F821D": { + "Type": "AWS::S3::Bucket", + "Properties": { + "Tags": [ + { + "Key": "aws-cdk:auto-delete-objects", + "Value": "true" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "S3Policy2E4AA1D6": { + "Type": "AWS::S3::BucketPolicy", + "Properties": { + "Bucket": { + "Ref": "S3486F821D" + }, + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + } + }, + "Resource": [ + { + "Fn::GetAtt": [ + "S3486F821D", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "S3486F821D", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": "s3:GetBucketAcl", + "Effect": "Allow", + "Principal": { + "Service": "cloudtrail.amazonaws.com" + }, + "Resource": { + "Fn::GetAtt": [ + "S3486F821D", + "Arn" + ] + } + }, + { + "Action": "s3:PutObject", + "Condition": { + "StringEquals": { + "s3:x-amz-acl": "bucket-owner-full-control" + } + }, + "Effect": "Allow", + "Principal": { + "Service": "cloudtrail.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "S3486F821D", + "Arn" + ] + }, + "/AWSLogs/", + { + "Ref": "AWS::AccountId" + }, + "/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, + "S3AutoDeleteObjectsCustomResource5A4102C9": { + "Type": "Custom::S3AutoDeleteObjects", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F", + "Arn" + ] + }, + "BucketName": { + "Ref": "S3486F821D" + } + }, + "DependsOn": [ + "S3Policy2E4AA1D6" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092": { + "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" + } + ] + } + }, + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c.zip" + }, + "Timeout": 900, + "MemorySize": 128, + "Handler": "__entrypoint__.handler", + "Role": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + }, + "Runtime": "nodejs14.x", + "Description": { + "Fn::Join": [ + "", + [ + "Lambda function for auto-deleting objects in ", + { + "Ref": "S3486F821D" + }, + " S3 bucket." + ] + ] + } + }, + "DependsOn": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092" + ] + }, + "Trail022F0CF2": { + "Type": "AWS::CloudTrail::Trail", + "Properties": { + "IsLogging": true, + "S3BucketName": { + "Ref": "S3486F821D" + }, + "EnableLogFileValidation": true, + "EventSelectors": [], + "IncludeGlobalServiceEvents": true, + "InsightSelectors": [ + { + "InsightType": "ApiCallRateInsight" + }, + { + "InsightType": "ApiErrorRateInsight" + } + ], + "IsMultiRegionTrail": true + }, + "DependsOn": [ + "S3Policy2E4AA1D6" + ] + } + }, + "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/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets.json new file mode 100644 index 0000000000000..afee199576ba7 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets.json @@ -0,0 +1,19 @@ +{ + "version": "21.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.template.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.template.json @@ -0,0 +1,36 @@ +{ + "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/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/cdk.out b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/cdk.out new file mode 100644 index 0000000000000..8ecc185e9dbee --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"21.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.assets.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.assets.json new file mode 100644 index 0000000000000..4300df11334c9 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.assets.json @@ -0,0 +1,32 @@ +{ + "version": "21.0.0", + "files": { + "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c": { + "source": { + "path": "asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "d2a43ea3712b74bd1dad6f4e75d59911217ff1df76a21330df94cc3551a4474a": { + "source": { + "path": "integ-cloudtrail.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "d2a43ea3712b74bd1dad6f4e75d59911217ff1df76a21330df94cc3551a4474a.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.template.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.template.json new file mode 100644 index 0000000000000..90b67f5c27ead --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.template.json @@ -0,0 +1,418 @@ +{ + "Resources": { + "Bucket83908E77": { + "Type": "AWS::S3::Bucket", + "Properties": { + "Tags": [ + { + "Key": "aws-cdk:auto-delete-objects", + "Value": "true" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "BucketPolicyE9A3008A": { + "Type": "AWS::S3::BucketPolicy", + "Properties": { + "Bucket": { + "Ref": "Bucket83908E77" + }, + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetBucket*", + "s3:List*", + "s3:DeleteObject*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + } + }, + "Resource": [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "BucketAutoDeleteObjectsCustomResourceBAFD23C2": { + "Type": "Custom::S3AutoDeleteObjects", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F", + "Arn" + ] + }, + "BucketName": { + "Ref": "Bucket83908E77" + } + }, + "DependsOn": [ + "BucketPolicyE9A3008A" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092": { + "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" + } + ] + } + }, + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c.zip" + }, + "Timeout": 900, + "MemorySize": 128, + "Handler": "__entrypoint__.handler", + "Role": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + }, + "Runtime": "nodejs14.x", + "Description": { + "Fn::Join": [ + "", + [ + "Lambda function for auto-deleting objects in ", + { + "Ref": "Bucket83908E77" + }, + " S3 bucket." + ] + ] + } + }, + "DependsOn": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092" + ] + }, + "LambdaFunctionServiceRoleC555A460": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "LambdaFunctionBF21E41F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "exports.handler = {}" + }, + "Role": { + "Fn::GetAtt": [ + "LambdaFunctionServiceRoleC555A460", + "Arn" + ] + }, + "Handler": "hello.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "LambdaFunctionServiceRoleC555A460" + ] + }, + "S3486F821D": { + "Type": "AWS::S3::Bucket", + "Properties": { + "Tags": [ + { + "Key": "aws-cdk:auto-delete-objects", + "Value": "true" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "S3Policy2E4AA1D6": { + "Type": "AWS::S3::BucketPolicy", + "Properties": { + "Bucket": { + "Ref": "S3486F821D" + }, + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetBucket*", + "s3:List*", + "s3:DeleteObject*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + } + }, + "Resource": [ + { + "Fn::GetAtt": [ + "S3486F821D", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "S3486F821D", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": "s3:GetBucketAcl", + "Effect": "Allow", + "Principal": { + "Service": "cloudtrail.amazonaws.com" + }, + "Resource": { + "Fn::GetAtt": [ + "S3486F821D", + "Arn" + ] + } + }, + { + "Action": "s3:PutObject", + "Condition": { + "StringEquals": { + "s3:x-amz-acl": "bucket-owner-full-control" + } + }, + "Effect": "Allow", + "Principal": { + "Service": "cloudtrail.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "S3486F821D", + "Arn" + ] + }, + "/AWSLogs/", + { + "Ref": "AWS::AccountId" + }, + "/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, + "S3AutoDeleteObjectsCustomResource5A4102C9": { + "Type": "Custom::S3AutoDeleteObjects", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F", + "Arn" + ] + }, + "BucketName": { + "Ref": "S3486F821D" + } + }, + "DependsOn": [ + "S3Policy2E4AA1D6" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Trail022F0CF2": { + "Type": "AWS::CloudTrail::Trail", + "Properties": { + "IsLogging": true, + "S3BucketName": { + "Ref": "S3486F821D" + }, + "EnableLogFileValidation": true, + "EventSelectors": [ + { + "DataResources": [ + { + "Type": "AWS::Lambda::Function", + "Values": [ + { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + } + ] + } + ] + }, + { + "DataResources": [ + { + "Type": "AWS::S3::Object", + "Values": [ + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "/" + ] + ] + } + ] + } + ] + } + ], + "IncludeGlobalServiceEvents": true, + "InsightSelectors": [ + { + "InsightType": "ApiCallRateInsight" + }, + { + "InsightType": "ApiErrorRateInsight" + } + ], + "IsMultiRegionTrail": true + }, + "DependsOn": [ + "S3Policy2E4AA1D6" + ] + } + }, + "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/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ.json new file mode 100644 index 0000000000000..33b6b4aefeaa7 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "21.0.0", + "testCases": { + "aws-cdk-cloudtrail-inshights/DefaultTest": { + "stacks": [ + "aws-cdk-cloudtrail-inshights-test" + ], + "assertionStack": "aws-cdk-cloudtrail-inshights/DefaultTest/DeployAssert", + "assertionStackName": "awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/manifest.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/manifest.json new file mode 100644 index 0000000000000..7953daf08201f --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/manifest.json @@ -0,0 +1,141 @@ +{ + "version": "21.0.0", + "artifacts": { + "aws-cdk-cloudtrail-inshights-test.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-cdk-cloudtrail-inshights-test.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-cdk-cloudtrail-inshights-test": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-cdk-cloudtrail-inshights-test.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/9e54867c184c79374c51ba171db494a5736a30294e618efa94e199b94e58868e.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-cdk-cloudtrail-inshights-test.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-cdk-cloudtrail-inshights-test.assets" + ], + "metadata": { + "/aws-cdk-cloudtrail-inshights-test/S3/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "S3486F821D" + } + ], + "/aws-cdk-cloudtrail-inshights-test/S3/Policy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "S3Policy2E4AA1D6" + } + ], + "/aws-cdk-cloudtrail-inshights-test/S3/AutoDeleteObjectsCustomResource/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "S3AutoDeleteObjectsCustomResource5A4102C9" + } + ], + "/aws-cdk-cloudtrail-inshights-test/Custom::S3AutoDeleteObjectsCustomResourceProvider/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092" + } + ], + "/aws-cdk-cloudtrail-inshights-test/Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F" + } + ], + "/aws-cdk-cloudtrail-inshights-test/Trail/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Trail022F0CF2" + } + ], + "/aws-cdk-cloudtrail-inshights-test/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-cloudtrail-inshights-test/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-cloudtrail-inshights-test" + }, + "awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets" + ], + "metadata": { + "/aws-cdk-cloudtrail-inshights/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-cloudtrail-inshights/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-cloudtrail-inshights/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/tree.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/tree.json new file mode 100644 index 0000000000000..208617f44a1be --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/tree.json @@ -0,0 +1,333 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-cdk-cloudtrail-inshights-test": { + "id": "aws-cdk-cloudtrail-inshights-test", + "path": "aws-cdk-cloudtrail-inshights-test", + "children": { + "S3": { + "id": "S3", + "path": "aws-cdk-cloudtrail-inshights-test/S3", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-cloudtrail-inshights-test/S3/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "aws-cdk:auto-delete-objects", + "value": "true" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.CfnBucket", + "version": "0.0.0" + } + }, + "Policy": { + "id": "Policy", + "path": "aws-cdk-cloudtrail-inshights-test/S3/Policy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-cloudtrail-inshights-test/S3/Policy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::BucketPolicy", + "aws:cdk:cloudformation:props": { + "bucket": { + "Ref": "S3486F821D" + }, + "policyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + } + }, + "Resource": [ + { + "Fn::GetAtt": [ + "S3486F821D", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "S3486F821D", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": "s3:GetBucketAcl", + "Effect": "Allow", + "Principal": { + "Service": "cloudtrail.amazonaws.com" + }, + "Resource": { + "Fn::GetAtt": [ + "S3486F821D", + "Arn" + ] + } + }, + { + "Action": "s3:PutObject", + "Condition": { + "StringEquals": { + "s3:x-amz-acl": "bucket-owner-full-control" + } + }, + "Effect": "Allow", + "Principal": { + "Service": "cloudtrail.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "S3486F821D", + "Arn" + ] + }, + "/AWSLogs/", + { + "Ref": "AWS::AccountId" + }, + "/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.CfnBucketPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.BucketPolicy", + "version": "0.0.0" + } + }, + "AutoDeleteObjectsCustomResource": { + "id": "AutoDeleteObjectsCustomResource", + "path": "aws-cdk-cloudtrail-inshights-test/S3/AutoDeleteObjectsCustomResource", + "children": { + "Default": { + "id": "Default", + "path": "aws-cdk-cloudtrail-inshights-test/S3/AutoDeleteObjectsCustomResource/Default", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.Bucket", + "version": "0.0.0" + } + }, + "Custom::S3AutoDeleteObjectsCustomResourceProvider": { + "id": "Custom::S3AutoDeleteObjectsCustomResourceProvider", + "path": "aws-cdk-cloudtrail-inshights-test/Custom::S3AutoDeleteObjectsCustomResourceProvider", + "children": { + "Staging": { + "id": "Staging", + "path": "aws-cdk-cloudtrail-inshights-test/Custom::S3AutoDeleteObjectsCustomResourceProvider/Staging", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "Role": { + "id": "Role", + "path": "aws-cdk-cloudtrail-inshights-test/Custom::S3AutoDeleteObjectsCustomResourceProvider/Role", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + }, + "Handler": { + "id": "Handler", + "path": "aws-cdk-cloudtrail-inshights-test/Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CustomResourceProvider", + "version": "0.0.0" + } + }, + "Trail": { + "id": "Trail", + "path": "aws-cdk-cloudtrail-inshights-test/Trail", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-cloudtrail-inshights-test/Trail/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudTrail::Trail", + "aws:cdk:cloudformation:props": { + "isLogging": true, + "s3BucketName": { + "Ref": "S3486F821D" + }, + "enableLogFileValidation": true, + "eventSelectors": [], + "includeGlobalServiceEvents": true, + "insightSelectors": [ + { + "insightType": "ApiCallRateInsight" + }, + { + "insightType": "ApiErrorRateInsight" + } + ], + "isMultiRegionTrail": true + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-cloudtrail.CfnTrail", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-cloudtrail.Trail", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-cloudtrail-inshights-test/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-cloudtrail-inshights-test/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "aws-cdk-cloudtrail-inshights": { + "id": "aws-cdk-cloudtrail-inshights", + "path": "aws-cdk-cloudtrail-inshights", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "aws-cdk-cloudtrail-inshights/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "aws-cdk-cloudtrail-inshights/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.161" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "aws-cdk-cloudtrail-inshights/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-cloudtrail-inshights/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-cloudtrail-inshights/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.161" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts new file mode 100644 index 0000000000000..52a86617932b6 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts @@ -0,0 +1,54 @@ +import * as iam from '@aws-cdk/aws-iam'; +import * as s3 from '@aws-cdk/aws-s3'; +import { App, RemovalPolicy, Stack } from '@aws-cdk/core'; +import * as integ from '@aws-cdk/integ-tests'; + +import * as cloudtrail from '../lib'; + +class CloudTrailInsightStack extends Stack { + constructor(scope: App, id: string) { + super(scope, id); + const cloudTrailPrincipal = new iam.ServicePrincipal('cloudtrail.amazonaws.com'); + + const Trailbucket = new s3.Bucket(this, 'S3', { + encryption: s3.BucketEncryption.UNENCRYPTED, + removalPolicy: RemovalPolicy.DESTROY, + autoDeleteObjects: true, + }); + + Trailbucket.addToResourcePolicy(new iam.PolicyStatement({ + resources: [Trailbucket.bucketArn], + actions: ['s3:GetBucketAcl'], + principals: [cloudTrailPrincipal], + })); + + Trailbucket.addToResourcePolicy(new iam.PolicyStatement({ + resources: [Trailbucket.arnForObjects(`AWSLogs/${Stack.of(this).account}/*`)], + actions: ['s3:PutObject'], + principals: [cloudTrailPrincipal], + conditions: { + StringEquals: { 's3:x-amz-acl': 'bucket-owner-full-control' }, + }, + })); + + new cloudtrail.Trail(this, 'Trail', { + bucket: Trailbucket, + insightSelectors: [ + { + insightType: cloudtrail.Insight.TYPE_API_CALL_RATE, + }, + { + insightType: cloudtrail.Insight.TYPE_API_ERROR_RATE, + }, + ], + }); + }; +}; + +const app = new App(); +const stack = new CloudTrailInsightStack(app, 'aws-cdk-cloudtrail-inshights-test'); +new integ.IntegTest(app, 'aws-cdk-cloudtrail-inshights', { + testCases: [stack], +}); + +app.synth(); \ No newline at end of file From d78e983375059ad5ecb5aeb747c6a49ffeda99dd Mon Sep 17 00:00:00 2001 From: watany <76135106+watany-dev@users.noreply.github.com> Date: Sat, 26 Nov 2022 12:14:47 +0000 Subject: [PATCH 2/4] simply --- packages/@aws-cdk/aws-cloudtrail/README.md | 12 ++---- .../@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts | 28 +++++++------- packages/@aws-cdk/aws-cloudtrail/package.json | 2 +- .../aws-cloudtrail/test/cloudtrail.test.ts | 38 +++++++------------ .../test/integ.cloudtrail-insight.lit.ts | 11 ++---- 5 files changed, 35 insertions(+), 56 deletions(-) diff --git a/packages/@aws-cdk/aws-cloudtrail/README.md b/packages/@aws-cdk/aws-cloudtrail/README.md index 47443a6dc24ea..26050e56a817d 100644 --- a/packages/@aws-cdk/aws-cloudtrail/README.md +++ b/packages/@aws-cdk/aws-cloudtrail/README.md @@ -205,13 +205,9 @@ Insights selector values can be `ApiCallRateInsight`, `ApiErrorRateInsight`, or ```ts new Trail(stack, 'Insights', { - insightSelectors: [ - { - insightType: Insight.TYPE_API_CALL_RATE, - }, - { - insightType: Insight.TYPE_API_ERROR_RATE, - }, - ], + insightTypes: [ + InsightType.API_CALL_RATE, + InsightType.API_ERROR_RATE, + ], }); ``` diff --git a/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts b/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts index 7c81bcb218fd1..8161e56fab336 100644 --- a/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts +++ b/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts @@ -133,7 +133,7 @@ export interface TrailProps { * * @default - No Value. */ - readonly insightSelectors?: InsightSelector[] + readonly insightTypes?: InsightType[] } /** @@ -168,17 +168,16 @@ export enum ReadWriteType { /** * Util element for InsightSelector */ -export class Insight { - +export class InsightType { /** * The type of insights to log on a trail. (API Call Rate) */ - public static readonly TYPE_API_CALL_RATE = 'ApiCallRateInsight' + public static readonly API_CALL_RATE = new InsightType('ApiCallRateInsight'); /** * The type of insights to log on a trail. (API Error Rate) */ - public static readonly TYPE_API_ERROR_RATE = 'ApiErrorRateInsight' + public static readonly API_ERROR_RATE = new InsightType('ApiErrorRateInsight'); protected constructor(public readonly value: string) {} } @@ -238,6 +237,7 @@ export class Trail extends Resource { private s3bucket: s3.IBucket; private eventSelectors: EventSelector[] = []; private topic: sns.ITopic | undefined; + private insightTypeValues: InsightSelector[] | undefined; constructor(scope: Construct, id: string, props: TrailProps = {}) { super(scope, id, { @@ -308,6 +308,12 @@ export class Trail extends Resource { throw new Error('Both kmsKey and encryptionKey must not be specified. Use only encryptionKey'); } + if (props.insightTypes) { + this.insightTypeValues = props.insightTypes.map(function(t) { + return { insightType: t.value }; + }); + } + // TODO: not all regions support validation. Use service configuration data to fail gracefully const trail = new CfnTrail(this, 'Resource', { isLogging: true, @@ -323,7 +329,7 @@ export class Trail extends Resource { snsTopicName: this.topic?.topicName, eventSelectors: this.eventSelectors, isOrganizationTrail: props.isOrganizationTrail, - insightSelectors: props.insightSelectors, + insightSelectors: this.insightTypeValues, }); this.trailArn = this.getResourceArnAttribute(trail.attrArn, { @@ -529,14 +535,6 @@ interface EventSelectorData { readonly values: string[]; } -/** - * A JSON string that contains a list of insight types that are logged on a trail. - */ -export interface InsightSelector { - /** - * The type of insights to log on a trail. - * - * @default - No Value. - */ +interface InsightSelector { readonly insightType?: string; } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/package.json b/packages/@aws-cdk/aws-cloudtrail/package.json index c6ca701fe34b9..6ae72b8456ee3 100644 --- a/packages/@aws-cdk/aws-cloudtrail/package.json +++ b/packages/@aws-cdk/aws-cloudtrail/package.json @@ -116,7 +116,7 @@ "awslint": { "exclude": [ "events-method-signature:@aws-cdk/aws-cloudtrail.Trail.onEvent", - "docs-public-apis:@aws-cdk/aws-cloudtrail.Insight.value" + "docs-public-apis:@aws-cdk/aws-cloudtrail.InsightType.value" ] }, "engines": { diff --git a/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts b/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts index dc5db15a8863c..c041a674621e6 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts +++ b/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts @@ -7,7 +7,7 @@ import * as s3 from '@aws-cdk/aws-s3'; import * as sns from '@aws-cdk/aws-sns'; import { testDeprecated } from '@aws-cdk/cdk-build-tools'; import { Stack } from '@aws-cdk/core'; -import { ManagementEventSources, ReadWriteType, Trail, Insight } from '../lib'; +import { ManagementEventSources, ReadWriteType, Trail, InsightType } from '../lib'; const ExpectedBucketPolicyProperties = { PolicyDocument: { @@ -706,7 +706,7 @@ describe('cloudtrail', () => { test('no properties', () => { const stack = getTestStack(); new Trail(stack, 'MyAmazingCloudTrail', { - insightSelectors: [], + insightTypes: [], }); Template.fromStack(stack).hasResourceProperties('AWS::CloudTrail::Trail', { InsightSelectors: [], @@ -715,10 +715,8 @@ describe('cloudtrail', () => { test('API Call Rate properties', () => { const stack = getTestStack(); new Trail(stack, 'MyAmazingCloudTrail', { - insightSelectors: [ - { - insightType: Insight.TYPE_API_CALL_RATE, - }, + insightTypes: [ + InsightType.API_CALL_RATE, ], }); Template.fromStack(stack).hasResourceProperties('AWS::CloudTrail::Trail', { @@ -727,13 +725,11 @@ describe('cloudtrail', () => { }], }); }); - test('API Call Rate properties', () => { + test('API Error Rate properties', () => { const stack = getTestStack(); new Trail(stack, 'MyAmazingCloudTrail', { - insightSelectors: [ - { - insightType: Insight.TYPE_API_ERROR_RATE, - }, + insightTypes: [ + InsightType.API_ERROR_RATE, ], }); Template.fromStack(stack).hasResourceProperties('AWS::CloudTrail::Trail', { @@ -745,13 +741,9 @@ describe('cloudtrail', () => { test('duplicate properties', () => { const stack = getTestStack(); new Trail(stack, 'MyAmazingCloudTrail', { - insightSelectors: [ - { - insightType: Insight.TYPE_API_CALL_RATE, - }, - { - insightType: Insight.TYPE_API_CALL_RATE, - }, + insightTypes: [ + InsightType.API_CALL_RATE, + InsightType.API_CALL_RATE, ], }); Template.fromStack(stack).hasResourceProperties('AWS::CloudTrail::Trail', { @@ -768,13 +760,9 @@ describe('cloudtrail', () => { test('ALL properties', () => { const stack = getTestStack(); new Trail(stack, 'MyAmazingCloudTrail', { - insightSelectors: [ - { - insightType: Insight.TYPE_API_CALL_RATE, - }, - { - insightType: Insight.TYPE_API_ERROR_RATE, - }, + insightTypes: [ + InsightType.API_CALL_RATE, + InsightType.API_ERROR_RATE, ], }); Template.fromStack(stack).hasResourceProperties('AWS::CloudTrail::Trail', { diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts index 52a86617932b6..f1da9a675e096 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts @@ -4,6 +4,7 @@ import { App, RemovalPolicy, Stack } from '@aws-cdk/core'; import * as integ from '@aws-cdk/integ-tests'; import * as cloudtrail from '../lib'; +import { InsightType } from '../lib/cloudtrail'; class CloudTrailInsightStack extends Stack { constructor(scope: App, id: string) { @@ -33,13 +34,9 @@ class CloudTrailInsightStack extends Stack { new cloudtrail.Trail(this, 'Trail', { bucket: Trailbucket, - insightSelectors: [ - { - insightType: cloudtrail.Insight.TYPE_API_CALL_RATE, - }, - { - insightType: cloudtrail.Insight.TYPE_API_ERROR_RATE, - }, + insightTypes: [ + InsightType.API_CALL_RATE, + InsightType.API_ERROR_RATE, ], }); }; From 75ea2ab7421195ea56fe9caeb3f0998b43cec035 Mon Sep 17 00:00:00 2001 From: watany <76135106+watany-dev@users.noreply.github.com> Date: Tue, 29 Nov 2022 23:49:36 +0900 Subject: [PATCH 3/4] Update integ.cloudtrail-insight.lit.ts error import --- .../aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts index f1da9a675e096..bd6fc988c2282 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts @@ -4,7 +4,6 @@ import { App, RemovalPolicy, Stack } from '@aws-cdk/core'; import * as integ from '@aws-cdk/integ-tests'; import * as cloudtrail from '../lib'; -import { InsightType } from '../lib/cloudtrail'; class CloudTrailInsightStack extends Stack { constructor(scope: App, id: string) { @@ -35,8 +34,8 @@ class CloudTrailInsightStack extends Stack { new cloudtrail.Trail(this, 'Trail', { bucket: Trailbucket, insightTypes: [ - InsightType.API_CALL_RATE, - InsightType.API_ERROR_RATE, + cloudtrail.InsightType.API_CALL_RATE, + cloudtrail.InsightType.API_ERROR_RATE, ], }); }; @@ -48,4 +47,4 @@ new integ.IntegTest(app, 'aws-cdk-cloudtrail-inshights', { testCases: [stack], }); -app.synth(); \ No newline at end of file +app.synth(); From c801462c8030d39a263af4e9faa651a2712de21f Mon Sep 17 00:00:00 2001 From: watany <76135106+watany-dev@users.noreply.github.com> Date: Wed, 30 Nov 2022 15:04:11 +0000 Subject: [PATCH 4/4] refresh integ-test --- .../__entrypoint__.js | 0 .../index.js | 0 ...-cdk-cloudtrail-inshights-test.assets.json | 2 +- ...dk-cloudtrail-inshights-test.template.json | 0 ...efaultTestDeployAssertF7B86FF0.assets.json | 2 +- ...aultTestDeployAssertF7B86FF0.template.json | 0 .../cdk.out | 1 + .../integ.json | 2 +- .../manifest.json | 2 +- .../tree.json | 0 .../cdk.out | 1 - .../integ-cloudtrail.assets.json | 32 -- .../integ-cloudtrail.template.json | 418 ------------------ .../test/integ.cloudtrail-insight.lit.ts | 50 --- .../test/integ.cloudtrail-insight.ts | 47 ++ 15 files changed, 52 insertions(+), 505 deletions(-) rename packages/@aws-cdk/aws-cloudtrail/test/{integ.cloudtrail-insight.lit.js.snapshot => integ.cloudtrail-insight.js.snapshot}/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js (100%) rename packages/@aws-cdk/aws-cloudtrail/test/{integ.cloudtrail-insight.lit.js.snapshot => integ.cloudtrail-insight.js.snapshot}/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js (100%) rename packages/@aws-cdk/aws-cloudtrail/test/{integ.cloudtrail-insight.lit.js.snapshot => integ.cloudtrail-insight.js.snapshot}/aws-cdk-cloudtrail-inshights-test.assets.json (98%) rename packages/@aws-cdk/aws-cloudtrail/test/{integ.cloudtrail-insight.lit.js.snapshot => integ.cloudtrail-insight.js.snapshot}/aws-cdk-cloudtrail-inshights-test.template.json (100%) rename packages/@aws-cdk/aws-cloudtrail/test/{integ.cloudtrail-insight.lit.js.snapshot => integ.cloudtrail-insight.js.snapshot}/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets.json (96%) rename packages/@aws-cdk/aws-cloudtrail/test/{integ.cloudtrail-insight.lit.js.snapshot => integ.cloudtrail-insight.js.snapshot}/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.template.json (100%) create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/cdk.out rename packages/@aws-cdk/aws-cloudtrail/test/{integ.cloudtrail-insight.lit.js.snapshot => integ.cloudtrail-insight.js.snapshot}/integ.json (92%) rename packages/@aws-cdk/aws-cloudtrail/test/{integ.cloudtrail-insight.lit.js.snapshot => integ.cloudtrail-insight.js.snapshot}/manifest.json (99%) rename packages/@aws-cdk/aws-cloudtrail/test/{integ.cloudtrail-insight.lit.js.snapshot => integ.cloudtrail-insight.js.snapshot}/tree.json (100%) delete mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/cdk.out delete mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.assets.json delete mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.template.json delete mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts create mode 100644 packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.ts diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js similarity index 100% rename from packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js rename to packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/__entrypoint__.js diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js similarity index 100% rename from packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js rename to packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c/index.js diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/aws-cdk-cloudtrail-inshights-test.assets.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/aws-cdk-cloudtrail-inshights-test.assets.json similarity index 98% rename from packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/aws-cdk-cloudtrail-inshights-test.assets.json rename to packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/aws-cdk-cloudtrail-inshights-test.assets.json index 411d02d2fa1ef..b8f6f1418d4b3 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/aws-cdk-cloudtrail-inshights-test.assets.json +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/aws-cdk-cloudtrail-inshights-test.assets.json @@ -1,5 +1,5 @@ { - "version": "21.0.0", + "version": "22.0.0", "files": { "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c": { "source": { diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/aws-cdk-cloudtrail-inshights-test.template.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/aws-cdk-cloudtrail-inshights-test.template.json similarity index 100% rename from packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/aws-cdk-cloudtrail-inshights-test.template.json rename to packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/aws-cdk-cloudtrail-inshights-test.template.json diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets.json similarity index 96% rename from packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets.json rename to packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets.json index afee199576ba7..e8b86d44c5823 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets.json +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.assets.json @@ -1,5 +1,5 @@ { - "version": "21.0.0", + "version": "22.0.0", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.template.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.template.json similarity index 100% rename from packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.template.json rename to packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/awscdkcloudtrailinshightsDefaultTestDeployAssertF7B86FF0.template.json diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/cdk.out b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/cdk.out new file mode 100644 index 0000000000000..145739f539580 --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"22.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/integ.json similarity index 92% rename from packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ.json rename to packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/integ.json index 33b6b4aefeaa7..c1ea903f0978f 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "21.0.0", + "version": "22.0.0", "testCases": { "aws-cdk-cloudtrail-inshights/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/manifest.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/manifest.json similarity index 99% rename from packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/manifest.json rename to packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/manifest.json index 7953daf08201f..11c9688123ea5 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "21.0.0", + "version": "22.0.0", "artifacts": { "aws-cdk-cloudtrail-inshights-test.assets": { "type": "cdk:asset-manifest", diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/tree.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/tree.json similarity index 100% rename from packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/tree.json rename to packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.js.snapshot/tree.json diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/cdk.out b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/cdk.out deleted file mode 100644 index 8ecc185e9dbee..0000000000000 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/cdk.out +++ /dev/null @@ -1 +0,0 @@ -{"version":"21.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.assets.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.assets.json deleted file mode 100644 index 4300df11334c9..0000000000000 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.assets.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "version": "21.0.0", - "files": { - "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c": { - "source": { - "path": "asset.33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c", - "packaging": "zip" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c.zip", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - }, - "d2a43ea3712b74bd1dad6f4e75d59911217ff1df76a21330df94cc3551a4474a": { - "source": { - "path": "integ-cloudtrail.template.json", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "d2a43ea3712b74bd1dad6f4e75d59911217ff1df76a21330df94cc3551a4474a.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - } - }, - "dockerImages": {} -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.template.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.template.json deleted file mode 100644 index 90b67f5c27ead..0000000000000 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.js.snapshot/integ-cloudtrail.template.json +++ /dev/null @@ -1,418 +0,0 @@ -{ - "Resources": { - "Bucket83908E77": { - "Type": "AWS::S3::Bucket", - "Properties": { - "Tags": [ - { - "Key": "aws-cdk:auto-delete-objects", - "Value": "true" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "BucketPolicyE9A3008A": { - "Type": "AWS::S3::BucketPolicy", - "Properties": { - "Bucket": { - "Ref": "Bucket83908E77" - }, - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "s3:GetBucket*", - "s3:List*", - "s3:DeleteObject*" - ], - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::GetAtt": [ - "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", - "Arn" - ] - } - }, - "Resource": [ - { - "Fn::GetAtt": [ - "Bucket83908E77", - "Arn" - ] - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "Bucket83908E77", - "Arn" - ] - }, - "/*" - ] - ] - } - ] - } - ], - "Version": "2012-10-17" - } - } - }, - "BucketAutoDeleteObjectsCustomResourceBAFD23C2": { - "Type": "Custom::S3AutoDeleteObjects", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F", - "Arn" - ] - }, - "BucketName": { - "Ref": "Bucket83908E77" - } - }, - "DependsOn": [ - "BucketPolicyE9A3008A" - ], - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092": { - "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" - } - ] - } - }, - "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "S3Key": "33e2651435a0d472a75c1e033c9832b21321d9e56711926b04c5705e5f63874c.zip" - }, - "Timeout": 900, - "MemorySize": 128, - "Handler": "__entrypoint__.handler", - "Role": { - "Fn::GetAtt": [ - "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", - "Arn" - ] - }, - "Runtime": "nodejs14.x", - "Description": { - "Fn::Join": [ - "", - [ - "Lambda function for auto-deleting objects in ", - { - "Ref": "Bucket83908E77" - }, - " S3 bucket." - ] - ] - } - }, - "DependsOn": [ - "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092" - ] - }, - "LambdaFunctionServiceRoleC555A460": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "LambdaFunctionBF21E41F": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "ZipFile": "exports.handler = {}" - }, - "Role": { - "Fn::GetAtt": [ - "LambdaFunctionServiceRoleC555A460", - "Arn" - ] - }, - "Handler": "hello.handler", - "Runtime": "nodejs14.x" - }, - "DependsOn": [ - "LambdaFunctionServiceRoleC555A460" - ] - }, - "S3486F821D": { - "Type": "AWS::S3::Bucket", - "Properties": { - "Tags": [ - { - "Key": "aws-cdk:auto-delete-objects", - "Value": "true" - } - ] - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "S3Policy2E4AA1D6": { - "Type": "AWS::S3::BucketPolicy", - "Properties": { - "Bucket": { - "Ref": "S3486F821D" - }, - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "s3:GetBucket*", - "s3:List*", - "s3:DeleteObject*" - ], - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::GetAtt": [ - "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", - "Arn" - ] - } - }, - "Resource": [ - { - "Fn::GetAtt": [ - "S3486F821D", - "Arn" - ] - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "S3486F821D", - "Arn" - ] - }, - "/*" - ] - ] - } - ] - }, - { - "Action": "s3:GetBucketAcl", - "Effect": "Allow", - "Principal": { - "Service": "cloudtrail.amazonaws.com" - }, - "Resource": { - "Fn::GetAtt": [ - "S3486F821D", - "Arn" - ] - } - }, - { - "Action": "s3:PutObject", - "Condition": { - "StringEquals": { - "s3:x-amz-acl": "bucket-owner-full-control" - } - }, - "Effect": "Allow", - "Principal": { - "Service": "cloudtrail.amazonaws.com" - }, - "Resource": { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "S3486F821D", - "Arn" - ] - }, - "/AWSLogs/", - { - "Ref": "AWS::AccountId" - }, - "/*" - ] - ] - } - } - ], - "Version": "2012-10-17" - } - } - }, - "S3AutoDeleteObjectsCustomResource5A4102C9": { - "Type": "Custom::S3AutoDeleteObjects", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F", - "Arn" - ] - }, - "BucketName": { - "Ref": "S3486F821D" - } - }, - "DependsOn": [ - "S3Policy2E4AA1D6" - ], - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "Trail022F0CF2": { - "Type": "AWS::CloudTrail::Trail", - "Properties": { - "IsLogging": true, - "S3BucketName": { - "Ref": "S3486F821D" - }, - "EnableLogFileValidation": true, - "EventSelectors": [ - { - "DataResources": [ - { - "Type": "AWS::Lambda::Function", - "Values": [ - { - "Fn::GetAtt": [ - "LambdaFunctionBF21E41F", - "Arn" - ] - } - ] - } - ] - }, - { - "DataResources": [ - { - "Type": "AWS::S3::Object", - "Values": [ - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "Bucket83908E77", - "Arn" - ] - }, - "/" - ] - ] - } - ] - } - ] - } - ], - "IncludeGlobalServiceEvents": true, - "InsightSelectors": [ - { - "InsightType": "ApiCallRateInsight" - }, - { - "InsightType": "ApiErrorRateInsight" - } - ], - "IsMultiRegionTrail": true - }, - "DependsOn": [ - "S3Policy2E4AA1D6" - ] - } - }, - "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/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts deleted file mode 100644 index bd6fc988c2282..0000000000000 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.lit.ts +++ /dev/null @@ -1,50 +0,0 @@ -import * as iam from '@aws-cdk/aws-iam'; -import * as s3 from '@aws-cdk/aws-s3'; -import { App, RemovalPolicy, Stack } from '@aws-cdk/core'; -import * as integ from '@aws-cdk/integ-tests'; - -import * as cloudtrail from '../lib'; - -class CloudTrailInsightStack extends Stack { - constructor(scope: App, id: string) { - super(scope, id); - const cloudTrailPrincipal = new iam.ServicePrincipal('cloudtrail.amazonaws.com'); - - const Trailbucket = new s3.Bucket(this, 'S3', { - encryption: s3.BucketEncryption.UNENCRYPTED, - removalPolicy: RemovalPolicy.DESTROY, - autoDeleteObjects: true, - }); - - Trailbucket.addToResourcePolicy(new iam.PolicyStatement({ - resources: [Trailbucket.bucketArn], - actions: ['s3:GetBucketAcl'], - principals: [cloudTrailPrincipal], - })); - - Trailbucket.addToResourcePolicy(new iam.PolicyStatement({ - resources: [Trailbucket.arnForObjects(`AWSLogs/${Stack.of(this).account}/*`)], - actions: ['s3:PutObject'], - principals: [cloudTrailPrincipal], - conditions: { - StringEquals: { 's3:x-amz-acl': 'bucket-owner-full-control' }, - }, - })); - - new cloudtrail.Trail(this, 'Trail', { - bucket: Trailbucket, - insightTypes: [ - cloudtrail.InsightType.API_CALL_RATE, - cloudtrail.InsightType.API_ERROR_RATE, - ], - }); - }; -}; - -const app = new App(); -const stack = new CloudTrailInsightStack(app, 'aws-cdk-cloudtrail-inshights-test'); -new integ.IntegTest(app, 'aws-cdk-cloudtrail-inshights', { - testCases: [stack], -}); - -app.synth(); diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.ts b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.ts new file mode 100644 index 0000000000000..d43dc2493394c --- /dev/null +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-insight.ts @@ -0,0 +1,47 @@ +import * as iam from '@aws-cdk/aws-iam'; +import * as s3 from '@aws-cdk/aws-s3'; +import { App, RemovalPolicy, Stack } from '@aws-cdk/core'; +import * as integ from '@aws-cdk/integ-tests'; + +import * as cloudtrail from '../lib'; + +const app = new App(); +const stack = new Stack(app, 'aws-cdk-cloudtrail-inshights-test'); + +const cloudTrailPrincipal = new iam.ServicePrincipal('cloudtrail.amazonaws.com'); + +const Trailbucket = new s3.Bucket(stack, 'S3', { + encryption: s3.BucketEncryption.UNENCRYPTED, + removalPolicy: RemovalPolicy.DESTROY, + autoDeleteObjects: true, +}); + +Trailbucket.addToResourcePolicy(new iam.PolicyStatement({ + resources: [Trailbucket.bucketArn], + actions: ['s3:GetBucketAcl'], + principals: [cloudTrailPrincipal], +})); + +Trailbucket.addToResourcePolicy(new iam.PolicyStatement({ + resources: [Trailbucket.arnForObjects(`AWSLogs/${Stack.of(stack).account}/*`)], + actions: ['s3:PutObject'], + principals: [cloudTrailPrincipal], + conditions: { + StringEquals: { 's3:x-amz-acl': 'bucket-owner-full-control' }, + }, +})); + +new cloudtrail.Trail(stack, 'Trail', { + bucket: Trailbucket, + insightTypes: [ + cloudtrail.InsightType.API_CALL_RATE, + cloudtrail.InsightType.API_ERROR_RATE, + ], +}); + + +new integ.IntegTest(app, 'aws-cdk-cloudtrail-inshights', { + testCases: [stack], +}); + +app.synth();