@liflig/cdk 1.48.1 → 1.51.0

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.
@@ -0,0 +1,249 @@
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)
@@ -69,4 +69,4 @@ const startDeployHandler = async (event, context) => {
69
69
  };
70
70
  };
71
71
  exports.startDeployHandler = startDeployHandler;
72
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnQtZGVwbG95LWhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2RrLWRlcGxveS9zdGFydC1kZXBsb3ktaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFhQSxtREFBbUQ7QUFDbkQsNkJBQTZCO0FBQ3RCLE1BQU0sa0JBQWtCLEdBQzdCLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7O0lBQ3ZCLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUU5QixNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxTQUFTLEVBQW9CLENBQUE7SUFDdkQsTUFBTSxFQUFFLEdBQUcsSUFBSSxHQUFHLENBQUMsRUFBRSxFQUFhLENBQUE7SUFFbEMsU0FBUyxVQUFVLENBQUMsSUFBWTtRQUM5QixNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQy9CLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRTtZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUMsQ0FBQTtTQUNuQztRQUNELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUVELE1BQU0sV0FBVyxHQUFHLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUM5QyxNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDNUMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQTtJQUV4RCx5REFBeUQ7SUFDekQsdURBQXVEO0lBQ3ZELE1BQU0sY0FBYyxHQUFHLDBCQUEwQixDQUFBO0lBRWpELE1BQU0sV0FBVyxHQUFHLEdBQUcsT0FBTyxDQUFDLFlBQVksR0FBRyxDQUFBO0lBRTlDLHNCQUFzQjtJQUN0QixJQUNFLE9BQU8sS0FBSyxDQUFDLFVBQVUsS0FBSyxRQUFRO1FBQ3BDLE9BQU8sS0FBSyxDQUFDLFNBQVMsS0FBSyxRQUFRO1FBQ25DLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQ2hDLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQ3JCLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxRQUFRLElBQUksY0FBYyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FDMUQsRUFDRDtRQUNBLE1BQU0sSUFBSSxLQUFLLENBQ2IsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUMzRCxDQUFBO0tBQ0Y7SUFFRCxLQUFLLFVBQVUsR0FBRyxDQUFDLElBQVksRUFBRSxJQUFpQjtRQUNoRCxNQUFNLEVBQUU7YUFDTCxTQUFTLENBQUM7WUFDVCxNQUFNLEVBQUUsVUFBVTtZQUNsQixHQUFHLEVBQUUsR0FBRyxXQUFXLEdBQUcsSUFBSSxFQUFFO1lBQzVCLElBQUksRUFBRSxJQUFJO1NBQ1gsQ0FBQzthQUNELE9BQU8sRUFBRSxDQUFBO0lBQ2QsQ0FBQztJQUVELE1BQU0sR0FBRyxDQUFDLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDeEQsMERBQTBEO0lBQzFELE1BQU0sR0FBRyxDQUNQLFVBQVUsRUFDVixJQUFJLENBQUMsU0FBUyxDQUFDO1FBQ2IsT0FBTyxFQUFFLFVBQVU7S0FDcEIsQ0FBQyxDQUNILENBQUE7SUFFRCxNQUFNLEtBQUssR0FBRyxNQUFNLFNBQVM7U0FDMUIsVUFBVSxDQUFDO1FBQ1YsV0FBVztRQUNYLGtCQUFrQixFQUFFLElBQUk7UUFDeEIsc0JBQXNCLEVBQUUsR0FBRyxVQUFVLElBQUksV0FBVyxFQUFFO1FBQ3RELHdCQUF3QixFQUFFO1lBQ3hCO2dCQUNFLElBQUksRUFBRSxJQUFJO2dCQUNWLFFBQVEsRUFBRSxHQUFHLEtBQUssQ0FBQyxVQUFVLElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRTtnQkFDbEQsZ0JBQWdCLEVBQUUsZUFBZTthQUNsQztTQUNGO0tBQ0YsQ0FBQztTQUNELE9BQU8sRUFBRSxDQUFBO0lBRVosTUFBTSxPQUFPLEdBQUcsTUFBQSxLQUFLLENBQUMsS0FBSywwQ0FBRSxFQUFFLENBQUE7SUFDL0IsSUFBSSxPQUFPLElBQUksSUFBSSxFQUFFO1FBQ25CLE1BQU0sSUFBSSxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtLQUNwQztJQUVELE9BQU87UUFDTCxpRUFBaUU7UUFDakUsb0VBQW9FO1FBQ3BFLG9DQUFvQztRQUNwQyxLQUFLLEVBQUUsT0FBTztLQUNmLENBQUE7QUFDSCxDQUFDLENBQUE7QUFwRlUsUUFBQSxrQkFBa0Isc0JBb0Y1QiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtYXNzaWdubWVudCAqL1xuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1jYWxsICovXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MgKi9cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXMgKi9cbmltcG9ydCB7IEhhbmRsZXIgfSBmcm9tIFwiYXdzLWxhbWJkYVwiXG5pbXBvcnQgdHlwZSAqIGFzIF9BV1MgZnJvbSBcImF3cy1zZGtcIlxuXG5pbnRlcmZhY2UgU3RhcnREZXBsb3lFeHBlY3RlZElucHV0IHtcbiAgYnVja2V0TmFtZTogc3RyaW5nXG4gIGJ1Y2tldEtleTogc3RyaW5nXG4gIHN0YWNrTmFtZXM6IHN0cmluZ1tdXG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgaW5saW5lLWNvbXBpbGVkIGZvciB0aGUgbGFtYmRhLlxuLy8gSXQgbXVzdCBiZSBzZWxmLWNvbnRhaW5lZC5cbmV4cG9ydCBjb25zdCBzdGFydERlcGxveUhhbmRsZXI6IEhhbmRsZXI8UGFydGlhbDxTdGFydERlcGxveUV4cGVjdGVkSW5wdXQ+PiA9XG4gIGFzeW5jIChldmVudCwgY29udGV4dCkgPT4ge1xuICAgIGNvbnN0IEFXUyA9IHJlcXVpcmUoXCJhd3Mtc2RrXCIpXG5cbiAgICBjb25zdCBjb2RlYnVpbGQgPSBuZXcgQVdTLkNvZGVCdWlsZCgpIGFzIF9BV1MuQ29kZUJ1aWxkXG4gICAgY29uc3QgczMgPSBuZXcgQVdTLlMzKCkgYXMgX0FXUy5TM1xuXG4gICAgZnVuY3Rpb24gcmVxdWlyZUVudihuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgY29uc3QgdmFsdWUgPSBwcm9jZXNzLmVudltuYW1lXVxuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNaXNzaW5nICR7bmFtZX1gKVxuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlXG4gICAgfVxuXG4gICAgY29uc3QgcHJvamVjdE5hbWUgPSByZXF1aXJlRW52KFwiUFJPSkVDVF9OQU1FXCIpXG4gICAgY29uc3QgYnVja2V0TmFtZSA9IHJlcXVpcmVFbnYoXCJCVUNLRVRfTkFNRVwiKVxuICAgIGNvbnN0IGNka0NvbnRleHQgPSBKU09OLnBhcnNlKHJlcXVpcmVFbnYoXCJDREtfQ09OVEVYVFwiKSlcblxuICAgIC8vIFNpbmNlIHdlIHBhc3MgdGhlIHN0YWNrIG5hbWVzIGFzIHN0cmluZ3MgdG8gdGhlIHNoZWxsLFxuICAgIC8vIGJlIGEgYml0IHJlc3RyaWN0aXZlIG9mIHRoZSB2YWxpZCB2YWx1ZXMgd2UgY2FuIHVzZS5cbiAgICBjb25zdCB2YWxpZFN0YWNrTmFtZSA9IC9eW2EtejAtOV9dW2EtejAtOVxcLV9dKiQvaVxuXG4gICAgY29uc3QgczNLZXlQcmVmaXggPSBgJHtjb250ZXh0LmF3c1JlcXVlc3RJZH0vYFxuXG4gICAgLy8gVmFsaWRhdGUgdGhlIGlucHV0LlxuICAgIGlmIChcbiAgICAgIHR5cGVvZiBldmVudC5idWNrZXROYW1lICE9PSBcInN0cmluZ1wiIHx8XG4gICAgICB0eXBlb2YgZXZlbnQuYnVja2V0S2V5ICE9PSBcInN0cmluZ1wiIHx8XG4gICAgICAhQXJyYXkuaXNBcnJheShldmVudC5zdGFja05hbWVzKSB8fFxuICAgICAgIWV2ZW50LnN0YWNrTmFtZXMuZXZlcnkoXG4gICAgICAgIChpdCkgPT4gdHlwZW9mIGl0ID09PSBcInN0cmluZ1wiICYmIHZhbGlkU3RhY2tOYW1lLnRlc3QoaXQpLFxuICAgICAgKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIklucHV0IGludmFsaWQ6IFwiICsgSlNPTi5zdHJpbmdpZnkoZXZlbnQsIHVuZGVmaW5lZCwgXCIgIFwiKSxcbiAgICAgIClcbiAgICB9XG5cbiAgICBhc3luYyBmdW5jdGlvbiBwdXQobmFtZTogc3RyaW5nLCBkYXRhOiBBV1MuUzMuQm9keSkge1xuICAgICAgYXdhaXQgczNcbiAgICAgICAgLnB1dE9iamVjdCh7XG4gICAgICAgICAgQnVja2V0OiBidWNrZXROYW1lLFxuICAgICAgICAgIEtleTogYCR7czNLZXlQcmVmaXh9JHtuYW1lfWAsXG4gICAgICAgICAgQm9keTogZGF0YSxcbiAgICAgICAgfSlcbiAgICAgICAgLnByb21pc2UoKVxuICAgIH1cblxuICAgIGF3YWl0IHB1dChcInN0YWNrLW5hbWVzLnR4dFwiLCBldmVudC5zdGFja05hbWVzLmpvaW4oXCIgXCIpKVxuICAgIC8vIEVuc3VyZSB0aGF0IHdlIHJ1biB0aGUgc2NyaXB0IHVzaW5nIHNhbWUgZmVhdHVyZSBmbGFncy5cbiAgICBhd2FpdCBwdXQoXG4gICAgICBcImNkay5qc29uXCIsXG4gICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIGNvbnRleHQ6IGNka0NvbnRleHQsXG4gICAgICB9KSxcbiAgICApXG5cbiAgICBjb25zdCBidWlsZCA9IGF3YWl0IGNvZGVidWlsZFxuICAgICAgLnN0YXJ0QnVpbGQoe1xuICAgICAgICBwcm9qZWN0TmFtZSxcbiAgICAgICAgc291cmNlVHlwZU92ZXJyaWRlOiBcIlMzXCIsXG4gICAgICAgIHNvdXJjZUxvY2F0aW9uT3ZlcnJpZGU6IGAke2J1Y2tldE5hbWV9LyR7czNLZXlQcmVmaXh9YCxcbiAgICAgICAgc2Vjb25kYXJ5U291cmNlc092ZXJyaWRlOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJTM1wiLFxuICAgICAgICAgICAgbG9jYXRpb246IGAke2V2ZW50LmJ1Y2tldE5hbWV9LyR7ZXZlbnQuYnVja2V0S2V5fWAsXG4gICAgICAgICAgICBzb3VyY2VJZGVudGlmaWVyOiBcIkNMT1VEQVNTRU1CTFlcIixcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSlcbiAgICAgIC5wcm9taXNlKClcblxuICAgIGNvbnN0IGJ1aWxkSWQgPSBidWlsZC5idWlsZD8uaWRcbiAgICBpZiAoYnVpbGRJZCA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIGJ1aWxkIElEXCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC8vIFRoaXMgaXMgdGhlIHZhbHVlIHRoZSBjYWxsZXIgd2lsbCB1c2UgdG8gZmV0Y2ggdXBkYXRlZCBzdGF0dXMuXG4gICAgICAvLyBBdm9pZCBleHBvc2luZyB3aGF0IGtpbmQgb2YgSUQgdGhpcyBpcywgYmVjYXVzZSB3ZSBzaG91bGQgYmUgZnJlZVxuICAgICAgLy8gdG8gY2hhbmdlIGltcGxlbWVudGF0aW9uIGRldGFpbHMuXG4gICAgICBqb2JJZDogYnVpbGRJZCxcbiAgICB9XG4gIH1cbiJdfQ==
72
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnQtZGVwbG95LWhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2RrLWRlcGxveS9zdGFydC1kZXBsb3ktaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFhQSxtREFBbUQ7QUFDbkQsNkJBQTZCO0FBQ3RCLE1BQU0sa0JBQWtCLEdBRTNCLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7O0lBQzNCLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUU5QixNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxTQUFTLEVBQW9CLENBQUE7SUFDdkQsTUFBTSxFQUFFLEdBQUcsSUFBSSxHQUFHLENBQUMsRUFBRSxFQUFhLENBQUE7SUFFbEMsU0FBUyxVQUFVLENBQUMsSUFBWTtRQUM5QixNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQy9CLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRTtZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUMsQ0FBQTtTQUNuQztRQUNELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUVELE1BQU0sV0FBVyxHQUFHLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUM5QyxNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDNUMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQTtJQUV4RCx5REFBeUQ7SUFDekQsdURBQXVEO0lBQ3ZELE1BQU0sY0FBYyxHQUFHLDBCQUEwQixDQUFBO0lBRWpELE1BQU0sV0FBVyxHQUFHLEdBQUcsT0FBTyxDQUFDLFlBQVksR0FBRyxDQUFBO0lBRTlDLHNCQUFzQjtJQUN0QixJQUNFLE9BQU8sS0FBSyxDQUFDLFVBQVUsS0FBSyxRQUFRO1FBQ3BDLE9BQU8sS0FBSyxDQUFDLFNBQVMsS0FBSyxRQUFRO1FBQ25DLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQ2hDLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQ3JCLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxRQUFRLElBQUksY0FBYyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FDMUQsRUFDRDtRQUNBLE1BQU0sSUFBSSxLQUFLLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUE7S0FDNUU7SUFFRCxLQUFLLFVBQVUsR0FBRyxDQUFDLElBQVksRUFBRSxJQUFpQjtRQUNoRCxNQUFNLEVBQUU7YUFDTCxTQUFTLENBQUM7WUFDVCxNQUFNLEVBQUUsVUFBVTtZQUNsQixHQUFHLEVBQUUsR0FBRyxXQUFXLEdBQUcsSUFBSSxFQUFFO1lBQzVCLElBQUksRUFBRSxJQUFJO1NBQ1gsQ0FBQzthQUNELE9BQU8sRUFBRSxDQUFBO0lBQ2QsQ0FBQztJQUVELE1BQU0sR0FBRyxDQUFDLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDeEQsMERBQTBEO0lBQzFELE1BQU0sR0FBRyxDQUNQLFVBQVUsRUFDVixJQUFJLENBQUMsU0FBUyxDQUFDO1FBQ2IsT0FBTyxFQUFFLFVBQVU7S0FDcEIsQ0FBQyxDQUNILENBQUE7SUFFRCxNQUFNLEtBQUssR0FBRyxNQUFNLFNBQVM7U0FDMUIsVUFBVSxDQUFDO1FBQ1YsV0FBVztRQUNYLGtCQUFrQixFQUFFLElBQUk7UUFDeEIsc0JBQXNCLEVBQUUsR0FBRyxVQUFVLElBQUksV0FBVyxFQUFFO1FBQ3RELHdCQUF3QixFQUFFO1lBQ3hCO2dCQUNFLElBQUksRUFBRSxJQUFJO2dCQUNWLFFBQVEsRUFBRSxHQUFHLEtBQUssQ0FBQyxVQUFVLElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRTtnQkFDbEQsZ0JBQWdCLEVBQUUsZUFBZTthQUNsQztTQUNGO0tBQ0YsQ0FBQztTQUNELE9BQU8sRUFBRSxDQUFBO0lBRVosTUFBTSxPQUFPLEdBQUcsTUFBQSxLQUFLLENBQUMsS0FBSywwQ0FBRSxFQUFFLENBQUE7SUFDL0IsSUFBSSxPQUFPLElBQUksSUFBSSxFQUFFO1FBQ25CLE1BQU0sSUFBSSxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtLQUNwQztJQUVELE9BQU87UUFDTCxpRUFBaUU7UUFDakUsb0VBQW9FO1FBQ3BFLG9DQUFvQztRQUNwQyxLQUFLLEVBQUUsT0FBTztLQUNmLENBQUE7QUFDSCxDQUFDLENBQUE7QUFuRlksUUFBQSxrQkFBa0Isc0JBbUY5QiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtYXNzaWdubWVudCAqL1xuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1jYWxsICovXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MgKi9cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXMgKi9cbmltcG9ydCB7IEhhbmRsZXIgfSBmcm9tIFwiYXdzLWxhbWJkYVwiXG5pbXBvcnQgdHlwZSAqIGFzIF9BV1MgZnJvbSBcImF3cy1zZGtcIlxuXG5pbnRlcmZhY2UgU3RhcnREZXBsb3lFeHBlY3RlZElucHV0IHtcbiAgYnVja2V0TmFtZTogc3RyaW5nXG4gIGJ1Y2tldEtleTogc3RyaW5nXG4gIHN0YWNrTmFtZXM6IHN0cmluZ1tdXG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgaW5saW5lLWNvbXBpbGVkIGZvciB0aGUgbGFtYmRhLlxuLy8gSXQgbXVzdCBiZSBzZWxmLWNvbnRhaW5lZC5cbmV4cG9ydCBjb25zdCBzdGFydERlcGxveUhhbmRsZXI6IEhhbmRsZXI8XG4gIFBhcnRpYWw8U3RhcnREZXBsb3lFeHBlY3RlZElucHV0PlxuPiA9IGFzeW5jIChldmVudCwgY29udGV4dCkgPT4ge1xuICBjb25zdCBBV1MgPSByZXF1aXJlKFwiYXdzLXNka1wiKVxuXG4gIGNvbnN0IGNvZGVidWlsZCA9IG5ldyBBV1MuQ29kZUJ1aWxkKCkgYXMgX0FXUy5Db2RlQnVpbGRcbiAgY29uc3QgczMgPSBuZXcgQVdTLlMzKCkgYXMgX0FXUy5TM1xuXG4gIGZ1bmN0aW9uIHJlcXVpcmVFbnYobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCB2YWx1ZSA9IHByb2Nlc3MuZW52W25hbWVdXG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyAke25hbWV9YClcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cblxuICBjb25zdCBwcm9qZWN0TmFtZSA9IHJlcXVpcmVFbnYoXCJQUk9KRUNUX05BTUVcIilcbiAgY29uc3QgYnVja2V0TmFtZSA9IHJlcXVpcmVFbnYoXCJCVUNLRVRfTkFNRVwiKVxuICBjb25zdCBjZGtDb250ZXh0ID0gSlNPTi5wYXJzZShyZXF1aXJlRW52KFwiQ0RLX0NPTlRFWFRcIikpXG5cbiAgLy8gU2luY2Ugd2UgcGFzcyB0aGUgc3RhY2sgbmFtZXMgYXMgc3RyaW5ncyB0byB0aGUgc2hlbGwsXG4gIC8vIGJlIGEgYml0IHJlc3RyaWN0aXZlIG9mIHRoZSB2YWxpZCB2YWx1ZXMgd2UgY2FuIHVzZS5cbiAgY29uc3QgdmFsaWRTdGFja05hbWUgPSAvXlthLXowLTlfXVthLXowLTlcXC1fXSokL2lcblxuICBjb25zdCBzM0tleVByZWZpeCA9IGAke2NvbnRleHQuYXdzUmVxdWVzdElkfS9gXG5cbiAgLy8gVmFsaWRhdGUgdGhlIGlucHV0LlxuICBpZiAoXG4gICAgdHlwZW9mIGV2ZW50LmJ1Y2tldE5hbWUgIT09IFwic3RyaW5nXCIgfHxcbiAgICB0eXBlb2YgZXZlbnQuYnVja2V0S2V5ICE9PSBcInN0cmluZ1wiIHx8XG4gICAgIUFycmF5LmlzQXJyYXkoZXZlbnQuc3RhY2tOYW1lcykgfHxcbiAgICAhZXZlbnQuc3RhY2tOYW1lcy5ldmVyeShcbiAgICAgIChpdCkgPT4gdHlwZW9mIGl0ID09PSBcInN0cmluZ1wiICYmIHZhbGlkU3RhY2tOYW1lLnRlc3QoaXQpLFxuICAgIClcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiSW5wdXQgaW52YWxpZDogXCIgKyBKU09OLnN0cmluZ2lmeShldmVudCwgdW5kZWZpbmVkLCBcIiAgXCIpKVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gcHV0KG5hbWU6IHN0cmluZywgZGF0YTogQVdTLlMzLkJvZHkpIHtcbiAgICBhd2FpdCBzM1xuICAgICAgLnB1dE9iamVjdCh7XG4gICAgICAgIEJ1Y2tldDogYnVja2V0TmFtZSxcbiAgICAgICAgS2V5OiBgJHtzM0tleVByZWZpeH0ke25hbWV9YCxcbiAgICAgICAgQm9keTogZGF0YSxcbiAgICAgIH0pXG4gICAgICAucHJvbWlzZSgpXG4gIH1cblxuICBhd2FpdCBwdXQoXCJzdGFjay1uYW1lcy50eHRcIiwgZXZlbnQuc3RhY2tOYW1lcy5qb2luKFwiIFwiKSlcbiAgLy8gRW5zdXJlIHRoYXQgd2UgcnVuIHRoZSBzY3JpcHQgdXNpbmcgc2FtZSBmZWF0dXJlIGZsYWdzLlxuICBhd2FpdCBwdXQoXG4gICAgXCJjZGsuanNvblwiLFxuICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGNvbnRleHQ6IGNka0NvbnRleHQsXG4gICAgfSksXG4gIClcblxuICBjb25zdCBidWlsZCA9IGF3YWl0IGNvZGVidWlsZFxuICAgIC5zdGFydEJ1aWxkKHtcbiAgICAgIHByb2plY3ROYW1lLFxuICAgICAgc291cmNlVHlwZU92ZXJyaWRlOiBcIlMzXCIsXG4gICAgICBzb3VyY2VMb2NhdGlvbk92ZXJyaWRlOiBgJHtidWNrZXROYW1lfS8ke3MzS2V5UHJlZml4fWAsXG4gICAgICBzZWNvbmRhcnlTb3VyY2VzT3ZlcnJpZGU6IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6IFwiUzNcIixcbiAgICAgICAgICBsb2NhdGlvbjogYCR7ZXZlbnQuYnVja2V0TmFtZX0vJHtldmVudC5idWNrZXRLZXl9YCxcbiAgICAgICAgICBzb3VyY2VJZGVudGlmaWVyOiBcIkNMT1VEQVNTRU1CTFlcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSlcbiAgICAucHJvbWlzZSgpXG5cbiAgY29uc3QgYnVpbGRJZCA9IGJ1aWxkLmJ1aWxkPy5pZFxuICBpZiAoYnVpbGRJZCA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBidWlsZCBJRFwiKVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAvLyBUaGlzIGlzIHRoZSB2YWx1ZSB0aGUgY2FsbGVyIHdpbGwgdXNlIHRvIGZldGNoIHVwZGF0ZWQgc3RhdHVzLlxuICAgIC8vIEF2b2lkIGV4cG9zaW5nIHdoYXQga2luZCBvZiBJRCB0aGlzIGlzLCBiZWNhdXNlIHdlIHNob3VsZCBiZSBmcmVlXG4gICAgLy8gdG8gY2hhbmdlIGltcGxlbWVudGF0aW9uIGRldGFpbHMuXG4gICAgam9iSWQ6IGJ1aWxkSWQsXG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,43 @@
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
+ }
@@ -0,0 +1,210 @@
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWR0cmFpbC1zbGFjay1pbnRlZ3JhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZHRyYWlsLXNsYWNrLWludGVncmF0aW9uL2Nsb3VkdHJhaWwtc2xhY2staW50ZWdyYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUNBQW9DO0FBQ3BDLHdDQUF1QztBQUN2QywwQ0FBeUM7QUFDekMsc0RBQXFEO0FBQ3JELDhDQUE2QztBQUM3Qyw4Q0FBNkM7QUFDN0MsNkRBQTREO0FBQzVELHdDQUF1QztBQUN2Qyx1REFBc0Q7QUFDdEQsNkJBQTRCO0FBa0M1Qjs7Ozs7O0dBTUc7QUFDSCxNQUFhLDBCQUEyQixTQUFRLEdBQUcsQ0FBQyxTQUFTO0lBQzNELFlBQ0UsS0FBb0IsRUFDcEIsRUFBVSxFQUNWLEtBQXNDO1FBRXRDLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFFaEIsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQzFDLElBQUksRUFDSix3QkFBd0IsRUFDeEI7WUFDRSxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQ3pCLElBQUksQ0FBQyxJQUFJLENBQ1AsU0FBUyxFQUNULGtEQUFrRCxDQUNuRCxDQUNGO1lBQ0QsV0FBVyxFQUNULHlJQUF5STtZQUMzSSxPQUFPLEVBQUUsZ0NBQWdDO1lBQ3pDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVU7WUFDbEMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNqQyxZQUFZLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVO1lBQzNDLFdBQVcsRUFBRTtnQkFDWCxhQUFhLEVBQUUsS0FBSyxDQUFDLFlBQVk7Z0JBQ2pDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQztnQkFDN0Qsc0JBQXNCLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FDcEMsS0FBSyxDQUFDLG9CQUFvQixJQUFJLEVBQUUsQ0FDakM7Z0JBQ0QsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLGVBQWU7YUFDekM7U0FDRixDQUNGLENBQUE7UUFDRCxnQkFBZ0IsQ0FBQyxlQUFlLENBQzlCLElBQUksR0FBRyxDQUFDLGVBQWUsQ0FBQztZQUN0QixPQUFPLEVBQUUsQ0FBQyx3QkFBd0IsQ0FBQztZQUNuQyxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7U0FDakIsQ0FBQyxDQUNILENBQUE7UUFDRCxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsRUFBRTtZQUNuQyxNQUFNLHFCQUFxQixHQUFHLGdCQUFnQjtpQkFDM0MsWUFBWSxDQUFDO2dCQUNaLE1BQU0sRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQy9CLFNBQVMsRUFBRSxVQUFVLENBQUMsU0FBUyxDQUFDLEdBQUc7YUFDcEMsQ0FBQztpQkFDRCxXQUFXLENBQUMsSUFBSSxFQUFFLDRCQUE0QixFQUFFO2dCQUMvQyxTQUFTLEVBQUUsQ0FBQztnQkFDWixpQkFBaUIsRUFBRSxDQUFDO2dCQUNwQixnQkFBZ0IsRUFDZCwrSUFBK0k7Z0JBQ2pKLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3BCLGdCQUFnQixFQUFFLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNO2FBQ3JELENBQUMsQ0FBQTtZQUNKLHFCQUFxQixDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQTtZQUNsRSxxQkFBcUIsQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUE7U0FDdEU7UUFDRCxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsRUFBRTtZQUMzQixNQUFNLGtCQUFrQixHQUFHLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFO2dCQUN0RCw0RkFBNEY7Z0JBQzVGLFNBQVMsRUFDUCxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDcEUsT0FBTztnQkFDVCxJQUFJLEVBQUUsSUFBSTthQUNYLENBQUMsQ0FBQTtZQUNGLGdCQUFnQixDQUFDLGNBQWMsQ0FDN0IsZUFBZSxFQUNmLGtCQUFrQixDQUFDLFFBQVEsQ0FDNUIsQ0FBQTtZQUNELGtCQUFrQixDQUFDLGlCQUFpQixDQUFDLGdCQUFnQixDQUFDLENBQUE7WUFDdEQsTUFBTSxjQUFjLEdBQUcsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxzQkFBc0IsRUFBRTtnQkFDdkUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUN6QixJQUFJLENBQUMsSUFBSSxDQUNQLFNBQVMsRUFDVCxrREFBa0QsQ0FDbkQsQ0FDRjtnQkFDRCxXQUFXLEVBQ1QsaUdBQWlHO2dCQUNuRyxPQUFPLEVBQUUsOEJBQThCO2dCQUN2QyxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFVO2dCQUNsQyxPQUFPLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNqQyxZQUFZLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTO2FBQzNDLENBQUMsQ0FBQTtZQUVGLElBQUksS0FBSyxDQUFDLHlCQUF5QixFQUFFO2dCQUNuQyxNQUFNLG1CQUFtQixHQUFHLGNBQWM7cUJBQ3ZDLFlBQVksQ0FBQztvQkFDWixNQUFNLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO29CQUMvQixTQUFTLEVBQUUsVUFBVSxDQUFDLFNBQVMsQ0FBQyxHQUFHO2lCQUNwQyxDQUFDO3FCQUNELFdBQVcsQ0FBQyxJQUFJLEVBQUUsMEJBQTBCLEVBQUU7b0JBQzdDLFNBQVMsRUFBRSxDQUFDO29CQUNaLGdCQUFnQixFQUNkLCtLQUErSztvQkFDakwsaUJBQWlCLEVBQUUsQ0FBQztvQkFDcEIsaUJBQWlCLEVBQUUsQ0FBQztvQkFDcEIsZ0JBQWdCLEVBQUUsVUFBVSxDQUFDLGdCQUFnQixDQUFDLE1BQU07aUJBQ3JELENBQUMsQ0FBQTtnQkFDSixtQkFBbUIsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUE7Z0JBQ2hFLG1CQUFtQixDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQTthQUNwRTtZQUNELGNBQWMsQ0FBQyxjQUFjLENBQzNCLElBQUksT0FBTyxDQUFDLGNBQWMsQ0FBQyxrQkFBa0IsQ0FBQyxDQUMvQyxDQUFBO1NBQ0Y7UUFFRCxJQUFJLEtBQUssQ0FBQyxjQUFjLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQzNELElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLEVBQUU7Z0JBQ3pDLE9BQU8sRUFBRSxJQUFJO2dCQUNiLE9BQU8sRUFBRSxDQUFDLElBQUksT0FBTyxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUN2RCxZQUFZLEVBQUU7b0JBQ1osTUFBTSxFQUFFO3dCQUNOLFNBQVMsRUFBRSxDQUFDLFlBQVksQ0FBQzt3QkFDekIsaUJBQWlCLEVBQUU7NEJBQ2pCLE9BQU8sRUFBRSxLQUFLLENBQUMsY0FBYzt5QkFDOUI7cUJBQ0Y7aUJBQ0Y7YUFDRixDQUFDLENBQUE7U0FDSDtRQUVELElBQUksS0FBSyxDQUFDLHNCQUFzQixLQUFLLEtBQUssRUFBRTtZQUMxQyxtREFBbUQ7WUFDbkQsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSwrQkFBK0IsRUFBRTtnQkFDckQsT0FBTyxFQUFFLElBQUk7Z0JBQ2IsT0FBTyxFQUFFLENBQUMsSUFBSSxPQUFPLENBQUMsY0FBYyxDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0JBQ3ZELFlBQVksRUFBRTtvQkFDWixNQUFNLEVBQUU7d0JBQ04sWUFBWSxFQUFFOzRCQUNaLElBQUksRUFBRSxDQUFDLE1BQU0sQ0FBQzt5QkFDZjt3QkFDRCxTQUFTLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQzt3QkFDOUIsU0FBUyxFQUFFLENBQUMsa0JBQWtCLENBQUM7cUJBQ2hDO2lCQUNGO2FBQ0YsQ0FBQyxDQUFBO1lBRUYsc0RBQXNEO1lBQ3RELElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsMEJBQTBCLEVBQUU7Z0JBQ2hELE9BQU8sRUFBRSxJQUFJO2dCQUNiLE9BQU8sRUFBRSxDQUFDLElBQUksT0FBTyxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUN2RCxZQUFZLEVBQUU7b0JBQ1osTUFBTSxFQUFFO3dCQUNOLFlBQVksRUFBRTs0QkFDWixJQUFJLEVBQUUsQ0FBQyxNQUFNLENBQUM7eUJBQ2Y7d0JBQ0QsU0FBUyxFQUFFLENBQUMsaUJBQWlCLENBQUM7d0JBQzlCLGlCQUFpQixFQUFFOzRCQUNqQixRQUFRLEVBQUUsQ0FBQyxlQUFlLENBQUM7eUJBQzVCO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQyxDQUFBO1lBRUYsK0RBQStEO1lBQy9ELElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsZ0NBQWdDLEVBQUU7Z0JBQ3RELE9BQU8sRUFBRSxJQUFJO2dCQUNiLE9BQU8sRUFBRSxDQUFDLElBQUksT0FBTyxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUN2RCxZQUFZLEVBQUU7b0JBQ1osTUFBTSxFQUFFO3dCQUNOLFlBQVksRUFBRTs0QkFDWixJQUFJLEVBQUUsQ0FBQyxNQUFNLENBQUM7eUJBQ2Y7d0JBQ0QsU0FBUyxFQUFFLENBQUMsY0FBYyxDQUFDO3dCQUMzQixTQUFTLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQzt3QkFDL0IsZ0JBQWdCLEVBQUU7NEJBQ2hCLFlBQVksRUFBRSxDQUFDLFNBQVMsQ0FBQzt5QkFDMUI7cUJBQ0Y7aUJBQ0Y7YUFDRixDQUFDLENBQUE7WUFFRixzRUFBc0U7WUFDdEUsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxrQ0FBa0MsRUFBRTtnQkFDeEQsT0FBTyxFQUFFLElBQUk7Z0JBQ2IsT0FBTyxFQUFFLENBQUMsSUFBSSxPQUFPLENBQUMsY0FBYyxDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0JBQ3ZELFlBQVksRUFBRTtvQkFDWixNQUFNLEVBQUU7d0JBQ04sWUFBWSxFQUFFOzRCQUNaLElBQUksRUFBRSxDQUFDLE1BQU0sQ0FBQzt5QkFDZjt3QkFDRCxTQUFTLEVBQUUsQ0FBQyxjQUFjLENBQUM7d0JBQzNCLFNBQVMsRUFBRSxDQUFDLGtCQUFrQixDQUFDO3dCQUMvQixnQkFBZ0IsRUFBRTs0QkFDaEIsWUFBWSxFQUFFLENBQUMsU0FBUyxDQUFDO3lCQUMxQjtxQkFDRjtpQkFDRjthQUNGLENBQUMsQ0FBQTtZQUVGLG1EQUFtRDtZQUNuRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLHdDQUF3QyxFQUFFO2dCQUM5RCxPQUFPLEVBQUUsSUFBSTtnQkFDYixPQUFPLEVBQUUsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDdkQsWUFBWSxFQUFFO29CQUNaLE1BQU0sRUFBRTt3QkFDTixZQUFZLEVBQUU7NEJBQ1osSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDO3lCQUNmO3dCQUNELFNBQVMsRUFBRSxDQUFDLDJCQUEyQixDQUFDO3dCQUN4QyxTQUFTLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQzt3QkFDL0IsZ0JBQWdCLEVBQUU7NEJBQ2hCLHlCQUF5QixFQUFFLENBQUMsU0FBUyxDQUFDO3lCQUN2QztxQkFDRjtpQkFDRjthQUNGLENBQUMsQ0FBQTtZQUVGLHNEQUFzRDtZQUN0RCxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLHlDQUF5QyxFQUFFO2dCQUMvRCxPQUFPLEVBQUUsSUFBSTtnQkFDYixPQUFPLEVBQUUsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDdkQsWUFBWSxFQUFFO29CQUNaLE1BQU0sRUFBRTt3QkFDTixZQUFZLEVBQUU7NEJBQ1osSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDO3lCQUNmO3dCQUNELFNBQVMsRUFBRSxDQUFDLDJCQUEyQixDQUFDO3dCQUN4QyxTQUFTLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQzt3QkFDL0IsZ0JBQWdCLEVBQUU7NEJBQ2hCLHlCQUF5QixFQUFFLENBQUMsU0FBUyxDQUFDO3lCQUN2QztxQkFDRjtpQkFDRjthQUNGLENBQUMsQ0FBQTtTQUNIO0lBQ0gsQ0FBQztDQUNGO0FBcE9ELGdFQW9PQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNkayBmcm9tIFwiQGF3cy1jZGsvY29yZVwiXG5pbXBvcnQgKiBhcyBpYW0gZnJvbSBcIkBhd3MtY2RrL2F3cy1pYW1cIlxuaW1wb3J0ICogYXMgbG9ncyBmcm9tIFwiQGF3cy1jZGsvYXdzLWxvZ3NcIlxuaW1wb3J0ICogYXMgY2xvdWR3YXRjaCBmcm9tIFwiQGF3cy1jZGsvYXdzLWNsb3Vkd2F0Y2hcIlxuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gXCJAYXdzLWNkay9hd3MtbGFtYmRhXCJcbmltcG9ydCAqIGFzIGV2ZW50cyBmcm9tIFwiQGF3cy1jZGsvYXdzLWV2ZW50c1wiXG5pbXBvcnQgKiBhcyBzb3VyY2VzIGZyb20gXCJAYXdzLWNkay9hd3MtbGFtYmRhLWV2ZW50LXNvdXJjZXNcIlxuaW1wb3J0ICogYXMgc3FzIGZyb20gXCJAYXdzLWNkay9hd3Mtc3FzXCJcbmltcG9ydCAqIGFzIHRhcmdldHMgZnJvbSBcIkBhd3MtY2RrL2F3cy1ldmVudHMtdGFyZ2V0c1wiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCJcblxuZXhwb3J0IGludGVyZmFjZSBDbG91ZFRyYWlsU2xhY2tJbnRlZ3JhdGlvblByb3BzIGV4dGVuZHMgY2RrLlN0YWNrUHJvcHMge1xuICAvKipcbiAgICogQSBrZXktdmFsdWUgcGFpciBvZiBBV1MgYWNjb3VudCBJRHMgYW5kIGZyaWVuZGx5IG5hbWVzIG9mIHRoZXNlIGFjY291bnRzXG4gICAqIHRvIHVzZSB3aGVuIHNlbmRpbmcgbWVzc2FnZXMgdG8gU2xhY2suXG4gICAqL1xuICBhY2NvdW50RnJpZW5kbHlOYW1lcz86IHtcbiAgICBba2V5OiBzdHJpbmddOiBzdHJpbmdcbiAgfVxuICBzbGFja1dlYmhvb2tVcmw6IHN0cmluZ1xuICBzbGFja0NoYW5uZWw6IHN0cmluZ1xuICAvKipcbiAgICogQSBsaXN0IG9mIEFSTnMgb2Ygcm9sZXMgaW4gdGhlIGN1cnJlbnQgYWNjb3VudCB0byBtb25pdG9yIHVzYWdlIG9mLlxuICAgKi9cbiAgcm9sZXNUb01vbml0b3I/OiBzdHJpbmdbXVxuICAvKipcbiAgICogV2hldGhlciB0byBtb25pdG9yIHZhcmlvdXMgSUFNIEFQSSBjYWxscyBhc3NvY2lhdGVkIHdpdGggdGhlIGN1cnJlbnQgYWNjb3VudCdzIHJvb3QgdXNlciAoZS5nLiwgY29uc29sZSBsb2dpbiwgcGFzc3dvcmQgcmVzZXQsIGV0Yy4pXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIG1vbml0b3JSb290VXNlckFjdGlvbnM/OiBib29sZWFuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHNldCB1cCBhZGRpdGlvbmFsIEFXUyBpbmZyYXN0cnVjdHVyZSB0byBkZWR1cGxpY2F0ZSBDbG91ZFRyYWlsIGV2ZW50cyBpbiBvcmRlciB0byBhdm9pZCBkdXBsaWNhdGUgU2xhY2sgbWVzc2FnZXMuIE1heSBiZSB1c2VkIHRvIGRlY3JlYXNlIG5vaXNlLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgZGVkdXBsaWNhdGVFdmVudHM/OiBib29sZWFuXG4gIC8qKlxuICAgKiBJZiBzdXBwbGllZCwgQ2xvdWRXYXRjaCBhbGFybXMgd2lsbCBiZSBjcmVhdGVkIGZvciB0aGUgY29uc3RydWN0J3MgdW5kZXJseWluZyBpbmZyYXN0cnVjdHVyZSAoZS5nLiwgTGFtYmRhIGZ1bmN0aW9ucykgYW5kIHRoZSBhY3Rpb24gd2lsbCBiZSB1c2VkIHRvIG5vdGlmeSBvbiBPSyBhbmQgQUxBUk0gYWN0aW9ucy5cbiAgICovXG4gIGluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvblxufVxuXG4vKipcbiAqIEZvcndhcmQgYSBwcmVkZWZpbmVkIHNldCBvZiBDbG91ZFRyYWlsIEFQSSBldmVudHMgdG8gU2xhY2sgdXNpbmcgRXZlbnRCcmlkZ2UsIExhbWJkYVxuICogYW5kIGFuIG9wdGlvbmFsIFNRUyBGSUZPIHF1ZXVlIGZvciBkZWR1cGxpY2F0aW5nIGV2ZW50cy5cbiAqIFRoZSBBUEkgZXZlbnRzIGFyZSBsaW1pdGVkIHRvIG1vbml0b3JpbmcgYWNjZXNzIHRvIHRoZSBjdXJyZW50IGFjY291bnQncyByb290IHVzZXIgYW5kL29yIHNwZWNpZmljIElBTSByb2xlcy5cbiAqXG4gKiBOT1RFOiBUaGUgY29uc3RydWN0IG5lZWRzIHRvIGJlIHByb3Zpc2lvbmVkIGluIHVzLWVhc3QtMSwgYW5kIHJlcXVpcmVzIGFuIGV4aXN0aW5nIENsb3VkVHJhaWwgc2V0IHVwIGluIHRoYXQgcmVnaW9uLlxuICovXG5leHBvcnQgY2xhc3MgQ2xvdWRUcmFpbFNsYWNrSW50ZWdyYXRpb24gZXh0ZW5kcyBjZGsuQ29uc3RydWN0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IGNkay5Db25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wczogQ2xvdWRUcmFpbFNsYWNrSW50ZWdyYXRpb25Qcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKVxuXG4gICAgY29uc3QgZXZlbnRUcmFuc2Zvcm1lciA9IG5ldyBsYW1iZGEuRnVuY3Rpb24oXG4gICAgICB0aGlzLFxuICAgICAgXCJFdmVudFRyYW5zZm9ybWVyTGFtYmRhXCIsXG4gICAgICB7XG4gICAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChcbiAgICAgICAgICBwYXRoLmpvaW4oXG4gICAgICAgICAgICBfX2Rpcm5hbWUsXG4gICAgICAgICAgICBcIi4uLy4uL2Fzc2V0cy9jbG91ZHRyYWlsLXNsYWNrLWludGVncmF0aW9uLWxhbWJkYVwiLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgIFwiRm9ybWF0cyBDbG91ZFRyYWlsIEFQSSBjYWxscyBzZW50IHRocm91Z2ggRXZlbnRCcmlkZ2UsIGFuZCBwb3N0cyB0aGVtIGRpcmVjdGx5IHRvIFNsYWNrIG9yIGZpcnN0IHRvIGFuIFNRUyBGSUZPIHF1ZXVlIGZvciBkZWR1cGxpY2F0aW9uXCIsXG4gICAgICAgIGhhbmRsZXI6IFwibWFpbi5oYW5kbGVyX2V2ZW50X3RyYW5zZm9ybWVyXCIsXG4gICAgICAgIHJ1bnRpbWU6IGxhbWJkYS5SdW50aW1lLlBZVEhPTl8zXzksXG4gICAgICAgIHRpbWVvdXQ6IGNkay5EdXJhdGlvbi5zZWNvbmRzKDE1KSxcbiAgICAgICAgbG9nUmV0ZW50aW9uOiBsb2dzLlJldGVudGlvbkRheXMuU0lYX01PTlRIUyxcbiAgICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBTTEFDS19DSEFOTkVMOiBwcm9wcy5zbGFja0NoYW5uZWwsXG4gICAgICAgICAgREVEVVBMSUNBVEVfRVZFTlRTOiBKU09OLnN0cmluZ2lmeSghIXByb3BzLmRlZHVwbGljYXRlRXZlbnRzKSxcbiAgICAgICAgICBBQ0NPVU5UX0ZSSUVORExZX05BTUVTOiBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgIHByb3BzLmFjY291bnRGcmllbmRseU5hbWVzIHx8IHt9LFxuICAgICAgICAgICksXG4gICAgICAgICAgU0xBQ0tfV0VCSE9PS19VUkw6IHByb3BzLnNsYWNrV2ViaG9va1VybCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgKVxuICAgIGV2ZW50VHJhbnNmb3JtZXIuYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbXCJpYW06TGlzdEFjY291bnRBbGlhc2VzXCJdLFxuICAgICAgICByZXNvdXJjZXM6IFtcIipcIl0sXG4gICAgICB9KSxcbiAgICApXG4gICAgaWYgKHByb3BzLmluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24pIHtcbiAgICAgIGNvbnN0IGV2ZW50VHJhbnNmb3JtZXJBbGFybSA9IGV2ZW50VHJhbnNmb3JtZXJcbiAgICAgICAgLm1ldHJpY0Vycm9ycyh7XG4gICAgICAgICAgcGVyaW9kOiBjZGsuRHVyYXRpb24ubWludXRlcyg1KSxcbiAgICAgICAgICBzdGF0aXN0aWM6IGNsb3Vkd2F0Y2guU3RhdGlzdGljLlNVTSxcbiAgICAgICAgfSlcbiAgICAgICAgLmNyZWF0ZUFsYXJtKHRoaXMsIFwiRXZlbnRUcmFuc2Zvcm1lckVycm9yQWxhcm1cIiwge1xuICAgICAgICAgIHRocmVzaG9sZDogMSxcbiAgICAgICAgICBldmFsdWF0aW9uUGVyaW9kczogMSxcbiAgICAgICAgICBhbGFybURlc2NyaXB0aW9uOlxuICAgICAgICAgICAgXCJUcmlnZ2VycyBpZiB0aGUgTGFtYmRhIGZ1bmN0aW9uIHRoYXQgdHJhbnNmb3JtcyBDbG91ZFRyYWlsIEFQSSBjYWxscyByZWNlaXZlZCB0aHJvdWdoIEV2ZW50QnJpZGdlIGZhaWxzIChlLmcuLCBpdCBmYWlscyB0byBwcm9jZXNzIHRoZSBldmVudClcIixcbiAgICAgICAgICBkYXRhcG9pbnRzVG9BbGFybTogMSxcbiAgICAgICAgICB0cmVhdE1pc3NpbmdEYXRhOiBjbG91ZHdhdGNoLlRyZWF0TWlzc2luZ0RhdGEuSUdOT1JFLFxuICAgICAgICB9KVxuICAgICAgZXZlbnRUcmFuc2Zvcm1lckFsYXJtLmFkZE9rQWN0aW9uKHByb3BzLmluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24pXG4gICAgICBldmVudFRyYW5zZm9ybWVyQWxhcm0uYWRkQWxhcm1BY3Rpb24ocHJvcHMuaW5mcmFzdHJ1Y3R1cmVBbGFybUFjdGlvbilcbiAgICB9XG4gICAgaWYgKHByb3BzLmRlZHVwbGljYXRlRXZlbnRzKSB7XG4gICAgICBjb25zdCBkZWR1cGxpY2F0aW9uUXVldWUgPSBuZXcgc3FzLlF1ZXVlKHRoaXMsIFwiUXVldWVcIiwge1xuICAgICAgICAvLyBXZSBleHBsaWNpdGx5IGdpdmUgdGhlIHF1ZXVlIGEgbmFtZSBkdWUgdG8gYnVnIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLWNkay9pc3N1ZXMvNTg2MFxuICAgICAgICBxdWV1ZU5hbWU6XG4gICAgICAgICAgYCR7dGhpcy5ub2RlLmlkLnN1YnN0cmluZygwLCAzMyl9JHt0aGlzLm5vZGUuYWRkcn1gLnN1YnN0cmluZygwLCA3NSkgK1xuICAgICAgICAgIFwiLmZpZm9cIixcbiAgICAgICAgZmlmbzogdHJ1ZSxcbiAgICAgIH0pXG4gICAgICBldmVudFRyYW5zZm9ybWVyLmFkZEVudmlyb25tZW50KFxuICAgICAgICBcIlNRU19RVUVVRV9VUkxcIixcbiAgICAgICAgZGVkdXBsaWNhdGlvblF1ZXVlLnF1ZXVlVXJsLFxuICAgICAgKVxuICAgICAgZGVkdXBsaWNhdGlvblF1ZXVlLmdyYW50U2VuZE1lc3NhZ2VzKGV2ZW50VHJhbnNmb3JtZXIpXG4gICAgICBjb25zdCBzbGFja0ZvcndhcmRlciA9IG5ldyBsYW1iZGEuRnVuY3Rpb24odGhpcywgXCJTbGFja0ZvcndhcmRlckxhbWJkYVwiLCB7XG4gICAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChcbiAgICAgICAgICBwYXRoLmpvaW4oXG4gICAgICAgICAgICBfX2Rpcm5hbWUsXG4gICAgICAgICAgICBcIi4uLy4uL2Fzc2V0cy9jbG91ZHRyYWlsLXNsYWNrLWludGVncmF0aW9uLWxhbWJkYVwiLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgIFwiUG9sbHMgZnJvbSBhbiBTUVMgRklGTyBxdWV1ZSBjb250YWluaW5nIGZvcm1hdHRlZCBDbG91ZFRyYWlsIEFQSSBjYWxscyBhbmQgc2VuZHMgdGhlbSB0byBTbGFjay5cIixcbiAgICAgICAgaGFuZGxlcjogXCJtYWluLmhhbmRsZXJfc2xhY2tfZm9yd2FyZGVyXCIsXG4gICAgICAgIHJ1bnRpbWU6IGxhbWJkYS5SdW50aW1lLlBZVEhPTl8zXzksXG4gICAgICAgIHRpbWVvdXQ6IGNkay5EdXJhdGlvbi5zZWNvbmRzKDE1KSxcbiAgICAgICAgbG9nUmV0ZW50aW9uOiBsb2dzLlJldGVudGlvbkRheXMuVFdPX1dFRUtTLFxuICAgICAgfSlcblxuICAgICAgaWYgKHByb3BzLmluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24pIHtcbiAgICAgICAgY29uc3Qgc2xhY2tGb3J3YXJkZXJBbGFybSA9IHNsYWNrRm9yd2FyZGVyXG4gICAgICAgICAgLm1ldHJpY0Vycm9ycyh7XG4gICAgICAgICAgICBwZXJpb2Q6IGNkay5EdXJhdGlvbi5taW51dGVzKDUpLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBjbG91ZHdhdGNoLlN0YXRpc3RpYy5TVU0sXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuY3JlYXRlQWxhcm0odGhpcywgXCJTbGFja0ZvcndhcmRlckVycm9yQWxhcm1cIiwge1xuICAgICAgICAgICAgdGhyZXNob2xkOiAxLFxuICAgICAgICAgICAgYWxhcm1EZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICAgXCJUcmlnZ2VycyBpZiB0aGUgTGFtYmRhIGZ1bmN0aW9uIHRoYXQgcG9sbHMgZnJvbSBTUVMgYW5kIHBvc3RzIGRlZHVwbGljYXRlZCBDbG91ZFRyYWlsIEFQSSBjYWxscyByZWNlaXZlZCB0aHJvdWdoIEV2ZW50QnJpZGdlIHRvIFNsYWNrIGZhaWxzIChlLmcuLCBpbnZhbGlkIFNsYWNrIHdlYmhvb2sgVVJMKVwiLFxuICAgICAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IDEsXG4gICAgICAgICAgICBkYXRhcG9pbnRzVG9BbGFybTogMSxcbiAgICAgICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5JR05PUkUsXG4gICAgICAgICAgfSlcbiAgICAgICAgc2xhY2tGb3J3YXJkZXJBbGFybS5hZGRPa0FjdGlvbihwcm9wcy5pbmZyYXN0cnVjdHVyZUFsYXJtQWN0aW9uKVxuICAgICAgICBzbGFja0ZvcndhcmRlckFsYXJtLmFkZEFsYXJtQWN0aW9uKHByb3BzLmluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24pXG4gICAgICB9XG4gICAgICBzbGFja0ZvcndhcmRlci5hZGRFdmVudFNvdXJjZShcbiAgICAgICAgbmV3IHNvdXJjZXMuU3FzRXZlbnRTb3VyY2UoZGVkdXBsaWNhdGlvblF1ZXVlKSxcbiAgICAgIClcbiAgICB9XG5cbiAgICBpZiAocHJvcHMucm9sZXNUb01vbml0b3IgJiYgcHJvcHMucm9sZXNUb01vbml0b3IubGVuZ3RoID4gMCkge1xuICAgICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsIFwiUnVsZUZvckFzc3VtZVJvbGVcIiwge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICB0YXJnZXRzOiBbbmV3IHRhcmdldHMuTGFtYmRhRnVuY3Rpb24oZXZlbnRUcmFuc2Zvcm1lcildLFxuICAgICAgICBldmVudFBhdHRlcm46IHtcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIGV2ZW50TmFtZTogW1wiQXNzdW1lUm9sZVwiXSxcbiAgICAgICAgICAgIHJlcXVlc3RQYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAgIHJvbGVBcm46IHByb3BzLnJvbGVzVG9Nb25pdG9yLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAocHJvcHMubW9uaXRvclJvb3RVc2VyQWN0aW9ucyAhPT0gZmFsc2UpIHtcbiAgICAgIC8vIFRyaWdnZXJzIHdoZW4gdGhlIHJvb3QgcGFzc3dvcmQgaGFzIGJlZW4gY2hhbmdlZFxuICAgICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsIFwiUnVsZUZvclJvb3RVc2VyUGFzc3dvcmRDaGFuZ2VcIiwge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICB0YXJnZXRzOiBbbmV3IHRhcmdldHMuTGFtYmRhRnVuY3Rpb24oZXZlbnRUcmFuc2Zvcm1lcildLFxuICAgICAgICBldmVudFBhdHRlcm46IHtcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIHVzZXJJZGVudGl0eToge1xuICAgICAgICAgICAgICB0eXBlOiBbXCJSb290XCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGV2ZW50TmFtZTogW1wiUGFzc3dvcmRVcGRhdGVkXCJdLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBbXCJBd3NDb25zb2xlU2lnbkluXCJdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuXG4gICAgICAvLyBUcmlnZ2VycyB3aGVuIE1GQSBmb3IgdGhlIHJvb3QgdXNlciBoYXMgYmVlbiBzZXQgdXBcbiAgICAgIG5ldyBldmVudHMuUnVsZSh0aGlzLCBcIlJ1bGVGb3JSb290VXNlck1mYUNoYW5nZVwiLCB7XG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgIHRhcmdldHM6IFtuZXcgdGFyZ2V0cy5MYW1iZGFGdW5jdGlvbihldmVudFRyYW5zZm9ybWVyKV0sXG4gICAgICAgIGV2ZW50UGF0dGVybjoge1xuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgdXNlcklkZW50aXR5OiB7XG4gICAgICAgICAgICAgIHR5cGU6IFtcIlJvb3RcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXZlbnROYW1lOiBbXCJFbmFibGVNRkFEZXZpY2VcIl0sXG4gICAgICAgICAgICByZXF1ZXN0UGFyYW1ldGVyczoge1xuICAgICAgICAgICAgICB1c2VyTmFtZTogW1wiQVdTIFJPT1QgVVNFUlwiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pXG5cbiAgICAgIC8vIFRyaWdnZXJzIHdoZW4gYSByb290IHVzZXIgc3VjY2VzZnVsbHkgbG9ncyBpbiB0byB0aGUgY29uc29sZVxuICAgICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsIFwiUnVsZUZvclJvb3RVc2VyU3VjY2Vzc2Z1bExvZ2luXCIsIHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgdGFyZ2V0czogW25ldyB0YXJnZXRzLkxhbWJkYUZ1bmN0aW9uKGV2ZW50VHJhbnNmb3JtZXIpXSxcbiAgICAgICAgZXZlbnRQYXR0ZXJuOiB7XG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICB1c2VySWRlbnRpdHk6IHtcbiAgICAgICAgICAgICAgdHlwZTogW1wiUm9vdFwiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBldmVudE5hbWU6IFtcIkNvbnNvbGVMb2dpblwiXSxcbiAgICAgICAgICAgIGV2ZW50VHlwZTogW1wiQXdzQ29uc29sZVNpZ25JblwiXSxcbiAgICAgICAgICAgIHJlc3BvbnNlRWxlbWVudHM6IHtcbiAgICAgICAgICAgICAgQ29uc29sZUxvZ2luOiBbXCJTdWNjZXNzXCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSlcblxuICAgICAgLy8gVHJpZ2dlcnMgZm9yIGJhZCBsb2dpbiBhdHRlbXBzIGZvciByb290IHVzZXIgKGUuZy4sIHdyb25nIHBhc3N3b3JkKVxuICAgICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsIFwiUnVsZUZvclJvb3RVc2VyVW5zdWNjZXNzZnVsTG9naW5cIiwge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICB0YXJnZXRzOiBbbmV3IHRhcmdldHMuTGFtYmRhRnVuY3Rpb24oZXZlbnRUcmFuc2Zvcm1lcildLFxuICAgICAgICBldmVudFBhdHRlcm46IHtcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIHVzZXJJZGVudGl0eToge1xuICAgICAgICAgICAgICB0eXBlOiBbXCJSb290XCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGV2ZW50TmFtZTogW1wiQ29uc29sZUxvZ2luXCJdLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBbXCJBd3NDb25zb2xlU2lnbkluXCJdLFxuICAgICAgICAgICAgcmVzcG9uc2VFbGVtZW50czoge1xuICAgICAgICAgICAgICBDb25zb2xlTG9naW46IFtcIkZhaWx1cmVcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuXG4gICAgICAvLyBUcmlnZ2VyZWQgd2hlbiBwYXNzd29yZCByZXNldCBoYXMgYmVlbiByZXF1ZXN0ZWRcbiAgICAgIG5ldyBldmVudHMuUnVsZSh0aGlzLCBcIlJ1bGVGb3JSb290VXNlclBhc3N3b3JkUmVjb3ZlcnlSZXF1ZXN0XCIsIHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgdGFyZ2V0czogW25ldyB0YXJnZXRzLkxhbWJkYUZ1bmN0aW9uKGV2ZW50VHJhbnNmb3JtZXIpXSxcbiAgICAgICAgZXZlbnRQYXR0ZXJuOiB7XG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICB1c2VySWRlbnRpdHk6IHtcbiAgICAgICAgICAgICAgdHlwZTogW1wiUm9vdFwiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBldmVudE5hbWU6IFtcIlBhc3N3b3JkUmVjb3ZlcnlSZXF1ZXN0ZWRcIl0sXG4gICAgICAgICAgICBldmVudFR5cGU6IFtcIkF3c0NvbnNvbGVTaWduSW5cIl0sXG4gICAgICAgICAgICByZXNwb25zZUVsZW1lbnRzOiB7XG4gICAgICAgICAgICAgIFBhc3N3b3JkUmVjb3ZlcnlSZXF1ZXN0ZWQ6IFtcIlN1Y2Nlc3NcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuXG4gICAgICAvLyBUcmlnZ2VyZWQgd2hlbiBwYXNzd29yZCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVzZXRcbiAgICAgIG5ldyBldmVudHMuUnVsZSh0aGlzLCBcIlJ1bGVGb3JSb290VXNlclBhc3N3b3JkUmVjb3ZlcnlDb21wbGV0ZVwiLCB7XG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgIHRhcmdldHM6IFtuZXcgdGFyZ2V0cy5MYW1iZGFGdW5jdGlvbihldmVudFRyYW5zZm9ybWVyKV0sXG4gICAgICAgIGV2ZW50UGF0dGVybjoge1xuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgdXNlcklkZW50aXR5OiB7XG4gICAgICAgICAgICAgIHR5cGU6IFtcIlJvb3RcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXZlbnROYW1lOiBbXCJQYXNzd29yZFJlY292ZXJ5Q29tcGxldGVkXCJdLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBbXCJBd3NDb25zb2xlU2lnbkluXCJdLFxuICAgICAgICAgICAgcmVzcG9uc2VFbGVtZW50czoge1xuICAgICAgICAgICAgICBQYXNzd29yZFJlY292ZXJ5Q29tcGxldGVkOiBbXCJTdWNjZXNzXCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1 @@
1
+ export { CloudTrailSlackIntegration, CloudTrailSlackIntegrationProps, } from "./cloudtrail-slack-integration";
@@ -0,0 +1,6 @@
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=
@@ -54,7 +54,6 @@ const startDeployHandler = async (event) => {
54
54
  "status",
55
55
  "taskDefinitionArn",
56
56
  ];
57
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
58
57
  const updatedSpec = {
59
58
  ...Object.fromEntries(Object.entries(prevTaskDefinition).filter(([key]) => !exclude.includes(key))),
60
59
  containerDefinitions: [
@@ -102,4 +101,4 @@ const startDeployHandler = async (event) => {
102
101
  return {};
103
102
  };
104
103
  exports.startDeployHandler = startDeployHandler;
105
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnQtZGVwbG95LWhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZWNzLXVwZGF0ZS1pbWFnZS9zdGFydC1kZXBsb3ktaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFZQSxtREFBbUQ7QUFDbkQsNkJBQTZCO0FBQ3RCLE1BQU0sa0JBQWtCLEdBQW9DLEtBQUssRUFDdEUsS0FBSyxFQUNMLEVBQUU7SUFDRixNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUE7SUFDOUIsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxFQUFjLENBQUE7SUFDckMsTUFBTSxFQUFFLEdBQUcsSUFBSSxHQUFHLENBQUMsY0FBYyxFQUF5QixDQUFBO0lBRTFELFNBQVMsVUFBVSxDQUFDLElBQVk7UUFDOUIsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUMvQixJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUU7WUFDdkIsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDLENBQUE7U0FDbkM7UUFDRCxPQUFPLEtBQUssQ0FBQTtJQUNkLENBQUM7SUFFRCxLQUFLLFVBQVUsVUFBVSxDQUN2QixXQUFtQixFQUNuQixXQUFtQjs7UUFFbkIsTUFBTSxRQUFRLEdBQUcsTUFBTSxHQUFHO2FBQ3ZCLGdCQUFnQixDQUFDO1lBQ2hCLE9BQU8sRUFBRSxXQUFXO1lBQ3BCLFFBQVEsRUFBRSxDQUFDLFdBQVcsQ0FBQztTQUN4QixDQUFDO2FBQ0QsT0FBTyxFQUFFLENBQUE7UUFFWixJQUFJLENBQUEsTUFBQSxRQUFRLENBQUMsUUFBUSwwQ0FBRSxNQUFNLE1BQUssQ0FBQyxFQUFFO1lBQ25DLE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLFdBQVcsSUFBSSxXQUFXLEVBQUUsQ0FBQyxDQUFBO1NBQ3BFO1FBRUQsT0FBTyxRQUFRLENB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O1FBQ1osUUFBUSxFQUFFLGVBQWU7UUFDekIsWUFBWSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDM0IsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHO1NBQ2YsQ0FBQztLQUNILENBQUM7U0FDRCxPQUFPLEVBQUUsQ0FBQTtJQUVaLGtFQUFrRTtJQUNsRSwwQ0FBMEM7SUFDMUMsSUFBSSxXQUFXLEtBQUssRUFBRSxFQUFFO1FBQ3RCLE1BQU0sS0FBSyxHQUFHLEdBQUcsYUFBYSxJQUFJLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQTtRQUM3QyxNQUFNLG9CQUFvQixDQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUE7S0FDNUQ7SUFFRCxPQUFPLEVBQUUsQ0FBQTtBQUNYLENBQUMsQ0FBQTtBQXhJWSxRQUFBLGtCQUFrQixzQkF3STlCIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1hc3NpZ25tZW50ICovXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWNhbGwgKi9cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtbWVtYmVyLWFjY2VzcyAqL1xuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1yZXR1cm4gKi9cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXMgKi9cbmltcG9ydCB0eXBlIHsgSGFuZGxlciB9IGZyb20gXCJhd3MtbGFtYmRhXCJcbmltcG9ydCB0eXBlICogYXMgX0FXUyBmcm9tIFwiYXdzLXNka1wiXG5cbmludGVyZmFjZSBFeHBlY3RlZElucHV0IHtcbiAgdGFnOiBzdHJpbmdcbn1cblxuLy8gVGhpcyBmdW5jdGlvbiBpcyBpbmxpbmUtY29tcGlsZWQgZm9yIHRoZSBsYW1iZGEuXG4vLyBJdCBtdXN0IGJlIHNlbGYtY29udGFpbmVkLlxuZXhwb3J0IGNvbnN0IHN0YXJ0RGVwbG95SGFuZGxlcjogSGFuZGxlcjxQYXJ0aWFsPEV4cGVjdGVkSW5wdXQ+PiA9IGFzeW5jIChcbiAgZXZlbnQsXG4pID0+IHtcbiAgY29uc3QgQVdTID0gcmVxdWlyZShcImF3cy1zZGtcIilcbiAgY29uc3QgZWNzID0gbmV3IEFXUy5FQ1MoKSBhcyBfQVdTLkVDU1xuICBjb25zdCBzbSA9IG5ldyBBV1MuU2VjcmV0c01hbmFnZXIoKSBhcyBfQVdTLlNlY3JldHNNYW5hZ2VyXG5cbiAgZnVuY3Rpb24gcmVxdWlyZUVudihuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHZhbHVlID0gcHJvY2Vzcy5lbnZbbmFtZV1cbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBNaXNzaW5nICR7bmFtZX1gKVxuICAgIH1cbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGdldFNlcnZpY2UoXG4gICAgY2x1c3Rlck5hbWU6IHN0cmluZyxcbiAgICBzZXJ2aWNlTmFtZTogc3RyaW5nLFxuICApOiBQcm9taXNlPEFXUy5FQ1MuU2VydmljZT4ge1xuICAgIGNvbnN0IHNlcnZpY2VzID0gYXdhaXQgZWNzXG4gICAgICAuZGVzY3JpYmVTZXJ2aWNlcyh7XG4gICAgICAgIGNsdXN0ZXI6IGNsdXN0ZXJOYW1lLFxuICAgICAgICBzZXJ2aWNlczogW3NlcnZpY2VOYW1lXSxcbiAgICAgIH0pXG4gICAgICAucHJvbWlzZSgpXG5cbiAgICBpZiAoc2VydmljZXMuc2VydmljZXM/Lmxlbmd0aCAhPT0gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBTZXJ2aWNlIG5vdCBmb3VuZDogJHtjbHVzdGVyTmFtZX0vJHtzZXJ2aWNlTmFtZX1gKVxuICAgIH1cblxuICAgIHJldHVybiBzZXJ2aWNlcy5zZXJ2aWNlc1swXVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gZ2V0VGFza0RlZmluaXRpb24oXG4gICAgdGFza0RlZmluaXRpb246IHN0cmluZyxcbiAgKTogUHJvbWlzZTxBV1MuRUNTLlRhc2tEZWZpbml0aW9uPiB7XG4gICAgcmV0dXJuIChcbiAgICAgIGF3YWl0IGVjc1xuICAgICAgICAuZGVzY3JpYmVUYXNrRGVmaW5pdGlvbih7XG4gICAgICAgICAgdGFza0RlZmluaXRpb246IHRhc2tEZWZpbml0aW9uLFxuICAgICAgICB9KVxuICAgICAgICAucHJvbWlzZSgpXG4gICAgKS50YXNrRGVmaW5pdGlvbiFcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHVwZGF0ZVNlcnZpY2VUb0ltYWdlKFxuICAgIGNsdXN0ZXJOYW1lOiBzdHJpbmcsXG4gICAgc2VydmljZU5hbWU6IHN0cmluZyxcbiAgICBpbWFnZTogc3RyaW5nLFxuICApIHtcbiAgICBjb25zb2xlLmxvZyhgQ2x1c3RlciBuYW1lOiAke2NsdXN0ZXJOYW1lfWApXG4gICAgY29uc29sZS5sb2coYFNlcnZpY2UgbmFtZTogJHtzZXJ2aWNlTmFtZX1gKVxuXG4gICAgY29uc3Qgc2VydmljZSA9IGF3YWl0IGdldFNlcnZpY2UoY2x1c3Rlck5hbWUsIHNlcnZpY2VOYW1lKVxuICAgIGNvbnN0IHByZXZUYXNrRGVmaW5pdGlvbiA9IGF3YWl0IGdldFRhc2tEZWZpbml0aW9uKHNlcnZpY2UudGFza0RlZmluaXRpb24hKVxuXG4gICAgLy8gRG9uJ3QgYm90aGVyIHVwZGF0aW5nIHRoZSBzZXJ2aWNlIGlmIHRoZSBpbWFnZSBpcyBhbHJlYWR5IHRoZSBsYXRlc3QuXG4gICAgY29uc3QgcHJldkltYWdlID0gcHJldlRhc2tEZWZpbml0aW9uLmNvbnRhaW5lckRlZmluaXRpb25zIVswXS5pbWFnZSFcbiAgICBpZiAocHJldkltYWdlID09PSBpbWFnZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc29sZS5sb2coXG4gICAgICBgVXBkYXRpbmcgaW1hZ2UgZm9yIHNlcnZpY2UgJyR7c2VydmljZU5hbWV9JyBmcm9tICcke3ByZXZJbWFnZX0nIHRvICcke2ltYWdlfSdgLFxuICAgIClcblxuICAgIGNvbnN0IGV4Y2x1ZGUgPSBbXG4gICAgICBcInJlZ2lzdGVyZWRBdFwiLFxuICAgICAgXCJyZWdpc3RlcmVkQnlcIixcbiAgICAgIFwiY29tcGF0aWJpbGl0aWVzXCIsXG4gICAgICBcInJlcXVpcmVzQXR0cmlidXRlc1wiLFxuICAgICAgXCJyZXZpc2lvblwiLFxuICAgICAgXCJzdGF0dXNcIixcbiAgICAgIFwidGFza0RlZmluaXRpb25Bcm5cIixcbiAgICBdXG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IHVwZGF0ZWRTcGVjOiBhbnkgPSB7XG4gICAgICAuLi5PYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgIE9iamVjdC5lbnRyaWVzKHByZXZUYXNrRGVmaW5pdGlvbikuZmlsdGVyKFxuICAgICAgICAgIChba2V5XSkgPT4gIWV4Y2x1ZGUuaW5jbHVkZXMoa2V5KSxcbiAgICAgICAgKSxcbiAgICAgICksXG4gICAgICBjb250YWluZXJEZWZpbml0aW9uczogW1xuICAgICAgICB7XG4gICAgICAgICAgLi4ucHJldlRhc2tEZWZpbml0aW9uLmNvbnRhaW5lckRlZmluaXRpb25zIVswXSxcbiAgICAgICAgICBpbWFnZSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgdXBkYXRlZFRhc2tEZWZpbml0aW9uID0gKFxuICAgICAgYXdhaXQgZWNzLnJlZ2lzdGVyVGFza0RlZmluaXRpb24odXBkYXRlZFNwZWMpLnByb21pc2UoKVxuICAgICkudGFza0RlZmluaXRpb24hXG5cbiAgICBhd2FpdCBlY3NcbiAgICAgIC51cGRhdGVTZXJ2aWNlKHtcbiAgICAgICAgY2x1c3RlcjogY2x1c3Rlck5hbWUsXG4gICAgICAgIHNlcnZpY2U6IHNlcnZpY2VOYW1lLFxuICAgICAgICB0YXNrRGVmaW5pdGlvbjogdXBkYXRlZFRhc2tEZWZpbml0aW9uLnRhc2tEZWZpbml0aW9uQXJuLFxuICAgICAgfSlcbiAgICAgIC5wcm9taXNlKClcblxuICAgIGNvbnNvbGUubG9nKFwiU2VydmljZSBpcyB1cGRhdGVkXCIpXG4gIH1cblxuICBjb25zdCBjbHVzdGVyTmFtZSA9IHJlcXVpcmVFbnYoXCJDTFVTVEVSX05BTUVcIilcbiAgY29uc3Qgc2VydmljZU5hbWUgPSByZXF1aXJlRW52KFwiU0VSVklDRV9OQU1FXCIpXG4gIGNvbnN0IHJlcG9zaXRvcnlVcmwgPSByZXF1aXJlRW52KFwiUkVQT1NJVE9SWV9VUkxcIilcbiAgY29uc3QgZWNyVGFnU2VjcmV0QXJuID0gcmVxdWlyZUVudihcIkVDUl9UQUdfU0VDUkVUX0FSTlwiKVxuXG4gIC8vIFZhbGlkYXRlIHRoZSBpbnB1dC5cbiAgaWYgKHR5cGVvZiBldmVudC50YWcgIT09IFwic3RyaW5nXCIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnB1dCBpbnZhbGlkOiBcIiArIEpTT04uc3RyaW5naWZ5KGV2ZW50LCB1bmRlZmluZWQsIFwiICBcIikpXG4gIH1cblxuICAvLyBSZWdpc3RlciB0YWcgYXMgY3VycmVudCB0YXJnZXQuXG4gIC8vIFRoaXMgaXMgbmVlZGVkIHNvIHRoYXQgQ2xvdWRGb3JtYXRpb24gZGVwbG95bWVudHMsIGUuZy5cbiAgLy8gdXBkYXRlcyB0byB0aGUgVGFzayBEZWZpbml0aW9uLCB3aWxsIHVzZSB0aGUgc2FtZSBpbWFnZS5cbiAgYXdhaXQgc21cbiAgICAudXBkYXRlU2VjcmV0KHtcbiAgICAgIFNlY3JldElkOiBlY3JUYWdTZWNyZXRBcm4sXG4gICAgICBTZWNyZXRTdHJpbmc6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgdGFnOiBldmVudC50YWcsXG4gICAgICB9KSxcbiAgICB9KVxuICAgIC5wcm9taXNlKClcblxuICAvLyBVcGRhdGUgdGhlIHNlcnZpY2UgaWYgd2Uga25vdyB0aGUgc2VydmljZSBuYW1lLiBUaGlzIGlzIHVua25vd25cbiAgLy8gZHVyaW5nIGluaXRpYWwgZGVwbG95bWVudCBvZiB0aGUgc3RhY2suXG4gIGlmIChzZXJ2aWNlTmFtZSAhPT0gXCJcIikge1xuICAgIGNvbnN0IGltYWdlID0gYCR7cmVwb3NpdG9yeVVybH06JHtldmVudC50YWd9YFxuICAgIGF3YWl0IHVwZGF0ZVNlcnZpY2VUb0ltYWdlKGNsdXN0ZXJOYW1lLCBzZXJ2aWNlTmFtZSwgaW1hZ2UpXG4gIH1cblxuICByZXR1cm4ge31cbn1cbiJdfQ==
104
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnQtZGVwbG95LWhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZWNzLXVwZGF0ZS1pbWFnZS9zdGFydC1kZXBsb3ktaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFhQSxtREFBbUQ7QUFDbkQsNkJBQTZCO0FBQ3RCLE1BQU0sa0JBQWtCLEdBQW9DLEtBQUssRUFDdEUsS0FBSyxFQUNMLEVBQUU7SUFDRixNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUE7SUFDOUIsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxFQUFjLENBQUE7SUFDckMsTUFBTSxFQUFFLEdBQUcsSUFBSSxHQUFHLENBQUMsY0FBYyxFQUF5QixDQUFBO0lBRTFELFNBQVMsVUFBVSxDQUFDLElBQVk7UUFDOUIsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUMvQixJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUU7WUFDdkIsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDLENBQUE7U0FDbkM7UUFDRCxPQUFPLEtBQUssQ0FBQTtJQUNkLENBQUM7SUFFRCxLQUFLLFVBQVUsVUFBVSxDQUN2QixXQUFtQixFQUNuQixXQUFtQjs7UUFFbkIsTUFBTSxRQUFRLEdBQUcsTUFBTSxHQUFHO2FBQ3ZCLGdCQUFnQixDQUFDO1lBQ2hCLE9BQU8sRUFBRSxXQUFXO1lBQ3BCLFFBQVEsRUFBRSxDQUFDLFdBQVcsQ0FBQztTQUN4QixDQUFDO2FBQ0QsT0FBTyxFQUFFLENBQUE7UUFFWixJQUFJLENBQUEsTUFBQSxRQUFRLENBQUMsUUFBUSwwQ0FBRSxNQUFNLE1BQUssQ0FBQyxFQUFFO1lBQ25DLE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLFdBQVcsSUFBSSxXQUFXLEVBQUUsQ0FBQyxDQUFBO1NBQ3BFO1FBRUQsT0FBTyxRQUFRLENB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LEVBQUUsZUFBZTtRQUN6QixZQUFZLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUMzQixHQUFHLEVBQUUsS0FBSyxDQUFDLEdBQUc7U0FDZixDQUFDO0tBQ0gsQ0FBQztTQUNELE9BQU8sRUFBRSxDQUFBO0lBRVosa0VBQWtFO0lBQ2xFLDBDQUEwQztJQUMxQyxJQUFJLFdBQVcsS0FBSyxFQUFFLEVBQUU7UUFDdEIsTUFBTSxLQUFLLEdBQUcsR0FBRyxhQUFhLElBQUksS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFBO1FBQzdDLE1BQU0sb0JBQW9CLENBQUMsV0FBVyxFQUFFLFdBQVcsRUFBRSxLQUFLLENBQUMsQ0FBQTtLQUM1RDtJQUVELE9BQU8sRUFBRSxDQUFBO0FBQ1gsQ0FBQyxDQUFBO0FBdklZLFFBQUEsa0JBQWtCLHNCQXVJOUIiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWFzc2lnbm1lbnQgKi9cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtY2FsbCAqL1xuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1tZW1iZXItYWNjZXNzICovXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLXJldHVybiAqL1xuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXZhci1yZXF1aXJlcyAqL1xuaW1wb3J0IHR5cGUgeyBIYW5kbGVyIH0gZnJvbSBcImF3cy1sYW1iZGFcIlxuaW1wb3J0IHR5cGUgKiBhcyBfQVdTIGZyb20gXCJhd3Mtc2RrXCJcbmltcG9ydCB7IFJlZ2lzdGVyVGFza0RlZmluaXRpb25SZXF1ZXN0IH0gZnJvbSBcImF3cy1zZGsvY2xpZW50cy9lY3NcIlxuXG5pbnRlcmZhY2UgRXhwZWN0ZWRJbnB1dCB7XG4gIHRhZzogc3RyaW5nXG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgaW5saW5lLWNvbXBpbGVkIGZvciB0aGUgbGFtYmRhLlxuLy8gSXQgbXVzdCBiZSBzZWxmLWNvbnRhaW5lZC5cbmV4cG9ydCBjb25zdCBzdGFydERlcGxveUhhbmRsZXI6IEhhbmRsZXI8UGFydGlhbDxFeHBlY3RlZElucHV0Pj4gPSBhc3luYyAoXG4gIGV2ZW50LFxuKSA9PiB7XG4gIGNvbnN0IEFXUyA9IHJlcXVpcmUoXCJhd3Mtc2RrXCIpXG4gIGNvbnN0IGVjcyA9IG5ldyBBV1MuRUNTKCkgYXMgX0FXUy5FQ1NcbiAgY29uc3Qgc20gPSBuZXcgQVdTLlNlY3JldHNNYW5hZ2VyKCkgYXMgX0FXUy5TZWNyZXRzTWFuYWdlclxuXG4gIGZ1bmN0aW9uIHJlcXVpcmVFbnYobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCB2YWx1ZSA9IHByb2Nlc3MuZW52W25hbWVdXG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyAke25hbWV9YClcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBnZXRTZXJ2aWNlKFxuICAgIGNsdXN0ZXJOYW1lOiBzdHJpbmcsXG4gICAgc2VydmljZU5hbWU6IHN0cmluZyxcbiAgKTogUHJvbWlzZTxBV1MuRUNTLlNlcnZpY2U+IHtcbiAgICBjb25zdCBzZXJ2aWNlcyA9IGF3YWl0IGVjc1xuICAgICAgLmRlc2NyaWJlU2VydmljZXMoe1xuICAgICAgICBjbHVzdGVyOiBjbHVzdGVyTmFtZSxcbiAgICAgICAgc2VydmljZXM6IFtzZXJ2aWNlTmFtZV0sXG4gICAgICB9KVxuICAgICAgLnByb21pc2UoKVxuXG4gICAgaWYgKHNlcnZpY2VzLnNlcnZpY2VzPy5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgU2VydmljZSBub3QgZm91bmQ6ICR7Y2x1c3Rlck5hbWV9LyR7c2VydmljZU5hbWV9YClcbiAgICB9XG5cbiAgICByZXR1cm4gc2VydmljZXMuc2VydmljZXNbMF1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGdldFRhc2tEZWZpbml0aW9uKFxuICAgIHRhc2tEZWZpbml0aW9uOiBzdHJpbmcsXG4gICk6IFByb21pc2U8QVdTLkVDUy5UYXNrRGVmaW5pdGlvbj4ge1xuICAgIHJldHVybiAoXG4gICAgICBhd2FpdCBlY3NcbiAgICAgICAgLmRlc2NyaWJlVGFza0RlZmluaXRpb24oe1xuICAgICAgICAgIHRhc2tEZWZpbml0aW9uOiB0YXNrRGVmaW5pdGlvbixcbiAgICAgICAgfSlcbiAgICAgICAgLnByb21pc2UoKVxuICAgICkudGFza0RlZmluaXRpb24hXG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiB1cGRhdGVTZXJ2aWNlVG9JbWFnZShcbiAgICBjbHVzdGVyTmFtZTogc3RyaW5nLFxuICAgIHNlcnZpY2VOYW1lOiBzdHJpbmcsXG4gICAgaW1hZ2U6IHN0cmluZyxcbiAgKSB7XG4gICAgY29uc29sZS5sb2coYENsdXN0ZXIgbmFtZTogJHtjbHVzdGVyTmFtZX1gKVxuICAgIGNvbnNvbGUubG9nKGBTZXJ2aWNlIG5hbWU6ICR7c2VydmljZU5hbWV9YClcblxuICAgIGNvbnN0IHNlcnZpY2UgPSBhd2FpdCBnZXRTZXJ2aWNlKGNsdXN0ZXJOYW1lLCBzZXJ2aWNlTmFtZSlcbiAgICBjb25zdCBwcmV2VGFza0RlZmluaXRpb24gPSBhd2FpdCBnZXRUYXNrRGVmaW5pdGlvbihzZXJ2aWNlLnRhc2tEZWZpbml0aW9uISlcblxuICAgIC8vIERvbid0IGJvdGhlciB1cGRhdGluZyB0aGUgc2VydmljZSBpZiB0aGUgaW1hZ2UgaXMgYWxyZWFkeSB0aGUgbGF0ZXN0LlxuICAgIGNvbnN0IHByZXZJbWFnZSA9IHByZXZUYXNrRGVmaW5pdGlvbi5jb250YWluZXJEZWZpbml0aW9ucyFbMF0uaW1hZ2UhXG4gICAgaWYgKHByZXZJbWFnZSA9PT0gaW1hZ2UpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKFxuICAgICAgYFVwZGF0aW5nIGltYWdlIGZvciBzZXJ2aWNlICcke3NlcnZpY2VOYW1lfScgZnJvbSAnJHtwcmV2SW1hZ2V9JyB0byAnJHtpbWFnZX0nYCxcbiAgICApXG5cbiAgICBjb25zdCBleGNsdWRlID0gW1xuICAgICAgXCJyZWdpc3RlcmVkQXRcIixcbiAgICAgIFwicmVnaXN0ZXJlZEJ5XCIsXG4gICAgICBcImNvbXBhdGliaWxpdGllc1wiLFxuICAgICAgXCJyZXF1aXJlc0F0dHJpYnV0ZXNcIixcbiAgICAgIFwicmV2aXNpb25cIixcbiAgICAgIFwic3RhdHVzXCIsXG4gICAgICBcInRhc2tEZWZpbml0aW9uQXJuXCIsXG4gICAgXVxuXG4gICAgY29uc3QgdXBkYXRlZFNwZWM6IFJlZ2lzdGVyVGFza0RlZmluaXRpb25SZXF1ZXN0ID0ge1xuICAgICAgLi4uT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICBPYmplY3QuZW50cmllcyhwcmV2VGFza0RlZmluaXRpb24pLmZpbHRlcihcbiAgICAgICAgICAoW2tleV0pID0+ICFleGNsdWRlLmluY2x1ZGVzKGtleSksXG4gICAgICAgICksXG4gICAgICApLFxuICAgICAgY29udGFpbmVyRGVmaW5pdGlvbnM6IFtcbiAgICAgICAge1xuICAgICAgICAgIC4uLnByZXZUYXNrRGVmaW5pdGlvbi5jb250YWluZXJEZWZpbml0aW9ucyFbMF0sXG4gICAgICAgICAgaW1hZ2UsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0gYXMgUmVnaXN0ZXJUYXNrRGVmaW5pdGlvblJlcXVlc3RcblxuICAgIGNvbnN0IHVwZGF0ZWRUYXNrRGVmaW5pdGlvbiA9IChcbiAgICAgIGF3YWl0IGVjcy5yZWdpc3RlclRhc2tEZWZpbml0aW9uKHVwZGF0ZWRTcGVjKS5wcm9taXNlKClcbiAgICApLnRhc2tEZWZpbml0aW9uIVxuXG4gICAgYXdhaXQgZWNzXG4gICAgICAudXBkYXRlU2VydmljZSh7XG4gICAgICAgIGNsdXN0ZXI6IGNsdXN0ZXJOYW1lLFxuICAgICAgICBzZXJ2aWNlOiBzZXJ2aWNlTmFtZSxcbiAgICAgICAgdGFza0RlZmluaXRpb246IHVwZGF0ZWRUYXNrRGVmaW5pdGlvbi50YXNrRGVmaW5pdGlvbkFybixcbiAgICAgIH0pXG4gICAgICAucHJvbWlzZSgpXG5cbiAgICBjb25zb2xlLmxvZyhcIlNlcnZpY2UgaXMgdXBkYXRlZFwiKVxuICB9XG5cbiAgY29uc3QgY2x1c3Rlck5hbWUgPSByZXF1aXJlRW52KFwiQ0xVU1RFUl9OQU1FXCIpXG4gIGNvbnN0IHNlcnZpY2VOYW1lID0gcmVxdWlyZUVudihcIlNFUlZJQ0VfTkFNRVwiKVxuICBjb25zdCByZXBvc2l0b3J5VXJsID0gcmVxdWlyZUVudihcIlJFUE9TSVRPUllfVVJMXCIpXG4gIGNvbnN0IGVjclRhZ1NlY3JldEFybiA9IHJlcXVpcmVFbnYoXCJFQ1JfVEFHX1NFQ1JFVF9BUk5cIilcblxuICAvLyBWYWxpZGF0ZSB0aGUgaW5wdXQuXG4gIGlmICh0eXBlb2YgZXZlbnQudGFnICE9PSBcInN0cmluZ1wiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiSW5wdXQgaW52YWxpZDogXCIgKyBKU09OLnN0cmluZ2lmeShldmVudCwgdW5kZWZpbmVkLCBcIiAgXCIpKVxuICB9XG5cbiAgLy8gUmVnaXN0ZXIgdGFnIGFzIGN1cnJlbnQgdGFyZ2V0LlxuICAvLyBUaGlzIGlzIG5lZWRlZCBzbyB0aGF0IENsb3VkRm9ybWF0aW9uIGRlcGxveW1lbnRzLCBlLmcuXG4gIC8vIHVwZGF0ZXMgdG8gdGhlIFRhc2sgRGVmaW5pdGlvbiwgd2lsbCB1c2UgdGhlIHNhbWUgaW1hZ2UuXG4gIGF3YWl0IHNtXG4gICAgLnVwZGF0ZVNlY3JldCh7XG4gICAgICBTZWNyZXRJZDogZWNyVGFnU2VjcmV0QXJuLFxuICAgICAgU2VjcmV0U3RyaW5nOiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIHRhZzogZXZlbnQudGFnLFxuICAgICAgfSksXG4gICAgfSlcbiAgICAucHJvbWlzZSgpXG5cbiAgLy8gVXBkYXRlIHRoZSBzZXJ2aWNlIGlmIHdlIGtub3cgdGhlIHNlcnZpY2UgbmFtZS4gVGhpcyBpcyB1bmtub3duXG4gIC8vIGR1cmluZyBpbml0aWFsIGRlcGxveW1lbnQgb2YgdGhlIHN0YWNrLlxuICBpZiAoc2VydmljZU5hbWUgIT09IFwiXCIpIHtcbiAgICBjb25zdCBpbWFnZSA9IGAke3JlcG9zaXRvcnlVcmx9OiR7ZXZlbnQudGFnfWBcbiAgICBhd2FpdCB1cGRhdGVTZXJ2aWNlVG9JbWFnZShjbHVzdGVyTmFtZSwgc2VydmljZU5hbWUsIGltYWdlKVxuICB9XG5cbiAgcmV0dXJuIHt9XG59XG4iXX0=