truemark-cdk-lib 1.28.2 → 1.30.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.
- package/dist/aws-securitylake/index.d.ts +1 -0
- package/dist/aws-securitylake/index.js +18 -0
- package/dist/aws-securitylake/lib/index.d.ts +1 -0
- package/dist/aws-securitylake/lib/index.js +18 -0
- package/dist/aws-securitylake/lib/standard-security-lake.d.ts +337 -0
- package/dist/aws-securitylake/lib/standard-security-lake.js +393 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -2
- package/package.json +9 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lib/index';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./lib/index"), exports);
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXdzLXNlY3VyaXR5bGFrZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsOENBQTRCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9saWIvaW5kZXgnO1xuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './standard-security-lake';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./standard-security-lake"), exports);
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXdzLXNlY3VyaXR5bGFrZS9saWIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDJEQUF5QyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vc3RhbmRhcmQtc2VjdXJpdHktbGFrZSc7XG4iXX0=
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { CfnServiceLinkedRole, Role } from 'aws-cdk-lib/aws-iam';
|
|
2
|
+
import { CfnAwsLogSource, CfnDataLake, CfnSubscriber, CfnSubscriberNotification } from 'aws-cdk-lib/aws-securitylake';
|
|
3
|
+
import type { Construct } from 'constructs';
|
|
4
|
+
import { ExtendedConstruct, type ExtendedConstructProps } from '../../aws-cdk/index';
|
|
5
|
+
/**
|
|
6
|
+
* The AWS-native log sources that Amazon Security Lake can ingest.
|
|
7
|
+
*
|
|
8
|
+
* @see https://docs.aws.amazon.com/security-lake/latest/userguide/internal-sources.html
|
|
9
|
+
*/
|
|
10
|
+
export declare enum AwsLogSourceName {
|
|
11
|
+
CLOUD_TRAIL_MGMT = "CLOUD_TRAIL_MGMT",
|
|
12
|
+
LAMBDA_EXECUTION = "LAMBDA_EXECUTION",
|
|
13
|
+
ROUTE53 = "ROUTE53",
|
|
14
|
+
S3_DATA = "S3_DATA",
|
|
15
|
+
SH_FINDINGS = "SH_FINDINGS",
|
|
16
|
+
VPC_FLOW = "VPC_FLOW",
|
|
17
|
+
EKS_AUDIT = "EKS_AUDIT",
|
|
18
|
+
WAF = "WAF"
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Properties for an individual AWS log source to enable on the data lake.
|
|
22
|
+
*/
|
|
23
|
+
export interface AwsLogSourceProps {
|
|
24
|
+
/**
|
|
25
|
+
* The name of the AWS log source to enable.
|
|
26
|
+
*/
|
|
27
|
+
readonly sourceName: AwsLogSourceName | string;
|
|
28
|
+
/**
|
|
29
|
+
* The version of the AWS log source to enable.
|
|
30
|
+
*
|
|
31
|
+
* @default - '2.0'
|
|
32
|
+
*/
|
|
33
|
+
readonly sourceVersion?: string;
|
|
34
|
+
/**
|
|
35
|
+
* The AWS accounts whose data should be collected for this source. If not
|
|
36
|
+
* provided, the data lake owner account is used.
|
|
37
|
+
*
|
|
38
|
+
* @default - [Stack.of(this).account]
|
|
39
|
+
*/
|
|
40
|
+
readonly accounts?: string[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Lifecycle transition for Security Lake data.
|
|
44
|
+
*/
|
|
45
|
+
export interface SecurityLakeTransitionProps {
|
|
46
|
+
/**
|
|
47
|
+
* The number of days before data transitions to the given storage class.
|
|
48
|
+
*/
|
|
49
|
+
readonly days: number;
|
|
50
|
+
/**
|
|
51
|
+
* The target S3 storage class. Supported values include `STANDARD_IA`,
|
|
52
|
+
* `ONEZONE_IA`, `INTELLIGENT_TIERING`, `GLACIER_IR`, `GLACIER` and
|
|
53
|
+
* `DEEP_ARCHIVE`.
|
|
54
|
+
*/
|
|
55
|
+
readonly storageClass: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Lifecycle configuration options for Security Lake managed S3 storage.
|
|
59
|
+
*/
|
|
60
|
+
export interface SecurityLakeLifecycleProps {
|
|
61
|
+
/**
|
|
62
|
+
* The number of days before Security Lake data is expired/deleted.
|
|
63
|
+
*
|
|
64
|
+
* @default - data is retained indefinitely
|
|
65
|
+
*/
|
|
66
|
+
readonly expirationDays?: number;
|
|
67
|
+
/**
|
|
68
|
+
* Transitions applied to Security Lake data.
|
|
69
|
+
*
|
|
70
|
+
* @default - no transitions
|
|
71
|
+
*/
|
|
72
|
+
readonly transitions?: SecurityLakeTransitionProps[];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Replication configuration for Security Lake data.
|
|
76
|
+
*/
|
|
77
|
+
export interface SecurityLakeReplicationProps {
|
|
78
|
+
/**
|
|
79
|
+
* One or more rollup Regions to replicate data to.
|
|
80
|
+
*/
|
|
81
|
+
readonly regions: string[];
|
|
82
|
+
/**
|
|
83
|
+
* The ARN of the IAM role Security Lake uses to replicate objects. If not
|
|
84
|
+
* provided, a role will be created automatically.
|
|
85
|
+
*
|
|
86
|
+
* @default - a new role is created
|
|
87
|
+
*/
|
|
88
|
+
readonly roleArn?: string;
|
|
89
|
+
/**
|
|
90
|
+
* The ARN of the customer-managed KMS key encrypting the source
|
|
91
|
+
* (originating-Region) Security Lake bucket. Required when the enclosing
|
|
92
|
+
* `StandardSecurityLake` is configured with a customer-managed `kmsKeyId`
|
|
93
|
+
* and this construct creates the replication role (i.e. when `roleArn`
|
|
94
|
+
* is not provided); S3 needs `kms:Decrypt` on this key to read objects
|
|
95
|
+
* before replicating them. Not required when the source bucket uses
|
|
96
|
+
* S3-managed or AWS-managed encryption.
|
|
97
|
+
*
|
|
98
|
+
* This is independent of `destinationKmsKeyArns`: Security Lake rollup
|
|
99
|
+
* Regions may use their own encryption settings, so a CMK source can
|
|
100
|
+
* replicate to an SSE-S3 rollup and vice versa.
|
|
101
|
+
*
|
|
102
|
+
* @default - no KMS decrypt statement is added
|
|
103
|
+
*/
|
|
104
|
+
readonly sourceKmsKeyArn?: string;
|
|
105
|
+
/**
|
|
106
|
+
* The ARNs of the customer-managed KMS keys encrypting the destination
|
|
107
|
+
* (rollup-Region) Security Lake buckets. Supply when any rollup Region's
|
|
108
|
+
* bucket uses a customer-managed KMS key so the replication role can
|
|
109
|
+
* `kms:Encrypt` / `kms:GenerateDataKey` against them. Not required when
|
|
110
|
+
* every rollup bucket uses S3-managed or AWS-managed encryption.
|
|
111
|
+
*
|
|
112
|
+
* This is independent of `sourceKmsKeyArn` and the source lake's
|
|
113
|
+
* `kmsKeyId`.
|
|
114
|
+
*
|
|
115
|
+
* @default - no KMS encrypt statement is added
|
|
116
|
+
*/
|
|
117
|
+
readonly destinationKmsKeyArns?: string[];
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The AWS log sources a subscriber should receive. Each entry maps to the
|
|
121
|
+
* same `sourceName`/`sourceVersion` pair used when enabling the source.
|
|
122
|
+
*/
|
|
123
|
+
export interface SecurityLakeSubscriberSourceProps {
|
|
124
|
+
/**
|
|
125
|
+
* The source name, e.g. `CLOUD_TRAIL_MGMT`.
|
|
126
|
+
*/
|
|
127
|
+
readonly sourceName: AwsLogSourceName | string;
|
|
128
|
+
/**
|
|
129
|
+
* The source version.
|
|
130
|
+
*
|
|
131
|
+
* @default - '2.0'
|
|
132
|
+
*/
|
|
133
|
+
readonly sourceVersion?: string;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Properties for a Security Lake subscriber with S3-notification access.
|
|
137
|
+
* Only the `S3` access type (asynchronous SQS notification of new objects)
|
|
138
|
+
* is modelled; Lake Formation subscribers can be created directly against
|
|
139
|
+
* the underlying `CfnSubscriber` L1.
|
|
140
|
+
*
|
|
141
|
+
* @see https://docs.aws.amazon.com/security-lake/latest/userguide/subscriber-management.html
|
|
142
|
+
*/
|
|
143
|
+
export interface SecurityLakeSubscriberProps {
|
|
144
|
+
/**
|
|
145
|
+
* The friendly name of the subscriber.
|
|
146
|
+
*/
|
|
147
|
+
readonly subscriberName: string;
|
|
148
|
+
/**
|
|
149
|
+
* The AWS account id of the principal that will consume data (typically
|
|
150
|
+
* the SIEM / downstream account id).
|
|
151
|
+
*/
|
|
152
|
+
readonly principal: string;
|
|
153
|
+
/**
|
|
154
|
+
* External id the subscriber must present when assuming the
|
|
155
|
+
* Security-Lake-managed role. Treat as a shared secret.
|
|
156
|
+
*/
|
|
157
|
+
readonly externalId: string;
|
|
158
|
+
/**
|
|
159
|
+
* Log sources this subscriber receives. Each entry must correspond to a
|
|
160
|
+
* source that is enabled on the data lake.
|
|
161
|
+
*/
|
|
162
|
+
readonly sources: SecurityLakeSubscriberSourceProps[];
|
|
163
|
+
/**
|
|
164
|
+
* Optional human-readable description.
|
|
165
|
+
*
|
|
166
|
+
* @default - no description
|
|
167
|
+
*/
|
|
168
|
+
readonly description?: string;
|
|
169
|
+
/**
|
|
170
|
+
* Optional HTTPS endpoint for subscriber notifications. If omitted,
|
|
171
|
+
* Security Lake creates an SQS queue in the data-lake account and
|
|
172
|
+
* notifies the subscriber via SQS messages (recommended default — the
|
|
173
|
+
* SIEM polls the queue).
|
|
174
|
+
*
|
|
175
|
+
* When set, {@link httpsNotificationTargetRoleArn} is required.
|
|
176
|
+
*
|
|
177
|
+
* @default - SQS notification
|
|
178
|
+
*/
|
|
179
|
+
readonly httpsNotificationEndpoint?: string;
|
|
180
|
+
/**
|
|
181
|
+
* IAM role ARN EventBridge assumes to invoke the HTTPS endpoint when
|
|
182
|
+
* {@link httpsNotificationEndpoint} is set. The role must trust
|
|
183
|
+
* `events.amazonaws.com` and have `events:InvokeApiDestination`
|
|
184
|
+
* permissions. The AWS console provisions this helper role
|
|
185
|
+
* automatically when a subscriber is created through the UI, but the
|
|
186
|
+
* CloudFormation / API path does **not** — so a fresh account must
|
|
187
|
+
* create and pass this role explicitly, or Security Lake will reject
|
|
188
|
+
* the subscriber-notification create call.
|
|
189
|
+
*
|
|
190
|
+
* Ignored when {@link httpsNotificationEndpoint} is omitted.
|
|
191
|
+
*
|
|
192
|
+
* @default - none; required when `httpsNotificationEndpoint` is set
|
|
193
|
+
*/
|
|
194
|
+
readonly httpsNotificationTargetRoleArn?: string;
|
|
195
|
+
/**
|
|
196
|
+
* When set and the subscriber uses the default SQS notification path,
|
|
197
|
+
* the construct patches the Security-Lake-managed Main-Queue's
|
|
198
|
+
* `VisibilityTimeout` attribute to this value (seconds) via an
|
|
199
|
+
* `AwsCustomResource`. Needed because Security Lake auto-provisions
|
|
200
|
+
* the queue with a 300s visibility timeout, which is **less than** the
|
|
201
|
+
* default aes-siem es-loader Lambda timeout of 600s, causing the
|
|
202
|
+
* event-source-mapping create to be rejected with
|
|
203
|
+
* `"The event source mapping's function timeout must be smaller than
|
|
204
|
+
* or equal to the queue's visibility timeout"`.
|
|
205
|
+
*
|
|
206
|
+
* Set to a value `>=` your subscriber Lambda's timeout. 3600 is a
|
|
207
|
+
* safe default for aes-siem.
|
|
208
|
+
*
|
|
209
|
+
* Ignored when {@link httpsNotificationEndpoint} is set.
|
|
210
|
+
*
|
|
211
|
+
* @default - no patch; the queue keeps the Security-Lake-provisioned 300s
|
|
212
|
+
*/
|
|
213
|
+
readonly sqsVisibilityTimeoutSeconds?: number;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Properties for StandardSecurityLake.
|
|
217
|
+
*/
|
|
218
|
+
export interface StandardSecurityLakeProps extends ExtendedConstructProps {
|
|
219
|
+
/**
|
|
220
|
+
* The KMS key id to use to encrypt data stored by Security Lake. Use the
|
|
221
|
+
* literal string `S3_MANAGED_KEY` to use S3 managed keys (SSE-S3). Omit to
|
|
222
|
+
* let Security Lake use its default managed key.
|
|
223
|
+
*
|
|
224
|
+
* @default - Security Lake managed encryption
|
|
225
|
+
*/
|
|
226
|
+
readonly kmsKeyId?: string;
|
|
227
|
+
/**
|
|
228
|
+
* The ARN of the role used by Security Lake to manage the AWS Glue
|
|
229
|
+
* metastore. If omitted, a role is created with the
|
|
230
|
+
* `AmazonSecurityLakeMetastoreManager` AWS managed policy attached.
|
|
231
|
+
*
|
|
232
|
+
* @default - a role is created
|
|
233
|
+
*/
|
|
234
|
+
readonly metaStoreManagerRoleArn?: string;
|
|
235
|
+
/**
|
|
236
|
+
* The ARN of the customer-managed KMS key used to encrypt Security Lake
|
|
237
|
+
* data. Required when `kmsKeyId` is set to a customer-managed key and this
|
|
238
|
+
* construct creates the metastore manager role (i.e. when
|
|
239
|
+
* `metaStoreManagerRoleArn` is not provided). The metastore manager
|
|
240
|
+
* Lambda must decrypt and (re)encrypt Security Lake metadata; the AWS
|
|
241
|
+
* managed policy `AmazonSecurityLakeMetastoreManager` does not include
|
|
242
|
+
* KMS permissions, so without this grant the stack deploys but partition
|
|
243
|
+
* updates and subscriber queries silently fail. Not required when
|
|
244
|
+
* `kmsKeyId` is unset or set to `S3_MANAGED_KEY`.
|
|
245
|
+
*
|
|
246
|
+
* @default - no KMS statement is added (sufficient when the data lake
|
|
247
|
+
* uses Security Lake defaults or SSE-S3)
|
|
248
|
+
*/
|
|
249
|
+
readonly metaStoreManagerKmsKeyArn?: string;
|
|
250
|
+
/**
|
|
251
|
+
* Lifecycle configuration for the Security Lake managed S3 storage.
|
|
252
|
+
*
|
|
253
|
+
* @default - Security Lake defaults
|
|
254
|
+
*/
|
|
255
|
+
readonly lifecycle?: SecurityLakeLifecycleProps;
|
|
256
|
+
/**
|
|
257
|
+
* Replication configuration for the Security Lake managed S3 storage.
|
|
258
|
+
*
|
|
259
|
+
* @default - no replication
|
|
260
|
+
*/
|
|
261
|
+
readonly replication?: SecurityLakeReplicationProps;
|
|
262
|
+
/**
|
|
263
|
+
* The AWS native log sources to enable on the data lake. Sources are
|
|
264
|
+
* created sequentially using `DependsOn` as required by Security Lake.
|
|
265
|
+
*
|
|
266
|
+
* @default - no log sources are enabled
|
|
267
|
+
*/
|
|
268
|
+
readonly logSources?: AwsLogSourceProps[];
|
|
269
|
+
/**
|
|
270
|
+
* Whether to create the `AWSServiceRoleForLakeFormationDataAccess`
|
|
271
|
+
* service-linked role. Security Lake requires this role to exist in the
|
|
272
|
+
* account before a data lake can be created; however the role is a
|
|
273
|
+
* singleton per account and is frequently auto-created on first use of
|
|
274
|
+
* Lake Formation. Enable this only when you know the role does not yet
|
|
275
|
+
* exist in the account, otherwise stack creation will fail with
|
|
276
|
+
* `has been taken in this account`.
|
|
277
|
+
*
|
|
278
|
+
* The data lake will `DependsOn` this role when it is created so ordering
|
|
279
|
+
* is handled automatically.
|
|
280
|
+
*
|
|
281
|
+
* @default false
|
|
282
|
+
*/
|
|
283
|
+
readonly createLakeFormationServiceLinkedRole?: boolean;
|
|
284
|
+
/**
|
|
285
|
+
* Subscribers that should receive S3 notifications of new Security Lake
|
|
286
|
+
* objects. Each entry creates an `AWS::SecurityLake::Subscriber` (access
|
|
287
|
+
* type `S3`) plus an `AWS::SecurityLake::SubscriberNotification`.
|
|
288
|
+
*
|
|
289
|
+
* @default - no subscribers are created
|
|
290
|
+
*/
|
|
291
|
+
readonly subscribers?: SecurityLakeSubscriberProps[];
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Standard Amazon Security Lake. Wraps the Security Lake L1 constructs to
|
|
295
|
+
* stand up a data lake with an optional set of AWS native log sources
|
|
296
|
+
* enabled, a metastore manager role, lifecycle policy and replication.
|
|
297
|
+
*
|
|
298
|
+
* Where this construct does not meet your needs, use the underlying
|
|
299
|
+
* `CfnDataLake` and `CfnAwsLogSource` constructs directly.
|
|
300
|
+
*/
|
|
301
|
+
export declare class StandardSecurityLake extends ExtendedConstruct {
|
|
302
|
+
/**
|
|
303
|
+
* The underlying `CfnDataLake` resource.
|
|
304
|
+
*/
|
|
305
|
+
readonly dataLake: CfnDataLake;
|
|
306
|
+
/**
|
|
307
|
+
* The IAM role used by Security Lake to manage the Glue metastore. When
|
|
308
|
+
* `metaStoreManagerRoleArn` is provided this will be `undefined`.
|
|
309
|
+
*/
|
|
310
|
+
readonly metaStoreManagerRole?: Role;
|
|
311
|
+
/**
|
|
312
|
+
* The IAM role used by Security Lake to replicate objects. Only created
|
|
313
|
+
* when replication is enabled and no `roleArn` was supplied.
|
|
314
|
+
*/
|
|
315
|
+
readonly replicationRole?: Role;
|
|
316
|
+
/**
|
|
317
|
+
* The Lake Formation `AWSServiceRoleForLakeFormationDataAccess`
|
|
318
|
+
* service-linked role, when it was provisioned by this construct.
|
|
319
|
+
*/
|
|
320
|
+
readonly lakeFormationServiceLinkedRole?: CfnServiceLinkedRole;
|
|
321
|
+
/**
|
|
322
|
+
* The `CfnAwsLogSource` resources created by this construct, in the order
|
|
323
|
+
* they were declared.
|
|
324
|
+
*/
|
|
325
|
+
readonly logSources: CfnAwsLogSource[];
|
|
326
|
+
/**
|
|
327
|
+
* The `CfnSubscriber` resources created by this construct, in the order
|
|
328
|
+
* they were declared.
|
|
329
|
+
*/
|
|
330
|
+
readonly subscribers: CfnSubscriber[];
|
|
331
|
+
/**
|
|
332
|
+
* The `CfnSubscriberNotification` resources created by this construct,
|
|
333
|
+
* one per subscriber, in the order they were declared.
|
|
334
|
+
*/
|
|
335
|
+
readonly subscriberNotifications: CfnSubscriberNotification[];
|
|
336
|
+
constructor(scope: Construct, id: string, props?: StandardSecurityLakeProps);
|
|
337
|
+
}
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StandardSecurityLake = exports.AwsLogSourceName = void 0;
|
|
4
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
5
|
+
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
|
6
|
+
const aws_securitylake_1 = require("aws-cdk-lib/aws-securitylake");
|
|
7
|
+
const custom_resources_1 = require("aws-cdk-lib/custom-resources");
|
|
8
|
+
const index_1 = require("../../aws-cdk/index");
|
|
9
|
+
/**
|
|
10
|
+
* The AWS-native log sources that Amazon Security Lake can ingest.
|
|
11
|
+
*
|
|
12
|
+
* @see https://docs.aws.amazon.com/security-lake/latest/userguide/internal-sources.html
|
|
13
|
+
*/
|
|
14
|
+
var AwsLogSourceName;
|
|
15
|
+
(function (AwsLogSourceName) {
|
|
16
|
+
AwsLogSourceName["CLOUD_TRAIL_MGMT"] = "CLOUD_TRAIL_MGMT";
|
|
17
|
+
AwsLogSourceName["LAMBDA_EXECUTION"] = "LAMBDA_EXECUTION";
|
|
18
|
+
AwsLogSourceName["ROUTE53"] = "ROUTE53";
|
|
19
|
+
AwsLogSourceName["S3_DATA"] = "S3_DATA";
|
|
20
|
+
AwsLogSourceName["SH_FINDINGS"] = "SH_FINDINGS";
|
|
21
|
+
AwsLogSourceName["VPC_FLOW"] = "VPC_FLOW";
|
|
22
|
+
AwsLogSourceName["EKS_AUDIT"] = "EKS_AUDIT";
|
|
23
|
+
AwsLogSourceName["WAF"] = "WAF";
|
|
24
|
+
})(AwsLogSourceName || (exports.AwsLogSourceName = AwsLogSourceName = {}));
|
|
25
|
+
/**
|
|
26
|
+
* Standard Amazon Security Lake. Wraps the Security Lake L1 constructs to
|
|
27
|
+
* stand up a data lake with an optional set of AWS native log sources
|
|
28
|
+
* enabled, a metastore manager role, lifecycle policy and replication.
|
|
29
|
+
*
|
|
30
|
+
* Where this construct does not meet your needs, use the underlying
|
|
31
|
+
* `CfnDataLake` and `CfnAwsLogSource` constructs directly.
|
|
32
|
+
*/
|
|
33
|
+
class StandardSecurityLake extends index_1.ExtendedConstruct {
|
|
34
|
+
constructor(scope, id, props) {
|
|
35
|
+
var _a, _b, _c, _d, _e;
|
|
36
|
+
super(scope, id, props);
|
|
37
|
+
/**
|
|
38
|
+
* The `CfnAwsLogSource` resources created by this construct, in the order
|
|
39
|
+
* they were declared.
|
|
40
|
+
*/
|
|
41
|
+
this.logSources = [];
|
|
42
|
+
/**
|
|
43
|
+
* The `CfnSubscriber` resources created by this construct, in the order
|
|
44
|
+
* they were declared.
|
|
45
|
+
*/
|
|
46
|
+
this.subscribers = [];
|
|
47
|
+
/**
|
|
48
|
+
* The `CfnSubscriberNotification` resources created by this construct,
|
|
49
|
+
* one per subscriber, in the order they were declared.
|
|
50
|
+
*/
|
|
51
|
+
this.subscriberNotifications = [];
|
|
52
|
+
// Optional Lake Formation service-linked role. Security Lake requires
|
|
53
|
+
// this SLR to exist in the account before a data lake can be created.
|
|
54
|
+
if (props === null || props === void 0 ? void 0 : props.createLakeFormationServiceLinkedRole) {
|
|
55
|
+
this.lakeFormationServiceLinkedRole = new aws_iam_1.CfnServiceLinkedRole(this, 'LakeFormationServiceLinkedRole', {
|
|
56
|
+
awsServiceName: 'lakeformation.amazonaws.com',
|
|
57
|
+
description: 'Service-linked role used by AWS Lake Formation to access registered S3 locations. Required by Amazon Security Lake.',
|
|
58
|
+
});
|
|
59
|
+
// The Lake Formation SLR is an account singleton that is frequently
|
|
60
|
+
// shared with other stacks and consoles. Retain it on
|
|
61
|
+
// stack-delete/opt-out so toggling this flag off (or removing this
|
|
62
|
+
// construct) does not strip Lake Formation access account-wide.
|
|
63
|
+
this.lakeFormationServiceLinkedRole.applyRemovalPolicy(aws_cdk_lib_1.RemovalPolicy.RETAIN);
|
|
64
|
+
}
|
|
65
|
+
// Metastore manager role.
|
|
66
|
+
let metaStoreManagerRoleArn = props === null || props === void 0 ? void 0 : props.metaStoreManagerRoleArn;
|
|
67
|
+
const usesCustomerManagedKey = (props === null || props === void 0 ? void 0 : props.kmsKeyId) !== undefined && props.kmsKeyId !== 'S3_MANAGED_KEY';
|
|
68
|
+
if (!metaStoreManagerRoleArn) {
|
|
69
|
+
// When the data lake is encrypted with a customer-managed KMS key,
|
|
70
|
+
// the metastore manager Lambda must be able to Decrypt / Encrypt /
|
|
71
|
+
// GenerateDataKey against that key. The AWS managed policy
|
|
72
|
+
// `AmazonSecurityLakeMetastoreManager` does NOT include KMS actions,
|
|
73
|
+
// so without this grant CFN deployment succeeds but partition
|
|
74
|
+
// updates and subscriber queries fail at runtime. The key ARN is
|
|
75
|
+
// not derivable at synth time, so require the caller to supply it
|
|
76
|
+
// explicitly via `metaStoreManagerKmsKeyArn` or pre-provision their
|
|
77
|
+
// own metastore manager role via `metaStoreManagerRoleArn`.
|
|
78
|
+
if (usesCustomerManagedKey && !(props === null || props === void 0 ? void 0 : props.metaStoreManagerKmsKeyArn)) {
|
|
79
|
+
throw new Error('StandardSecurityLake: a customer-managed `kmsKeyId` requires ' +
|
|
80
|
+
'`metaStoreManagerKmsKeyArn` so the generated metastore manager ' +
|
|
81
|
+
'role can be granted the necessary KMS permissions. ' +
|
|
82
|
+
'Alternatively, pre-provision the metastore manager role ' +
|
|
83
|
+
'yourself and pass its ARN via `metaStoreManagerRoleArn`.');
|
|
84
|
+
}
|
|
85
|
+
const metaStoreInlinePolicies = {};
|
|
86
|
+
if (usesCustomerManagedKey && (props === null || props === void 0 ? void 0 : props.metaStoreManagerKmsKeyArn)) {
|
|
87
|
+
metaStoreInlinePolicies.AmazonSecurityLakeMetastoreManagerKmsPolicy =
|
|
88
|
+
new aws_iam_1.PolicyDocument({
|
|
89
|
+
statements: [
|
|
90
|
+
new aws_iam_1.PolicyStatement({
|
|
91
|
+
sid: 'AllowMetaStoreManagerKmsAccess',
|
|
92
|
+
actions: [
|
|
93
|
+
'kms:Decrypt',
|
|
94
|
+
'kms:Encrypt',
|
|
95
|
+
'kms:GenerateDataKey',
|
|
96
|
+
'kms:DescribeKey',
|
|
97
|
+
],
|
|
98
|
+
resources: [props.metaStoreManagerKmsKeyArn],
|
|
99
|
+
}),
|
|
100
|
+
],
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
this.metaStoreManagerRole = new aws_iam_1.Role(this, 'MetaStoreManagerRole', {
|
|
104
|
+
// The partition-updater Lambda functions created by Security Lake are
|
|
105
|
+
// hard-coded to assume a role named
|
|
106
|
+
// `AmazonSecurityLakeMetaStoreManagerV2` under the `/service-role/`
|
|
107
|
+
// path and do not honor an arbitrary role ARN. Without a matching
|
|
108
|
+
// role name, CFN deployment and `CreateDataLake` succeed but the
|
|
109
|
+
// partition updater silently fails and subscribers cannot query
|
|
110
|
+
// replicated objects. The role name is account-global; for
|
|
111
|
+
// multi-Region deploys in the same account pass
|
|
112
|
+
// `metaStoreManagerRoleArn` for all but one Region.
|
|
113
|
+
path: '/service-role/',
|
|
114
|
+
roleName: 'AmazonSecurityLakeMetaStoreManagerV2',
|
|
115
|
+
assumedBy: new aws_iam_1.ServicePrincipal('lambda.amazonaws.com'),
|
|
116
|
+
description: 'Role used by Amazon Security Lake metastore manager Lambda to manage the AWS Glue metastore.',
|
|
117
|
+
managedPolicies: [
|
|
118
|
+
aws_iam_1.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonSecurityLakeMetastoreManager'),
|
|
119
|
+
],
|
|
120
|
+
inlinePolicies: metaStoreInlinePolicies,
|
|
121
|
+
});
|
|
122
|
+
metaStoreManagerRoleArn = this.metaStoreManagerRole.roleArn;
|
|
123
|
+
}
|
|
124
|
+
// Encryption configuration.
|
|
125
|
+
const encryptionConfiguration = (props === null || props === void 0 ? void 0 : props.kmsKeyId) !== undefined ? { kmsKeyId: props.kmsKeyId } : undefined;
|
|
126
|
+
// Lifecycle configuration.
|
|
127
|
+
let lifecycleConfiguration;
|
|
128
|
+
if (props === null || props === void 0 ? void 0 : props.lifecycle) {
|
|
129
|
+
lifecycleConfiguration = {
|
|
130
|
+
expiration: props.lifecycle.expirationDays !== undefined
|
|
131
|
+
? { days: props.lifecycle.expirationDays }
|
|
132
|
+
: undefined,
|
|
133
|
+
transitions: (_a = props.lifecycle.transitions) === null || _a === void 0 ? void 0 : _a.map((t) => ({
|
|
134
|
+
days: t.days,
|
|
135
|
+
storageClass: t.storageClass,
|
|
136
|
+
})),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// Replication configuration.
|
|
140
|
+
let replicationConfiguration;
|
|
141
|
+
if (props === null || props === void 0 ? void 0 : props.replication) {
|
|
142
|
+
let replicationRoleArn = props.replication.roleArn;
|
|
143
|
+
if (!replicationRoleArn) {
|
|
144
|
+
const account = aws_cdk_lib_1.Stack.of(this).account;
|
|
145
|
+
const sourceRegion = aws_cdk_lib_1.Stack.of(this).region;
|
|
146
|
+
const destinationRegions = props.replication.regions;
|
|
147
|
+
// Source and destination encryption are independent in Security
|
|
148
|
+
// Lake: a CMK source can replicate to an SSE-S3 rollup and vice
|
|
149
|
+
// versa. Grant `kms:Decrypt` on the source key only when the
|
|
150
|
+
// source lake uses a CMK, and grant `kms:Encrypt` /
|
|
151
|
+
// `kms:GenerateDataKey` on the destination keys only when any
|
|
152
|
+
// rollup bucket uses a CMK. The key ARNs are not derivable at
|
|
153
|
+
// synth time, so require the caller to supply them explicitly on
|
|
154
|
+
// the encrypted side (or pre-provision their own replication role
|
|
155
|
+
// via `replication.roleArn`).
|
|
156
|
+
if (usesCustomerManagedKey && !props.replication.sourceKmsKeyArn) {
|
|
157
|
+
throw new Error('StandardSecurityLake: a customer-managed `kmsKeyId` with ' +
|
|
158
|
+
'replication requires `replication.sourceKmsKeyArn` so the ' +
|
|
159
|
+
'generated replication role can `kms:Decrypt` source objects. ' +
|
|
160
|
+
'If any rollup Region bucket is also encrypted with a ' +
|
|
161
|
+
'customer-managed key, pass its ARN via ' +
|
|
162
|
+
'`replication.destinationKmsKeyArns`. Alternatively, ' +
|
|
163
|
+
'pre-provision the replication role yourself and pass its ARN ' +
|
|
164
|
+
'via `replication.roleArn`.');
|
|
165
|
+
}
|
|
166
|
+
const kmsStatements = [];
|
|
167
|
+
if (usesCustomerManagedKey && props.replication.sourceKmsKeyArn) {
|
|
168
|
+
kmsStatements.push(new aws_iam_1.PolicyStatement({
|
|
169
|
+
sid: 'AllowDecryptSourceKmsKey',
|
|
170
|
+
actions: ['kms:Decrypt'],
|
|
171
|
+
resources: [props.replication.sourceKmsKeyArn],
|
|
172
|
+
}));
|
|
173
|
+
}
|
|
174
|
+
if (props.replication.destinationKmsKeyArns &&
|
|
175
|
+
props.replication.destinationKmsKeyArns.length > 0) {
|
|
176
|
+
kmsStatements.push(new aws_iam_1.PolicyStatement({
|
|
177
|
+
sid: 'AllowEncryptDestinationKmsKeys',
|
|
178
|
+
actions: ['kms:Encrypt', 'kms:GenerateDataKey'],
|
|
179
|
+
resources: props.replication.destinationKmsKeyArns,
|
|
180
|
+
}));
|
|
181
|
+
}
|
|
182
|
+
this.replicationRole = new aws_iam_1.Role(this, 'ReplicationRole', {
|
|
183
|
+
// Security Lake requires the replication role to live under the
|
|
184
|
+
// service-role/ path and start with `SecurityLake`. IAM role names
|
|
185
|
+
// are account-global, so include the source Region in the suffix to
|
|
186
|
+
// avoid collisions when the construct is deployed to multiple
|
|
187
|
+
// Regions in the same account.
|
|
188
|
+
path: '/service-role/',
|
|
189
|
+
roleName: `SecurityLakeS3ReplicationRole-${sourceRegion}`,
|
|
190
|
+
// Amazon S3 performs the cross-Region replication, so it (not the
|
|
191
|
+
// Security Lake service) must be allowed to assume this role.
|
|
192
|
+
assumedBy: new aws_iam_1.ServicePrincipal('s3.amazonaws.com'),
|
|
193
|
+
description: 'Role used by Amazon S3 to replicate Amazon Security Lake objects across Regions.',
|
|
194
|
+
// No AWS managed policy exists for this role; attach the inline
|
|
195
|
+
// policy documented by Security Lake.
|
|
196
|
+
// https://docs.aws.amazon.com/security-lake/latest/userguide/add-rollup-region.html
|
|
197
|
+
inlinePolicies: {
|
|
198
|
+
AmazonSecurityLakeS3ReplicationRolePolicy: new aws_iam_1.PolicyDocument({
|
|
199
|
+
statements: [
|
|
200
|
+
new aws_iam_1.PolicyStatement({
|
|
201
|
+
sid: 'AllowReadS3ReplicationSetting',
|
|
202
|
+
actions: [
|
|
203
|
+
's3:ListBucket',
|
|
204
|
+
's3:GetReplicationConfiguration',
|
|
205
|
+
's3:GetObjectVersionForReplication',
|
|
206
|
+
's3:GetObjectVersion',
|
|
207
|
+
's3:GetObjectVersionAcl',
|
|
208
|
+
's3:GetObjectVersionTagging',
|
|
209
|
+
's3:GetObjectRetention',
|
|
210
|
+
's3:GetObjectLegalHold',
|
|
211
|
+
],
|
|
212
|
+
resources: [
|
|
213
|
+
`arn:${aws_cdk_lib_1.Stack.of(this).partition}:s3:::aws-security-data-lake-${sourceRegion}*`,
|
|
214
|
+
`arn:${aws_cdk_lib_1.Stack.of(this).partition}:s3:::aws-security-data-lake-${sourceRegion}*/*`,
|
|
215
|
+
],
|
|
216
|
+
conditions: {
|
|
217
|
+
StringEquals: { 's3:ResourceAccount': [account] },
|
|
218
|
+
},
|
|
219
|
+
}),
|
|
220
|
+
new aws_iam_1.PolicyStatement({
|
|
221
|
+
sid: 'AllowS3Replication',
|
|
222
|
+
actions: [
|
|
223
|
+
's3:ReplicateObject',
|
|
224
|
+
's3:ReplicateDelete',
|
|
225
|
+
's3:ReplicateTags',
|
|
226
|
+
's3:GetObjectVersionTagging',
|
|
227
|
+
],
|
|
228
|
+
resources: destinationRegions.flatMap((r) => [
|
|
229
|
+
`arn:${aws_cdk_lib_1.Stack.of(this).partition}:s3:::aws-security-data-lake-${r}*/*`,
|
|
230
|
+
]),
|
|
231
|
+
conditions: {
|
|
232
|
+
StringEquals: { 's3:ResourceAccount': [account] },
|
|
233
|
+
},
|
|
234
|
+
}),
|
|
235
|
+
...kmsStatements,
|
|
236
|
+
],
|
|
237
|
+
}),
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
replicationRoleArn = this.replicationRole.roleArn;
|
|
241
|
+
}
|
|
242
|
+
replicationConfiguration = {
|
|
243
|
+
regions: props.replication.regions,
|
|
244
|
+
roleArn: replicationRoleArn,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
this.dataLake = new aws_securitylake_1.CfnDataLake(this, 'DataLake', {
|
|
248
|
+
metaStoreManagerRoleArn,
|
|
249
|
+
encryptionConfiguration,
|
|
250
|
+
lifecycleConfiguration,
|
|
251
|
+
replicationConfiguration,
|
|
252
|
+
});
|
|
253
|
+
if (this.lakeFormationServiceLinkedRole) {
|
|
254
|
+
this.dataLake.addDependency(this.lakeFormationServiceLinkedRole);
|
|
255
|
+
}
|
|
256
|
+
// Create AWS log sources sequentially using DependsOn, as required by
|
|
257
|
+
// Security Lake when more than one source is created in the same
|
|
258
|
+
// template.
|
|
259
|
+
let previous;
|
|
260
|
+
for (const source of (_b = props === null || props === void 0 ? void 0 : props.logSources) !== null && _b !== void 0 ? _b : []) {
|
|
261
|
+
const logSource = new aws_securitylake_1.CfnAwsLogSource(this, `LogSource${source.sourceName}`, {
|
|
262
|
+
dataLakeArn: this.dataLake.attrArn,
|
|
263
|
+
sourceName: source.sourceName,
|
|
264
|
+
sourceVersion: (_c = source.sourceVersion) !== null && _c !== void 0 ? _c : '2.0',
|
|
265
|
+
accounts: (_d = source.accounts) !== null && _d !== void 0 ? _d : [aws_cdk_lib_1.Stack.of(this).account],
|
|
266
|
+
});
|
|
267
|
+
logSource.addDependency(this.dataLake);
|
|
268
|
+
if (previous) {
|
|
269
|
+
logSource.addDependency(previous);
|
|
270
|
+
}
|
|
271
|
+
previous = logSource;
|
|
272
|
+
this.logSources.push(logSource);
|
|
273
|
+
}
|
|
274
|
+
// Subscribers. Each entry becomes a `CfnSubscriber` with `accessTypes:
|
|
275
|
+
// ['S3']` plus a sibling `CfnSubscriberNotification`. The notification
|
|
276
|
+
// defaults to SQS (Security Lake creates the queue in this account);
|
|
277
|
+
// callers can switch to HTTPS by passing `httpsNotificationEndpoint`.
|
|
278
|
+
for (const sub of (_e = props === null || props === void 0 ? void 0 : props.subscribers) !== null && _e !== void 0 ? _e : []) {
|
|
279
|
+
const subscriber = new aws_securitylake_1.CfnSubscriber(this, `Subscriber${sub.subscriberName}`, {
|
|
280
|
+
accessTypes: ['S3'],
|
|
281
|
+
dataLakeArn: this.dataLake.attrArn,
|
|
282
|
+
subscriberName: sub.subscriberName,
|
|
283
|
+
subscriberDescription: sub.description,
|
|
284
|
+
subscriberIdentity: {
|
|
285
|
+
externalId: sub.externalId,
|
|
286
|
+
principal: sub.principal,
|
|
287
|
+
},
|
|
288
|
+
sources: sub.sources.map((s) => {
|
|
289
|
+
var _a;
|
|
290
|
+
return ({
|
|
291
|
+
awsLogSource: {
|
|
292
|
+
sourceName: s.sourceName,
|
|
293
|
+
sourceVersion: (_a = s.sourceVersion) !== null && _a !== void 0 ? _a : '2.0',
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
}),
|
|
297
|
+
});
|
|
298
|
+
subscriber.addDependency(this.dataLake);
|
|
299
|
+
// Subscriber creation requires the AwsLogSource to exist for every
|
|
300
|
+
// source it references; chain through the last log source we created
|
|
301
|
+
// so CFN waits for ingestion to be enabled.
|
|
302
|
+
for (const ls of this.logSources) {
|
|
303
|
+
subscriber.addDependency(ls);
|
|
304
|
+
}
|
|
305
|
+
this.subscribers.push(subscriber);
|
|
306
|
+
if (sub.httpsNotificationEndpoint &&
|
|
307
|
+
!sub.httpsNotificationTargetRoleArn) {
|
|
308
|
+
throw new Error(`StandardSecurityLake: subscriber "${sub.subscriberName}" sets ` +
|
|
309
|
+
'`httpsNotificationEndpoint` but no ' +
|
|
310
|
+
'`httpsNotificationTargetRoleArn`. The CloudFormation/API path ' +
|
|
311
|
+
'does not auto-provision the EventBridge invocation role (only ' +
|
|
312
|
+
'the AWS console does). Create a role trusted by ' +
|
|
313
|
+
'`events.amazonaws.com` with `events:InvokeApiDestination` on ' +
|
|
314
|
+
'the target endpoint and pass its ARN as ' +
|
|
315
|
+
'`httpsNotificationTargetRoleArn`.');
|
|
316
|
+
}
|
|
317
|
+
const notification = new aws_securitylake_1.CfnSubscriberNotification(this, `SubscriberNotification${sub.subscriberName}`, {
|
|
318
|
+
subscriberArn: subscriber.attrSubscriberArn,
|
|
319
|
+
notificationConfiguration: sub.httpsNotificationEndpoint
|
|
320
|
+
? {
|
|
321
|
+
httpsNotificationConfiguration: {
|
|
322
|
+
endpoint: sub.httpsNotificationEndpoint,
|
|
323
|
+
targetRoleArn: sub.httpsNotificationTargetRoleArn,
|
|
324
|
+
},
|
|
325
|
+
}
|
|
326
|
+
: {
|
|
327
|
+
sqsNotificationConfiguration: {},
|
|
328
|
+
},
|
|
329
|
+
});
|
|
330
|
+
notification.addDependency(subscriber);
|
|
331
|
+
this.subscriberNotifications.push(notification);
|
|
332
|
+
// Patch the Security-Lake-managed SQS Main-Queue's visibility
|
|
333
|
+
// timeout. Needed because Security Lake auto-provisions the queue
|
|
334
|
+
// with 300s, less than the aes-siem es-loader Lambda timeout (600s
|
|
335
|
+
// default), causing event-source-mapping creation to fail with
|
|
336
|
+
// "The event source mapping's function timeout must be smaller
|
|
337
|
+
// than or equal to the queue's visibility timeout."
|
|
338
|
+
if (!sub.httpsNotificationEndpoint &&
|
|
339
|
+
sub.sqsVisibilityTimeoutSeconds !== undefined) {
|
|
340
|
+
const timeout = sub.sqsVisibilityTimeoutSeconds;
|
|
341
|
+
const stack = aws_cdk_lib_1.Stack.of(this);
|
|
342
|
+
// The notification resource returns the queue ARN via
|
|
343
|
+
// `SubscriberEndpoint`. Convert to a queue URL for the SQS SDK.
|
|
344
|
+
// ARN: arn:<partition>:sqs:<region>:<account>:<name>
|
|
345
|
+
// URL: https://sqs.<region>.<url-suffix>/<account>/<name>
|
|
346
|
+
//
|
|
347
|
+
// The URL suffix is partition-aware (`amazonaws.com`,
|
|
348
|
+
// `amazonaws.com.cn`, `c2s.ic.gov`, etc.); hard-coding
|
|
349
|
+
// `amazonaws.com` breaks `aws-cn` and GovCloud. Use the stack's
|
|
350
|
+
// `urlSuffix` token so CloudFormation substitutes the right
|
|
351
|
+
// value at deploy time.
|
|
352
|
+
const queueName = aws_cdk_lib_1.Fn.select(5, aws_cdk_lib_1.Fn.split(':', notification.attrSubscriberEndpoint));
|
|
353
|
+
const queueUrl = `https://sqs.${stack.region}.${stack.urlSuffix}/${stack.account}/${queueName}`;
|
|
354
|
+
const patch = new custom_resources_1.AwsCustomResource(this, `SubscriberQueueVisibilityPatch${sub.subscriberName}`, {
|
|
355
|
+
onCreate: {
|
|
356
|
+
service: 'SQS',
|
|
357
|
+
action: 'setQueueAttributes',
|
|
358
|
+
parameters: {
|
|
359
|
+
QueueUrl: queueUrl,
|
|
360
|
+
Attributes: { VisibilityTimeout: timeout.toString() },
|
|
361
|
+
},
|
|
362
|
+
physicalResourceId: custom_resources_1.PhysicalResourceId.of(`${sub.subscriberName}-visibility-${timeout}`),
|
|
363
|
+
},
|
|
364
|
+
onUpdate: {
|
|
365
|
+
service: 'SQS',
|
|
366
|
+
action: 'setQueueAttributes',
|
|
367
|
+
parameters: {
|
|
368
|
+
QueueUrl: queueUrl,
|
|
369
|
+
Attributes: { VisibilityTimeout: timeout.toString() },
|
|
370
|
+
},
|
|
371
|
+
physicalResourceId: custom_resources_1.PhysicalResourceId.of(`${sub.subscriberName}-visibility-${timeout}`),
|
|
372
|
+
},
|
|
373
|
+
policy: custom_resources_1.AwsCustomResourcePolicy.fromStatements([
|
|
374
|
+
new aws_iam_1.PolicyStatement({
|
|
375
|
+
actions: ['sqs:SetQueueAttributes'],
|
|
376
|
+
// Scope to the exact queue ARN exposed by the
|
|
377
|
+
// SubscriberNotification resource
|
|
378
|
+
// (`attrSubscriberEndpoint`), which is already an SQS
|
|
379
|
+
// ARN. Using the token means CloudFormation substitutes
|
|
380
|
+
// the real queue ARN at deploy-time, so the custom-
|
|
381
|
+
// resource role cannot be abused to modify unrelated
|
|
382
|
+
// queues in the account.
|
|
383
|
+
resources: [notification.attrSubscriberEndpoint],
|
|
384
|
+
}),
|
|
385
|
+
]),
|
|
386
|
+
});
|
|
387
|
+
patch.node.addDependency(notification);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
exports.StandardSecurityLake = StandardSecurityLake;
|
|
393
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhcmQtc2VjdXJpdHktbGFrZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hd3Mtc2VjdXJpdHlsYWtlL2xpYi9zdGFuZGFyZC1zZWN1cml0eS1sYWtlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUFxRDtBQUNyRCxpREFPNkI7QUFDN0IsbUVBS3NDO0FBQ3RDLG1FQUlzQztBQUV0QywrQ0FHNkI7QUFFN0I7Ozs7R0FJRztBQUNILElBQVksZ0JBU1g7QUFURCxXQUFZLGdCQUFnQjtJQUMxQix5REFBcUMsQ0FBQTtJQUNyQyx5REFBcUMsQ0FBQTtJQUNyQyx1Q0FBbUIsQ0FBQTtJQUNuQix1Q0FBbUIsQ0FBQTtJQUNuQiwrQ0FBMkIsQ0FBQTtJQUMzQix5Q0FBcUIsQ0FBQTtJQUNyQiwyQ0FBdUIsQ0FBQTtJQUN2QiwrQkFBVyxDQUFBO0FBQ2IsQ0FBQyxFQVRXLGdCQUFnQixnQ0FBaEIsZ0JBQWdCLFFBUzNCO0FBZ1REOzs7Ozs7O0dBT0c7QUFDSCxNQUFhLG9CQUFxQixTQUFRLHlCQUFpQjtJQTBDekQsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFpQzs7UUFDekUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFuQjFCOzs7V0FHRztRQUNNLGVBQVUsR0FBc0IsRUFBRSxDQUFDO1FBRTVDOzs7V0FHRztRQUNNLGdCQUFXLEdBQW9CLEVBQUUsQ0FBQztRQUUzQzs7O1dBR0c7UUFDTSw0QkFBdUIsR0FBZ0MsRUFBRSxDQUFDO1FBS2pFLHNFQUFzRTtRQUN0RSxzRUFBc0U7UUFDdEUsSUFBSSxLQUFLLGFBQUwsS0FBSyx1QkFBTCxLQUFLLENBQUUsb0NBQW9DLEVBQUUsQ0FBQztZQUNoRCxJQUFJLENBQUMsOEJBQThCLEdBQUcsSUFBSSw4QkFBb0IsQ0FDNUQsSUFBSSxFQUNKLGdDQUFnQyxFQUNoQztnQkFDRSxjQUFjLEVBQUUsNkJBQTZCO2dCQUM3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UUFBUSxFQUFFLFFBQVE7NEJBQ2xCLFVBQVUsRUFBRSxFQUFDLGlCQUFpQixFQUFFLE9BQU8sQ0FBQyxRQUFRLEVBQUUsRUFBQzt5QkFDcEQ7d0JBQ0Qsa0JBQWtCLEVBQUUscUNBQWtCLENBQUMsRUFBRSxDQUN2QyxHQUFHLEdBQUcsQ0FBQyxjQUFjLGVBQWUsT0FBTyxFQUFFLENBQzlDO3FCQUNGO29CQUNELFFBQVEsRUFBRTt3QkFDUixPQUFPLEVBQUUsS0FBSzt3QkFDZCxNQUFNLEVBQUUsb0JBQW9CO3dCQUM1QixVQUFVLEVBQUU7NEJBQ1YsUUFBUSxFQUFFLFFBQVE7NEJBQ2xCLFVBQVUsRUFBRSxFQUFDLGlCQUFpQixFQUFFLE9BQU8sQ0FBQyxRQUFRLEVBQUUsRUFBQzt5QkFDcEQ7d0JBQ0Qsa0JBQWtCLEVBQUUscUNBQWtCLENBQUMsRUFBRSxDQUN2QyxHQUFHLEdBQUcsQ0FBQyxjQUFjLGVBQWUsT0FBTyxFQUFFLENBQzlDO3FCQUNGO29CQUNELE1BQU0sRUFBRSwwQ0FBdUIsQ0FBQyxjQUFjLENBQUM7d0JBQzdDLElBQUkseUJBQWUsQ0FBQzs0QkFDbEIsT0FBTyxFQUFFLENBQUMsd0JBQXdCLENBQUM7NEJBQ25DLDhDQUE4Qzs0QkFDOUMsa0NBQWtDOzRCQUNsQyxzREFBc0Q7NEJBQ3RELHdEQUF3RDs0QkFDeEQsb0RBQW9EOzRCQUNwRCxxREFBcUQ7NEJBQ3JELHlCQUF5Qjs0QkFDekIsU0FBUyxFQUFFLENBQUMsWUFBWSxDQUFDLHNCQUFzQixDQUFDO3lCQUNqRCxDQUFDO3FCQUNILENBQUM7aUJBQ0gsQ0FDRixDQUFDO2dCQUNGLEtBQUssQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3pDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBcmNELG9EQXFjQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Rm4sIFJlbW92YWxQb2xpY3ksIFN0YWNrfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQge1xuICBDZm5TZXJ2aWNlTGlua2VkUm9sZSxcbiAgTWFuYWdlZFBvbGljeSxcbiAgUG9saWN5RG9jdW1lbnQsXG4gIFBvbGljeVN0YXRlbWVudCxcbiAgUm9sZSxcbiAgU2VydmljZVByaW5jaXBhbCxcbn0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQge1xuICBDZm5Bd3NMb2dTb3VyY2UsXG4gIENmbkRhdGFMYWtlLFxuICBDZm5TdWJzY3JpYmVyLFxuICBDZm5TdWJzY3JpYmVyTm90aWZpY2F0aW9uLFxufSBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtc2VjdXJpdHlsYWtlJztcbmltcG9ydCB7XG4gIEF3c0N1c3RvbVJlc291cmNlLFxuICBBd3NDdXN0b21SZXNvdXJjZVBvbGljeSxcbiAgUGh5c2ljYWxSZXNvdXJjZUlkLFxufSBmcm9tICdhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzJztcbmltcG9ydCB0eXBlIHtDb25zdHJ1Y3R9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHtcbiAgRXh0ZW5kZWRDb25zdHJ1Y3QsXG4gIHR5cGUgRXh0ZW5kZWRDb25zdHJ1Y3RQcm9wcyxcbn0gZnJvbSAnLi4vLi4vYXdzLWNkay9pbmRleCc7XG5cbi8qKlxuICogVGhlIEFXUy1uYXRpdmUgbG9nIHNvdXJjZXMgdGhhdCBBbWF6b24gU2VjdXJpdHkgTGFrZSBjYW4gaW5nZXN0LlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L3VzZXJndWlkZS9pbnRlcm5hbC1zb3VyY2VzLmh0bWxcbiAqL1xuZXhwb3J0IGVudW0gQXdzTG9nU291cmNlTmFtZSB7XG4gIENMT1VEX1RSQUlMX01HTVQgPSAnQ0xPVURfVFJBSUxfTUdNVCcsXG4gIExBTUJEQV9FWEVDVVRJT04gPSAnTEFNQkRBX0VYRUNVVElPTicsXG4gIFJPVVRFNTMgPSAnUk9VVEU1MycsXG4gIFMzX0RBVEEgPSAnUzNfREFUQScsXG4gIFNIX0ZJTkRJTkdTID0gJ1NIX0ZJTkRJTkdTJyxcbiAgVlBDX0ZMT1cgPSAnVlBDX0ZMT1cnLFxuICBFS1NfQVVESVQgPSAnRUtTX0FVRElUJyxcbiAgV0FGID0gJ1dBRicsXG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgYW4gaW5kaXZpZHVhbCBBV1MgbG9nIHNvdXJjZSB0byBlbmFibGUgb24gdGhlIGRhdGEgbGFrZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBd3NMb2dTb3VyY2VQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgQVdTIGxvZyBzb3VyY2UgdG8gZW5hYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlTmFtZTogQXdzTG9nU291cmNlTmFtZSB8IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHZlcnNpb24gb2YgdGhlIEFXUyBsb2cgc291cmNlIHRvIGVuYWJsZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSAnMi4wJ1xuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlVmVyc2lvbj86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIEFXUyBhY2NvdW50cyB3aG9zZSBkYXRhIHNob3VsZCBiZSBjb2xsZWN0ZWQgZm9yIHRoaXMgc291cmNlLiBJZiBub3RcbiAgICogcHJvdmlkZWQsIHRoZSBkYXRhIGxha2Ugb3duZXIgYWNjb3VudCBpcyB1c2VkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFtTdGFjay5vZih0aGlzKS5hY2NvdW50XVxuICAgKi9cbiAgcmVhZG9ubHkgYWNjb3VudHM/OiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBMaWZlY3ljbGUgdHJhbnNpdGlvbiBmb3IgU2VjdXJpdHkgTGFrZSBkYXRhLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNlY3VyaXR5TGFrZVRyYW5zaXRpb25Qcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIGRheXMgYmVmb3JlIGRhdGEgdHJhbnNpdGlvbnMgdG8gdGhlIGdpdmVuIHN0b3JhZ2UgY2xhc3MuXG4gICAqL1xuICByZWFkb25seSBkYXlzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSB0YXJnZXQgUzMgc3RvcmFnZSBjbGFzcy4gU3VwcG9ydGVkIHZhbHVlcyBpbmNsdWRlIGBTVEFOREFSRF9JQWAsXG4gICAqIGBPTkVaT05FX0lBYCwgYElOVEVMTElHRU5UX1RJRVJJTkdgLCBgR0xBQ0lFUl9JUmAsIGBHTEFDSUVSYCBhbmRcbiAgICogYERFRVBfQVJDSElWRWAuXG4gICAqL1xuICByZWFkb25seSBzdG9yYWdlQ2xhc3M6IHN0cmluZztcbn1cblxuLyoqXG4gKiBMaWZlY3ljbGUgY29uZmlndXJhdGlvbiBvcHRpb25zIGZvciBTZWN1cml0eSBMYWtlIG1hbmFnZWQgUzMgc3RvcmFnZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZWN1cml0eUxha2VMaWZlY3ljbGVQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIGRheXMgYmVmb3JlIFNlY3VyaXR5IExha2UgZGF0YSBpcyBleHBpcmVkL2RlbGV0ZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZGF0YSBpcyByZXRhaW5lZCBpbmRlZmluaXRlbHlcbiAgICovXG4gIHJlYWRvbmx5IGV4cGlyYXRpb25EYXlzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUcmFuc2l0aW9ucyBhcHBsaWVkIHRvIFNlY3VyaXR5IExha2UgZGF0YS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyB0cmFuc2l0aW9uc1xuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNpdGlvbnM/OiBTZWN1cml0eUxha2VUcmFuc2l0aW9uUHJvcHNbXTtcbn1cblxuLyoqXG4gKiBSZXBsaWNhdGlvbiBjb25maWd1cmF0aW9uIGZvciBTZWN1cml0eSBMYWtlIGRhdGEuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VjdXJpdHlMYWtlUmVwbGljYXRpb25Qcm9wcyB7XG4gIC8qKlxuICAgKiBPbmUgb3IgbW9yZSByb2xsdXAgUmVnaW9ucyB0byByZXBsaWNhdGUgZGF0YSB0by5cbiAgICovXG4gIHJlYWRvbmx5IHJlZ2lvbnM6IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSBJQU0gcm9sZSBTZWN1cml0eSBMYWtlIHVzZXMgdG8gcmVwbGljYXRlIG9iamVjdHMuIElmIG5vdFxuICAgKiBwcm92aWRlZCwgYSByb2xlIHdpbGwgYmUgY3JlYXRlZCBhdXRvbWF0aWNhbGx5LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGEgbmV3IHJvbGUgaXMgY3JlYXRlZFxuICAgKi9cbiAgcmVhZG9ubHkgcm9sZUFybj86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIEFSTiBvZiB0aGUgY3VzdG9tZXItbWFuYWdlZCBLTVMga2V5IGVuY3J5cHRpbmcgdGhlIHNvdXJjZVxuICAgKiAob3JpZ2luYXRpbmctUmVnaW9uKSBTZWN1cml0eSBMYWtlIGJ1Y2tldC4gUmVxdWlyZWQgd2hlbiB0aGUgZW5jbG9zaW5nXG4gICAqIGBTdGFuZGFyZFNlY3VyaXR5TGFrZWAgaXMgY29uZmlndXJlZCB3aXRoIGEgY3VzdG9tZXItbWFuYWdlZCBga21zS2V5SWRgXG4gICAqIGFuZCB0aGlzIGNvbnN0cnVjdCBjcmVhdGVzIHRoZSByZXBsaWNhdGlvbiByb2xlIChpLmUuIHdoZW4gYHJvbGVBcm5gXG4gICAqIGlzIG5vdCBwcm92aWRlZCk7IFMzIG5lZWRzIGBrbXM6RGVjcnlwdGAgb24gdGhpcyBrZXkgdG8gcmVhZCBvYmplY3RzXG4gICAqIGJlZm9yZSByZXBsaWNhdGluZyB0aGVtLiBOb3QgcmVxdWlyZWQgd2hlbiB0aGUgc291cmNlIGJ1Y2tldCB1c2VzXG4gICAqIFMzLW1hbmFnZWQgb3IgQVdTLW1hbmFnZWQgZW5jcnlwdGlvbi5cbiAgICpcbiAgICogVGhpcyBpcyBpbmRlcGVuZGVudCBvZiBgZGVzdGluYXRpb25LbXNLZXlBcm5zYDogU2VjdXJpdHkgTGFrZSByb2xsdXBcbiAgICogUmVnaW9ucyBtYXkgdXNlIHRoZWlyIG93biBlbmNyeXB0aW9uIHNldHRpbmdzLCBzbyBhIENNSyBzb3VyY2UgY2FuXG4gICAqIHJlcGxpY2F0ZSB0byBhbiBTU0UtUzMgcm9sbHVwIGFuZCB2aWNlIHZlcnNhLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIEtNUyBkZWNyeXB0IHN0YXRlbWVudCBpcyBhZGRlZFxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlS21zS2V5QXJuPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgQVJOcyBvZiB0aGUgY3VzdG9tZXItbWFuYWdlZCBLTVMga2V5cyBlbmNyeXB0aW5nIHRoZSBkZXN0aW5hdGlvblxuICAgKiAocm9sbHVwLVJlZ2lvbikgU2VjdXJpdHkgTGFrZSBidWNrZXRzLiBTdXBwbHkgd2hlbiBhbnkgcm9sbHVwIFJlZ2lvbidzXG4gICAqIGJ1Y2tldCB1c2VzIGEgY3VzdG9tZXItbWFuYWdlZCBLTVMga2V5IHNvIHRoZSByZXBsaWNhdGlvbiByb2xlIGNhblxuICAgKiBga21zOkVuY3J5cHRgIC8gYGttczpHZW5lcmF0ZURhdGFLZXlgIGFnYWluc3QgdGhlbS4gTm90IHJlcXVpcmVkIHdoZW5cbiAgICogZXZlcnkgcm9sbHVwIGJ1Y2tldCB1c2VzIFMzLW1hbmFnZWQgb3IgQVdTLW1hbmFnZWQgZW5jcnlwdGlvbi5cbiAgICpcbiAgICogVGhpcyBpcyBpbmRlcGVuZGVudCBvZiBgc291cmNlS21zS2V5QXJuYCBhbmQgdGhlIHNvdXJjZSBsYWtlJ3NcbiAgICogYGttc0tleUlkYC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBLTVMgZW5jcnlwdCBzdGF0ZW1lbnQgaXMgYWRkZWRcbiAgICovXG4gIHJlYWRvbmx5IGRlc3RpbmF0aW9uS21zS2V5QXJucz86IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIFRoZSBBV1MgbG9nIHNvdXJjZXMgYSBzdWJzY3JpYmVyIHNob3VsZCByZWNlaXZlLiBFYWNoIGVudHJ5IG1hcHMgdG8gdGhlXG4gKiBzYW1lIGBzb3VyY2VOYW1lYC9gc291cmNlVmVyc2lvbmAgcGFpciB1c2VkIHdoZW4gZW5hYmxpbmcgdGhlIHNvdXJjZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZWN1cml0eUxha2VTdWJzY3JpYmVyU291cmNlUHJvcHMge1xuICAvKipcbiAgICogVGhlIHNvdXJjZSBuYW1lLCBlLmcuIGBDTE9VRF9UUkFJTF9NR01UYC5cbiAgICovXG4gIHJlYWRvbmx5IHNvdXJjZU5hbWU6IEF3c0xvZ1NvdXJjZU5hbWUgfCBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBzb3VyY2UgdmVyc2lvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSAnMi4wJ1xuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlVmVyc2lvbj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBhIFNlY3VyaXR5IExha2Ugc3Vic2NyaWJlciB3aXRoIFMzLW5vdGlmaWNhdGlvbiBhY2Nlc3MuXG4gKiBPbmx5IHRoZSBgUzNgIGFjY2VzcyB0eXBlIChhc3luY2hyb25vdXMgU1FTIG5vdGlmaWNhdGlvbiBvZiBuZXcgb2JqZWN0cylcbiAqIGlzIG1vZGVsbGVkOyBMYWtlIEZvcm1hdGlvbiBzdWJzY3JpYmVycyBjYW4gYmUgY3JlYXRlZCBkaXJlY3RseSBhZ2FpbnN0XG4gKiB0aGUgdW5kZXJseWluZyBgQ2ZuU3Vic2NyaWJlcmAgTDEuXG4gKlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VjdXJpdHktbGFrZS9sYXRlc3QvdXNlcmd1aWRlL3N1YnNjcmliZXItbWFuYWdlbWVudC5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VjdXJpdHlMYWtlU3Vic2NyaWJlclByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBmcmllbmRseSBuYW1lIG9mIHRoZSBzdWJzY3JpYmVyLlxuICAgKi9cbiAgcmVhZG9ubHkgc3Vic2NyaWJlck5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIEFXUyBhY2NvdW50IGlkIG9mIHRoZSBwcmluY2lwYWwgdGhhdCB3aWxsIGNvbnN1bWUgZGF0YSAodHlwaWNhbGx5XG4gICAqIHRoZSBTSUVNIC8gZG93bnN0cmVhbSBhY2NvdW50IGlkKS5cbiAgICovXG4gIHJlYWRvbmx5IHByaW5jaXBhbDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBFeHRlcm5hbCBpZCB0aGUgc3Vic2NyaWJlciBtdXN0IHByZXNlbnQgd2hlbiBhc3N1bWluZyB0aGVcbiAgICogU2VjdXJpdHktTGFrZS1tYW5hZ2VkIHJvbGUuIFRyZWF0IGFzIGEgc2hhcmVkIHNlY3JldC5cbiAgICovXG4gIHJlYWRvbmx5IGV4dGVybmFsSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogTG9nIHNvdXJjZXMgdGhpcyBzdWJzY3JpYmVyIHJlY2VpdmVzLiBFYWNoIGVudHJ5IG11c3QgY29ycmVzcG9uZCB0byBhXG4gICAqIHNvdXJjZSB0aGF0IGlzIGVuYWJsZWQgb24gdGhlIGRhdGEgbGFrZS5cbiAgICovXG4gIHJlYWRvbmx5IHNvdXJjZXM6IFNlY3VyaXR5TGFrZVN1YnNjcmliZXJTb3VyY2VQcm9wc1tdO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBkZXNjcmlwdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIEhUVFBTIGVuZHBvaW50IGZvciBzdWJzY3JpYmVyIG5vdGlmaWNhdGlvbnMuIElmIG9taXR0ZWQsXG4gICAqIFNlY3VyaXR5IExha2UgY3JlYXRlcyBhbiBTUVMgcXVldWUgaW4gdGhlIGRhdGEtbGFrZSBhY2NvdW50IGFuZFxuICAgKiBub3RpZmllcyB0aGUgc3Vic2NyaWJlciB2aWEgU1FTIG1lc3NhZ2VzIChyZWNvbW1lbmRlZCBkZWZhdWx0IOKAlCB0aGVcbiAgICogU0lFTSBwb2xscyB0aGUgcXVldWUpLlxuICAgKlxuICAgKiBXaGVuIHNldCwge0BsaW5rIGh0dHBzTm90aWZpY2F0aW9uVGFyZ2V0Um9sZUFybn0gaXMgcmVxdWlyZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gU1FTIG5vdGlmaWNhdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgaHR0cHNOb3RpZmljYXRpb25FbmRwb2ludD86IHN0cmluZztcblxuICAvKipcbiAgICogSUFNIHJvbGUgQVJOIEV2ZW50QnJpZGdlIGFzc3VtZXMgdG8gaW52b2tlIHRoZSBIVFRQUyBlbmRwb2ludCB3aGVuXG4gICAqIHtAbGluayBodHRwc05vdGlmaWNhdGlvbkVuZHBvaW50fSBpcyBzZXQuIFRoZSByb2xlIG11c3QgdHJ1c3RcbiAgICogYGV2ZW50cy5hbWF6b25hd3MuY29tYCBhbmQgaGF2ZSBgZXZlbnRzOkludm9rZUFwaURlc3RpbmF0aW9uYFxuICAgKiBwZXJtaXNzaW9ucy4gVGhlIEFXUyBjb25zb2xlIHByb3Zpc2lvbnMgdGhpcyBoZWxwZXIgcm9sZVxuICAgKiBhdXRvbWF0aWNhbGx5IHdoZW4gYSBzdWJzY3JpYmVyIGlzIGNyZWF0ZWQgdGhyb3VnaCB0aGUgVUksIGJ1dCB0aGVcbiAgICogQ2xvdWRGb3JtYXRpb24gLyBBUEkgcGF0aCBkb2VzICoqbm90Kiog4oCUIHNvIGEgZnJlc2ggYWNjb3VudCBtdXN0XG4gICAqIGNyZWF0ZSBhbmQgcGFzcyB0aGlzIHJvbGUgZXhwbGljaXRseSwgb3IgU2VjdXJpdHkgTGFrZSB3aWxsIHJlamVjdFxuICAgKiB0aGUgc3Vic2NyaWJlci1ub3RpZmljYXRpb24gY3JlYXRlIGNhbGwuXG4gICAqXG4gICAqIElnbm9yZWQgd2hlbiB7QGxpbmsgaHR0cHNOb3RpZmljYXRpb25FbmRwb2ludH0gaXMgb21pdHRlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBub25lOyByZXF1aXJlZCB3aGVuIGBodHRwc05vdGlmaWNhdGlvbkVuZHBvaW50YCBpcyBzZXRcbiAgICovXG4gIHJlYWRvbmx5IGh0dHBzTm90aWZpY2F0aW9uVGFyZ2V0Um9sZUFybj86IHN0cmluZztcblxuICAvKipcbiAgICogV2hlbiBzZXQgYW5kIHRoZSBzdWJzY3JpYmVyIHVzZXMgdGhlIGRlZmF1bHQgU1FTIG5vdGlmaWNhdGlvbiBwYXRoLFxuICAgKiB0aGUgY29uc3RydWN0IHBhdGNoZXMgdGhlIFNlY3VyaXR5LUxha2UtbWFuYWdlZCBNYWluLVF1ZXVlJ3NcbiAgICogYFZpc2liaWxpdHlUaW1lb3V0YCBhdHRyaWJ1dGUgdG8gdGhpcyB2YWx1ZSAoc2Vjb25kcykgdmlhIGFuXG4gICAqIGBBd3NDdXN0b21SZXNvdXJjZWAuIE5lZWRlZCBiZWNhdXNlIFNlY3VyaXR5IExha2UgYXV0by1wcm92aXNpb25zXG4gICAqIHRoZSBxdWV1ZSB3aXRoIGEgMzAwcyB2aXNpYmlsaXR5IHRpbWVvdXQsIHdoaWNoIGlzICoqbGVzcyB0aGFuKiogdGhlXG4gICAqIGRlZmF1bHQgYWVzLXNpZW0gZXMtbG9hZGVyIExhbWJkYSB0aW1lb3V0IG9mIDYwMHMsIGNhdXNpbmcgdGhlXG4gICAqIGV2ZW50LXNvdXJjZS1tYXBwaW5nIGNyZWF0ZSB0byBiZSByZWplY3RlZCB3aXRoXG4gICAqIGBcIlRoZSBldmVudCBzb3VyY2UgbWFwcGluZydzIGZ1bmN0aW9uIHRpbWVvdXQgbXVzdCBiZSBzbWFsbGVyIHRoYW5cbiAgICogb3IgZXF1YWwgdG8gdGhlIHF1ZXVlJ3MgdmlzaWJpbGl0eSB0aW1lb3V0XCJgLlxuICAgKlxuICAgKiBTZXQgdG8gYSB2YWx1ZSBgPj1gIHlvdXIgc3Vic2NyaWJlciBMYW1iZGEncyB0aW1lb3V0LiAzNjAwIGlzIGFcbiAgICogc2FmZSBkZWZhdWx0IGZvciBhZXMtc2llbS5cbiAgICpcbiAgICogSWdub3JlZCB3aGVuIHtAbGluayBodHRwc05vdGlmaWNhdGlvbkVuZHBvaW50fSBpcyBzZXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gcGF0Y2g7IHRoZSBxdWV1ZSBrZWVwcyB0aGUgU2VjdXJpdHktTGFrZS1wcm92aXNpb25lZCAzMDBzXG4gICAqL1xuICByZWFkb25seSBzcXNWaXNpYmlsaXR5VGltZW91dFNlY29uZHM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgU3RhbmRhcmRTZWN1cml0eUxha2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhbmRhcmRTZWN1cml0eUxha2VQcm9wcyBleHRlbmRzIEV4dGVuZGVkQ29uc3RydWN0UHJvcHMge1xuICAvKipcbiAgICogVGhlIEtNUyBrZXkgaWQgdG8gdXNlIHRvIGVuY3J5cHQgZGF0YSBzdG9yZWQgYnkgU2VjdXJpdHkgTGFrZS4gVXNlIHRoZVxuICAgKiBsaXRlcmFsIHN0cmluZyBgUzNfTUFOQUdFRF9LRVlgIHRvIHVzZSBTMyBtYW5hZ2VkIGtleXMgKFNTRS1TMykuIE9taXQgdG9cbiAgICogbGV0IFNlY3VyaXR5IExha2UgdXNlIGl0cyBkZWZhdWx0IG1hbmFnZWQga2V5LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFNlY3VyaXR5IExha2UgbWFuYWdlZCBlbmNyeXB0aW9uXG4gICAqL1xuICByZWFkb25seSBrbXNLZXlJZD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIEFSTiBvZiB0aGUgcm9sZSB1c2VkIGJ5IFNlY3VyaXR5IExha2UgdG8gbWFuYWdlIHRoZSBBV1MgR2x1ZVxuICAgKiBtZXRhc3RvcmUuIElmIG9taXR0ZWQsIGEgcm9sZSBpcyBjcmVhdGVkIHdpdGggdGhlXG4gICAqIGBBbWF6b25TZWN1cml0eUxha2VNZXRhc3RvcmVNYW5hZ2VyYCBBV1MgbWFuYWdlZCBwb2xpY3kgYXR0YWNoZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYSByb2xlIGlzIGNyZWF0ZWRcbiAgICovXG4gIHJlYWRvbmx5IG1ldGFTdG9yZU1hbmFnZXJSb2xlQXJuPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSBjdXN0b21lci1tYW5hZ2VkIEtNUyBrZXkgdXNlZCB0byBlbmNyeXB0IFNlY3VyaXR5IExha2VcbiAgICogZGF0YS4gUmVxdWlyZWQgd2hlbiBga21zS2V5SWRgIGlzIHNldCB0byBhIGN1c3RvbWVyLW1hbmFnZWQga2V5IGFuZCB0aGlzXG4gICAqIGNvbnN0cnVjdCBjcmVhdGVzIHRoZSBtZXRhc3RvcmUgbWFuYWdlciByb2xlIChpLmUuIHdoZW5cbiAgICogYG1ldGFTdG9yZU1hbmFnZXJSb2xlQXJuYCBpcyBub3QgcHJvdmlkZWQpLiBUaGUgbWV0YXN0b3JlIG1hbmFnZXJcbiAgICogTGFtYmRhIG11c3QgZGVjcnlwdCBhbmQgKHJlKWVuY3J5cHQgU2VjdXJpdHkgTGFrZSBtZXRhZGF0YTsgdGhlIEFXU1xuICAgKiBtYW5hZ2VkIHBvbGljeSBgQW1hem9uU2VjdXJpdHlMYWtlTWV0YXN0b3JlTWFuYWdlcmAgZG9lcyBub3QgaW5jbHVkZVxuICAgKiBLTVMgcGVybWlzc2lvbnMsIHNvIHdpdGhvdXQgdGhpcyBncmFudCB0aGUgc3RhY2sgZGVwbG95cyBidXQgcGFydGl0aW9uXG4gICAqIHVwZGF0ZXMgYW5kIHN1YnNjcmliZXIgcXVlcmllcyBzaWxlbnRseSBmYWlsLiBOb3QgcmVxdWlyZWQgd2hlblxuICAgKiBga21zS2V5SWRgIGlzIHVuc2V0IG9yIHNldCB0byBgUzNfTUFOQUdFRF9LRVlgLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIEtNUyBzdGF0ZW1lbnQgaXMgYWRkZWQgKHN1ZmZpY2llbnQgd2hlbiB0aGUgZGF0YSBsYWtlXG4gICAqIHVzZXMgU2VjdXJpdHkgTGFrZSBkZWZhdWx0cyBvciBTU0UtUzMpXG4gICAqL1xuICByZWFkb25seSBtZXRhU3RvcmVNYW5hZ2VyS21zS2V5QXJuPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBMaWZlY3ljbGUgY29uZmlndXJhdGlvbiBmb3IgdGhlIFNlY3VyaXR5IExha2UgbWFuYWdlZCBTMyBzdG9yYWdlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFNlY3VyaXR5IExha2UgZGVmYXVsdHNcbiAgICovXG4gIHJlYWRvbmx5IGxpZmVjeWNsZT86IFNlY3VyaXR5TGFrZUxpZmVjeWNsZVByb3BzO1xuXG4gIC8qKlxuICAgKiBSZXBsaWNhdGlvbiBjb25maWd1cmF0aW9uIGZvciB0aGUgU2VjdXJpdHkgTGFrZSBtYW5hZ2VkIFMzIHN0b3JhZ2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gcmVwbGljYXRpb25cbiAgICovXG4gIHJlYWRvbmx5IHJlcGxpY2F0aW9uPzogU2VjdXJpdHlMYWtlUmVwbGljYXRpb25Qcm9wcztcblxuICAvKipcbiAgICogVGhlIEFXUyBuYXRpdmUgbG9nIHNvdXJjZXMgdG8gZW5hYmxlIG9uIHRoZSBkYXRhIGxha2UuIFNvdXJjZXMgYXJlXG4gICAqIGNyZWF0ZWQgc2VxdWVudGlhbGx5IHVzaW5nIGBEZXBlbmRzT25gIGFzIHJlcXVpcmVkIGJ5IFNlY3VyaXR5IExha2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gbG9nIHNvdXJjZXMgYXJlIGVuYWJsZWRcbiAgICovXG4gIHJlYWRvbmx5IGxvZ1NvdXJjZXM/OiBBd3NMb2dTb3VyY2VQcm9wc1tdO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNyZWF0ZSB0aGUgYEFXU1NlcnZpY2VSb2xlRm9yTGFrZUZvcm1hdGlvbkRhdGFBY2Nlc3NgXG4gICAqIHNlcnZpY2UtbGlua2VkIHJvbGUuIFNlY3VyaXR5IExha2UgcmVxdWlyZXMgdGhpcyByb2xlIHRvIGV4aXN0IGluIHRoZVxuICAgKiBhY2NvdW50IGJlZm9yZSBhIGRhdGEgbGFrZSBjYW4gYmUgY3JlYXRlZDsgaG93ZXZlciB0aGUgcm9sZSBpcyBhXG4gICAqIHNpbmdsZXRvbiBwZXIgYWNjb3VudCBhbmQgaXMgZnJlcXVlbnRseSBhdXRvLWNyZWF0ZWQgb24gZmlyc3QgdXNlIG9mXG4gICAqIExha2UgRm9ybWF0aW9uLiBFbmFibGUgdGhpcyBvbmx5IHdoZW4geW91IGtub3cgdGhlIHJvbGUgZG9lcyBub3QgeWV0XG4gICAqIGV4aXN0IGluIHRoZSBhY2NvdW50LCBvdGhlcndpc2Ugc3RhY2sgY3JlYXRpb24gd2lsbCBmYWlsIHdpdGhcbiAgICogYGhhcyBiZWVuIHRha2VuIGluIHRoaXMgYWNjb3VudGAuXG4gICAqXG4gICAqIFRoZSBkYXRhIGxha2Ugd2lsbCBgRGVwZW5kc09uYCB0aGlzIHJvbGUgd2hlbiBpdCBpcyBjcmVhdGVkIHNvIG9yZGVyaW5nXG4gICAqIGlzIGhhbmRsZWQgYXV0b21hdGljYWxseS5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGNyZWF0ZUxha2VGb3JtYXRpb25TZXJ2aWNlTGlua2VkUm9sZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFN1YnNjcmliZXJzIHRoYXQgc2hvdWxkIHJlY2VpdmUgUzMgbm90aWZpY2F0aW9ucyBvZiBuZXcgU2VjdXJpdHkgTGFrZVxuICAgKiBvYmplY3RzLiBFYWNoIGVudHJ5IGNyZWF0ZXMgYW4gYEFXUzo6U2VjdXJpdHlMYWtlOjpTdWJzY3JpYmVyYCAoYWNjZXNzXG4gICAqIHR5cGUgYFMzYCkgcGx1cyBhbiBgQVdTOjpTZWN1cml0eUxha2U6OlN1YnNjcmliZXJOb3RpZmljYXRpb25gLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIHN1YnNjcmliZXJzIGFyZSBjcmVhdGVkXG4gICAqL1xuICByZWFkb25seSBzdWJzY3JpYmVycz86IFNlY3VyaXR5TGFrZVN1YnNjcmliZXJQcm9wc1tdO1xufVxuXG4vKipcbiAqIFN0YW5kYXJkIEFtYXpvbiBTZWN1cml0eSBMYWtlLiBXcmFwcyB0aGUgU2VjdXJpdHkgTGFrZSBMMSBjb25zdHJ1Y3RzIHRvXG4gKiBzdGFuZCB1cCBhIGRhdGEgbGFrZSB3aXRoIGFuIG9wdGlvbmFsIHNldCBvZiBBV1MgbmF0aXZlIGxvZyBzb3VyY2VzXG4gKiBlbmFibGVkLCBhIG1ldGFzdG9yZSBtYW5hZ2VyIHJvbGUsIGxpZmVjeWNsZSBwb2xpY3kgYW5kIHJlcGxpY2F0aW9uLlxuICpcbiAqIFdoZXJlIHRoaXMgY29uc3RydWN0IGRvZXMgbm90IG1lZXQgeW91ciBuZWVkcywgdXNlIHRoZSB1bmRlcmx5aW5nXG4gKiBgQ2ZuRGF0YUxha2VgIGFuZCBgQ2ZuQXdzTG9nU291cmNlYCBjb25zdHJ1Y3RzIGRpcmVjdGx5LlxuICovXG5leHBvcnQgY2xhc3MgU3RhbmRhcmRTZWN1cml0eUxha2UgZXh0ZW5kcyBFeHRlbmRlZENvbnN0cnVjdCB7XG4gIC8qKlxuICAgKiBUaGUgdW5kZXJseWluZyBgQ2ZuRGF0YUxha2VgIHJlc291cmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YUxha2U6IENmbkRhdGFMYWtlO1xuXG4gIC8qKlxuICAgKiBUaGUgSUFNIHJvbGUgdXNlZCBieSBTZWN1cml0eSBMYWtlIHRvIG1hbmFnZSB0aGUgR2x1ZSBtZXRhc3RvcmUuIFdoZW5cbiAgICogYG1ldGFTdG9yZU1hbmFnZXJSb2xlQXJuYCBpcyBwcm92aWRlZCB0aGlzIHdpbGwgYmUgYHVuZGVmaW5lZGAuXG4gICAqL1xuICByZWFkb25seSBtZXRhU3RvcmVNYW5hZ2VyUm9sZT86IFJvbGU7XG5cbiAgLyoqXG4gICAqIFRoZSBJQU0gcm9sZSB1c2VkIGJ5IFNlY3VyaXR5IExha2UgdG8gcmVwbGljYXRlIG9iamVjdHMuIE9ubHkgY3JlYXRlZFxuICAgKiB3aGVuIHJlcGxpY2F0aW9uIGlzIGVuYWJsZWQgYW5kIG5vIGByb2xlQXJuYCB3YXMgc3VwcGxpZWQuXG4gICAqL1xuICByZWFkb25seSByZXBsaWNhdGlvblJvbGU/OiBSb2xlO1xuXG4gIC8qKlxuICAgKiBUaGUgTGFrZSBGb3JtYXRpb24gYEFXU1NlcnZpY2VSb2xlRm9yTGFrZUZvcm1hdGlvbkRhdGFBY2Nlc3NgXG4gICAqIHNlcnZpY2UtbGlua2VkIHJvbGUsIHdoZW4gaXQgd2FzIHByb3Zpc2lvbmVkIGJ5IHRoaXMgY29uc3RydWN0LlxuICAgKi9cbiAgcmVhZG9ubHkgbGFrZUZvcm1hdGlvblNlcnZpY2VMaW5rZWRSb2xlPzogQ2ZuU2VydmljZUxpbmtlZFJvbGU7XG5cbiAgLyoqXG4gICAqIFRoZSBgQ2ZuQXdzTG9nU291cmNlYCByZXNvdXJjZXMgY3JlYXRlZCBieSB0aGlzIGNvbnN0cnVjdCwgaW4gdGhlIG9yZGVyXG4gICAqIHRoZXkgd2VyZSBkZWNsYXJlZC5cbiAgICovXG4gIHJlYWRvbmx5IGxvZ1NvdXJjZXM6IENmbkF3c0xvZ1NvdXJjZVtdID0gW107XG5cbiAgLyoqXG4gICAqIFRoZSBgQ2ZuU3Vic2NyaWJlcmAgcmVzb3VyY2VzIGNyZWF0ZWQgYnkgdGhpcyBjb25zdHJ1Y3QsIGluIHRoZSBvcmRlclxuICAgKiB0aGV5IHdlcmUgZGVjbGFyZWQuXG4gICAqL1xuICByZWFkb25seSBzdWJzY3JpYmVyczogQ2ZuU3Vic2NyaWJlcltdID0gW107XG5cbiAgLyoqXG4gICAqIFRoZSBgQ2ZuU3Vic2NyaWJlck5vdGlmaWNhdGlvbmAgcmVzb3VyY2VzIGNyZWF0ZWQgYnkgdGhpcyBjb25zdHJ1Y3QsXG4gICAqIG9uZSBwZXIgc3Vic2NyaWJlciwgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBkZWNsYXJlZC5cbiAgICovXG4gIHJlYWRvbmx5IHN1YnNjcmliZXJOb3RpZmljYXRpb25zOiBDZm5TdWJzY3JpYmVyTm90aWZpY2F0aW9uW10gPSBbXTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wcz86IFN0YW5kYXJkU2VjdXJpdHlMYWtlUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKTtcblxuICAgIC8vIE9wdGlvbmFsIExha2UgRm9ybWF0aW9uIHNlcnZpY2UtbGlua2VkIHJvbGUuIFNlY3VyaXR5IExha2UgcmVxdWlyZXNcbiAgICAvLyB0aGlzIFNMUiB0byBleGlzdCBpbiB0aGUgYWNjb3VudCBiZWZvcmUgYSBkYXRhIGxha2UgY2FuIGJlIGNyZWF0ZWQuXG4gICAgaWYgKHByb3BzPy5jcmVhdGVMYWtlRm9ybWF0aW9uU2VydmljZUxpbmtlZFJvbGUpIHtcbiAgICAgIHRoaXMubGFrZUZvcm1hdGlvblNlcnZpY2VMaW5rZWRSb2xlID0gbmV3IENmblNlcnZpY2VMaW5rZWRSb2xlKFxuICAgICAgICB0aGlzLFxuICAgICAgICAnTGFrZUZvcm1hdGlvblNlcnZpY2VMaW5rZWRSb2xlJyxcbiAgICAgICAge1xuICAgICAgICAgIGF3c1NlcnZpY2VOYW1lOiAnbGFrZWZvcm1hdGlvbi5hbWF6b25hd3MuY29tJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICdTZXJ2aWNlLWxpbmtlZCByb2xlIHVzZWQgYnkgQVdTIExha2UgRm9ybWF0aW9uIHRvIGFjY2VzcyByZWdpc3RlcmVkIFMzIGxvY2F0aW9ucy4gUmVxdWlyZWQgYnkgQW1hem9uIFNlY3VyaXR5IExha2UuJyxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgICAvLyBUaGUgTGFrZSBGb3JtYXRpb24gU0xSIGlzIGFuIGFjY291bnQgc2luZ2xldG9uIHRoYXQgaXMgZnJlcXVlbnRseVxuICAgICAgLy8gc2hhcmVkIHdpdGggb3RoZXIgc3RhY2tzIGFuZCBjb25zb2xlcy4gUmV0YWluIGl0IG9uXG4gICAgICAvLyBzdGFjay1kZWxldGUvb3B0LW91dCBzbyB0b2dnbGluZyB0aGlzIGZsYWcgb2ZmIChvciByZW1vdmluZyB0aGlzXG4gICAgICAvLyBjb25zdHJ1Y3QpIGRvZXMgbm90IHN0cmlwIExha2UgRm9ybWF0aW9uIGFjY2VzcyBhY2NvdW50LXdpZGUuXG4gICAgICB0aGlzLmxha2VGb3JtYXRpb25TZXJ2aWNlTGlua2VkUm9sZS5hcHBseVJlbW92YWxQb2xpY3koXG4gICAgICAgIFJlbW92YWxQb2xpY3kuUkVUQUlOLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBNZXRhc3RvcmUgbWFuYWdlciByb2xlLlxuICAgIGxldCBtZXRhU3RvcmVNYW5hZ2VyUm9sZUFybiA9IHByb3BzPy5tZXRhU3RvcmVNYW5hZ2VyUm9sZUFybjtcbiAgICBjb25zdCB1c2VzQ3VzdG9tZXJNYW5hZ2VkS2V5ID1cbiAgICAgIHByb3BzPy5rbXNLZXlJZCAhPT0gdW5kZWZpbmVkICYmIHByb3BzLmttc0tleUlkICE9PSAnUzNfTUFOQUdFRF9LRVknO1xuICAgIGlmICghbWV0YVN0b3JlTWFuYWdlclJvbGVBcm4pIHtcbiAgICAgIC8vIFdoZW4gdGhlIGRhdGEgbGFrZSBpcyBlbmNyeXB0ZWQgd2l0aCBhIGN1c3RvbWVyLW1hbmFnZWQgS01TIGtleSxcbiAgICAgIC8vIHRoZSBtZXRhc3RvcmUgbWFuYWdlciBMYW1iZGEgbXVzdCBiZSBhYmxlIHRvIERlY3J5cHQgLyBFbmNyeXB0IC9cbiAgICAgIC8vIEdlbmVyYXRlRGF0YUtleSBhZ2FpbnN0IHRoYXQga2V5LiBUaGUgQVdTIG1hbmFnZWQgcG9saWN5XG4gICAgICAvLyBgQW1hem9uU2VjdXJpdHlMYWtlTWV0YXN0b3JlTWFuYWdlcmAgZG9lcyBOT1QgaW5jbHVkZSBLTVMgYWN0aW9ucyxcbiAgICAgIC8vIHNvIHdpdGhvdXQgdGhpcyBncmFudCBDRk4gZGVwbG95bWVudCBzdWNjZWVkcyBidXQgcGFydGl0aW9uXG4gICAgICAvLyB1cGRhdGVzIGFuZCBzdWJzY3JpYmVyIHF1ZXJpZXMgZmFpbCBhdCBydW50aW1lLiBUaGUga2V5IEFSTiBpc1xuICAgICAgLy8gbm90IGRlcml2YWJsZSBhdCBzeW50aCB0aW1lLCBzbyByZXF1aXJlIHRoZSBjYWxsZXIgdG8gc3VwcGx5IGl0XG4gICAgICAvLyBleHBsaWNpdGx5IHZpYSBgbWV0YVN0b3JlTWFuYWdlckttc0tleUFybmAgb3IgcHJlLXByb3Zpc2lvbiB0aGVpclxuICAgICAgLy8gb3duIG1ldGFzdG9yZSBtYW5hZ2VyIHJvbGUgdmlhIGBtZXRhU3RvcmVNYW5hZ2VyUm9sZUFybmAuXG4gICAgICBpZiAodXNlc0N1c3RvbWVyTWFuYWdlZEtleSAmJiAhcHJvcHM/Lm1ldGFTdG9yZU1hbmFnZXJLbXNLZXlBcm4pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdTdGFuZGFyZFNlY3VyaXR5TGFrZTogYSBjdXN0b21lci1tYW5hZ2VkIGBrbXNLZXlJZGAgcmVxdWlyZXMgJyArXG4gICAgICAgICAgICAnYG1ldGFTdG9yZU1hbmFnZXJLbXNLZXlBcm5gIHNvIHRoZSBnZW5lcmF0ZWQgbWV0YXN0b3JlIG1hbmFnZXIgJyArXG4gICAgICAgICAgICAncm9sZSBjYW4gYmUgZ3JhbnRlZCB0aGUgbmVjZXNzYXJ5IEtNUyBwZXJtaXNzaW9ucy4gJyArXG4gICAgICAgICAgICAnQWx0ZXJuYXRpdmVseSwgcHJlLXByb3Zpc2lvbiB0aGUgbWV0YXN0b3JlIG1hbmFnZXIgcm9sZSAnICtcbiAgICAgICAgICAgICd5b3Vyc2VsZiBhbmQgcGFzcyBpdHMgQVJOIHZpYSBgbWV0YVN0b3JlTWFuYWdlclJvbGVBcm5gLicsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBjb25zdCBtZXRhU3RvcmVJbmxpbmVQb2xpY2llczoge1tuYW1lOiBzdHJpbmddOiBQb2xpY3lEb2N1bWVudH0gPSB7fTtcbiAgICAgIGlmICh1c2VzQ3VzdG9tZXJNYW5hZ2VkS2V5ICYmIHByb3BzPy5tZXRhU3RvcmVNYW5hZ2VyS21zS2V5QXJuKSB7XG4gICAgICAgIG1ldGFTdG9yZUlubGluZVBvbGljaWVzLkFtYXpvblNlY3VyaXR5TGFrZU1ldGFzdG9yZU1hbmFnZXJLbXNQb2xpY3kgPVxuICAgICAgICAgIG5ldyBQb2xpY3lEb2N1bWVudCh7XG4gICAgICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgICAgIHNpZDogJ0FsbG93TWV0YVN0b3JlTWFuYWdlckttc0FjY2VzcycsXG4gICAgICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAgICAgJ2ttczpEZWNyeXB0JyxcbiAgICAgICAgICAgICAgICAgICdrbXM6RW5jcnlwdCcsXG4gICAgICAgICAgICAgICAgICAna21zOkdlbmVyYXRlRGF0YUtleScsXG4gICAgICAgICAgICAgICAgICAna21zOkRlc2NyaWJlS2V5JyxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIHJlc291cmNlczogW3Byb3BzLm1ldGFTdG9yZU1hbmFnZXJLbXNLZXlBcm5dLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICB0aGlzLm1ldGFTdG9yZU1hbmFnZXJSb2xlID0gbmV3IFJvbGUodGhpcywgJ01ldGFTdG9yZU1hbmFnZXJSb2xlJywge1xuICAgICAgICAvLyBUaGUgcGFydGl0aW9uLXVwZGF0ZXIgTGFtYmRhIGZ1bmN0aW9ucyBjcmVhdGVkIGJ5IFNlY3VyaXR5IExha2UgYXJlXG4gICAgICAgIC8vIGhhcmQtY29kZWQgdG8gYXNzdW1lIGEgcm9sZSBuYW1lZFxuICAgICAgICAvLyBgQW1hem9uU2VjdXJpdHlMYWtlTWV0YVN0b3JlTWFuYWdlclYyYCB1bmRlciB0aGUgYC9zZXJ2aWNlLXJvbGUvYFxuICAgICAgICAvLyBwYXRoIGFuZCBkbyBub3QgaG9ub3IgYW4gYXJiaXRyYXJ5IHJvbGUgQVJOLiBXaXRob3V0IGEgbWF0Y2hpbmdcbiAgICAgICAgLy8gcm9sZSBuYW1lLCBDRk4gZGVwbG95bWVudCBhbmQgYENyZWF0ZURhdGFMYWtlYCBzdWNjZWVkIGJ1dCB0aGVcbiAgICAgICAgLy8gcGFydGl0aW9uIHVwZGF0ZXIgc2lsZW50bHkgZmFpbHMgYW5kIHN1YnNjcmliZXJzIGNhbm5vdCBxdWVyeVxuICAgICAgICAvLyByZXBsaWNhdGVkIG9iamVjdHMuIFRoZSByb2xlIG5hbWUgaXMgYWNjb3VudC1nbG9iYWw7IGZvclxuICAgICAgICAvLyBtdWx0aS1SZWdpb24gZGVwbG95cyBpbiB0aGUgc2FtZSBhY2NvdW50IHBhc3NcbiAgICAgICAgLy8gYG1ldGFTdG9yZU1hbmFnZXJSb2xlQXJuYCBmb3IgYWxsIGJ1dCBvbmUgUmVnaW9uLlxuICAgICAgICBwYXRoOiAnL3NlcnZpY2Utcm9sZS8nLFxuICAgICAgICByb2xlTmFtZTogJ0FtYXpvblNlY3VyaXR5TGFrZU1ldGFTdG9yZU1hbmFnZXJWMicsXG4gICAgICAgIGFzc3VtZWRCeTogbmV3IFNlcnZpY2VQcmluY2lwYWwoJ2xhbWJkYS5hbWF6b25hd3MuY29tJyksXG4gICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICdSb2xlIHVzZWQgYnkgQW1hem9uIFNlY3VyaXR5IExha2UgbWV0YXN0b3JlIG1hbmFnZXIgTGFtYmRhIHRvIG1hbmFnZSB0aGUgQVdTIEdsdWUgbWV0YXN0b3JlLicsXG4gICAgICAgIG1hbmFnZWRQb2xpY2llczogW1xuICAgICAgICAgIE1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKFxuICAgICAgICAgICAgJ3NlcnZpY2Utcm9sZS9BbWF6b25TZWN1cml0eUxha2VNZXRhc3RvcmVNYW5hZ2VyJyxcbiAgICAgICAgICApLFxuICAgICAgICBdLFxuICAgICAgICBpbmxpbmVQb2xpY2llczogbWV0YVN0b3JlSW5saW5lUG9saWNpZXMsXG4gICAgICB9KTtcbiAgICAgIG1ldGFTdG9yZU1hbmFnZXJSb2xlQXJuID0gdGhpcy5tZXRhU3RvcmVNYW5hZ2VyUm9sZS5yb2xlQXJuO1xuICAgIH1cblxuICAgIC8vIEVuY3J5cHRpb24gY29uZmlndXJhdGlvbi5cbiAgICBjb25zdCBlbmNyeXB0aW9uQ29uZmlndXJhdGlvbjpcbiAgICAgIHwgQ2ZuRGF0YUxha2UuRW5jcnlwdGlvbkNvbmZpZ3VyYXRpb25Qcm9wZXJ0eVxuICAgICAgfCB1bmRlZmluZWQgPVxuICAgICAgcHJvcHM/Lmttc0tleUlkICE9PSB1bmRlZmluZWQgPyB7a21zS2V5SWQ6IHByb3BzLmttc0tleUlkfSA6IHVuZGVmaW5lZDtcblxuICAgIC8vIExpZmVjeWNsZSBjb25maWd1cmF0aW9uLlxuICAgIGxldCBsaWZlY3ljbGVDb25maWd1cmF0aW9uOlxuICAgICAgfCBDZm5EYXRhTGFrZS5MaWZlY3ljbGVDb25maWd1cmF0aW9uUHJvcGVydHlcbiAgICAgIHwgdW5kZWZpbmVkO1xuICAgIGlmIChwcm9wcz8ubGlmZWN5Y2xlKSB7XG4gICAgICBsaWZlY3ljbGVDb25maWd1cmF0aW9uID0ge1xuICAgICAgICBleHBpcmF0aW9uOlxuICAgICAgICAgIHByb3BzLmxpZmVjeWNsZS5leHBpcmF0aW9uRGF5cyAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IHtkYXlzOiBwcm9wcy5saWZlY3ljbGUuZXhwaXJhdGlvbkRheXN9XG4gICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgdHJhbnNpdGlvbnM6IHByb3BzLmxpZmVjeWNsZS50cmFuc2l0aW9ucz8ubWFwKCh0KSA9PiAoe1xuICAgICAgICAgIGRheXM6IHQuZGF5cyxcbiAgICAgICAgICBzdG9yYWdlQ2xhc3M6IHQuc3RvcmFnZUNsYXNzLFxuICAgICAgICB9KSksXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIFJlcGxpY2F0aW9uIGNvbmZpZ3VyYXRpb24uXG4gICAgbGV0IHJlcGxpY2F0aW9uQ29uZmlndXJhdGlvbjpcbiAgICAgIHwgQ2ZuRGF0YUxha2UuUmVwbGljYXRpb25Db25maWd1cmF0aW9uUHJvcGVydHlcbiAgICAgIHwgdW5kZWZpbmVkO1xuICAgIGlmIChwcm9wcz8ucmVwbGljYXRpb24pIHtcbiAgICAgIGxldCByZXBsaWNhdGlvblJvbGVBcm4gPSBwcm9wcy5yZXBsaWNhdGlvbi5yb2xlQXJuO1xuICAgICAgaWYgKCFyZXBsaWNhdGlvblJvbGVBcm4pIHtcbiAgICAgICAgY29uc3QgYWNjb3VudCA9IFN0YWNrLm9mKHRoaXMpLmFjY291bnQ7XG4gICAgICAgIGNvbnN0IHNvdXJjZVJlZ2lvbiA9IFN0YWNrLm9mKHRoaXMpLnJlZ2lvbjtcbiAgICAgICAgY29uc3QgZGVzdGluYXRpb25SZWdpb25zID0gcHJvcHMucmVwbGljYXRpb24ucmVnaW9ucztcblxuICAgICAgICAvLyBTb3VyY2UgYW5kIGRlc3RpbmF0aW9uIGVuY3J5cHRpb24gYXJlIGluZGVwZW5kZW50IGluIFNlY3VyaXR5XG4gICAgICAgIC8vIExha2U6IGEgQ01LIHNvdXJjZSBjYW4gcmVwbGljYXRlIHRvIGFuIFNTRS1TMyByb2xsdXAgYW5kIHZpY2VcbiAgICAgICAgLy8gdmVyc2EuIEdyYW50IGBrbXM6RGVjcnlwdGAgb24gdGhlIHNvdXJjZSBrZXkgb25seSB3aGVuIHRoZVxuICAgICAgICAvLyBzb3VyY2UgbGFrZSB1c2VzIGEgQ01LLCBhbmQgZ3JhbnQgYGttczpFbmNyeXB0YCAvXG4gICAgICAgIC8vIGBrbXM6R2VuZXJhdGVEYXRhS2V5YCBvbiB0aGUgZGVzdGluYXRpb24ga2V5cyBvbmx5IHdoZW4gYW55XG4gICAgICAgIC8vIHJvbGx1cCBidWNrZXQgdXNlcyBhIENNSy4gVGhlIGtleSBBUk5zIGFyZSBub3QgZGVyaXZhYmxlIGF0XG4gICAgICAgIC8vIHN5bnRoIHRpbWUsIHNvIHJlcXVpcmUgdGhlIGNhbGxlciB0byBzdXBwbHkgdGhlbSBleHBsaWNpdGx5IG9uXG4gICAgICAgIC8vIHRoZSBlbmNyeXB0ZWQgc2lkZSAob3IgcHJlLXByb3Zpc2lvbiB0aGVpciBvd24gcmVwbGljYXRpb24gcm9sZVxuICAgICAgICAvLyB2aWEgYHJlcGxpY2F0aW9uLnJvbGVBcm5gKS5cbiAgICAgICAgaWYgKHVzZXNDdXN0b21lck1hbmFnZWRLZXkgJiYgIXByb3BzLnJlcGxpY2F0aW9uLnNvdXJjZUttc0tleUFybikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICdTdGFuZGFyZFNlY3VyaXR5TGFrZTogYSBjdXN0b21lci1tYW5hZ2VkIGBrbXNLZXlJZGAgd2l0aCAnICtcbiAgICAgICAgICAgICAgJ3JlcGxpY2F0aW9uIHJlcXVpcmVzIGByZXBsaWNhdGlvbi5zb3VyY2VLbXNLZXlBcm5gIHNvIHRoZSAnICtcbiAgICAgICAgICAgICAgJ2dlbmVyYXRlZCByZXBsaWNhdGlvbiByb2xlIGNhbiBga21zOkRlY3J5cHRgIHNvdXJjZSBvYmplY3RzLiAnICtcbiAgICAgICAgICAgICAgJ0lmIGFueSByb2xsdXAgUmVnaW9uIGJ1Y2tldCBpcyBhbHNvIGVuY3J5cHRlZCB3aXRoIGEgJyArXG4gICAgICAgICAgICAgICdjdXN0b21lci1tYW5hZ2VkIGtleSwgcGFzcyBpdHMgQVJOIHZpYSAnICtcbiAgICAgICAgICAgICAgJ2ByZXBsaWNhdGlvbi5kZXN0aW5hdGlvbkttc0tleUFybnNgLiBBbHRlcm5hdGl2ZWx5LCAnICtcbiAgICAgICAgICAgICAgJ3ByZS1wcm92aXNpb24gdGhlIHJlcGxpY2F0aW9uIHJvbGUgeW91cnNlbGYgYW5kIHBhc3MgaXRzIEFSTiAnICtcbiAgICAgICAgICAgICAgJ3ZpYSBgcmVwbGljYXRpb24ucm9sZUFybmAuJyxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qga21zU3RhdGVtZW50czogUG9saWN5U3RhdGVtZW50W10gPSBbXTtcbiAgICAgICAgaWYgKHVzZXNDdXN0b21lck1hbmFnZWRLZXkgJiYgcHJvcHMucmVwbGljYXRpb24uc291cmNlS21zS2V5QXJuKSB7XG4gICAgICAgICAga21zU3RhdGVtZW50cy5wdXNoKFxuICAgICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICAgIHNpZDogJ0FsbG93RGVjcnlwdFNvdXJjZUttc0tleScsXG4gICAgICAgICAgICAgIGFjdGlvbnM6IFsna21zOkRlY3J5cHQnXSxcbiAgICAgICAgICAgICAgcmVzb3VyY2VzOiBbcHJvcHMucmVwbGljYXRpb24uc291cmNlS21zS2V5QXJuXSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHByb3BzLnJlcGxpY2F0aW9uLmRlc3RpbmF0aW9uS21zS2V5QXJucyAmJlxuICAgICAgICAgIHByb3BzLnJlcGxpY2F0aW9uLmRlc3RpbmF0aW9uS21zS2V5QXJucy5sZW5ndGggPiAwXG4gICAgICAgICkge1xuICAgICAgICAgIGttc1N0YXRlbWVudHMucHVzaChcbiAgICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgICBzaWQ6ICdBbGxvd0VuY3J5cHREZXN0aW5hdGlvbkttc0tleXMnLFxuICAgICAgICAgICAgICBhY3Rpb25zOiBbJ2ttczpFbmNyeXB0JywgJ2ttczpHZW5lcmF0ZURhdGFLZXknXSxcbiAgICAgICAgICAgICAgcmVzb3VyY2VzOiBwcm9wcy5yZXBsaWNhdGlvbi5kZXN0aW5hdGlvbkttc0tleUFybnMsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZXBsaWNhdGlvblJvbGUgPSBuZXcgUm9sZSh0aGlzLCAnUmVwbGljYXRpb25Sb2xlJywge1xuICAgICAgICAgIC8vIFNlY3VyaXR5IExha2UgcmVxdWlyZXMgdGhlIHJlcGxpY2F0aW9uIHJvbGUgdG8gbGl2ZSB1bmRlciB0aGVcbiAgICAgICAgICAvLyBzZXJ2aWNlLXJvbGUvIHBhdGggYW5kIHN0YXJ0IHdpdGggYFNlY3VyaXR5TGFrZWAuIElBTSByb2xlIG5hbWVzXG4gICAgICAgICAgLy8gYXJlIGFjY291bnQtZ2xvYmFsLCBzbyBpbmNsdWRlIHRoZSBzb3VyY2UgUmVnaW9uIGluIHRoZSBzdWZmaXggdG9cbiAgICAgICAgICAvLyBhdm9pZCBjb2xsaXNpb25zIHdoZW4gdGhlIGNvbnN0cnVjdCBpcyBkZXBsb3llZCB0byBtdWx0aXBsZVxuICAgICAgICAgIC8vIFJlZ2lvbnMgaW4gdGhlIHNhbWUgYWNjb3VudC5cbiAgICAgICAgICBwYXRoOiAnL3NlcnZpY2Utcm9sZS8nLFxuICAgICAgICAgIHJvbGVOYW1lOiBgU2VjdXJpdHlMYWtlUzNSZXBsaWNhdGlvblJvbGUtJHtzb3VyY2VSZWdpb259YCxcbiAgICAgICAgICAvLyBBbWF6b24gUzMgcGVyZm9ybXMgdGhlIGNyb3NzLVJlZ2lvbiByZXBsaWNhdGlvbiwgc28gaXQgKG5vdCB0aGVcbiAgICAgICAgICAvLyBTZWN1cml0eSBMYWtlIHNlcnZpY2UpIG11c3QgYmUgYWxsb3dlZCB0byBhc3N1bWUgdGhpcyByb2xlLlxuICAgICAgICAgIGFzc3VtZWRCeTogbmV3IFNlcnZpY2VQcmluY2lwYWwoJ3MzLmFtYXpvbmF3cy5jb20nKSxcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICdSb2xlIHVzZWQgYnkgQW1hem9uIFMzIHRvIHJlcGxpY2F0ZSBBbWF6b24gU2VjdXJpdHkgTGFrZSBvYmplY3RzIGFjcm9zcyBSZWdpb25zLicsXG4gICAgICAgICAgLy8gTm8gQVdTIG1hbmFnZWQgcG9saWN5IGV4aXN0cyBmb3IgdGhpcyByb2xlOyBhdHRhY2ggdGhlIGlubGluZVxuICAgICAgICAgIC8vIHBvbGljeSBkb2N1bWVudGVkIGJ5IFNlY3VyaXR5IExha2UuXG4gICAgICAgICAgLy8gaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlY3VyaXR5LWxha2UvbGF0ZXN0L3VzZXJndWlkZS9hZGQtcm9sbHVwLXJlZ2lvbi5odG1sXG4gICAgICAgICAgaW5saW5lUG9saWNpZXM6IHtcbiAgICAgICAgICAgIEFtYXpvblNlY3VyaXR5TGFrZVMzUmVwbGljYXRpb25Sb2xlUG9saWN5OiBuZXcgUG9saWN5RG9jdW1lbnQoe1xuICAgICAgICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICAgICAgICBzaWQ6ICdBbGxvd1JlYWRTM1JlcGxpY2F0aW9uU2V0dGluZycsXG4gICAgICAgICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICAgICAgICdzMzpMaXN0QnVja2V0JyxcbiAgICAgICAgICAgICAgICAgICAgJ3MzOkdldFJlcGxpY2F0aW9uQ29uZmlndXJhdGlvbicsXG4gICAgICAgICAgICAgICAgICAgICdzMzpHZXRPYmplY3RWZXJzaW9uRm9yUmVwbGljYXRpb24nLFxuICAgICAgICAgICAgICAgICAgICAnczM6R2V0T2JqZWN0VmVyc2lvbicsXG4gICAgICAgICAgICAgICAgICAgICdzMzpHZXRPYmplY3RWZXJzaW9uQWNsJyxcbiAgICAgICAgICAgICAgICAgICAgJ3MzOkdldE9iamVjdFZlcnNpb25UYWdnaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgJ3MzOkdldE9iamVjdFJldGVudGlvbicsXG4gICAgICAgICAgICAgICAgICAgICdzMzpHZXRPYmplY3RMZWdhbEhvbGQnLFxuICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICAgICAgICBgYXJuOiR7U3RhY2sub2YodGhpcykucGFydGl0aW9ufTpzMzo6OmF3cy1zZWN1cml0eS1kYXRhLWxha2UtJHtzb3VyY2VSZWdpb259KmAsXG4gICAgICAgICAgICAgICAgICAgIGBhcm46JHtTdGFjay5vZih0aGlzKS5wYXJ0aXRpb259OnMzOjo6YXdzLXNlY3VyaXR5LWRhdGEtbGFrZS0ke3NvdXJjZVJlZ2lvbn0qLypgLFxuICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbnM6IHtcbiAgICAgICAgICAgICAgICAgICAgU3RyaW5nRXF1YWxzOiB7J3MzOlJlc291cmNlQWNjb3VudCc6IFthY2NvdW50XX0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgICAgICAgc2lkOiAnQWxsb3dTM1JlcGxpY2F0aW9uJyxcbiAgICAgICAgICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgICAgICAgICAgJ3MzOlJlcGxpY2F0ZU9iamVjdCcsXG4gICAgICAgICAgICAgICAgICAgICdzMzpSZXBsaWNhdGVEZWxldGUnLFxuICAgICAgICAgICAgICAgICAgICAnczM6UmVwbGljYXRlVGFncycsXG4gICAgICAgICAgICAgICAgICAgICdzMzpHZXRPYmplY3RWZXJzaW9uVGFnZ2luZycsXG4gICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgcmVzb3VyY2VzOiBkZXN0aW5hdGlvblJlZ2lvbnMuZmxhdE1hcCgocikgPT4gW1xuICAgICAgICAgICAgICAgICAgICBgYXJuOiR7U3RhY2sub2YodGhpcykucGFydGl0aW9ufTpzMzo6OmF3cy1zZWN1cml0eS1kYXRhLWxha2UtJHtyfSovKmAsXG4gICAgICAgICAgICAgICAgICBdKSxcbiAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbnM6IHtcbiAgICAgICAgICAgICAgICAgICAgU3RyaW5nRXF1YWxzOiB7J3MzOlJlc291cmNlQWNjb3VudCc6IFthY2NvdW50XX0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIC4uLmttc1N0YXRlbWVudHMsXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgcmVwbGljYXRpb25Sb2xlQXJuID0gdGhpcy5yZXBsaWNhdGlvblJvbGUucm9sZUFybjtcbiAgICAgIH1cbiAgICAgIHJlcGxpY2F0aW9uQ29uZmlndXJhdGlvbiA9IHtcbiAgICAgICAgcmVnaW9uczogcHJvcHMucmVwbGljYXRpb24ucmVnaW9ucyxcbiAgICAgICAgcm9sZUFybjogcmVwbGljYXRpb25Sb2xlQXJuLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLmRhdGFMYWtlID0gbmV3IENmbkRhdGFMYWtlKHRoaXMsICdEYXRhTGFrZScsIHtcbiAgICAgIG1ldGFTdG9yZU1hbmFnZXJSb2xlQXJuLFxuICAgICAgZW5jcnlwdGlvbkNvbmZpZ3VyYXRpb24sXG4gICAgICBsaWZlY3ljbGVDb25maWd1cmF0aW9uLFxuICAgICAgcmVwbGljYXRpb25Db25maWd1cmF0aW9uLFxuICAgIH0pO1xuICAgIGlmICh0aGlzLmxha2VGb3JtYXRpb25TZXJ2aWNlTGlua2VkUm9sZSkge1xuICAgICAgdGhpcy5kYXRhTGFrZS5hZGREZXBlbmRlbmN5KHRoaXMubGFrZUZvcm1hdGlvblNlcnZpY2VMaW5rZWRSb2xlKTtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgQVdTIGxvZyBzb3VyY2VzIHNlcXVlbnRpYWxseSB1c2luZyBEZXBlbmRzT24sIGFzIHJlcXVpcmVkIGJ5XG4gICAgLy8gU2VjdXJpdHkgTGFrZSB3aGVuIG1vcmUgdGhhbiBvbmUgc291cmNlIGlzIGNyZWF0ZWQgaW4gdGhlIHNhbWVcbiAgICAvLyB0ZW1wbGF0ZS5cbiAgICBsZXQgcHJldmlvdXM6IENmbkF3c0xvZ1NvdXJjZSB8IHVuZGVmaW5lZDtcbiAgICBmb3IgKGNvbnN0IHNvdXJjZSBvZiBwcm9wcz8ubG9nU291cmNlcyA/PyBbXSkge1xuICAgICAgY29uc3QgbG9nU291cmNlID0gbmV3IENmbkF3c0xvZ1NvdXJjZShcbiAgICAgICAgdGhpcyxcbiAgICAgICAgYExvZ1NvdXJjZSR7c291cmNlLnNvdXJjZU5hbWV9YCxcbiAgICAgICAge1xuICAgICAgICAgIGRhdGFMYWtlQXJuOiB0aGlzLmRhdGFMYWtlLmF0dHJBcm4sXG4gICAgICAgICAgc291cmNlTmFtZTogc291cmNlLnNvdXJjZU5hbWUsXG4gICAgICAgICAgc291cmNlVmVyc2lvbjogc291cmNlLnNvdXJjZVZlcnNpb24gPz8gJzIuMCcsXG4gICAgICAgICAgYWNjb3VudHM6IHNvdXJjZS5hY2NvdW50cyA/PyBbU3RhY2sub2YodGhpcykuYWNjb3VudF0sXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgICAgbG9nU291cmNlLmFkZERlcGVuZGVuY3kodGhpcy5kYXRhTGFrZSk7XG4gICAgICBpZiAocHJldmlvdXMpIHtcbiAgICAgICAgbG9nU291cmNlLmFkZERlcGVuZGVuY3kocHJldmlvdXMpO1xuICAgICAgfVxuICAgICAgcHJldmlvdXMgPSBsb2dTb3VyY2U7XG4gICAgICB0aGlzLmxvZ1NvdXJjZXMucHVzaChsb2dTb3VyY2UpO1xuICAgIH1cblxuICAgIC8vIFN1YnNjcmliZXJzLiBFYWNoIGVudHJ5IGJlY29tZXMgYSBgQ2ZuU3Vic2NyaWJlcmAgd2l0aCBgYWNjZXNzVHlwZXM6XG4gICAgLy8gWydTMyddYCBwbHVzIGEgc2libGluZyBgQ2ZuU3Vic2NyaWJlck5vdGlmaWNhdGlvbmAuIFRoZSBub3RpZmljYXRpb25cbiAgICAvLyBkZWZhdWx0cyB0byBTUVMgKFNlY3VyaXR5IExha2UgY3JlYXRlcyB0aGUgcXVldWUgaW4gdGhpcyBhY2NvdW50KTtcbiAgICAvLyBjYWxsZXJzIGNhbiBzd2l0Y2ggdG8gSFRUUFMgYnkgcGFzc2luZyBgaHR0cHNOb3RpZmljYXRpb25FbmRwb2ludGAuXG4gICAgZm9yIChjb25zdCBzdWIgb2YgcHJvcHM/LnN1YnNjcmliZXJzID8/IFtdKSB7XG4gICAgICBjb25zdCBzdWJzY3JpYmVyID0gbmV3IENmblN1YnNjcmliZXIoXG4gICAgICAgIHRoaXMsXG4gICAgICAgIGBTdWJzY3JpYmVyJHtzdWIuc3Vic2NyaWJlck5hbWV9YCxcbiAgICAgICAge1xuICAgICAgICAgIGFjY2Vzc1R5cGVzOiBbJ1MzJ10sXG4gICAgICAgICAgZGF0YUxha2VBcm46IHRoaXMuZGF0YUxha2UuYXR0ckFybixcbiAgICAgICAgICBzdWJzY3JpYmVyTmFtZTogc3ViLnN1YnNjcmliZXJOYW1lLFxuICAgICAgICAgIHN1YnNjcmliZXJEZXNjcmlwdGlvbjogc3ViLmRlc2NyaXB0aW9uLFxuICAgICAgICAgIHN1YnNjcmliZXJJZGVudGl0eToge1xuICAgICAgICAgICAgZXh0ZXJuYWxJZDogc3ViLmV4dGVybmFsSWQsXG4gICAgICAgICAgICBwcmluY2lwYWw6IHN1Yi5wcmluY2lwYWwsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzb3VyY2VzOiBzdWIuc291cmNlcy5tYXAoKHMpID0+ICh7XG4gICAgICAgICAgICBhd3NMb2dTb3VyY2U6IHtcbiAgICAgICAgICAgICAgc291cmNlTmFtZTogcy5zb3VyY2VOYW1lLFxuICAgICAgICAgICAgICBzb3VyY2VWZXJzaW9uOiBzLnNvdXJjZVZlcnNpb24gPz8gJzIuMCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pKSxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgICBzdWJzY3JpYmVyLmFkZERlcGVuZGVuY3kodGhpcy5kYXRhTGFrZSk7XG4gICAgICAvLyBTdWJzY3JpYmVyIGNyZWF0aW9uIHJlcXVpcmVzIHRoZSBBd3NMb2dTb3VyY2UgdG8gZXhpc3QgZm9yIGV2ZXJ5XG4gICAgICAvLyBzb3VyY2UgaXQgcmVmZXJlbmNlczsgY2hhaW4gdGhyb3VnaCB0aGUgbGFzdCBsb2cgc291cmNlIHdlIGNyZWF0ZWRcbiAgICAgIC8vIHNvIENGTiB3YWl0cyBmb3IgaW5nZXN0aW9uIHRvIGJlIGVuYWJsZWQuXG4gICAgICBmb3IgKGNvbnN0IGxzIG9mIHRoaXMubG9nU291cmNlcykge1xuICAgICAgICBzdWJzY3JpYmVyLmFkZERlcGVuZGVuY3kobHMpO1xuICAgICAgfVxuICAgICAgdGhpcy5zdWJzY3JpYmVycy5wdXNoKHN1YnNjcmliZXIpO1xuXG4gICAgICBpZiAoXG4gICAgICAgIHN1Yi5odHRwc05vdGlmaWNhdGlvbkVuZHBvaW50ICYmXG4gICAgICAgICFzdWIuaHR0cHNOb3RpZmljYXRpb25UYXJnZXRSb2xlQXJuXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBTdGFuZGFyZFNlY3VyaXR5TGFrZTogc3Vic2NyaWJlciBcIiR7c3ViLnN1YnNjcmliZXJOYW1lfVwiIHNldHMgYCArXG4gICAgICAgICAgICAnYGh0dHBzTm90aWZpY2F0aW9uRW5kcG9pbnRgIGJ1dCBubyAnICtcbiAgICAgICAgICAgICdgaHR0cHNOb3RpZmljYXRpb25UYXJnZXRSb2xlQXJuYC4gVGhlIENsb3VkRm9ybWF0aW9uL0FQSSBwYXRoICcgK1xuICAgICAgICAgICAgJ2RvZXMgbm90IGF1dG8tcHJvdmlzaW9uIHRoZSBFdmVudEJyaWRnZSBpbnZvY2F0aW9uIHJvbGUgKG9ubHkgJyArXG4gICAgICAgICAgICAndGhlIEFXUyBjb25zb2xlIGRvZXMpLiBDcmVhdGUgYSByb2xlIHRydXN0ZWQgYnkgJyArXG4gICAgICAgICAgICAnYGV2ZW50cy5hbWF6b25hd3MuY29tYCB3aXRoIGBldmVudHM6SW52b2tlQXBpRGVzdGluYXRpb25gIG9uICcgK1xuICAgICAgICAgICAgJ3RoZSB0YXJnZXQgZW5kcG9pbnQgYW5kIHBhc3MgaXRzIEFSTiBhcyAnICtcbiAgICAgICAgICAgICdgaHR0cHNOb3RpZmljYXRpb25UYXJnZXRSb2xlQXJuYC4nLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBub3RpZmljYXRpb24gPSBuZXcgQ2ZuU3Vic2NyaWJlck5vdGlmaWNhdGlvbihcbiAgICAgICAgdGhpcyxcbiAgICAgICAgYFN1YnNjcmliZXJOb3RpZmljYXRpb24ke3N1Yi5zdWJzY3JpYmVyTmFtZX1gLFxuICAgICAgICB7XG4gICAgICAgICAgc3Vic2NyaWJlckFybjogc3Vic2NyaWJlci5hdHRyU3Vic2NyaWJlckFybixcbiAgICAgICAgICBub3RpZmljYXRpb25Db25maWd1cmF0aW9uOiBzdWIuaHR0cHNOb3RpZmljYXRpb25FbmRwb2ludFxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgaHR0cHNOb3RpZmljYXRpb25Db25maWd1cmF0aW9uOiB7XG4gICAgICAgICAgICAgICAgICBlbmRwb2ludDogc3ViLmh0dHBzTm90aWZpY2F0aW9uRW5kcG9pbnQsXG4gICAgICAgICAgICAgICAgICB0YXJnZXRSb2xlQXJuOiBzdWIuaHR0cHNOb3RpZmljYXRpb25UYXJnZXRSb2xlQXJuIGFzIHN0cmluZyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IHtcbiAgICAgICAgICAgICAgICBzcXNOb3RpZmljYXRpb25Db25maWd1cmF0aW9uOiB7fSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgICBub3RpZmljYXRpb24uYWRkRGVwZW5kZW5jeShzdWJzY3JpYmVyKTtcbiAgICAgIHRoaXMuc3Vic2NyaWJlck5vdGlmaWNhdGlvbnMucHVzaChub3RpZmljYXRpb24pO1xuXG4gICAgICAvLyBQYXRjaCB0aGUgU2VjdXJpdHktTGFrZS1tYW5hZ2VkIFNRUyBNYWluLVF1ZXVlJ3MgdmlzaWJpbGl0eVxuICAgICAgLy8gdGltZW91dC4gTmVlZGVkIGJlY2F1c2UgU2VjdXJpdHkgTGFrZSBhdXRvLXByb3Zpc2lvbnMgdGhlIHF1ZXVlXG4gICAgICAvLyB3aXRoIDMwMHMsIGxlc3MgdGhhbiB0aGUgYWVzLXNpZW0gZXMtbG9hZGVyIExhbWJkYSB0aW1lb3V0ICg2MDBzXG4gICAgICAvLyBkZWZhdWx0KSwgY2F1c2luZyBldmVudC1zb3VyY2UtbWFwcGluZyBjcmVhdGlvbiB0byBmYWlsIHdpdGhcbiAgICAgIC8vIFwiVGhlIGV2ZW50IHNvdXJjZSBtYXBwaW5nJ3MgZnVuY3Rpb24gdGltZW91dCBtdXN0IGJlIHNtYWxsZXJcbiAgICAgIC8vIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHF1ZXVlJ3MgdmlzaWJpbGl0eSB0aW1lb3V0LlwiXG4gICAgICBpZiAoXG4gICAgICAgICFzdWIuaHR0cHNOb3RpZmljYXRpb25FbmRwb2ludCAmJlxuICAgICAgICBzdWIuc3FzVmlzaWJpbGl0eVRpbWVvdXRTZWNvbmRzICE9PSB1bmRlZmluZWRcbiAgICAgICkge1xuICAgICAgICBjb25zdCB0aW1lb3V0ID0gc3ViLnNxc1Zpc2liaWxpdHlUaW1lb3V0U2Vjb25kcztcbiAgICAgICAgY29uc3Qgc3RhY2sgPSBTdGFjay5vZih0aGlzKTtcbiAgICAgICAgLy8gVGhlIG5vdGlmaWNhdGlvbiByZXNvdXJjZSByZXR1cm5zIHRoZSBxdWV1ZSBBUk4gdmlhXG4gICAgICAgIC8vIGBTdWJzY3JpYmVyRW5kcG9pbnRgLiBDb252ZXJ0IHRvIGEgcXVldWUgVVJMIGZvciB0aGUgU1FTIFNESy5cbiAgICAgICAgLy8gQVJOOiBhcm46PHBhcnRpdGlvbj46c3FzOjxyZWdpb24+OjxhY2NvdW50Pjo8bmFtZT5cbiAgICAgICAgLy8gVVJMOiBodHRwczovL3Nxcy48cmVnaW9uPi48dXJsLXN1ZmZpeD4vPGFjY291bnQ+LzxuYW1lPlxuICAgICAgICAvL1xuICAgICAgICAvLyBUaGUgVVJMIHN1ZmZpeCBpcyBwYXJ0aXRpb24tYXdhcmUgKGBhbWF6b25hd3MuY29tYCxcbiAgICAgICAgLy8gYGFtYXpvbmF3cy5jb20uY25gLCBgYzJzLmljLmdvdmAsIGV0Yy4pOyBoYXJkLWNvZGluZ1xuICAgICAgICAvLyBgYW1hem9uYXdzLmNvbWAgYnJlYWtzIGBhd3MtY25gIGFuZCBHb3ZDbG91ZC4gVXNlIHRoZSBzdGFjaydzXG4gICAgICAgIC8vIGB1cmxTdWZmaXhgIHRva2VuIHNvIENsb3VkRm9ybWF0aW9uIHN1YnN0aXR1dGVzIHRoZSByaWdodFxuICAgICAgICAvLyB2YWx1ZSBhdCBkZXBsb3kgdGltZS5cbiAgICAgICAgY29uc3QgcXVldWVOYW1lID0gRm4uc2VsZWN0KFxuICAgICAgICAgIDUsXG4gICAgICAgICAgRm4uc3BsaXQoJzonLCBub3RpZmljYXRpb24uYXR0clN1YnNjcmliZXJFbmRwb2ludCksXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHF1ZXVlVXJsID0gYGh0dHBzOi8vc3FzLiR7c3RhY2sucmVnaW9ufS4ke3N0YWNrLnVybFN1ZmZpeH0vJHtzdGFjay5hY2NvdW50fS8ke3F1ZXVlTmFtZX1gO1xuICAgICAgICBjb25zdCBwYXRjaCA9IG5ldyBBd3NDdXN0b21SZXNvdXJjZShcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGBTdWJzY3JpYmVyUXVldWVWaXNpYmlsaXR5UGF0Y2gke3N1Yi5zdWJzY3JpYmVyTmFtZX1gLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG9uQ3JlYXRlOiB7XG4gICAgICAgICAgICAgIHNlcnZpY2U6ICdTUVMnLFxuICAgICAgICAgICAgICBhY3Rpb246ICdzZXRRdWV1ZUF0dHJpYnV0ZXMnLFxuICAgICAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAgICAgUXVldWVVcmw6IHF1ZXVlVXJsLFxuICAgICAgICAgICAgICAgIEF0dHJpYnV0ZXM6IHtWaXNpYmlsaXR5VGltZW91dDogdGltZW91dC50b1N0cmluZygpfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcGh5c2ljYWxSZXNvdXJjZUlkOiBQaHlzaWNhbFJlc291cmNlSWQub2YoXG4gICAgICAgICAgICAgICAgYCR7c3ViLnN1YnNjcmliZXJOYW1lfS12aXNpYmlsaXR5LSR7dGltZW91dH1gLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9uVXBkYXRlOiB7XG4gICAgICAgICAgICAgIHNlcnZpY2U6ICdTUVMnLFxuICAgICAgICAgICAgICBhY3Rpb246ICdzZXRRdWV1ZUF0dHJpYnV0ZXMnLFxuICAgICAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAgICAgUXVldWVVcmw6IHF1ZXVlVXJsLFxuICAgICAgICAgICAgICAgIEF0dHJpYnV0ZXM6IHtWaXNpYmlsaXR5VGltZW91dDogdGltZW91dC50b1N0cmluZygpfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcGh5c2ljYWxSZXNvdXJjZUlkOiBQaHlzaWNhbFJlc291cmNlSWQub2YoXG4gICAgICAgICAgICAgICAgYCR7c3ViLnN1YnNjcmliZXJOYW1lfS12aXNpYmlsaXR5LSR7dGltZW91dH1gLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBvbGljeTogQXdzQ3VzdG9tUmVzb3VyY2VQb2xpY3kuZnJvbVN0YXRlbWVudHMoW1xuICAgICAgICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgICAgICBhY3Rpb25zOiBbJ3NxczpTZXRRdWV1ZUF0dHJpYnV0ZXMnXSxcbiAgICAgICAgICAgICAgICAvLyBTY29wZSB0byB0aGUgZXhhY3QgcXVldWUgQVJOIGV4cG9zZWQgYnkgdGhlXG4gICAgICAgICAgICAgICAgLy8gU3Vic2NyaWJlck5vdGlmaWNhdGlvbiByZXNvdXJjZVxuICAgICAgICAgICAgICAgIC8vIChgYXR0clN1YnNjcmliZXJFbmRwb2ludGApLCB3aGljaCBpcyBhbHJlYWR5IGFuIFNRU1xuICAgICAgICAgICAgICAgIC8vIEFSTi4gVXNpbmcgdGhlIHRva2VuIG1lYW5zIENsb3VkRm9ybWF0aW9uIHN1YnN0aXR1dGVzXG4gICAgICAgICAgICAgICAgLy8gdGhlIHJlYWwgcXVldWUgQVJOIGF0IGRlcGxveS10aW1lLCBzbyB0aGUgY3VzdG9tLVxuICAgICAgICAgICAgICAgIC8vIHJlc291cmNlIHJvbGUgY2Fubm90IGJlIGFidXNlZCB0byBtb2RpZnkgdW5yZWxhdGVkXG4gICAgICAgICAgICAgICAgLy8gcXVldWVzIGluIHRoZSBhY2NvdW50LlxuICAgICAgICAgICAgICAgIHJlc291cmNlczogW25vdGlmaWNhdGlvbi5hdHRyU3Vic2NyaWJlckVuZHBvaW50XSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBdKSxcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgICBwYXRjaC5ub2RlLmFkZERlcGVuZGVuY3kobm90aWZpY2F0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export * as aws_patterns_workspaces from './aws-patterns-workspaces/index';
|
|
|
17
17
|
export * as aws_rds from './aws-rds/index';
|
|
18
18
|
export * as aws_route53 from './aws-route53/index';
|
|
19
19
|
export * as aws_s3 from './aws-s3/index';
|
|
20
|
+
export * as aws_securitylake from './aws-securitylake/index';
|
|
20
21
|
export * as aws_ses from './aws-ses/index';
|
|
21
22
|
export * as aws_sqs from './aws-sqs/index';
|
|
22
23
|
export * as aws_ssm from './aws-ssm/index';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.helpers = exports.aws_workspaces = exports.aws_wafv2 = exports.aws_vpc = exports.aws_ssm_patch = exports.aws_ssm_activation = exports.aws_ssm = exports.aws_sqs = exports.aws_ses = exports.aws_s3 = exports.aws_route53 = exports.aws_rds = exports.aws_patterns_workspaces = exports.wordpress = exports.website = exports.domain_redirect = exports.aws_monitoring = exports.aws_lambda = exports.aws_ecs = exports.aws_dynamodb = exports.aws_directory_service = exports.aws_codepipeline = exports.aws_cloudwatch = exports.aws_cloudfront = exports.aws_centergauge = exports.aws_cdk = exports.aws_bedrock = exports.aws_apigatewayv2 = void 0;
|
|
3
|
+
exports.helpers = exports.aws_workspaces = exports.aws_wafv2 = exports.aws_vpc = exports.aws_ssm_patch = exports.aws_ssm_activation = exports.aws_ssm = exports.aws_sqs = exports.aws_ses = exports.aws_securitylake = exports.aws_s3 = exports.aws_route53 = exports.aws_rds = exports.aws_patterns_workspaces = exports.wordpress = exports.website = exports.domain_redirect = exports.aws_monitoring = exports.aws_lambda = exports.aws_ecs = exports.aws_dynamodb = exports.aws_directory_service = exports.aws_codepipeline = exports.aws_cloudwatch = exports.aws_cloudfront = exports.aws_centergauge = exports.aws_cdk = exports.aws_bedrock = exports.aws_apigatewayv2 = void 0;
|
|
4
4
|
exports.aws_apigatewayv2 = require("./aws-apigatewayv2/index");
|
|
5
5
|
exports.aws_bedrock = require("./aws-bedrock/index");
|
|
6
6
|
exports.aws_cdk = require("./aws-cdk/index");
|
|
@@ -20,6 +20,7 @@ exports.aws_patterns_workspaces = require("./aws-patterns-workspaces/index");
|
|
|
20
20
|
exports.aws_rds = require("./aws-rds/index");
|
|
21
21
|
exports.aws_route53 = require("./aws-route53/index");
|
|
22
22
|
exports.aws_s3 = require("./aws-s3/index");
|
|
23
|
+
exports.aws_securitylake = require("./aws-securitylake/index");
|
|
23
24
|
exports.aws_ses = require("./aws-ses/index");
|
|
24
25
|
exports.aws_sqs = require("./aws-sqs/index");
|
|
25
26
|
exports.aws_ssm = require("./aws-ssm/index");
|
|
@@ -29,4 +30,4 @@ exports.aws_vpc = require("./aws-vpc/index");
|
|
|
29
30
|
exports.aws_wafv2 = require("./aws-wafv2/index");
|
|
30
31
|
exports.aws_workspaces = require("./aws-workspaces/index");
|
|
31
32
|
exports.helpers = require("./helpers/index");
|
|
32
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsK0RBQTZEO0FBQzdELHFEQUFtRDtBQUNuRCw2Q0FBMkM7QUFDM0MsNkRBQTJEO0FBQzNELDJEQUF5RDtBQUN6RCwyREFBeUQ7QUFDekQsK0RBQTZEO0FBQzdELHlFQUF1RTtBQUN2RSx1REFBcUQ7QUFDckQsNkNBQTJDO0FBQzNDLG1EQUFpRDtBQUNqRCwyREFBeUQ7QUFDekQsMEVBQXdFO0FBQ3hFLDBEQUF3RDtBQUN4RCw4REFBNEQ7QUFDNUQsNkVBQTJFO0FBQzNFLDZDQUEyQztBQUMzQyxxREFBbUQ7QUFDbkQsMkNBQXlDO0FBQ3pDLCtEQUE2RDtBQUM3RCw2Q0FBMkM7QUFDM0MsNkNBQTJDO0FBQzNDLDZDQUEyQztBQUMzQyxtRUFBaUU7QUFDakUseURBQXVEO0FBQ3ZELDZDQUEyQztBQUMzQyxpREFBK0M7QUFDL0MsMkRBQXlEO0FBQ3pELDZDQUEyQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGFzIGF3c19hcGlnYXRld2F5djIgZnJvbSAnLi9hd3MtYXBpZ2F0ZXdheXYyL2luZGV4JztcbmV4cG9ydCAqIGFzIGF3c19iZWRyb2NrIGZyb20gJy4vYXdzLWJlZHJvY2svaW5kZXgnO1xuZXhwb3J0ICogYXMgYXdzX2NkayBmcm9tICcuL2F3cy1jZGsvaW5kZXgnO1xuZXhwb3J0ICogYXMgYXdzX2NlbnRlcmdhdWdlIGZyb20gJy4vYXdzLWNlbnRlcmdhdWdlL2luZGV4JztcbmV4cG9ydCAqIGFzIGF3c19jbG91ZGZyb250IGZyb20gJy4vYXdzLWNsb3VkZnJvbnQvaW5kZXgnO1xuZXhwb3J0ICogYXMgYXdzX2Nsb3Vkd2F0Y2ggZnJvbSAnLi9hd3MtY2xvdWR3YXRjaC9pbmRleCc7XG5leHBvcnQgKiBhcyBhd3NfY29kZXBpcGVsaW5lIGZyb20gJy4vYXdzLWNvZGVwaXBlbGluZS9pbmRleCc7XG5leHBvcnQgKiBhcyBhd3NfZGlyZWN0b3J5X3NlcnZpY2UgZnJvbSAnLi9hd3MtZGlyZWN0b3J5LXNlcnZpY2UvaW5kZXgnO1xuZXhwb3J0ICogYXMgYXdzX2R5bmFtb2RiIGZyb20gJy4vYXdzLWR5bmFtb2RiL2luZGV4JztcbmV4cG9ydCAqIGFzIGF3c19lY3MgZnJvbSAnLi9hd3MtZWNzL2luZGV4JztcbmV4cG9ydCAqIGFzIGF3c19sYW1iZGEgZnJvbSAnLi9hd3MtbGFtYmRhL2luZGV4JztcbmV4cG9ydCAqIGFzIGF3c19tb25pdG9yaW5nIGZyb20gJy4vYXdzLW1vbml0b3JpbmcvaW5kZXgnO1xuZXhwb3J0ICogYXMgZG9tYWluX3JlZGlyZWN0IGZyb20gJy4vYXdzLXBhdHRlcm5zLWRvbWFpbi1yZWRpcmVjdC9pbmRleCc7XG5leHBvcnQgKiBhcyB3ZWJzaXRlIGZyb20gJy4vYXdzLXBhdHRlcm5zLXdlYnNpdGUvaW5kZXgnO1xuZXhwb3J0ICogYXMgd29yZHByZXNzIGZyb20gJy4vYXdzLXBhdHRlcm5zLXdvcmRwcmVzcy9pbmRleCc7XG5leHBvcnQgKiBhcyBhd3NfcGF0dGVybnNfd29ya3NwYWNlcyBmcm9tICcuL2F3cy1wYXR0ZXJucy13b3Jrc3BhY2VzL2luZGV4JztcbmV4cG9ydCAqIGFzIGF3c19yZHMgZnJvbSAnLi9hd3MtcmRzL2luZGV4JztcbmV4cG9ydCAqIGFzIGF3c19yb3V0ZTUzIGZyb20gJy4vYXdzLXJvdXRlNTMvaW5kZXgnO1xuZXhwb3J0ICogYXMgYXdzX3MzIGZyb20gJy4vYXdzLXMzL2luZGV4JztcbmV4cG9ydCAqIGFzIGF3c19zZWN1cml0eWxha2UgZnJvbSAnLi9hd3Mtc2VjdXJpdHlsYWtlL2luZGV4JztcbmV4cG9ydCAqIGFzIGF3c19zZXMgZnJvbSAnLi9hd3Mtc2VzL2luZGV4JztcbmV4cG9ydCAqIGFzIGF3c19zcXMgZnJvbSAnLi9hd3Mtc3FzL2luZGV4JztcbmV4cG9ydCAqIGFzIGF3c19zc20gZnJvbSAnLi9hd3Mtc3NtL2luZGV4JztcbmV4cG9ydCAqIGFzIGF3c19zc21fYWN0aXZhdGlvbiBmcm9tICcuL2F3cy1zc20tYWN0aXZhdGlvbi9pbmRleCc7XG5leHBvcnQgKiBhcyBhd3Nfc3NtX3BhdGNoIGZyb20gJy4vYXdzLXNzbS1wYXRjaC9pbmRleCc7XG5leHBvcnQgKiBhcyBhd3NfdnBjIGZyb20gJy4vYXdzLXZwYy9pbmRleCc7XG5leHBvcnQgKiBhcyBhd3Nfd2FmdjIgZnJvbSAnLi9hd3Mtd2FmdjIvaW5kZXgnO1xuZXhwb3J0ICogYXMgYXdzX3dvcmtzcGFjZXMgZnJvbSAnLi9hd3Mtd29ya3NwYWNlcy9pbmRleCc7XG5leHBvcnQgKiBhcyBoZWxwZXJzIGZyb20gJy4vaGVscGVycy9pbmRleCc7XG4iXX0=
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "truemark-cdk-lib",
|
|
3
3
|
"description": "AWS CDK constructs created by TrueMark",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.30.0",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"typesVersions": {
|
|
@@ -57,6 +57,9 @@
|
|
|
57
57
|
"aws-s3": [
|
|
58
58
|
"./dist/aws-s3/index.d.ts"
|
|
59
59
|
],
|
|
60
|
+
"aws-securitylake": [
|
|
61
|
+
"./dist/aws-securitylake/index.d.ts"
|
|
62
|
+
],
|
|
60
63
|
"aws-ses": [
|
|
61
64
|
"./dist/aws-ses/index.d.ts"
|
|
62
65
|
],
|
|
@@ -100,7 +103,7 @@
|
|
|
100
103
|
],
|
|
101
104
|
"devDependencies": {
|
|
102
105
|
"@aws-sdk/client-dynamodb": "^3.996.2",
|
|
103
|
-
"@aws-sdk/client-elastic-load-balancing-v2": "
|
|
106
|
+
"@aws-sdk/client-elastic-load-balancing-v2": "3.1050.0",
|
|
104
107
|
"@aws-sdk/util-dynamodb": "^3.996.2",
|
|
105
108
|
"@biomejs/biome": "2.4.5",
|
|
106
109
|
"@opensearch-project/opensearch": "^2.13.0",
|
|
@@ -200,6 +203,10 @@
|
|
|
200
203
|
"types": "./dist/aws-s3/index.d.ts",
|
|
201
204
|
"default": "./dist/aws-s3/index.js"
|
|
202
205
|
},
|
|
206
|
+
"./aws-securitylake": {
|
|
207
|
+
"types": "./dist/aws-securitylake/index.d.ts",
|
|
208
|
+
"default": "./dist/aws-securitylake/index.js"
|
|
209
|
+
},
|
|
203
210
|
"./aws-ses": {
|
|
204
211
|
"types": "./dist/aws-ses/index.d.ts",
|
|
205
212
|
"default": "./dist/aws-ses/index.js"
|