@liflig/cdk 1.51.0 → 1.51.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -7,7 +7,6 @@ import * as webapp from "./webapp";
7
7
  import * as configureParameters from "./configure-parameters";
8
8
  import * as ecs from "./ecs";
9
9
  import * as loadBalancer from "./load-balancer";
10
- import * as cloudTrailSlackIntegration from "./cloudtrail-slack-integration";
11
10
  import * as rds from "./rds";
12
11
  import * as platform from "./platform";
13
12
  export { BastionHost } from "./bastion-host";
@@ -21,7 +20,7 @@ export { SsmParameterBackedResource } from "./ssm-parameter-backed-resource";
21
20
  export { SsmParameterReader } from "./ssm-parameter-reader";
22
21
  export { tagResources } from "./tags";
23
22
  export { WebappDeployViaRole } from "./webapp-deploy-via-role";
24
- export { alarms, cdkPipelines, griid, pipelines, ses, webapp, configureParameters, ecs, loadBalancer, rds, platform, cloudTrailSlackIntegration, };
23
+ export { alarms, cdkPipelines, griid, pipelines, ses, webapp, configureParameters, ecs, loadBalancer, rds, platform, };
25
24
  /**
26
25
  * Check if we are synthesizing a snapshot by setting IS_SNAPSHOT
27
26
  * environment variable to true.
package/lib/index.js CHANGED
@@ -10,7 +10,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
10
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.isSnapshot = exports.cloudTrailSlackIntegration = exports.platform = exports.rds = exports.loadBalancer = exports.ecs = exports.configureParameters = exports.webapp = exports.ses = exports.pipelines = exports.griid = exports.cdkPipelines = exports.alarms = exports.WebappDeployViaRole = exports.tagResources = exports.SsmParameterReader = exports.SsmParameterBackedResource = exports.createCloudAssemblySnapshot = exports.HostedZoneWithParam = exports.CrossRegionSsmParameter = exports.BastionHost = void 0;
13
+ exports.isSnapshot = exports.platform = exports.rds = exports.loadBalancer = exports.ecs = exports.configureParameters = exports.webapp = exports.ses = exports.pipelines = exports.griid = exports.cdkPipelines = exports.alarms = exports.WebappDeployViaRole = exports.tagResources = exports.SsmParameterReader = exports.SsmParameterBackedResource = exports.createCloudAssemblySnapshot = exports.HostedZoneWithParam = exports.CrossRegionSsmParameter = exports.BastionHost = void 0;
14
14
  const alarms = require("./alarms");
15
15
  exports.alarms = alarms;
16
16
  const cdkPipelines = require("./cdk-pipelines");
@@ -29,8 +29,6 @@ const ecs = require("./ecs");
29
29
  exports.ecs = ecs;
30
30
  const loadBalancer = require("./load-balancer");
31
31
  exports.loadBalancer = loadBalancer;
32
- const cloudTrailSlackIntegration = require("./cloudtrail-slack-integration");
33
- exports.cloudTrailSlackIntegration = cloudTrailSlackIntegration;
34
32
  const rds = require("./rds");
35
33
  exports.rds = rds;
36
34
  const platform = require("./platform");
@@ -64,4 +62,4 @@ Object.defineProperty(exports, "WebappDeployViaRole", { enumerable: true, get: f
64
62
  * happen during snapshot creation.
65
63
  */
66
64
  exports.isSnapshot = process.env.IS_SNAPSHOT === "true";
67
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUFBLG1DQUFrQztBQTZCaEMsd0JBQU07QUE1QlIsZ0RBQStDO0FBNkI3QyxvQ0FBWTtBQTVCZCxpQ0FBZ0M7QUE2QjlCLHNCQUFLO0FBNUJQLHlDQUF3QztBQTZCdEMsOEJBQVM7QUE1QlgsNkJBQTRCO0FBNkIxQixrQkFBRztBQTVCTCxtQ0FBa0M7QUE2QmhDLHdCQUFNO0FBNUJSLDhEQUE2RDtBQTZCM0Qsa0RBQW1CO0FBNUJyQiw2QkFBNEI7QUE2QjFCLGtCQUFHO0FBNUJMLGdEQUErQztBQTZCN0Msb0NBQVk7QUE1QmQsNkVBQTRFO0FBK0IxRSxnRUFBMEI7QUE5QjVCLDZCQUE0QjtBQTRCMUIsa0JBQUc7QUEzQkwsdUNBQXNDO0FBNEJwQyw0QkFBUTtBQTFCVixnRUFBZ0U7QUFDaEUsdUNBQXVDO0FBRXZDLCtDQUE0QztBQUFuQywyR0FBQSxXQUFXLE9BQUE7QUFDcEIsb0RBQWlDO0FBQ2pDLCtDQUE0QjtBQUM1QiwyRUFBc0U7QUFBN0QscUlBQUEsdUJBQXVCLE9BQUE7QUFDaEMscURBQWtDO0FBQ2xDLG1FQUE4RDtBQUFyRCw2SEFBQSxtQkFBbUIsT0FBQTtBQUM1Qix5Q0FBeUQ7QUFBaEQsd0hBQUEsMkJBQTJCLE9BQUE7QUFDcEMsaUZBQTRFO0FBQW5FLDJJQUFBLDBCQUEwQixPQUFBO0FBQ25DLCtEQUEyRDtBQUFsRCwwSEFBQSxrQkFBa0IsT0FBQTtBQUMzQiwrQkFBcUM7QUFBNUIsb0dBQUEsWUFBWSxPQUFBO0FBQ3JCLG1FQUE4RDtBQUFyRCw2SEFBQSxtQkFBbUIsT0FBQTtBQWlCNUI7Ozs7OztHQU1HO0FBQ1UsUUFBQSxVQUFVLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEtBQUssTUFBTSxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgYWxhcm1zIGZyb20gXCIuL2FsYXJtc1wiXG5pbXBvcnQgKiBhcyBjZGtQaXBlbGluZXMgZnJvbSBcIi4vY2RrLXBpcGVsaW5lc1wiXG5pbXBvcnQgKiBhcyBncmlpZCBmcm9tIFwiLi9ncmlpZFwiXG5pbXBvcnQgKiBhcyBwaXBlbGluZXMgZnJvbSBcIi4vcGlwZWxpbmVzXCJcbmltcG9ydCAqIGFzIHNlcyBmcm9tIFwiLi9zZXNcIlxuaW1wb3J0ICogYXMgd2ViYXBwIGZyb20gXCIuL3dlYmFwcFwiXG5pbXBvcnQgKiBhcyBjb25maWd1cmVQYXJhbWV0ZXJzIGZyb20gXCIuL2NvbmZpZ3VyZS1wYXJhbWV0ZXJzXCJcbmltcG9ydCAqIGFzIGVjcyBmcm9tIFwiLi9lY3NcIlxuaW1wb3J0ICogYXMgbG9hZEJhbGFuY2VyIGZyb20gXCIuL2xvYWQtYmFsYW5jZXJcIlxuaW1wb3J0ICogYXMgY2xvdWRUcmFpbFNsYWNrSW50ZWdyYXRpb24gZnJvbSBcIi4vY2xvdWR0cmFpbC1zbGFjay1pbnRlZ3JhdGlvblwiXG5pbXBvcnQgKiBhcyByZHMgZnJvbSBcIi4vcmRzXCJcbmltcG9ydCAqIGFzIHBsYXRmb3JtIGZyb20gXCIuL3BsYXRmb3JtXCJcblxuLy8gVE9ETzogV2Ugd2FudCB0byBzd2l0Y2ggZXhwb3J0cyBzbyB0aGV5IGV2ZXJ5IGNvbnN0cnVjdCB1bmRlclxuLy8gIGEgbmFtZXNwYWNlIHN1Y2ggYXMgdGhlIHNucyBleHBvcnQuXG5cbmV4cG9ydCB7IEJhc3Rpb25Ib3N0IH0gZnJvbSBcIi4vYmFzdGlvbi1ob3N0XCJcbmV4cG9ydCAqIGZyb20gXCIuL2J1aWxkLWFydGlmYWN0c1wiXG5leHBvcnQgKiBmcm9tIFwiLi9jZGstZGVwbG95XCJcbmV4cG9ydCB7IENyb3NzUmVnaW9uU3NtUGFyYW1ldGVyIH0gZnJvbSBcIi4vY3Jvc3MtcmVnaW9uLXNzbS1wYXJhbWV0ZXJcIlxuZXhwb3J0ICogZnJvbSBcIi4vZWNzLXVwZGF0ZS1pbWFnZVwiXG5leHBvcnQgeyBIb3N0ZWRab25lV2l0aFBhcmFtIH0gZnJvbSBcIi4vaG9zdGVkLXpvbmUtd2l0aC1wYXJhbVwiXG5leHBvcnQgeyBjcmVhdGVDbG91ZEFzc2VtYmx5U25hcHNob3QgfSBmcm9tIFwiLi9zbmFwc2hvdHNcIlxuZXhwb3J0IHsgU3NtUGFyYW1ldGVyQmFja2VkUmVzb3VyY2UgfSBmcm9tIFwiLi9zc20tcGFyYW1ldGVyLWJhY2tlZC1yZXNvdXJjZVwiXG5leHBvcnQgeyBTc21QYXJhbWV0ZXJSZWFkZXIgfSBmcm9tIFwiLi9zc20tcGFyYW1ldGVyLXJlYWRlclwiXG5leHBvcnQgeyB0YWdSZXNvdXJjZXMgfSBmcm9tIFwiLi90YWdzXCJcbmV4cG9ydCB7IFdlYmFwcERlcGxveVZpYVJvbGUgfSBmcm9tIFwiLi93ZWJhcHAtZGVwbG95LXZpYS1yb2xlXCJcblxuZXhwb3J0IHtcbiAgYWxhcm1zLFxuICBjZGtQaXBlbGluZXMsXG4gIGdyaWlkLFxuICBwaXBlbGluZXMsXG4gIHNlcyxcbiAgd2ViYXBwLFxuICBjb25maWd1cmVQYXJhbWV0ZXJzLFxuICBlY3MsXG4gIGxvYWRCYWxhbmNlcixcbiAgcmRzLFxuICBwbGF0Zm9ybSxcbiAgY2xvdWRUcmFpbFNsYWNrSW50ZWdyYXRpb24sXG59XG5cbi8qKlxuICogQ2hlY2sgaWYgd2UgYXJlIHN5bnRoZXNpemluZyBhIHNuYXBzaG90IGJ5IHNldHRpbmcgSVNfU05BUFNIT1RcbiAqIGVudmlyb25tZW50IHZhcmlhYmxlIHRvIHRydWUuXG4gKlxuICogVGhpcyBhbGxvd3MgZm9yIHNwZWNpYWwgY29uZGl0aW9uYWwgbG9naWMgdGhhdCBzaG91bGQgb25seVxuICogaGFwcGVuIGR1cmluZyBzbmFwc2hvdCBjcmVhdGlvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IGlzU25hcHNob3QgPSBwcm9jZXNzLmVudi5JU19TTkFQU0hPVCA9PT0gXCJ0cnVlXCJcbiJdfQ==
65
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUFBLG1DQUFrQztBQTRCaEMsd0JBQU07QUEzQlIsZ0RBQStDO0FBNEI3QyxvQ0FBWTtBQTNCZCxpQ0FBZ0M7QUE0QjlCLHNCQUFLO0FBM0JQLHlDQUF3QztBQTRCdEMsOEJBQVM7QUEzQlgsNkJBQTRCO0FBNEIxQixrQkFBRztBQTNCTCxtQ0FBa0M7QUE0QmhDLHdCQUFNO0FBM0JSLDhEQUE2RDtBQTRCM0Qsa0RBQW1CO0FBM0JyQiw2QkFBNEI7QUE0QjFCLGtCQUFHO0FBM0JMLGdEQUErQztBQTRCN0Msb0NBQVk7QUEzQmQsNkJBQTRCO0FBNEIxQixrQkFBRztBQTNCTCx1Q0FBc0M7QUE0QnBDLDRCQUFRO0FBMUJWLGdFQUFnRTtBQUNoRSx1Q0FBdUM7QUFFdkMsK0NBQTRDO0FBQW5DLDJHQUFBLFdBQVcsT0FBQTtBQUNwQixvREFBaUM7QUFDakMsK0NBQTRCO0FBQzVCLDJFQUFzRTtBQUE3RCxxSUFBQSx1QkFBdUIsT0FBQTtBQUNoQyxxREFBa0M7QUFDbEMsbUVBQThEO0FBQXJELDZIQUFBLG1CQUFtQixPQUFBO0FBQzVCLHlDQUF5RDtBQUFoRCx3SEFBQSwyQkFBMkIsT0FBQTtBQUNwQyxpRkFBNEU7QUFBbkUsMklBQUEsMEJBQTBCLE9BQUE7QUFDbkMsK0RBQTJEO0FBQWxELDBIQUFBLGtCQUFrQixPQUFBO0FBQzNCLCtCQUFxQztBQUE1QixvR0FBQSxZQUFZLE9BQUE7QUFDckIsbUVBQThEO0FBQXJELDZIQUFBLG1CQUFtQixPQUFBO0FBZ0I1Qjs7Ozs7O0dBTUc7QUFDVSxRQUFBLFVBQVUsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsS0FBSyxNQUFNLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBhbGFybXMgZnJvbSBcIi4vYWxhcm1zXCJcbmltcG9ydCAqIGFzIGNka1BpcGVsaW5lcyBmcm9tIFwiLi9jZGstcGlwZWxpbmVzXCJcbmltcG9ydCAqIGFzIGdyaWlkIGZyb20gXCIuL2dyaWlkXCJcbmltcG9ydCAqIGFzIHBpcGVsaW5lcyBmcm9tIFwiLi9waXBlbGluZXNcIlxuaW1wb3J0ICogYXMgc2VzIGZyb20gXCIuL3Nlc1wiXG5pbXBvcnQgKiBhcyB3ZWJhcHAgZnJvbSBcIi4vd2ViYXBwXCJcbmltcG9ydCAqIGFzIGNvbmZpZ3VyZVBhcmFtZXRlcnMgZnJvbSBcIi4vY29uZmlndXJlLXBhcmFtZXRlcnNcIlxuaW1wb3J0ICogYXMgZWNzIGZyb20gXCIuL2Vjc1wiXG5pbXBvcnQgKiBhcyBsb2FkQmFsYW5jZXIgZnJvbSBcIi4vbG9hZC1iYWxhbmNlclwiXG5pbXBvcnQgKiBhcyByZHMgZnJvbSBcIi4vcmRzXCJcbmltcG9ydCAqIGFzIHBsYXRmb3JtIGZyb20gXCIuL3BsYXRmb3JtXCJcblxuLy8gVE9ETzogV2Ugd2FudCB0byBzd2l0Y2ggZXhwb3J0cyBzbyB0aGV5IGV2ZXJ5IGNvbnN0cnVjdCB1bmRlclxuLy8gIGEgbmFtZXNwYWNlIHN1Y2ggYXMgdGhlIHNucyBleHBvcnQuXG5cbmV4cG9ydCB7IEJhc3Rpb25Ib3N0IH0gZnJvbSBcIi4vYmFzdGlvbi1ob3N0XCJcbmV4cG9ydCAqIGZyb20gXCIuL2J1aWxkLWFydGlmYWN0c1wiXG5leHBvcnQgKiBmcm9tIFwiLi9jZGstZGVwbG95XCJcbmV4cG9ydCB7IENyb3NzUmVnaW9uU3NtUGFyYW1ldGVyIH0gZnJvbSBcIi4vY3Jvc3MtcmVnaW9uLXNzbS1wYXJhbWV0ZXJcIlxuZXhwb3J0ICogZnJvbSBcIi4vZWNzLXVwZGF0ZS1pbWFnZVwiXG5leHBvcnQgeyBIb3N0ZWRab25lV2l0aFBhcmFtIH0gZnJvbSBcIi4vaG9zdGVkLXpvbmUtd2l0aC1wYXJhbVwiXG5leHBvcnQgeyBjcmVhdGVDbG91ZEFzc2VtYmx5U25hcHNob3QgfSBmcm9tIFwiLi9zbmFwc2hvdHNcIlxuZXhwb3J0IHsgU3NtUGFyYW1ldGVyQmFja2VkUmVzb3VyY2UgfSBmcm9tIFwiLi9zc20tcGFyYW1ldGVyLWJhY2tlZC1yZXNvdXJjZVwiXG5leHBvcnQgeyBTc21QYXJhbWV0ZXJSZWFkZXIgfSBmcm9tIFwiLi9zc20tcGFyYW1ldGVyLXJlYWRlclwiXG5leHBvcnQgeyB0YWdSZXNvdXJjZXMgfSBmcm9tIFwiLi90YWdzXCJcbmV4cG9ydCB7IFdlYmFwcERlcGxveVZpYVJvbGUgfSBmcm9tIFwiLi93ZWJhcHAtZGVwbG95LXZpYS1yb2xlXCJcblxuZXhwb3J0IHtcbiAgYWxhcm1zLFxuICBjZGtQaXBlbGluZXMsXG4gIGdyaWlkLFxuICBwaXBlbGluZXMsXG4gIHNlcyxcbiAgd2ViYXBwLFxuICBjb25maWd1cmVQYXJhbWV0ZXJzLFxuICBlY3MsXG4gIGxvYWRCYWxhbmNlcixcbiAgcmRzLFxuICBwbGF0Zm9ybSxcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB3ZSBhcmUgc3ludGhlc2l6aW5nIGEgc25hcHNob3QgYnkgc2V0dGluZyBJU19TTkFQU0hPVFxuICogZW52aXJvbm1lbnQgdmFyaWFibGUgdG8gdHJ1ZS5cbiAqXG4gKiBUaGlzIGFsbG93cyBmb3Igc3BlY2lhbCBjb25kaXRpb25hbCBsb2dpYyB0aGF0IHNob3VsZCBvbmx5XG4gKiBoYXBwZW4gZHVyaW5nIHNuYXBzaG90IGNyZWF0aW9uLlxuICovXG5leHBvcnQgY29uc3QgaXNTbmFwc2hvdCA9IHByb2Nlc3MuZW52LklTX1NOQVBTSE9UID09PSBcInRydWVcIlxuIl19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liflig/cdk",
3
- "version": "1.51.0",
3
+ "version": "1.51.1",
4
4
  "description": "Experimental CDK library for Liflig",
5
5
  "repository": {
6
6
  "type": "git",
@@ -47,7 +47,6 @@
47
47
  "@aws-cdk/aws-events-targets": "1.135.0",
48
48
  "@aws-cdk/aws-iam": "1.135.0",
49
49
  "@aws-cdk/aws-lambda": "1.135.0",
50
- "@aws-cdk/aws-lambda-event-sources": "1.135.0",
51
50
  "@aws-cdk/aws-logs": "1.135.0",
52
51
  "@aws-cdk/aws-rds": "1.135.0",
53
52
  "@aws-cdk/aws-route53": "1.135.0",
@@ -105,7 +104,6 @@
105
104
  "@aws-cdk/aws-events-targets": "^1.108.1",
106
105
  "@aws-cdk/aws-iam": "^1.108.1",
107
106
  "@aws-cdk/aws-lambda": "^1.108.1",
108
- "@aws-cdk/aws-lambda-event-sources": "^1.108.1",
109
107
  "@aws-cdk/aws-logs": "^1.108.1",
110
108
  "@aws-cdk/aws-rds": "^1.108.1",
111
109
  "@aws-cdk/aws-route53": "^1.108.1",
@@ -1,249 +0,0 @@
1
- #!/usr/bin/env python
2
-
3
- """
4
- Transform CloudTrail events to payloads formatted for Slack's API, and send them
5
- directly to Slack or through an SQS FIFO queue for deduplication.
6
-
7
- The code below contains entrypoints for two Lambda functions (prefixed with `handler_`).
8
- """
9
-
10
- import os
11
- import logging
12
- import json
13
- import urllib.request
14
- import boto3
15
-
16
- logger = logging.getLogger()
17
- logger.setLevel(logging.INFO)
18
-
19
-
20
- def get_slack_payload_for_assume_role_event(event, account_friendly_names):
21
- """Parse a CloudTrail event related to the API call sts:AssumeRole,
22
- and return a Slack-formatted attachment"""
23
- event_account_id = event["account"]
24
- event_detail = event["detail"]
25
- request_parameters = event_detail.get("requestParameters", {}) or {}
26
-
27
- timestamp = event_detail["eventTime"]
28
- user_identity = event_detail["userIdentity"]
29
- principal_id = user_identity["principalId"]
30
- principal_account_id = user_identity["accountId"]
31
- source_identity = request_parameters.get("sourceIdentity", "")
32
- source_ip = event_detail.get("sourceIPAddress", "")
33
- role_arn = request_parameters.get("roleArn", "")
34
-
35
- fallback = f"Sensitive role accessed in '{event_account_id}'"
36
- pretext_messages = [f":warning: Sensitive role in `{event_account_id}` assumed by"]
37
- if principal_id.startswith("AIDA"):
38
- pretext_messages.append("IAM user")
39
- elif principal_id.startswith("AROA"):
40
- pretext_messages.append("IAM role")
41
- else:
42
- pretext_messages.append("principal")
43
- pretext_messages.append(f"in `{principal_account_id}`")
44
- pretext = " ".join(pretext_messages)
45
-
46
- text = [
47
- f"*Role ARN:* `{role_arn}`",
48
- f"*Principal Account ID:* `{principal_account_id}`",
49
- f"*Principal ID:* `{principal_id}`",
50
- f"*Source IP:* `{source_ip}`",
51
- f"*Source Identity:* `{source_identity}`" if source_identity else "",
52
- f"*Timestamp:* `{timestamp}`",
53
- ]
54
- text = "\n".join(line for line in text if line)
55
- for account_id, friendly_name in account_friendly_names.items():
56
- pretext = pretext.replace(account_id, friendly_name)
57
- fallback = fallback.replace(account_id, friendly_name)
58
- return {
59
- "attachments": [
60
- {
61
- "pretext": pretext,
62
- "color": "warning",
63
- "text": text,
64
- "fallback": fallback,
65
- "mrkdwn_in": ["pretext", "text"],
66
- }
67
- ]
68
- }
69
-
70
-
71
- def get_fallback_slack_payload_for_event(
72
- event, account_friendly_names, fallback_parse_behavior=""
73
- ):
74
- """Parse a generic CloudTrail event related to an API call
75
- and return a Slack-formatted attachment"""
76
- event_account_id = event["account"]
77
- event_detail = event["detail"]
78
- event_name = event_detail["eventName"]
79
- event_type = event_detail["eventType"]
80
- event_time = event_detail["eventTime"]
81
- pretext = f":warning: CloudTrail event in account `{event_account_id}`"
82
- fallback = f"CloudTrail event in account '{event_account_id}'"
83
- if fallback_parse_behavior == "DUMP_EVENT":
84
- text = "\n".join(
85
- ["*Event:*", "```", json.dumps(event, sort_keys=True, indent=2), "```"]
86
- )
87
- else:
88
- error_message = event_detail.get("errorMessage", "")
89
- # This may be None, in which case we force it to an empty dict instead
90
- response_element = (event_detail.get("responseElements", {}) or {}).get(
91
- event_name, ""
92
- )
93
- user_identity = event_detail["userIdentity"]
94
- principal_id = user_identity.get("principalId", "")
95
- principal_type = user_identity.get("type", "")
96
- principal_account_id = user_identity.get("accountId", "")
97
- principal_arn = user_identity.get("arn", "")
98
- source_ip = event_detail.get("sourceIPAddress", "")
99
- resources = event_detail.get("resources", []) or []
100
- text = [
101
- f"*Event Type:* `{event_type}`",
102
- f"*Event Name:* `{event_name}`",
103
- f"*Event Time:* `{event_time}`",
104
- f"*Error Message:* `{error_message}`" if error_message else "",
105
- f"*Response Code:* `{response_element}`" if response_element else "",
106
- f"*Principal Type:* `{principal_type}`" if principal_type else "",
107
- f"*Principal Account ID:* `{principal_account_id}`"
108
- if principal_account_id
109
- else "",
110
- f"*Principal ARN:* `{principal_arn}`" if principal_arn else "",
111
- f"*Principal ID:* `{principal_id}`" if principal_id else "",
112
- f"*Source IP:* `{source_ip}`" if source_ip else "",
113
- f"*Resources:*\n```{json.dumps(resources, indent=2, sort_keys=True)}\n```"
114
- if len(resources)
115
- else "",
116
- ]
117
- # Filter out empty strings
118
- text = "\n".join(line for line in text if line)
119
-
120
- for account_id, friendly_name in account_friendly_names.items():
121
- pretext = pretext.replace(account_id, friendly_name)
122
- fallback = fallback.replace(account_id, friendly_name)
123
- return {
124
- "attachments": [
125
- {
126
- "pretext": pretext,
127
- "color": "warning",
128
- "text": text,
129
- "fallback": fallback,
130
- "mrkdwn_in": ["pretext", "text"],
131
- }
132
- ]
133
- }
134
-
135
-
136
- def get_augmented_account_friendly_names(event, account_friendly_names):
137
- """Return an augmented dictionary containing the alias of the current
138
- AWS account if relevant"""
139
- augmented_account_friendly_names = {**account_friendly_names}
140
- try:
141
- event_account_id = event["account"]
142
- event_detail = event["detail"]
143
- recipient_account_id = event_detail["recipientAccountId"]
144
- if (
145
- not augmented_account_friendly_names.get(event_account_id, "")
146
- and event_account_id == recipient_account_id
147
- ):
148
- logger.info(
149
- "No friendly name was supplied for current account '%s', so looking up account alias",
150
- event_account_id,
151
- )
152
- iam = boto3.client("iam")
153
- aliases = iam.list_account_aliases()["AccountAliases"]
154
- if len(aliases):
155
- augmented_account_friendly_names[event_account_id] = aliases[0]
156
- except:
157
- logger.exception("Failed to look up alias of current AWS account")
158
-
159
- return augmented_account_friendly_names
160
-
161
-
162
- def post_to_slack(slack_payload, slack_webhook_url):
163
- """Post a payload to Slack's webhook API"""
164
- encoded_slack_payload = json.dumps(slack_payload).encode("utf-8")
165
- try:
166
- slack_request = urllib.request.Request(
167
- slack_webhook_url,
168
- data=encoded_slack_payload,
169
- headers={"Content-Type": "application/json"},
170
- )
171
- urllib.request.urlopen(slack_request)
172
- except:
173
- logger.exception("Failed to post to Slack")
174
- raise
175
-
176
-
177
- def handler_event_transformer(event, context):
178
- """Lambda handler for the event transformer Lambda"""
179
- logger.info("Triggered with event: %s", json.dumps(event, indent=2))
180
-
181
- account_friendly_names = json.loads(os.environ["ACCOUNT_FRIENDLY_NAMES"])
182
- slack_webhook_url = os.environ["SLACK_WEBHOOK_URL"]
183
- slack_channel = os.environ["SLACK_CHANNEL"]
184
- sqs_queue_url = os.environ.get("SQS_QUEUE_URL", "")
185
- fallback_parse_behavior = os.environ.get("FALLBACK_PARSE_BEHAVIOR", "")
186
- deduplicate_events = os.environ.get("DEDUPLICATE_EVENTS", "false") == "true"
187
-
188
- account_friendly_names = get_augmented_account_friendly_names(
189
- event, account_friendly_names
190
- )
191
-
192
- if not event["detail-type"].endswith("via CloudTrail"):
193
- logger.warn("Invalid event received")
194
- return
195
-
196
- slack_payload = {}
197
- try:
198
- if event["detail"]["eventName"] == "AssumeRole":
199
- slack_payload = get_slack_payload_for_assume_role_event(
200
- event, account_friendly_names
201
- )
202
- except:
203
- logger.exception("Failed to parse event using predefined schema")
204
- if not slack_payload:
205
- logger.warn("Using a fallback schema to parse event")
206
- slack_payload = get_fallback_slack_payload_for_event(
207
- event,
208
- account_friendly_names,
209
- fallback_parse_behavior=fallback_parse_behavior,
210
- )
211
- slack_payload = {**slack_payload, "channel": slack_channel}
212
-
213
- if deduplicate_events and sqs_queue_url:
214
- logger.info("Sending message to SQS for deduplication")
215
- deduplication_id = (
216
- event["detail"].get("requestID", "")
217
- or event["detail"].get("eventID", "")
218
- or event["id"]
219
- )
220
- body = {
221
- "slackWebhookUrl": slack_webhook_url,
222
- "slackPayload": slack_payload,
223
- }
224
-
225
- sqs = boto3.client("sqs")
226
- sqs.send_message(
227
- QueueUrl=sqs_queue_url,
228
- MessageBody=json.dumps(body),
229
- MessageDeduplicationId=deduplication_id,
230
- MessageGroupId=deduplication_id,
231
- )
232
- else:
233
- logger.info("Sending message directly to Slack")
234
- post_to_slack(slack_payload, slack_webhook_url)
235
-
236
-
237
- def handler_slack_forwarder(event, context):
238
- """Lambda handler for the Slack forwarder Lambda"""
239
- logger.info("Triggered with event: %s", json.dumps(event, indent=2))
240
- records = event["Records"]
241
- for record in records:
242
- body = json.loads(record["body"])
243
- slack_channel = body.get("slackChannel", "")
244
- slack_webhook_url = body.get("slackWebhookUrl", "")
245
- slack_payload = {
246
- **body["slackPayload"],
247
- **({"channel": slack_channel} if slack_channel else {}),
248
- }
249
- post_to_slack(slack_payload, slack_webhook_url)
@@ -1,43 +0,0 @@
1
- import * as cdk from "@aws-cdk/core";
2
- import * as cloudwatch from "@aws-cdk/aws-cloudwatch";
3
- export interface CloudTrailSlackIntegrationProps extends cdk.StackProps {
4
- /**
5
- * A key-value pair of AWS account IDs and friendly names of these accounts
6
- * to use when sending messages to Slack.
7
- */
8
- accountFriendlyNames?: {
9
- [key: string]: string;
10
- };
11
- slackWebhookUrl: string;
12
- slackChannel: string;
13
- /**
14
- * A list of ARNs of roles in the current account to monitor usage of.
15
- */
16
- rolesToMonitor?: string[];
17
- /**
18
- * Whether to monitor various IAM API calls associated with the current account's root user (e.g., console login, password reset, etc.)
19
- *
20
- * @default true
21
- */
22
- monitorRootUserActions?: boolean;
23
- /**
24
- * Whether to set up additional AWS infrastructure to deduplicate CloudTrail events in order to avoid duplicate Slack messages. May be used to decrease noise.
25
- *
26
- * @default false
27
- */
28
- deduplicateEvents?: boolean;
29
- /**
30
- * If supplied, CloudWatch alarms will be created for the construct's underlying infrastructure (e.g., Lambda functions) and the action will be used to notify on OK and ALARM actions.
31
- */
32
- infrastructureAlarmAction?: cloudwatch.IAlarmAction;
33
- }
34
- /**
35
- * Forward a predefined set of CloudTrail API events to Slack using EventBridge, Lambda
36
- * and an optional SQS FIFO queue for deduplicating events.
37
- * The API events are limited to monitoring access to the current account's root user and/or specific IAM roles.
38
- *
39
- * NOTE: The construct needs to be provisioned in us-east-1, and requires an existing CloudTrail set up in that region.
40
- */
41
- export declare class CloudTrailSlackIntegration extends cdk.Construct {
42
- constructor(scope: cdk.Construct, id: string, props: CloudTrailSlackIntegrationProps);
43
- }
@@ -1,210 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CloudTrailSlackIntegration = void 0;
4
- const cdk = require("@aws-cdk/core");
5
- const iam = require("@aws-cdk/aws-iam");
6
- const logs = require("@aws-cdk/aws-logs");
7
- const cloudwatch = require("@aws-cdk/aws-cloudwatch");
8
- const lambda = require("@aws-cdk/aws-lambda");
9
- const events = require("@aws-cdk/aws-events");
10
- const sources = require("@aws-cdk/aws-lambda-event-sources");
11
- const sqs = require("@aws-cdk/aws-sqs");
12
- const targets = require("@aws-cdk/aws-events-targets");
13
- const path = require("path");
14
- /**
15
- * Forward a predefined set of CloudTrail API events to Slack using EventBridge, Lambda
16
- * and an optional SQS FIFO queue for deduplicating events.
17
- * The API events are limited to monitoring access to the current account's root user and/or specific IAM roles.
18
- *
19
- * NOTE: The construct needs to be provisioned in us-east-1, and requires an existing CloudTrail set up in that region.
20
- */
21
- class CloudTrailSlackIntegration extends cdk.Construct {
22
- constructor(scope, id, props) {
23
- super(scope, id);
24
- const eventTransformer = new lambda.Function(this, "EventTransformerLambda", {
25
- code: lambda.Code.fromAsset(path.join(__dirname, "../../assets/cloudtrail-slack-integration-lambda")),
26
- description: "Formats CloudTrail API calls sent through EventBridge, and posts them directly to Slack or first to an SQS FIFO queue for deduplication",
27
- handler: "main.handler_event_transformer",
28
- runtime: lambda.Runtime.PYTHON_3_9,
29
- timeout: cdk.Duration.seconds(15),
30
- logRetention: logs.RetentionDays.SIX_MONTHS,
31
- environment: {
32
- SLACK_CHANNEL: props.slackChannel,
33
- DEDUPLICATE_EVENTS: JSON.stringify(!!props.deduplicateEvents),
34
- ACCOUNT_FRIENDLY_NAMES: JSON.stringify(props.accountFriendlyNames || {}),
35
- SLACK_WEBHOOK_URL: props.slackWebhookUrl,
36
- },
37
- });
38
- eventTransformer.addToRolePolicy(new iam.PolicyStatement({
39
- actions: ["iam:ListAccountAliases"],
40
- resources: ["*"],
41
- }));
42
- if (props.infrastructureAlarmAction) {
43
- const eventTransformerAlarm = eventTransformer
44
- .metricErrors({
45
- period: cdk.Duration.minutes(5),
46
- statistic: cloudwatch.Statistic.SUM,
47
- })
48
- .createAlarm(this, "EventTransformerErrorAlarm", {
49
- threshold: 1,
50
- evaluationPeriods: 1,
51
- alarmDescription: "Triggers if the Lambda function that transforms CloudTrail API calls received through EventBridge fails (e.g., it fails to process the event)",
52
- datapointsToAlarm: 1,
53
- treatMissingData: cloudwatch.TreatMissingData.IGNORE,
54
- });
55
- eventTransformerAlarm.addOkAction(props.infrastructureAlarmAction);
56
- eventTransformerAlarm.addAlarmAction(props.infrastructureAlarmAction);
57
- }
58
- if (props.deduplicateEvents) {
59
- const deduplicationQueue = new sqs.Queue(this, "Queue", {
60
- // We explicitly give the queue a name due to bug https://github.com/aws/aws-cdk/issues/5860
61
- queueName: `${this.node.id.substring(0, 33)}${this.node.addr}`.substring(0, 75) +
62
- ".fifo",
63
- fifo: true,
64
- });
65
- eventTransformer.addEnvironment("SQS_QUEUE_URL", deduplicationQueue.queueUrl);
66
- deduplicationQueue.grantSendMessages(eventTransformer);
67
- const slackForwarder = new lambda.Function(this, "SlackForwarderLambda", {
68
- code: lambda.Code.fromAsset(path.join(__dirname, "../../assets/cloudtrail-slack-integration-lambda")),
69
- description: "Polls from an SQS FIFO queue containing formatted CloudTrail API calls and sends them to Slack.",
70
- handler: "main.handler_slack_forwarder",
71
- runtime: lambda.Runtime.PYTHON_3_9,
72
- timeout: cdk.Duration.seconds(15),
73
- logRetention: logs.RetentionDays.TWO_WEEKS,
74
- });
75
- if (props.infrastructureAlarmAction) {
76
- const slackForwarderAlarm = slackForwarder
77
- .metricErrors({
78
- period: cdk.Duration.minutes(5),
79
- statistic: cloudwatch.Statistic.SUM,
80
- })
81
- .createAlarm(this, "SlackForwarderErrorAlarm", {
82
- threshold: 1,
83
- alarmDescription: "Triggers if the Lambda function that polls from SQS and posts deduplicated CloudTrail API calls received through EventBridge to Slack fails (e.g., invalid Slack webhook URL)",
84
- evaluationPeriods: 1,
85
- datapointsToAlarm: 1,
86
- treatMissingData: cloudwatch.TreatMissingData.IGNORE,
87
- });
88
- slackForwarderAlarm.addOkAction(props.infrastructureAlarmAction);
89
- slackForwarderAlarm.addAlarmAction(props.infrastructureAlarmAction);
90
- }
91
- slackForwarder.addEventSource(new sources.SqsEventSource(deduplicationQueue));
92
- }
93
- if (props.rolesToMonitor && props.rolesToMonitor.length > 0) {
94
- new events.Rule(this, "RuleForAssumeRole", {
95
- enabled: true,
96
- targets: [new targets.LambdaFunction(eventTransformer)],
97
- eventPattern: {
98
- detail: {
99
- eventName: ["AssumeRole"],
100
- requestParameters: {
101
- roleArn: props.rolesToMonitor,
102
- },
103
- },
104
- },
105
- });
106
- }
107
- if (props.monitorRootUserActions !== false) {
108
- // Triggers when the root password has been changed
109
- new events.Rule(this, "RuleForRootUserPasswordChange", {
110
- enabled: true,
111
- targets: [new targets.LambdaFunction(eventTransformer)],
112
- eventPattern: {
113
- detail: {
114
- userIdentity: {
115
- type: ["Root"],
116
- },
117
- eventName: ["PasswordUpdated"],
118
- eventType: ["AwsConsoleSignIn"],
119
- },
120
- },
121
- });
122
- // Triggers when MFA for the root user has been set up
123
- new events.Rule(this, "RuleForRootUserMfaChange", {
124
- enabled: true,
125
- targets: [new targets.LambdaFunction(eventTransformer)],
126
- eventPattern: {
127
- detail: {
128
- userIdentity: {
129
- type: ["Root"],
130
- },
131
- eventName: ["EnableMFADevice"],
132
- requestParameters: {
133
- userName: ["AWS ROOT USER"],
134
- },
135
- },
136
- },
137
- });
138
- // Triggers when a root user succesfully logs in to the console
139
- new events.Rule(this, "RuleForRootUserSuccessfulLogin", {
140
- enabled: true,
141
- targets: [new targets.LambdaFunction(eventTransformer)],
142
- eventPattern: {
143
- detail: {
144
- userIdentity: {
145
- type: ["Root"],
146
- },
147
- eventName: ["ConsoleLogin"],
148
- eventType: ["AwsConsoleSignIn"],
149
- responseElements: {
150
- ConsoleLogin: ["Success"],
151
- },
152
- },
153
- },
154
- });
155
- // Triggers for bad login attemps for root user (e.g., wrong password)
156
- new events.Rule(this, "RuleForRootUserUnsuccessfulLogin", {
157
- enabled: true,
158
- targets: [new targets.LambdaFunction(eventTransformer)],
159
- eventPattern: {
160
- detail: {
161
- userIdentity: {
162
- type: ["Root"],
163
- },
164
- eventName: ["ConsoleLogin"],
165
- eventType: ["AwsConsoleSignIn"],
166
- responseElements: {
167
- ConsoleLogin: ["Failure"],
168
- },
169
- },
170
- },
171
- });
172
- // Triggered when password reset has been requested
173
- new events.Rule(this, "RuleForRootUserPasswordRecoveryRequest", {
174
- enabled: true,
175
- targets: [new targets.LambdaFunction(eventTransformer)],
176
- eventPattern: {
177
- detail: {
178
- userIdentity: {
179
- type: ["Root"],
180
- },
181
- eventName: ["PasswordRecoveryRequested"],
182
- eventType: ["AwsConsoleSignIn"],
183
- responseElements: {
184
- PasswordRecoveryRequested: ["Success"],
185
- },
186
- },
187
- },
188
- });
189
- // Triggered when password has been successfully reset
190
- new events.Rule(this, "RuleForRootUserPasswordRecoveryComplete", {
191
- enabled: true,
192
- targets: [new targets.LambdaFunction(eventTransformer)],
193
- eventPattern: {
194
- detail: {
195
- userIdentity: {
196
- type: ["Root"],
197
- },
198
- eventName: ["PasswordRecoveryCompleted"],
199
- eventType: ["AwsConsoleSignIn"],
200
- responseElements: {
201
- PasswordRecoveryCompleted: ["Success"],
202
- },
203
- },
204
- },
205
- });
206
- }
207
- }
208
- }
209
- exports.CloudTrailSlackIntegration = CloudTrailSlackIntegration;
210
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWR0cmFpbC1zbGFjay1pbnRlZ3JhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZHRyYWlsLXNsYWNrLWludGVncmF0aW9uL2Nsb3VkdHJhaWwtc2xhY2staW50ZWdyYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUNBQW9DO0FBQ3BDLHdDQUF1QztBQUN2QywwQ0FBeUM7QUFDekMsc0RBQXFEO0FBQ3JELDhDQUE2QztBQUM3Qyw4Q0FBNkM7QUFDN0MsNkRBQTREO0FBQzVELHdDQUF1QztBQUN2Qyx1REFBc0Q7QUFDdEQsNkJBQTRCO0FBa0M1Qjs7Ozs7O0dBTUc7QUFDSCxNQUFhLDBCQUEyQixTQUFRLEdBQUcsQ0FBQyxTQUFTO0lBQzNELFlBQ0UsS0FBb0IsRUFDcEIsRUFBVSxFQUNWLEtBQXNDO1FBRXRDLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFFaEIsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQzFDLElBQUksRUFDSix3QkFBd0IsRUFDeEI7WUFDRSxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQ3pCLElBQUksQ0FBQyxJQUFJLENBQ1AsU0FBUyxFQUNULGtEQUFrRCxDQUNuRCxDQUNGO1lBQ0QsV0FBVyxFQUNULHlJQUF5STtZQUMzSSxPQUFPLEVBQUUsZ0NBQWdDO1lBQ3pDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVU7WUFDbEMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNqQyxZQUFZLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVO1lBQzNDLFdBQVcsRUFBRTtnQkFDWCxhQUFhLEVBQUUsS0FBSyxDQUFDLFlBQVk7Z0JBQ2pDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxp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QUUsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDdkQsWUFBWSxFQUFFO29CQUNaLE1BQU0sRUFBRTt3QkFDTixZQUFZLEVBQUU7NEJBQ1osSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDO3lCQUNmO3dCQUNELFNBQVMsRUFBRSxDQUFDLDJCQUEyQixDQUFDO3dCQUN4QyxTQUFTLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQzt3QkFDL0IsZ0JBQWdCLEVBQUU7NEJBQ2hCLHlCQUF5QixFQUFFLENBQUMsU0FBUyxDQUFDO3lCQUN2QztxQkFDRjtpQkFDRjthQUNGLENBQUMsQ0FBQTtTQUNIO0lBQ0gsQ0FBQztDQUNGO0FBcE9ELGdFQW9PQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNkayBmcm9tIFwiQGF3cy1jZGsvY29yZVwiXG5pbXBvcnQgKiBhcyBpYW0gZnJvbSBcIkBhd3MtY2RrL2F3cy1pYW1cIlxuaW1wb3J0ICogYXMgbG9ncyBmcm9tIFwiQGF3cy1jZGsvYXdzLWxvZ3NcIlxuaW1wb3J0ICogYXMgY2xvdWR3YXRjaCBmcm9tIFwiQGF3cy1jZGsvYXdzLWNsb3Vkd2F0Y2hcIlxuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gXCJAYXdzLWNkay9hd3MtbGFtYmRhXCJcbmltcG9ydCAqIGFzIGV2ZW50cyBmcm9tIFwiQGF3cy1jZGsvYXdzLWV2ZW50c1wiXG5pbXBvcnQgKiBhcyBzb3VyY2VzIGZyb20gXCJAYXdzLWNkay9hd3MtbGFtYmRhLWV2ZW50LXNvdXJjZXNcIlxuaW1wb3J0ICogYXMgc3FzIGZyb20gXCJAYXdzLWNkay9hd3Mtc3FzXCJcbmltcG9ydCAqIGFzIHRhcmdldHMgZnJvbSBcIkBhd3MtY2RrL2F3cy1ldmVudHMtdGFyZ2V0c1wiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCJcblxuZXhwb3J0IGludGVyZmFjZSBDbG91ZFRyYWlsU2xhY2tJbnRlZ3JhdGlvblByb3BzIGV4dGVuZHMgY2RrLlN0YWNrUHJvcHMge1xuICAvKipcbiAgICogQSBrZXktdmFsdWUgcGFpciBvZiBBV1MgYWNjb3VudCBJRHMgYW5kIGZyaWVuZGx5IG5hbWVzIG9mIHRoZXNlIGFjY291bnRzXG4gICAqIHRvIHVzZSB3aGVuIHNlbmRpbmcgbWVzc2FnZXMgdG8gU2xhY2suXG4gICAqL1xuICBhY2NvdW50RnJpZW5kbHlOYW1lcz86IHtcbiAgICBba2V5OiBzdHJpbmddOiBzdHJpbmdcbiAgfVxuICBzbGFja1dlYmhvb2tVcmw6IHN0cmluZ1xuICBzbGFja0NoYW5uZWw6IHN0cmluZ1xuICAvKipcbiAgICogQSBsaXN0IG9mIEFSTnMgb2Ygcm9sZXMgaW4gdGhlIGN1cnJlbnQgYWNjb3VudCB0byBtb25pdG9yIHVzYWdlIG9mLlxuICAgKi9cbiAgcm9sZXNUb01vbml0b3I/OiBzdHJpbmdbXVxuICAvKipcbiAgICogV2hldGhlciB0byBtb25pdG9yIHZhcmlvdXMgSUFNIEFQSSBjYWxscyBhc3NvY2lhdGVkIHdpdGggdGhlIGN1cnJlbnQgYWNjb3VudCdzIHJvb3QgdXNlciAoZS5nLiwgY29uc29sZSBsb2dpbiwgcGFzc3dvcmQgcmVzZXQsIGV0Yy4pXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIG1vbml0b3JSb290VXNlckFjdGlvbnM/OiBib29sZWFuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHNldCB1cCBhZGRpdGlvbmFsIEFXUyBpbmZyYXN0cnVjdHVyZSB0byBkZWR1cGxpY2F0ZSBDbG91ZFRyYWlsIGV2ZW50cyBpbiBvcmRlciB0byBhdm9pZCBkdXBsaWNhdGUgU2xhY2sgbWVzc2FnZXMuIE1heSBiZSB1c2VkIHRvIGRlY3JlYXNlIG5vaXNlLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgZGVkdXBsaWNhdGVFdmVudHM/OiBib29sZWFuXG4gIC8qKlxuICAgKiBJZiBzdXBwbGllZCwgQ2xvdWRXYXRjaCBhbGFybXMgd2lsbCBiZSBjcmVhdGVkIGZvciB0aGUgY29uc3RydWN0J3MgdW5kZXJseWluZyBpbmZyYXN0cnVjdHVyZSAoZS5nLiwgTGFtYmRhIGZ1bmN0aW9ucykgYW5kIHRoZSBhY3Rpb24gd2lsbCBiZSB1c2VkIHRvIG5vdGlmeSBvbiBPSyBhbmQgQUxBUk0gYWN0aW9ucy5cbiAgICovXG4gIGluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvblxufVxuXG4vKipcbiAqIEZvcndhcmQgYSBwcmVkZWZpbmVkIHNldCBvZiBDbG91ZFRyYWlsIEFQSSBldmVudHMgdG8gU2xhY2sgdXNpbmcgRXZlbnRCcmlkZ2UsIExhbWJkYVxuICogYW5kIGFuIG9wdGlvbmFsIFNRUyBGSUZPIHF1ZXVlIGZvciBkZWR1cGxpY2F0aW5nIGV2ZW50cy5cbiAqIFRoZSBBUEkgZXZlbnRzIGFyZSBsaW1pdGVkIHRvIG1vbml0b3JpbmcgYWNjZXNzIHRvIHRoZSBjdXJyZW50IGFjY291bnQncyByb290IHVzZXIgYW5kL29yIHNwZWNpZmljIElBTSByb2xlcy5cbiAqXG4gKiBOT1RFOiBUaGUgY29uc3RydWN0IG5lZWRzIHRvIGJlIHByb3Zpc2lvbmVkIGluIHVzLWVhc3QtMSwgYW5kIHJlcXVpcmVzIGFuIGV4aXN0aW5nIENsb3VkVHJhaWwgc2V0IHVwIGluIHRoYXQgcmVnaW9uLlxuICovXG5leHBvcnQgY2xhc3MgQ2xvdWRUcmFpbFNsYWNrSW50ZWdyYXRpb24gZXh0ZW5kcyBjZGsuQ29uc3RydWN0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IGNkay5Db25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wczogQ2xvdWRUcmFpbFNsYWNrSW50ZWdyYXRpb25Qcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKVxuXG4gICAgY29uc3QgZXZlbnRUcmFuc2Zvcm1lciA9IG5ldyBsYW1iZGEuRnVuY3Rpb24oXG4gICAgICB0aGlzLFxuICAgICAgXCJFdmVudFRyYW5zZm9ybWVyTGFtYmRhXCIsXG4gICAgICB7XG4gICAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChcbiAgICAgICAgICBwYXRoLmpvaW4oXG4gICAgICAgICAgICBfX2Rpcm5hbWUsXG4gICAgICAgICAgICBcIi4uLy4uL2Fzc2V0cy9jbG91ZHRyYWlsLXNsYWNrLWludGVncmF0aW9uLWxhbWJkYVwiLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgIFwiRm9ybWF0cyBDbG91ZFRyYWlsIEFQSSBjYWxscyBzZW50IHRocm91Z2ggRXZlbnRCcmlkZ2UsIGFuZCBwb3N0cyB0aGVtIGRpcmVjdGx5IHRvIFNsYWNrIG9yIGZpcnN0IHRvIGFuIFNRUyBGSUZPIHF1ZXVlIGZvciBkZWR1cGxpY2F0aW9uXCIsXG4gICAgICAgIGhhbmRsZXI6IFwibWFpbi5oYW5kbGVyX2V2ZW50X3RyYW5zZm9ybWVyXCIsXG4gICAgICAgIHJ1bnRpbWU6IGxhbWJkYS5SdW50aW1lLlBZVEhPTl8zXzksXG4gICAgICAgIHRpbWVvdXQ6IGNkay5EdXJhdGlvbi5zZWNvbmRzKDE1KSxcbiAgICAgICAgbG9nUmV0ZW50aW9uOiBsb2dzLlJldGVudGlvbkRheXMuU0lYX01PTlRIUyxcbiAgICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBTTEFDS19DSEFOTkVMOiBwcm9wcy5zbGFja0NoYW5uZWwsXG4gICAgICAgICAgREVEVVBMSUNBVEVfRVZFTlRTOiBKU09OLnN0cmluZ2lmeSghIXByb3BzLmRlZHVwbGljYXRlRXZlbnRzKSxcbiAgICAgICAgICBBQ0NPVU5UX0ZSSUVORExZX05BTUVTOiBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgIHByb3BzLmFjY291bnRGcmllbmRseU5hbWVzIHx8IHt9LFxuICAgICAgICAgICksXG4gICAgICAgICAgU0xBQ0tfV0VCSE9PS19VUkw6IHByb3BzLnNsYWNrV2ViaG9va1VybCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgKVxuICAgIGV2ZW50VHJhbnNmb3JtZXIuYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbXCJpYW06TGlzdEFjY291bnRBbGlhc2VzXCJdLFxuICAgICAgICByZXNvdXJjZXM6IFtcIipcIl0sXG4gICAgICB9KSxcbiAgICApXG4gICAgaWYgKHByb3BzLmluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24pIHtcbiAgICAgIGNvbnN0IGV2ZW50VHJhbnNmb3JtZXJBbGFybSA9IGV2ZW50VHJhbnNmb3JtZXJcbiAgICAgICAgLm1ldHJpY0Vycm9ycyh7XG4gICAgICAgICAgcGVyaW9kOiBjZGsuRHVyYXRpb24ubWludXRlcyg1KSxcbiAgICAgICAgICBzdGF0aXN0aWM6IGNsb3Vkd2F0Y2guU3RhdGlzdGljLlNVTSxcbiAgICAgICAgfSlcbiAgICAgICAgLmNyZWF0ZUFsYXJtKHRoaXMsIFwiRXZlbnRUcmFuc2Zvcm1lckVycm9yQWxhcm1cIiwge1xuICAgICAgICAgIHRocmVzaG9sZDogMSxcbiAgICAgICAgICBldmFsdWF0aW9uUGVyaW9kczogMSxcbiAgICAgICAgICBhbGFybURlc2NyaXB0aW9uOlxuICAgICAgICAgICAgXCJUcmlnZ2VycyBpZiB0aGUgTGFtYmRhIGZ1bmN0aW9uIHRoYXQgdHJhbnNmb3JtcyBDbG91ZFRyYWlsIEFQSSBjYWxscyByZWNlaXZlZCB0aHJvdWdoIEV2ZW50QnJpZGdlIGZhaWxzIChlLmcuLCBpdCBmYWlscyB0byBwcm9jZXNzIHRoZSBldmVudClcIixcbiAgICAgICAgICBkYXRhcG9pbnRzVG9BbGFybTogMSxcbiAgICAgICAgICB0cmVhdE1pc3NpbmdEYXRhOiBjbG91ZHdhdGNoLlRyZWF0TWlzc2luZ0RhdGEuSUdOT1JFLFxuICAgICAgICB9KVxuICAgICAgZXZlbnRUcmFuc2Zvcm1lckFsYXJtLmFkZE9rQWN0aW9uKHByb3BzLmluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24pXG4gICAgICBldmVudFRyYW5zZm9ybWVyQWxhcm0uYWRkQWxhcm1BY3Rpb24ocHJvcHMuaW5mcmFzdHJ1Y3R1cmVBbGFybUFjdGlvbilcbiAgICB9XG4gICAgaWYgKHByb3BzLmRlZHVwbGljYXRlRXZlbnRzKSB7XG4gICAgICBjb25zdCBkZWR1cGxpY2F0aW9uUXVldWUgPSBuZXcgc3FzLlF1ZXVlKHRoaXMsIFwiUXVldWVcIiwge1xuICAgICAgICAvLyBXZSBleHBsaWNpdGx5IGdpdmUgdGhlIHF1ZXVlIGEgbmFtZSBkdWUgdG8gYnVnIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLWNkay9pc3N1ZXMvNTg2MFxuICAgICAgICBxdWV1ZU5hbWU6XG4gICAgICAgICAgYCR7dGhpcy5ub2RlLmlkLnN1YnN0cmluZygwLCAzMyl9JHt0aGlzLm5vZGUuYWRkcn1gLnN1YnN0cmluZygwLCA3NSkgK1xuICAgICAgICAgIFwiLmZpZm9cIixcbiAgICAgICAgZmlmbzogdHJ1ZSxcbiAgICAgIH0pXG4gICAgICBldmVudFRyYW5zZm9ybWVyLmFkZEVudmlyb25tZW50KFxuICAgICAgICBcIlNRU19RVUVVRV9VUkxcIixcbiAgICAgICAgZGVkdXBsaWNhdGlvblF1ZXVlLnF1ZXVlVXJsLFxuICAgICAgKVxuICAgICAgZGVkdXBsaWNhdGlvblF1ZXVlLmdyYW50U2VuZE1lc3NhZ2VzKGV2ZW50VHJhbnNmb3JtZXIpXG4gICAgICBjb25zdCBzbGFja0ZvcndhcmRlciA9IG5ldyBsYW1iZGEuRnVuY3Rpb24odGhpcywgXCJTbGFja0ZvcndhcmRlckxhbWJkYVwiLCB7XG4gICAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChcbiAgICAgICAgICBwYXRoLmpvaW4oXG4gICAgICAgICAgICBfX2Rpcm5hbWUsXG4gICAgICAgICAgICBcIi4uLy4uL2Fzc2V0cy9jbG91ZHRyYWlsLXNsYWNrLWludGVncmF0aW9uLWxhbWJkYVwiLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgIFwiUG9sbHMgZnJvbSBhbiBTUVMgRklGTyBxdWV1ZSBjb250YWluaW5nIGZvcm1hdHRlZCBDbG91ZFRyYWlsIEFQSSBjYWxscyBhbmQgc2VuZHMgdGhlbSB0byBTbGFjay5cIixcbiAgICAgICAgaGFuZGxlcjogXCJtYWluLmhhbmRsZXJfc2xhY2tfZm9yd2FyZGVyXCIsXG4gICAgICAgIHJ1bnRpbWU6IGxhbWJkYS5SdW50aW1lLlBZVEhPTl8zXzksXG4gICAgICAgIHRpbWVvdXQ6IGNkay5EdXJhdGlvbi5zZWNvbmRzKDE1KSxcbiAgICAgICAgbG9nUmV0ZW50aW9uOiBsb2dzLlJldGVudGlvbkRheXMuVFdPX1dFRUtTLFxuICAgICAgfSlcblxuICAgICAgaWYgKHByb3BzLmluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24pIHtcbiAgICAgICAgY29uc3Qgc2xhY2tGb3J3YXJkZXJBbGFybSA9IHNsYWNrRm9yd2FyZGVyXG4gICAgICAgICAgLm1ldHJpY0Vycm9ycyh7XG4gICAgICAgICAgICBwZXJpb2Q6IGNkay5EdXJhdGlvbi5taW51dGVzKDUpLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBjbG91ZHdhdGNoLlN0YXRpc3RpYy5TVU0sXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuY3JlYXRlQWxhcm0odGhpcywgXCJTbGFja0ZvcndhcmRlckVycm9yQWxhcm1cIiwge1xuICAgICAgICAgICAgdGhyZXNob2xkOiAxLFxuICAgICAgICAgICAgYWxhcm1EZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICAgXCJUcmlnZ2VycyBpZiB0aGUgTGFtYmRhIGZ1bmN0aW9uIHRoYXQgcG9sbHMgZnJvbSBTUVMgYW5kIHBvc3RzIGRlZHVwbGljYXRlZCBDbG91ZFRyYWlsIEFQSSBjYWxscyByZWNlaXZlZCB0aHJvdWdoIEV2ZW50QnJpZGdlIHRvIFNsYWNrIGZhaWxzIChlLmcuLCBpbnZhbGlkIFNsYWNrIHdlYmhvb2sgVVJMKVwiLFxuICAgICAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IDEsXG4gICAgICAgICAgICBkYXRhcG9pbnRzVG9BbGFybTogMSxcbiAgICAgICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5JR05PUkUsXG4gICAgICAgICAgfSlcbiAgICAgICAgc2xhY2tGb3J3YXJkZXJBbGFybS5hZGRPa0FjdGlvbihwcm9wcy5pbmZyYXN0cnVjdHVyZUFsYXJtQWN0aW9uKVxuICAgICAgICBzbGFja0ZvcndhcmRlckFsYXJtLmFkZEFsYXJtQWN0aW9uKHByb3BzLmluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24pXG4gICAgICB9XG4gICAgICBzbGFja0ZvcndhcmRlci5hZGRFdmVudFNvdXJjZShcbiAgICAgICAgbmV3IHNvdXJjZXMuU3FzRXZlbnRTb3VyY2UoZGVkdXBsaWNhdGlvblF1ZXVlKSxcbiAgICAgIClcbiAgICB9XG5cbiAgICBpZiAocHJvcHMucm9sZXNUb01vbml0b3IgJiYgcHJvcHMucm9sZXNUb01vbml0b3IubGVuZ3RoID4gMCkge1xuICAgICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsIFwiUnVsZUZvckFzc3VtZVJvbGVcIiwge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICB0YXJnZXRzOiBbbmV3IHRhcmdldHMuTGFtYmRhRnVuY3Rpb24oZXZlbnRUcmFuc2Zvcm1lcildLFxuICAgICAgICBldmVudFBhdHRlcm46IHtcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIGV2ZW50TmFtZTogW1wiQXNzdW1lUm9sZVwiXSxcbiAgICAgICAgICAgIHJlcXVlc3RQYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAgIHJvbGVBcm46IHByb3BzLnJvbGVzVG9Nb25pdG9yLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAocHJvcHMubW9uaXRvclJvb3RVc2VyQWN0aW9ucyAhPT0gZmFsc2UpIHtcbiAgICAgIC8vIFRyaWdnZXJzIHdoZW4gdGhlIHJvb3QgcGFzc3dvcmQgaGFzIGJlZW4gY2hhbmdlZFxuICAgICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsIFwiUnVsZUZvclJvb3RVc2VyUGFzc3dvcmRDaGFuZ2VcIiwge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICB0YXJnZXRzOiBbbmV3IHRhcmdldHMuTGFtYmRhRnVuY3Rpb24oZXZlbnRUcmFuc2Zvcm1lcildLFxuICAgICAgICBldmVudFBhdHRlcm46IHtcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIHVzZXJJZGVudGl0eToge1xuICAgICAgICAgICAgICB0eXBlOiBbXCJSb290XCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGV2ZW50TmFtZTogW1wiUGFzc3dvcmRVcGRhdGVkXCJdLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBbXCJBd3NDb25zb2xlU2lnbkluXCJdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuXG4gICAgICAvLyBUcmlnZ2VycyB3aGVuIE1GQSBmb3IgdGhlIHJvb3QgdXNlciBoYXMgYmVlbiBzZXQgdXBcbiAgICAgIG5ldyBldmVudHMuUnVsZSh0aGlzLCBcIlJ1bGVGb3JSb290VXNlck1mYUNoYW5nZVwiLCB7XG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgIHRhcmdldHM6IFtuZXcgdGFyZ2V0cy5MYW1iZGFGdW5jdGlvbihldmVudFRyYW5zZm9ybWVyKV0sXG4gICAgICAgIGV2ZW50UGF0dGVybjoge1xuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgdXNlcklkZW50aXR5OiB7XG4gICAgICAgICAgICAgIHR5cGU6IFtcIlJvb3RcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXZlbnROYW1lOiBbXCJFbmFibGVNRkFEZXZpY2VcIl0sXG4gICAgICAgICAgICByZXF1ZXN0UGFyYW1ldGVyczoge1xuICAgICAgICAgICAgICB1c2VyTmFtZTogW1wiQVdTIFJPT1QgVVNFUlwiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pXG5cbiAgICAgIC8vIFRyaWdnZXJzIHdoZW4gYSByb290IHVzZXIgc3VjY2VzZnVsbHkgbG9ncyBpbiB0byB0aGUgY29uc29sZVxuICAgICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsIFwiUnVsZUZvclJvb3RVc2VyU3VjY2Vzc2Z1bExvZ2luXCIsIHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgdGFyZ2V0czogW25ldyB0YXJnZXRzLkxhbWJkYUZ1bmN0aW9uKGV2ZW50VHJhbnNmb3JtZXIpXSxcbiAgICAgICAgZXZlbnRQYXR0ZXJuOiB7XG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICB1c2VySWRlbnRpdHk6IHtcbiAgICAgICAgICAgICAgdHlwZTogW1wiUm9vdFwiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBldmVudE5hbWU6IFtcIkNvbnNvbGVMb2dpblwiXSxcbiAgICAgICAgICAgIGV2ZW50VHlwZTogW1wiQXdzQ29uc29sZVNpZ25JblwiXSxcbiAgICAgICAgICAgIHJlc3BvbnNlRWxlbWVudHM6IHtcbiAgICAgICAgICAgICAgQ29uc29sZUxvZ2luOiBbXCJTdWNjZXNzXCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSlcblxuICAgICAgLy8gVHJpZ2dlcnMgZm9yIGJhZCBsb2dpbiBhdHRlbXBzIGZvciByb290IHVzZXIgKGUuZy4sIHdyb25nIHBhc3N3b3JkKVxuICAgICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsIFwiUnVsZUZvclJvb3RVc2VyVW5zdWNjZXNzZnVsTG9naW5cIiwge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICB0YXJnZXRzOiBbbmV3IHRhcmdldHMuTGFtYmRhRnVuY3Rpb24oZXZlbnRUcmFuc2Zvcm1lcildLFxuICAgICAgICBldmVudFBhdHRlcm46IHtcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIHVzZXJJZGVudGl0eToge1xuICAgICAgICAgICAgICB0eXBlOiBbXCJSb290XCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGV2ZW50TmFtZTogW1wiQ29uc29sZUxvZ2luXCJdLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBbXCJBd3NDb25zb2xlU2lnbkluXCJdLFxuICAgICAgICAgICAgcmVzcG9uc2VFbGVtZW50czoge1xuICAgICAgICAgICAgICBDb25zb2xlTG9naW46IFtcIkZhaWx1cmVcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuXG4gICAgICAvLyBUcmlnZ2VyZWQgd2hlbiBwYXNzd29yZCByZXNldCBoYXMgYmVlbiByZXF1ZXN0ZWRcbiAgICAgIG5ldyBldmVudHMuUnVsZSh0aGlzLCBcIlJ1bGVGb3JSb290VXNlclBhc3N3b3JkUmVjb3ZlcnlSZXF1ZXN0XCIsIHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgdGFyZ2V0czogW25ldyB0YXJnZXRzLkxhbWJkYUZ1bmN0aW9uKGV2ZW50VHJhbnNmb3JtZXIpXSxcbiAgICAgICAgZXZlbnRQYXR0ZXJuOiB7XG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICB1c2VySWRlbnRpdHk6IHtcbiAgICAgICAgICAgICAgdHlwZTogW1wiUm9vdFwiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBldmVudE5hbWU6IFtcIlBhc3N3b3JkUmVjb3ZlcnlSZXF1ZXN0ZWRcIl0sXG4gICAgICAgICAgICBldmVudFR5cGU6IFtcIkF3c0NvbnNvbGVTaWduSW5cIl0sXG4gICAgICAgICAgICByZXNwb25zZUVsZW1lbnRzOiB7XG4gICAgICAgICAgICAgIFBhc3N3b3JkUmVjb3ZlcnlSZXF1ZXN0ZWQ6IFtcIlN1Y2Nlc3NcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuXG4gICAgICAvLyBUcmlnZ2VyZWQgd2hlbiBwYXNzd29yZCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVzZXRcbiAgICAgIG5ldyBldmVudHMuUnVsZSh0aGlzLCBcIlJ1bGVGb3JSb290VXNlclBhc3N3b3JkUmVjb3ZlcnlDb21wbGV0ZVwiLCB7XG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgIHRhcmdldHM6IFtuZXcgdGFyZ2V0cy5MYW1iZGFGdW5jdGlvbihldmVudFRyYW5zZm9ybWVyKV0sXG4gICAgICAgIGV2ZW50UGF0dGVybjoge1xuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgdXNlcklkZW50aXR5OiB7XG4gICAgICAgICAgICAgIHR5cGU6IFtcIlJvb3RcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXZlbnROYW1lOiBbXCJQYXNzd29yZFJlY292ZXJ5Q29tcGxldGVkXCJdLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBbXCJBd3NDb25zb2xlU2lnbkluXCJdLFxuICAgICAgICAgICAgcmVzcG9uc2VFbGVtZW50czoge1xuICAgICAgICAgICAgICBQYXNzd29yZFJlY292ZXJ5Q29tcGxldGVkOiBbXCJTdWNjZXNzXCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -1 +0,0 @@
1
- export { CloudTrailSlackIntegration, CloudTrailSlackIntegrationProps, } from "./cloudtrail-slack-integration";
@@ -1,6 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CloudTrailSlackIntegration = void 0;
4
- var cloudtrail_slack_integration_1 = require("./cloudtrail-slack-integration");
5
- Object.defineProperty(exports, "CloudTrailSlackIntegration", { enumerable: true, get: function () { return cloudtrail_slack_integration_1.CloudTrailSlackIntegration; } });
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2xvdWR0cmFpbC1zbGFjay1pbnRlZ3JhdGlvbi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrRUFHdUM7QUFGckMsMElBQUEsMEJBQTBCLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQge1xuICBDbG91ZFRyYWlsU2xhY2tJbnRlZ3JhdGlvbixcbiAgQ2xvdWRUcmFpbFNsYWNrSW50ZWdyYXRpb25Qcm9wcyxcbn0gZnJvbSBcIi4vY2xvdWR0cmFpbC1zbGFjay1pbnRlZ3JhdGlvblwiXG4iXX0=