token-injectable-docker-builder 1.13.4 → 2.0.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/lib/builder.js ADDED
@@ -0,0 +1,289 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.TokenInjectableDockerBuilder = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const crypto = require("crypto");
7
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
8
+ const aws_codebuild_1 = require("aws-cdk-lib/aws-codebuild");
9
+ const aws_ecr_1 = require("aws-cdk-lib/aws-ecr");
10
+ const aws_ecs_1 = require("aws-cdk-lib/aws-ecs");
11
+ const aws_iam_1 = require("aws-cdk-lib/aws-iam");
12
+ const aws_kms_1 = require("aws-cdk-lib/aws-kms");
13
+ const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
14
+ const aws_s3_assets_1 = require("aws-cdk-lib/aws-s3-assets");
15
+ const constructs_1 = require("constructs");
16
+ const build_spec_1 = require("./build-spec");
17
+ const constants_1 = require("./constants");
18
+ const ecr_1 = require("./ecr");
19
+ const provider_1 = require("./provider");
20
+ /**
21
+ * A CDK construct to build and push Docker images to an ECR repository using
22
+ * CodeBuild and Lambda custom resources, **then** retrieve the final image tag
23
+ * so that ECS/Lambda references use the exact built image.
24
+ */
25
+ class TokenInjectableDockerBuilder extends constructs_1.Construct {
26
+ constructor(scope, id, props) {
27
+ super(scope, id);
28
+ const { path: sourcePath, buildArgs, dockerLoginSecretArn, vpc, securityGroups, subnetSelection, installCommands, preBuildCommands, kmsEncryption = false, exclude, file: dockerFile, cacheDisabled = false, buildLogGroup, platform = 'linux/amd64', provider, ecrPullThroughCachePrefixes, retainBuildLogs = false, replicaRegions = [], } = props;
29
+ const stack = aws_cdk_lib_1.Stack.of(this);
30
+ this.primaryRegion = stack.region;
31
+ this.accountId = stack.account;
32
+ this.replicaRegions = [...replicaRegions];
33
+ const encryptionKey = kmsEncryption
34
+ ? new aws_kms_1.Key(this, 'EcrEncryptionKey', { enableKeyRotation: true })
35
+ : undefined;
36
+ this.ecrRepository = (0, ecr_1.createBuilderEcrRepository)(this, 'ECRRepository', {
37
+ kmsEncryption,
38
+ encryptionKey,
39
+ });
40
+ const dockerFileName = dockerFile ?? 'Dockerfile';
41
+ const effectiveExclude = (0, build_spec_1.resolveExcludes)(sourcePath, dockerFileName, exclude);
42
+ const sourceAsset = new aws_s3_assets_1.Asset(this, 'SourceAsset', {
43
+ path: sourcePath,
44
+ exclude: effectiveExclude,
45
+ });
46
+ // Deterministic image tag: a hash of every input that materially affects
47
+ // the built image. Stable across synths → no spurious rebuilds, and
48
+ // cross-region SSM exports don't churn between deploys (which used to
49
+ // wedge the CDK CrossRegionExportReader/Writer when a deploy was retried
50
+ // after a rollback).
51
+ const imageTag = crypto.createHash('sha256').update(JSON.stringify({
52
+ assetHash: sourceAsset.assetHash,
53
+ dockerFile: dockerFileName,
54
+ buildArgs: buildArgs ?? {},
55
+ platform,
56
+ installCommands: installCommands ?? [],
57
+ preBuildCommands: preBuildCommands ?? [],
58
+ cacheDisabled,
59
+ dockerLoginSecretArn: dockerLoginSecretArn ?? null,
60
+ ecrPullThroughCachePrefixes: ecrPullThroughCachePrefixes ?? [],
61
+ })).digest('hex');
62
+ const buildSpecObj = (0, build_spec_1.buildBuildSpec)({
63
+ imageTag,
64
+ dockerFile,
65
+ buildArgs,
66
+ dockerLoginSecretArn,
67
+ installCommands,
68
+ preBuildCommands,
69
+ cacheDisabled,
70
+ platform,
71
+ });
72
+ const codeBuildImage = platform === 'linux/arm64'
73
+ ? aws_codebuild_1.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0
74
+ : aws_codebuild_1.LinuxBuildImage.STANDARD_7_0;
75
+ const codeBuildProject = new aws_codebuild_1.Project(this, 'CodeBuildProject', {
76
+ source: aws_codebuild_1.Source.s3({
77
+ bucket: sourceAsset.bucket,
78
+ path: sourceAsset.s3ObjectKey,
79
+ }),
80
+ environment: {
81
+ buildImage: codeBuildImage,
82
+ privileged: true,
83
+ },
84
+ environmentVariables: {
85
+ ECR_REPO_URI: { value: this.ecrRepository.repositoryUri },
86
+ },
87
+ buildSpec: aws_codebuild_1.BuildSpec.fromObject(buildSpecObj),
88
+ ...(buildLogGroup && {
89
+ logging: { cloudWatch: { logGroup: buildLogGroup } },
90
+ }),
91
+ vpc,
92
+ securityGroups,
93
+ subnetSelection,
94
+ });
95
+ this.grantBuildLogsAccess(codeBuildProject, retainBuildLogs);
96
+ this.grantEcrAccess(codeBuildProject);
97
+ this.grantPullThroughCacheAccess(codeBuildProject, ecrPullThroughCachePrefixes);
98
+ if (dockerLoginSecretArn) {
99
+ codeBuildProject.addToRolePolicy(new aws_iam_1.PolicyStatement({
100
+ actions: ['secretsmanager:GetSecretValue'],
101
+ resources: [dockerLoginSecretArn],
102
+ }));
103
+ }
104
+ if (encryptionKey) {
105
+ encryptionKey.grantEncryptDecrypt(codeBuildProject.role);
106
+ }
107
+ const effectiveProvider = provider ?? provider_1.TokenInjectableDockerBuilderProvider.getOrCreate(this);
108
+ effectiveProvider.registerProject(codeBuildProject, this.ecrRepository, encryptionKey);
109
+ if (replicaRegions.length > 0) {
110
+ this.validateReplicaRegions(replicaRegions);
111
+ effectiveProvider.registerReplication(this.ecrRepository.repositoryName, replicaRegions);
112
+ }
113
+ // The CR's construct ID has a "V2" suffix so that a v1-deployed stack
114
+ // upgrading to v2 sees a NEW resource (Replace), not an in-place update
115
+ // of the old `BuildTriggerResource`. CloudFormation forbids modifying a
116
+ // custom resource's `ServiceToken` in-place ("Modifying service token is
117
+ // not allowed."), and the serviceToken changes from v1's per-instance
118
+ // provider to v2's singleton provider. Replace dodges the constraint:
119
+ // the old CR is deleted, and a new one is created with the singleton's
120
+ // serviceToken — at the cost of one fresh build per builder on upgrade.
121
+ const buildTriggerResource = new aws_cdk_lib_1.CustomResource(this, 'BuildTriggerResourceV2', {
122
+ serviceToken: effectiveProvider.serviceToken,
123
+ properties: {
124
+ ProjectName: codeBuildProject.projectName,
125
+ ImageTag: imageTag,
126
+ Trigger: sourceAsset.assetHash,
127
+ RetainBuildLogs: retainBuildLogs ? 'true' : 'false',
128
+ RepositoryName: this.ecrRepository.repositoryName,
129
+ ReplicaRegions: JSON.stringify(replicaRegions),
130
+ },
131
+ });
132
+ buildTriggerResource.node.addDependency(codeBuildProject);
133
+ // SAFETY: reference by tag, not digest. The lifecycle policy above never
134
+ // deletes tagged images, so the digest behind this tag is guaranteed to
135
+ // remain in ECR for the life of the repository.
136
+ const imageTagRef = buildTriggerResource.getAttString('ImageTag');
137
+ this.imageTag = imageTagRef;
138
+ this.repositoryName = this.ecrRepository.repositoryName;
139
+ this.containerImage = aws_ecs_1.ContainerImage.fromEcrRepository(this.ecrRepository, imageTagRef);
140
+ this.dockerImageCode = aws_lambda_1.DockerImageCode.fromEcr(this.ecrRepository, {
141
+ tagOrDigest: imageTagRef,
142
+ });
143
+ }
144
+ /**
145
+ * Format the ECR repository URI for a given region. The region must
146
+ * be either the primary region or one of `replicaRegions`.
147
+ */
148
+ repositoryUriFor(region) {
149
+ this.assertRegionIsKnown(region);
150
+ return `${this.accountId}.dkr.ecr.${region}.amazonaws.com/${this.repositoryName}`;
151
+ }
152
+ /**
153
+ * Import the replicated repository as an ECS-compatible
154
+ * `ContainerImage` in a consumer scope (typically a stack in `region`).
155
+ *
156
+ * The consumer's stack must have `crossRegionReferences: true` when
157
+ * `region` differs from the builder's region.
158
+ */
159
+ containerImageFor(scope, region) {
160
+ return aws_ecs_1.ContainerImage.fromEcrRepository(this.importRepoFor(scope, region), this.imageTag);
161
+ }
162
+ /**
163
+ * Import the replicated repository as a Lambda-compatible
164
+ * `DockerImageCode` in a consumer scope (typically a stack in `region`).
165
+ *
166
+ * The consumer's stack must have `crossRegionReferences: true` when
167
+ * `region` differs from the builder's region.
168
+ */
169
+ dockerImageCodeFor(scope, region) {
170
+ return aws_lambda_1.DockerImageCode.fromEcr(this.importRepoFor(scope, region), {
171
+ tagOrDigest: this.imageTag,
172
+ });
173
+ }
174
+ importRepoFor(scope, region) {
175
+ this.assertRegionIsKnown(region);
176
+ if (region === this.primaryRegion)
177
+ return this.ecrRepository;
178
+ // Include the builder's own node.addr in the import id so two different
179
+ // builders importing the same region into the same scope each get their
180
+ // own Repository child (otherwise the second call would collide with the
181
+ // first and return the wrong builder's repo).
182
+ const importId = `ImportedRepo${region}${this.node.addr}`;
183
+ const existing = scope.node.tryFindChild(importId);
184
+ if (existing)
185
+ return existing;
186
+ return aws_ecr_1.Repository.fromRepositoryAttributes(scope, importId, {
187
+ repositoryName: this.repositoryName,
188
+ repositoryArn: aws_cdk_lib_1.Stack.of(scope).formatArn({
189
+ service: 'ecr',
190
+ resource: 'repository',
191
+ resourceName: this.repositoryName,
192
+ region,
193
+ account: this.accountId,
194
+ }),
195
+ });
196
+ }
197
+ assertRegionIsKnown(region) {
198
+ if (region === this.primaryRegion)
199
+ return;
200
+ if (this.replicaRegions.includes(region))
201
+ return;
202
+ throw new Error(`Region "${region}" is not the primary region (${this.primaryRegion}) ` +
203
+ `or one of the configured replicaRegions (${this.replicaRegions.join(', ') || '<none>'}). ` +
204
+ 'Add the region to the builder\'s replicaRegions prop to make it available.');
205
+ }
206
+ validateReplicaRegions(replicaRegions) {
207
+ const stack = aws_cdk_lib_1.Stack.of(this);
208
+ const primaryPartition = stack.partition;
209
+ for (const region of replicaRegions) {
210
+ if (region === this.primaryRegion) {
211
+ throw new Error(`replicaRegions cannot include the primary region "${this.primaryRegion}". ` +
212
+ 'Remove it from the list.');
213
+ }
214
+ // Partition cannot be cleanly inferred from region alone at synth time
215
+ // (it's a CDK pseudo-parameter and may be a token). We do the best-effort
216
+ // check: if both partition values are concrete and they differ, fail.
217
+ // Cross-partition replication is unsupported by ECR.
218
+ if (!aws_cdk_lib_1.Token.isUnresolved(primaryPartition)) {
219
+ const expectedPartition = inferPartition(region);
220
+ if (expectedPartition && expectedPartition !== primaryPartition) {
221
+ throw new Error('Cross-partition ECR replication is not supported. ' +
222
+ `Primary partition is "${primaryPartition}" but replica region ` +
223
+ `"${region}" appears to be in partition "${expectedPartition}".`);
224
+ }
225
+ }
226
+ }
227
+ }
228
+ grantEcrAccess(project) {
229
+ this.ecrRepository.grantPullPush(project);
230
+ project.addToRolePolicy(new aws_iam_1.PolicyStatement({
231
+ actions: [
232
+ 'ecr:GetAuthorizationToken',
233
+ 'ecr:GetDownloadUrlForLayer',
234
+ 'ecr:BatchCheckLayerAvailability',
235
+ 'ecr:BatchGetImage',
236
+ ],
237
+ resources: ['*'],
238
+ }));
239
+ }
240
+ grantPullThroughCacheAccess(project, prefixes) {
241
+ if (!prefixes || prefixes.length === 0)
242
+ return;
243
+ const stack = aws_cdk_lib_1.Stack.of(this);
244
+ project.addToRolePolicy(new aws_iam_1.PolicyStatement({
245
+ actions: [
246
+ 'ecr:BatchGetImage',
247
+ 'ecr:GetDownloadUrlForLayer',
248
+ 'ecr:BatchCheckLayerAvailability',
249
+ 'ecr:BatchImportUpstreamImage',
250
+ 'ecr:CreateRepository',
251
+ ],
252
+ resources: prefixes.map((prefix) => `arn:aws:ecr:${stack.region}:${stack.account}:repository/${prefix}/*`),
253
+ }));
254
+ }
255
+ grantBuildLogsAccess(project, retainBuildLogs) {
256
+ if (!retainBuildLogs)
257
+ return;
258
+ const stack = aws_cdk_lib_1.Stack.of(this);
259
+ project.addToRolePolicy(new aws_iam_1.PolicyStatement({
260
+ actions: ['logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents'],
261
+ resources: [
262
+ `arn:aws:logs:${stack.region}:${stack.account}:log-group:${constants_1.BUILD_LOG_GROUP_PREFIX}${project.projectName}`,
263
+ `arn:aws:logs:${stack.region}:${stack.account}:log-group:${constants_1.BUILD_LOG_GROUP_PREFIX}${project.projectName}:*`,
264
+ ],
265
+ }));
266
+ }
267
+ }
268
+ exports.TokenInjectableDockerBuilder = TokenInjectableDockerBuilder;
269
+ _a = JSII_RTTI_SYMBOL_1;
270
+ TokenInjectableDockerBuilder[_a] = { fqn: "token-injectable-docker-builder.TokenInjectableDockerBuilder", version: "2.0.0" };
271
+ /**
272
+ * Best-effort partition inference from an AWS region name. Returns
273
+ * undefined if the region doesn't look like a known partition prefix —
274
+ * callers should treat that as "skip the partition check".
275
+ */
276
+ function inferPartition(region) {
277
+ if (region.startsWith('cn-'))
278
+ return 'aws-cn';
279
+ if (region.startsWith('us-gov-'))
280
+ return 'aws-us-gov';
281
+ if (region.startsWith('us-iso-'))
282
+ return 'aws-iso';
283
+ if (region.startsWith('us-isob-'))
284
+ return 'aws-iso-b';
285
+ if (/^[a-z]{2}-[a-z]+-\d+$/.test(region))
286
+ return 'aws';
287
+ return undefined;
288
+ }
289
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsaUNBQWlDO0FBRWpDLDZDQUEyRDtBQUMzRCw2REFNbUM7QUFFbkMsaURBQWlEO0FBQ2pELGlEQUFxRDtBQUNyRCxpREFBc0Q7QUFDdEQsaURBQTBDO0FBQzFDLHVEQUF5RDtBQUV6RCw2REFBa0Q7QUFDbEQsMkNBQXVDO0FBRXZDLDZDQUErRDtBQUMvRCwyQ0FBcUQ7QUFDckQsK0JBQW1EO0FBQ25ELHlDQUFrRTtBQTBLbEU7Ozs7R0FJRztBQUNILE1BQWEsNEJBQTZCLFNBQVEsc0JBQVM7SUFvQnpELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBd0M7UUFDaEYsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLEVBQ0osSUFBSSxFQUFFLFVBQVUsRUFDaEIsU0FBUyxFQUNULG9CQUFvQixFQUNwQixHQUFHLEVBQ0gsY0FBYyxFQUNkLGVBQWUsRUFDZixlQUFlLEVBQ2YsZ0JBQWdCLEVBQ2hCLGFBQWEsR0FBRyxLQUFLLEVBQ3JCLE9BQU8sRUFDUCxJQUFJLEVBQUUsVUFBVSxFQUNoQixhQUFhLEdBQUcsS0FBSyxFQUNyQixhQUFhLEVBQ2IsUUFBUSxHQUFHLGFBQWEsRUFDeEIsUUFBUSxFQUNSLDJCQUEyQixFQUMzQixlQUFlLEdBQUcsS0FBSyxFQUN2QixjQUFjLEdBQUcsRUFBRSxHQUNwQixHQUFHLEtBQUssQ0FBQztRQUVWLE1BQU0sS0FBSyxHQUFHLG1CQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdCLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUNsQyxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDL0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLEdBQUcsY0FBYyxD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QUFDO1lBQ2xCLE9BQU8sRUFBRSxDQUFDLHFCQUFxQixFQUFFLHNCQUFzQixFQUFFLG1CQUFtQixDQUFDO1lBQzdFLFNBQVMsRUFBRTtnQkFDVCxnQkFBZ0IsS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxjQUFjLGtDQUFzQixHQUFHLE9BQU8sQ0FBQyxXQUFXLEVBQUU7Z0JBQ3pHLGdCQUFnQixLQUFLLENBQUMsTUFBTSxJQUFJLEtBQUssQ0FBQyxPQUFPLGNBQWMsa0NBQXNCLEdBQUcsT0FBTyxDQUFDLFdBQVcsSUFBSTthQUM1RztTQUNGLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQzs7QUFoVUgsb0VBaVVDOzs7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyxjQUFjLENBQUMsTUFBYztJQUNwQyxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxRQUFRLENBQUM7SUFDOUMsSUFBSSxNQUFNLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQztRQUFFLE9BQU8sWUFBWSxDQUFDO0lBQ3RELElBQUksTUFBTSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUNuRCxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDO1FBQUUsT0FBTyxXQUFXLENBQUM7SUFDdEQsSUFBSSx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDdkQsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdjcnlwdG8nO1xuXG5pbXBvcnQgeyBDdXN0b21SZXNvdXJjZSwgU3RhY2ssIFRva2VuIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHtcbiAgUHJvamVjdCxcbiAgU291cmNlLFxuICBMaW51eEJ1aWxkSW1hZ2UsXG4gIExpbnV4QXJtQnVpbGRJbWFnZSxcbiAgQnVpbGRTcGVjLFxufSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY29kZWJ1aWxkJztcbmltcG9ydCB7IElWcGMsIElTZWN1cml0eUdyb3VwLCBTdWJuZXRTZWxlY3Rpb24gfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWMyJztcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWNyJztcbmltcG9ydCB7IENvbnRhaW5lckltYWdlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWVjcyc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7IEtleSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1rbXMnO1xuaW1wb3J0IHsgRG9ja2VySW1hZ2VDb2RlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBJTG9nR3JvdXAgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbG9ncyc7XG5pbXBvcnQgeyBBc3NldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMy1hc3NldHMnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5cbmltcG9ydCB7IGJ1aWxkQnVpbGRTcGVjLCByZXNvbHZlRXhjbHVkZXMgfSBmcm9tICcuL2J1aWxkLXNwZWMnO1xuaW1wb3J0IHsgQlVJTERfTE9HX0dST1VQX1BSRUZJWCB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB7IGNyZWF0ZUJ1aWxkZXJFY3JSZXBvc2l0b3J5IH0gZnJvbSAnLi9lY3InO1xuaW1wb3J0IHsgVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlclByb3ZpZGVyIH0gZnJvbSAnLi9wcm92aWRlcic7XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgdGhlIGBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyYCBjb25zdHJ1Y3QuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlclByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBwYXRoIHRvIHRoZSBkaXJlY3RvcnkgY29udGFpbmluZyB0aGUgRG9ja2VyZmlsZSBvciBzb3VyY2UgY29kZS5cbiAgICovXG4gIHJlYWRvbmx5IHBhdGg6IHN0cmluZztcblxuICAvKipcbiAgICogQnVpbGQgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIERvY2tlciBidWlsZCBwcm9jZXNzLlxuICAgKiBUaGVzZSBhcmUgdHJhbnNmb3JtZWQgaW50byBgLS1idWlsZC1hcmcgS0VZPVZBTFVFYCBmbGFncy5cbiAgICogQGV4YW1wbGVcbiAgICoge1xuICAgKiAgIFRPS0VOOiAnbXktc2VjcmV0LXRva2VuJyxcbiAgICogICBFTlY6ICdwcm9kdWN0aW9uJ1xuICAgKiB9XG4gICAqL1xuICByZWFkb25seSBidWlsZEFyZ3M/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuXG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSBBV1MgU2VjcmV0cyBNYW5hZ2VyIHNlY3JldCBjb250YWluaW5nIERvY2tlciBsb2dpbiBjcmVkZW50aWFscy5cbiAgICogVGhlIHNlY3JldCBtdXN0IHN0b3JlIGEgSlNPTiBvYmplY3Q6IGB7XCJ1c2VybmFtZVwiOlwiLi4uXCIsXCJwYXNzd29yZFwiOlwiLi4uXCJ9YC5cbiAgICogTXVzdCBiZSBpbiB0aGUgc2FtZSByZWdpb24gYXMgdGhlIHN0YWNrLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIERvY2tlciBIdWIgbG9naW4uXG4gICAqL1xuICByZWFkb25seSBkb2NrZXJMb2dpblNlY3JldEFybj86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIFZQQyBpbiB3aGljaCB0aGUgQ29kZUJ1aWxkIHByb2plY3Qgd2lsbCBiZSBkZXBsb3llZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBDb2RlQnVpbGQgdXNlcyBwdWJsaWMgaW50ZXJuZXQuXG4gICAqL1xuICByZWFkb25seSB2cGM/OiBJVnBjO1xuXG4gIC8qKlxuICAgKiBTZWN1cml0eSBncm91cHMgYXR0YWNoZWQgdG8gdGhlIENvZGVCdWlsZCBwcm9qZWN0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIHNlY3VyaXR5IGdyb3VwcyBhdHRhY2hlZC5cbiAgICovXG4gIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXBzPzogSVNlY3VyaXR5R3JvdXBbXTtcblxuICAvKipcbiAgICogU3VibmV0IHNlbGVjdGlvbiB3aXRoaW4gdGhlIFZQQy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBBbGwgc3VibmV0cyBpbiB0aGUgVlBDLlxuICAgKi9cbiAgcmVhZG9ubHkgc3VibmV0U2VsZWN0aW9uPzogU3VibmV0U2VsZWN0aW9uO1xuXG4gIC8qKlxuICAgKiBDdXN0b20gY29tbWFuZHMgdG8gcnVuIGR1cmluZyB0aGUgaW5zdGFsbCBwaGFzZSBvZiBDb2RlQnVpbGQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gYWRkaXRpb25hbCBpbnN0YWxsIGNvbW1hbmRzLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5zdGFsbENvbW1hbmRzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBjb21tYW5kcyB0byBydW4gZHVyaW5nIHRoZSBwcmVfYnVpbGQgcGhhc2Ugb2YgQ29kZUJ1aWxkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGFkZGl0aW9uYWwgcHJlLWJ1aWxkIGNvbW1hbmRzLlxuICAgKi9cbiAgcmVhZG9ubHkgcHJlQnVpbGRDb21tYW5kcz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGVuYWJsZSBLTVMgZW5jcnlwdGlvbiBmb3IgdGhlIEVDUiByZXBvc2l0b3J5LlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkga21zRW5jcnlwdGlvbj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEZpbGUgcGF0aHMgaW4gdGhlIERvY2tlciBkaXJlY3RvcnkgdG8gZXhjbHVkZSBmcm9tIHRoZSBidWlsZCBhc3NldC5cbiAgICogRmFsbHMgYmFjayB0byBgLmRvY2tlcmlnbm9yZWAgaWYgcHJlc2VudC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBmaWxlIHBhdGggZXhjbHVzaW9ucy5cbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGU/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogTmFtZSBvZiB0aGUgRG9ja2VyZmlsZSAocGFzc2VkIGFzIGAtZmApLlxuICAgKlxuICAgKiBAZXhhbXBsZSAnRG9ja2VyZmlsZS5wcm9kdWN0aW9uJ1xuICAgKiBAZGVmYXVsdCAnRG9ja2VyZmlsZSdcbiAgICovXG4gIHJlYWRvbmx5IGZpbGU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZW4gYHRydWVgLCBkaXNhYmxlcyBEb2NrZXIgbGF5ZXIgY2FjaGluZy5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGNhY2hlRGlzYWJsZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDbG91ZFdhdGNoIGxvZyBncm91cCBmb3IgQ29kZUJ1aWxkIGJ1aWxkIGxvZ3MuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQ29kZUJ1aWxkIGRlZmF1bHQgbG9nZ2luZy5cbiAgICovXG4gIHJlYWRvbmx5IGJ1aWxkTG9nR3JvdXA/OiBJTG9nR3JvdXA7XG5cbiAgLyoqXG4gICAqIFRhcmdldCBwbGF0Zm9ybSBmb3IgdGhlIERvY2tlciBpbWFnZS5cbiAgICpcbiAgICogQGRlZmF1bHQgJ2xpbnV4L2FtZDY0J1xuICAgKi9cbiAgcmVhZG9ubHkgcGxhdGZvcm0/OiAnbGludXgvYW1kNjQnIHwgJ2xpbnV4L2FybTY0JztcblxuICAvKipcbiAgICogU2hhcmVkIHByb3ZpZGVyIGZvciB0aGUgY3VzdG9tIHJlc291cmNlIExhbWJkYXMuXG4gICAqXG4gICAqIFBhc3MgYFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXJQcm92aWRlci5nZXRPckNyZWF0ZSh0aGlzLCB7IHF1ZXJ5SW50ZXJ2YWwgfSlgXG4gICAqIGlmIHlvdSBuZWVkIGEgbm9uLWRlZmF1bHQgcXVlcnkgaW50ZXJ2YWwuIE90aGVyd2lzZSwgdGhlIGNvbnN0cnVjdCB3aWxsXG4gICAqIGNhbGwgYGdldE9yQ3JlYXRlKHRoaXMpYCBpdHNlbGYgYW5kIHJldXNlIHRoZSBwZXItc3RhY2sgc2luZ2xldG9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFBlci1zdGFjayBzaW5nbGV0b24gcHJvdmlkZXIsIGNyZWF0ZWQgb24gZmlyc3QgdXNlLlxuICAgKi9cbiAgcmVhZG9ubHkgcHJvdmlkZXI/OiBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyUHJvdmlkZXI7XG5cbiAgLyoqXG4gICAqIEVDUiBwdWxsLXRocm91Z2ggY2FjaGUgcmVwb3NpdG9yeSBwcmVmaXhlcyB0byBncmFudCBwdWxsIGFjY2VzcyB0by5cbiAgICpcbiAgICogQGV4YW1wbGUgWydkb2NrZXItaHViJywgJ2doY3InXVxuICAgKiBAZGVmYXVsdCAtIE5vIHB1bGwtdGhyb3VnaCBjYWNoZSBhY2Nlc3MuXG4gICAqL1xuICByZWFkb25seSBlY3JQdWxsVGhyb3VnaENhY2hlUHJlZml4ZXM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogV2hlbiBgdHJ1ZWAsIGNyZWF0ZXMgYSBDbG91ZFdhdGNoIGxvZyBncm91cCBvdXRzaWRlIG9mIENsb3VkRm9ybWF0aW9uXG4gICAqIChgL2RvY2tlci1idWlsZGVyLzxwcm9qZWN0TmFtZT5gKSBhbmQgZGlyZWN0cyBDb2RlQnVpbGQgb3V0cHV0IHRoZXJlLlxuICAgKiBTdXJ2aXZlcyBzdGFjayByb2xsYmFja3MgZm9yIGRlYnVnZ2luZy4gNy1kYXkgcmV0ZW50aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgcmV0YWluQnVpbGRMb2dzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCBBV1MgcmVnaW9ucyB0byByZXBsaWNhdGUgdGhlIGJ1aWx0IGltYWdlIHRvIHZpYSBFQ1Inc1xuICAgKiBuYXRpdmUgcmVnaXN0cnkgcmVwbGljYXRpb24uIFRoZSBpbWFnZSBpcyBwdXNoZWQgdG8gdGhlIHByaW1hcnlcbiAgICogcmVnaW9uJ3MgRUNSIGFzIHVzdWFsOyBFQ1IgYXN5bmNocm9ub3VzbHkgcmVwbGljYXRlcyB0aGUgc2FtZVxuICAgKiBgcmVwb3NpdG9yeU5hbWVgICsgYGltYWdlVGFnYCB0byBlYWNoIHJlZ2lvbiBsaXN0ZWQgaGVyZS5cbiAgICpcbiAgICogQ29uc3VtZXJzIGluIGFub3RoZXIgcmVnaW9uIChhIExhbWJkYSBpbiBgdXMtd2VzdC0yYCByZWZlcmVuY2luZyBhblxuICAgKiBpbWFnZSBidWlsdCBpbiBgdXMtZWFzdC0xYCkgY2FuIHVzZSBgZG9ja2VySW1hZ2VDb2RlRm9yKHJlZ2lvbilgIG9yXG4gICAqIGBjb250YWluZXJJbWFnZUZvcihyZWdpb24pYCB0byBpbXBvcnQgdGhlIHJlcGxpY2F0ZWQgaW1hZ2UuXG4gICAqXG4gICAqIFRoZSBjdXN0b20gcmVzb3VyY2Ugd2FpdHMgZm9yIHJlcGxpY2F0aW9uIHRvIGNvbXBsZXRlIGJlZm9yZVxuICAgKiBzaWduYWxsaW5nIGRlcGxveS1jb21wbGV0ZSwgc28gZG93bnN0cmVhbSBzdGFja3MgY2FuIHNhZmVseSBkZXBsb3lcbiAgICogaW1tZWRpYXRlbHkgYWZ0ZXIuXG4gICAqXG4gICAqICoqQ2F2ZWF0czoqKlxuICAgKiAtIENyb3NzLXJlZ2lvbiByZXBsaWNhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIGJldHdlZW4gQVdTIHBhcnRpdGlvbnMuXG4gICAqIC0gUmVwbGljYXMgZG8gKipub3QqKiBpbmhlcml0IHRoZSBwcmltYXJ5J3MgZW5jcnlwdGlvbiAoZGVmYXVsdHMgdG9cbiAgICogICBBRVMtMjU2KSwgbGlmZWN5Y2xlIHBvbGljaWVzLCBvciByZXBvc2l0b3J5IHBvbGljaWVzLlxuICAgKiAtIFJlcGxpY2F0ZWQgcmVwb3NpdG9yaWVzIHBlcnNpc3Qgb24gc3RhY2sgZGVsZXRpb24g4oCUIEFXUyBkb2VzIG5vdFxuICAgKiAgIGF1dG8tZGVsZXRlIHRoZW0uIENsZWFuIHVwIG1hbnVhbGx5IHZpYSB0aGUgRUNSIGNvbnNvbGUgLyBDTEkgaWZcbiAgICogICBuZWVkZWQuXG4gICAqIC0gQm90aCB0aGUgYnVpbGRlciBzdGFjayBhbmQgYW55IGNvbnN1bWVyIHN0YWNrIGluIGFub3RoZXIgcmVnaW9uXG4gICAqICAgbXVzdCBzZXQgYGNyb3NzUmVnaW9uUmVmZXJlbmNlczogdHJ1ZWAgZm9yIHRoZSBpbWFnZSB0YWcgdG8gZmxvdy5cbiAgICogLSBTdGFja3MgbXVzdCBoYXZlIGEgY29uY3JldGUgcmVnaW9uIChgZW52OiB7IGFjY291bnQsIHJlZ2lvbiB9YCksXG4gICAqICAgbm90IHRoZSBlbnYtYWdub3N0aWMgZGVmYXVsdC5cbiAgICpcbiAgICogQGV4YW1wbGUgWyd1cy13ZXN0LTInLCAnZXUtd2VzdC0xJ11cbiAgICogQGRlZmF1bHQgW10gLSBubyByZXBsaWNhdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgcmVwbGljYVJlZ2lvbnM/OiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBBIENESyBjb25zdHJ1Y3QgdG8gYnVpbGQgYW5kIHB1c2ggRG9ja2VyIGltYWdlcyB0byBhbiBFQ1IgcmVwb3NpdG9yeSB1c2luZ1xuICogQ29kZUJ1aWxkIGFuZCBMYW1iZGEgY3VzdG9tIHJlc291cmNlcywgKip0aGVuKiogcmV0cmlldmUgdGhlIGZpbmFsIGltYWdlIHRhZ1xuICogc28gdGhhdCBFQ1MvTGFtYmRhIHJlZmVyZW5jZXMgdXNlIHRoZSBleGFjdCBidWlsdCBpbWFnZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXIgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKiogVGhlIEVDUiByZXBvc2l0b3J5IHRoYXQgc3RvcmVzIHRoZSByZXN1bHRpbmcgRG9ja2VyIGltYWdlLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGVjclJlcG9zaXRvcnk6IFJlcG9zaXRvcnk7XG5cbiAgLyoqIEVDUy1jb21wYXRpYmxlIGNvbnRhaW5lciBpbWFnZSByZWZlcmVuY2UgKHByaW1hcnkgcmVnaW9uKS4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGNvbnRhaW5lckltYWdlOiBDb250YWluZXJJbWFnZTtcblxuICAvKiogTGFtYmRhLWNvbXBhdGlibGUgRG9ja2VySW1hZ2VDb2RlIHJlZmVyZW5jZSAocHJpbWFyeSByZWdpb24pLiAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZG9ja2VySW1hZ2VDb2RlOiBEb2NrZXJJbWFnZUNvZGU7XG5cbiAgLyoqIFRoZSBFQ1IgcmVwb3NpdG9yeSBuYW1lIOKAlCBwcmVzZXJ2ZWQgYWNyb3NzIHJlcGxpY2EgcmVnaW9ucy4gKi9cbiAgcHVibGljIHJlYWRvbmx5IHJlcG9zaXRvcnlOYW1lOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSByZXNvbHZlZCBpbWFnZSB0YWcgKENGTiB0b2tlbjsgYXZhaWxhYmxlIGF0IGRlcGxveSB0aW1lKS4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGltYWdlVGFnOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBwcmltYXJ5UmVnaW9uOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgYWNjb3VudElkOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVwbGljYVJlZ2lvbnM6IHN0cmluZ1tdO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3Qge1xuICAgICAgcGF0aDogc291cmNlUGF0aCxcbiAgICAgIGJ1aWxkQXJncyxcbiAgICAgIGRvY2tlckxvZ2luU2VjcmV0QXJuLFxuICAgICAgdnBjLFxuICAgICAgc2VjdXJpdHlHcm91cHMsXG4gICAgICBzdWJuZXRTZWxlY3Rpb24sXG4gICAgICBpbnN0YWxsQ29tbWFuZHMsXG4gICAgICBwcmVCdWlsZENvbW1hbmRzLFxuICAgICAga21zRW5jcnlwdGlvbiA9IGZhbHNlLFxuICAgICAgZXhjbHVkZSxcbiAgICAgIGZpbGU6IGRvY2tlckZpbGUsXG4gICAgICBjYWNoZURpc2FibGVkID0gZmFsc2UsXG4gICAgICBidWlsZExvZ0dyb3VwLFxuICAgICAgcGxhdGZvcm0gPSAnbGludXgvYW1kNjQnLFxuICAgICAgcHJvdmlkZXIsXG4gICAgICBlY3JQdWxsVGhyb3VnaENhY2hlUHJlZml4ZXMsXG4gICAgICByZXRhaW5CdWlsZExvZ3MgPSBmYWxzZSxcbiAgICAgIHJlcGxpY2FSZWdpb25zID0gW10sXG4gICAgfSA9IHByb3BzO1xuXG4gICAgY29uc3Qgc3RhY2sgPSBTdGFjay5vZih0aGlzKTtcbiAgICB0aGlzLnByaW1hcnlSZWdpb24gPSBzdGFjay5yZWdpb247XG4gICAgdGhpcy5hY2NvdW50SWQgPSBzdGFjay5hY2NvdW50O1xuICAgIHRoaXMucmVwbGljYVJlZ2lvbnMgPSBbLi4ucmVwbGljYVJlZ2lvbnNdO1xuXG4gICAgY29uc3QgZW5jcnlwdGlvbktleSA9IGttc0VuY3J5cHRpb25cbiAgICAgID8gbmV3IEtleSh0aGlzLCAnRWNyRW5jcnlwdGlvbktleScsIHsgZW5hYmxlS2V5Um90YXRpb246IHRydWUgfSlcbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgdGhpcy5lY3JSZXBvc2l0b3J5ID0gY3JlYXRlQnVpbGRlckVjclJlcG9zaXRvcnkodGhpcywgJ0VDUlJlcG9zaXRvcnknLCB7XG4gICAgICBrbXNFbmNyeXB0aW9uLFxuICAgICAgZW5jcnlwdGlvbktleSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGRvY2tlckZpbGVOYW1lID0gZG9ja2VyRmlsZSA/PyAnRG9ja2VyZmlsZSc7XG4gICAgY29uc3QgZWZmZWN0aXZlRXhjbHVkZSA9IHJlc29sdmVFeGNsdWRlcyhzb3VyY2VQYXRoLCBkb2NrZXJGaWxlTmFtZSwgZXhjbHVkZSk7XG5cbiAgICBjb25zdCBzb3VyY2VBc3NldCA9IG5ldyBBc3NldCh0aGlzLCAnU291cmNlQXNzZXQnLCB7XG4gICAgICBwYXRoOiBzb3VyY2VQYXRoLFxuICAgICAgZXhjbHVkZTogZWZmZWN0aXZlRXhjbHVkZSxcbiAgICB9KTtcblxuICAgIC8vIERldGVybWluaXN0aWMgaW1hZ2UgdGFnOiBhIGhhc2ggb2YgZXZlcnkgaW5wdXQgdGhhdCBtYXRlcmlhbGx5IGFmZmVjdHNcbiAgICAvLyB0aGUgYnVpbHQgaW1hZ2UuIFN0YWJsZSBhY3Jvc3Mgc3ludGhzIOKGkiBubyBzcHVyaW91cyByZWJ1aWxkcywgYW5kXG4gICAgLy8gY3Jvc3MtcmVnaW9uIFNTTSBleHBvcnRzIGRvbid0IGNodXJuIGJldHdlZW4gZGVwbG95cyAod2hpY2ggdXNlZCB0b1xuICAgIC8vIHdlZGdlIHRoZSBDREsgQ3Jvc3NSZWdpb25FeHBvcnRSZWFkZXIvV3JpdGVyIHdoZW4gYSBkZXBsb3kgd2FzIHJldHJpZWRcbiAgICAvLyBhZnRlciBhIHJvbGxiYWNrKS5cbiAgICBjb25zdCBpbWFnZVRhZyA9IGNyeXB0by5jcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUoSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgYXNzZXRIYXNoOiBzb3VyY2VBc3NldC5hc3NldEhhc2gsXG4gICAgICBkb2NrZXJGaWxlOiBkb2NrZXJGaWxlTmFtZSxcbiAgICAgIGJ1aWxkQXJnczogYnVpbGRBcmdzID8/IHt9LFxuICAgICAgcGxhdGZvcm0sXG4gICAgICBpbnN0YWxsQ29tbWFuZHM6IGluc3RhbGxDb21tYW5kcyA/PyBbXSxcbiAgICAgIHByZUJ1aWxkQ29tbWFuZHM6IHByZUJ1aWxkQ29tbWFuZHMgPz8gW10sXG4gICAgICBjYWNoZURpc2FibGVkLFxuICAgICAgZG9ja2VyTG9naW5TZWNyZXRBcm46IGRvY2tlckxvZ2luU2VjcmV0QXJuID8/IG51bGwsXG4gICAgICBlY3JQdWxsVGhyb3VnaENhY2hlUHJlZml4ZXM6IGVjclB1bGxUaHJvdWdoQ2FjaGVQcmVmaXhlcyA/PyBbXSxcbiAgICB9KSkuZGlnZXN0KCdoZXgnKTtcblxuICAgIGNvbnN0IGJ1aWxkU3BlY09iaiA9IGJ1aWxkQnVpbGRTcGVjKHtcbiAgICAgIGltYWdlVGFnLFxuICAgICAgZG9ja2VyRmlsZSxcbiAgICAgIGJ1aWxkQXJncyxcbiAgICAgIGRvY2tlckxvZ2luU2VjcmV0QXJuLFxuICAgICAgaW5zdGFsbENvbW1hbmRzLFxuICAgICAgcHJlQnVpbGRDb21tYW5kcyxcbiAgICAgIGNhY2hlRGlzYWJsZWQsXG4gICAgICBwbGF0Zm9ybSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGNvZGVCdWlsZEltYWdlID0gcGxhdGZvcm0gPT09ICdsaW51eC9hcm02NCdcbiAgICAgID8gTGludXhBcm1CdWlsZEltYWdlLkFNQVpPTl9MSU5VWF8yX1NUQU5EQVJEXzNfMFxuICAgICAgOiBMaW51eEJ1aWxkSW1hZ2UuU1RBTkRBUkRfN18wO1xuXG4gICAgY29uc3QgY29kZUJ1aWxkUHJvamVjdCA9IG5ldyBQcm9qZWN0KHRoaXMsICdDb2RlQnVpbGRQcm9qZWN0Jywge1xuICAgICAgc291cmNlOiBTb3VyY2UuczMoe1xuICAgICAgICBidWNrZXQ6IHNvdXJjZUFzc2V0LmJ1Y2tldCxcbiAgICAgICAgcGF0aDogc291cmNlQXNzZXQuczNPYmplY3RLZXksXG4gICAgICB9KSxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIGJ1aWxkSW1hZ2U6IGNvZGVCdWlsZEltYWdlLFxuICAgICAgICBwcml2aWxlZ2VkOiB0cnVlLFxuICAgICAgfSxcbiAgICAgIGVudmlyb25tZW50VmFyaWFibGVzOiB7XG4gICAgICAgIEVDUl9SRVBPX1VSSTogeyB2YWx1ZTogdGhpcy5lY3JSZXBvc2l0b3J5LnJlcG9zaXRvcnlVcmkgfSxcbiAgICAgIH0sXG4gICAgICBidWlsZFNwZWM6IEJ1aWxkU3BlYy5mcm9tT2JqZWN0KGJ1aWxkU3BlY09iaiksXG4gICAgICAuLi4oYnVpbGRMb2dHcm91cCAmJiB7XG4gICAgICAgIGxvZ2dpbmc6IHsgY2xvdWRXYXRjaDogeyBsb2dHcm91cDogYnVpbGRMb2dHcm91cCB9IH0sXG4gICAgICB9KSxcbiAgICAgIHZwYyxcbiAgICAgIHNlY3VyaXR5R3JvdXBzLFxuICAgICAgc3VibmV0U2VsZWN0aW9uLFxuICAgIH0pO1xuXG4gICAgdGhpcy5ncmFudEJ1aWxkTG9nc0FjY2Vzcyhjb2RlQnVpbGRQcm9qZWN0LCByZXRhaW5CdWlsZExvZ3MpO1xuICAgIHRoaXMuZ3JhbnRFY3JBY2Nlc3MoY29kZUJ1aWxkUHJvamVjdCk7XG4gICAgdGhpcy5ncmFudFB1bGxUaHJvdWdoQ2FjaGVBY2Nlc3MoY29kZUJ1aWxkUHJvamVjdCwgZWNyUHVsbFRocm91Z2hDYWNoZVByZWZpeGVzKTtcblxuICAgIGlmIChkb2NrZXJMb2dpblNlY3JldEFybikge1xuICAgICAgY29kZUJ1aWxkUHJvamVjdC5hZGRUb1JvbGVQb2xpY3koXG4gICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGFjdGlvbnM6IFsnc2VjcmV0c21hbmFnZXI6R2V0U2VjcmV0VmFsdWUnXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFtkb2NrZXJMb2dpblNlY3JldEFybl0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoZW5jcnlwdGlvbktleSkge1xuICAgICAgZW5jcnlwdGlvbktleS5ncmFudEVuY3J5cHREZWNyeXB0KGNvZGVCdWlsZFByb2plY3Qucm9sZSEpO1xuICAgIH1cblxuICAgIGNvbnN0IGVmZmVjdGl2ZVByb3ZpZGVyID0gcHJvdmlkZXIgPz8gVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlclByb3ZpZGVyLmdldE9yQ3JlYXRlKHRoaXMpO1xuICAgIGVmZmVjdGl2ZVByb3ZpZGVyLnJlZ2lzdGVyUHJvamVjdChjb2RlQnVpbGRQcm9qZWN0LCB0aGlzLmVjclJlcG9zaXRvcnksIGVuY3J5cHRpb25LZXkpO1xuXG4gICAgaWYgKHJlcGxpY2FSZWdpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMudmFsaWRhdGVSZXBsaWNhUmVnaW9ucyhyZXBsaWNhUmVnaW9ucyk7XG4gICAgICBlZmZlY3RpdmVQcm92aWRlci5yZWdpc3RlclJlcGxpY2F0aW9uKHRoaXMuZWNyUmVwb3NpdG9yeS5yZXBvc2l0b3J5TmFtZSwgcmVwbGljYVJlZ2lvbnMpO1xuICAgIH1cblxuICAgIC8vIFRoZSBDUidzIGNvbnN0cnVjdCBJRCBoYXMgYSBcIlYyXCIgc3VmZml4IHNvIHRoYXQgYSB2MS1kZXBsb3llZCBzdGFja1xuICAgIC8vIHVwZ3JhZGluZyB0byB2MiBzZWVzIGEgTkVXIHJlc291cmNlIChSZXBsYWNlKSwgbm90IGFuIGluLXBsYWNlIHVwZGF0ZVxuICAgIC8vIG9mIHRoZSBvbGQgYEJ1aWxkVHJpZ2dlclJlc291cmNlYC4gQ2xvdWRGb3JtYXRpb24gZm9yYmlkcyBtb2RpZnlpbmcgYVxuICAgIC8vIGN1c3RvbSByZXNvdXJjZSdzIGBTZXJ2aWNlVG9rZW5gIGluLXBsYWNlIChcIk1vZGlmeWluZyBzZXJ2aWNlIHRva2VuIGlzXG4gICAgLy8gbm90IGFsbG93ZWQuXCIpLCBhbmQgdGhlIHNlcnZpY2VUb2tlbiBjaGFuZ2VzIGZyb20gdjEncyBwZXItaW5zdGFuY2VcbiAgICAvLyBwcm92aWRlciB0byB2MidzIHNpbmdsZXRvbiBwcm92aWRlci4gUmVwbGFjZSBkb2RnZXMgdGhlIGNvbnN0cmFpbnQ6XG4gICAgLy8gdGhlIG9sZCBDUiBpcyBkZWxldGVkLCBhbmQgYSBuZXcgb25lIGlzIGNyZWF0ZWQgd2l0aCB0aGUgc2luZ2xldG9uJ3NcbiAgICAvLyBzZXJ2aWNlVG9rZW4g4oCUIGF0IHRoZSBjb3N0IG9mIG9uZSBmcmVzaCBidWlsZCBwZXIgYnVpbGRlciBvbiB1cGdyYWRlLlxuICAgIGNvbnN0IGJ1aWxkVHJpZ2dlclJlc291cmNlID0gbmV3IEN1c3RvbVJlc291cmNlKHRoaXMsICdCdWlsZFRyaWdnZXJSZXNvdXJjZVYyJywge1xuICAgICAgc2VydmljZVRva2VuOiBlZmZlY3RpdmVQcm92aWRlci5zZXJ2aWNlVG9rZW4sXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIFByb2plY3ROYW1lOiBjb2RlQnVpbGRQcm9qZWN0LnByb2plY3ROYW1lLFxuICAgICAgICBJbWFnZVRhZzogaW1hZ2VUYWcsXG4gICAgICAgIFRyaWdnZXI6IHNvdXJjZUFzc2V0LmFzc2V0SGFzaCxcbiAgICAgICAgUmV0YWluQnVpbGRMb2dzOiByZXRhaW5CdWlsZExvZ3MgPyAndHJ1ZScgOiAnZmFsc2UnLFxuICAgICAgICBSZXBvc2l0b3J5TmFtZTogdGhpcy5lY3JSZXBvc2l0b3J5LnJlcG9zaXRvcnlOYW1lLFxuICAgICAgICBSZXBsaWNhUmVnaW9uczogSlNPTi5zdHJpbmdpZnkocmVwbGljYVJlZ2lvbnMpLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBidWlsZFRyaWdnZXJSZXNvdXJjZS5ub2RlLmFkZERlcGVuZGVuY3koY29kZUJ1aWxkUHJvamVjdCk7XG5cbiAgICAvLyBTQUZFVFk6IHJlZmVyZW5jZSBieSB0YWcsIG5vdCBkaWdlc3QuIFRoZSBsaWZlY3ljbGUgcG9saWN5IGFib3ZlIG5ldmVyXG4gICAgLy8gZGVsZXRlcyB0YWdnZWQgaW1hZ2VzLCBzbyB0aGUgZGlnZXN0IGJlaGluZCB0aGlzIHRhZyBpcyBndWFyYW50ZWVkIHRvXG4gICAgLy8gcmVtYWluIGluIEVDUiBmb3IgdGhlIGxpZmUgb2YgdGhlIHJlcG9zaXRvcnkuXG4gICAgY29uc3QgaW1hZ2VUYWdSZWYgPSBidWlsZFRyaWdnZXJSZXNvdXJjZS5nZXRBdHRTdHJpbmcoJ0ltYWdlVGFnJyk7XG4gICAgdGhpcy5pbWFnZVRhZyA9IGltYWdlVGFnUmVmO1xuICAgIHRoaXMucmVwb3NpdG9yeU5hbWUgPSB0aGlzLmVjclJlcG9zaXRvcnkucmVwb3NpdG9yeU5hbWU7XG4gICAgdGhpcy5jb250YWluZXJJbWFnZSA9IENvbnRhaW5lckltYWdlLmZyb21FY3JSZXBvc2l0b3J5KHRoaXMuZWNyUmVwb3NpdG9yeSwgaW1hZ2VUYWdSZWYpO1xuICAgIHRoaXMuZG9ja2VySW1hZ2VDb2RlID0gRG9ja2VySW1hZ2VDb2RlLmZyb21FY3IodGhpcy5lY3JSZXBvc2l0b3J5LCB7XG4gICAgICB0YWdPckRpZ2VzdDogaW1hZ2VUYWdSZWYsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRm9ybWF0IHRoZSBFQ1IgcmVwb3NpdG9yeSBVUkkgZm9yIGEgZ2l2ZW4gcmVnaW9uLiBUaGUgcmVnaW9uIG11c3RcbiAgICogYmUgZWl0aGVyIHRoZSBwcmltYXJ5IHJlZ2lvbiBvciBvbmUgb2YgYHJlcGxpY2FSZWdpb25zYC5cbiAgICovXG4gIHB1YmxpYyByZXBvc2l0b3J5VXJpRm9yKHJlZ2lvbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICB0aGlzLmFzc2VydFJlZ2lvbklzS25vd24ocmVnaW9uKTtcbiAgICByZXR1cm4gYCR7dGhpcy5hY2NvdW50SWR9LmRrci5lY3IuJHtyZWdpb259LmFtYXpvbmF3cy5jb20vJHt0aGlzLnJlcG9zaXRvcnlOYW1lfWA7XG4gIH1cblxuICAvKipcbiAgICogSW1wb3J0IHRoZSByZXBsaWNhdGVkIHJlcG9zaXRvcnkgYXMgYW4gRUNTLWNvbXBhdGlibGVcbiAgICogYENvbnRhaW5lckltYWdlYCBpbiBhIGNvbnN1bWVyIHNjb3BlICh0eXBpY2FsbHkgYSBzdGFjayBpbiBgcmVnaW9uYCkuXG4gICAqXG4gICAqIFRoZSBjb25zdW1lcidzIHN0YWNrIG11c3QgaGF2ZSBgY3Jvc3NSZWdpb25SZWZlcmVuY2VzOiB0cnVlYCB3aGVuXG4gICAqIGByZWdpb25gIGRpZmZlcnMgZnJvbSB0aGUgYnVpbGRlcidzIHJlZ2lvbi5cbiAgICovXG4gIHB1YmxpYyBjb250YWluZXJJbWFnZUZvcihzY29wZTogQ29uc3RydWN0LCByZWdpb246IHN0cmluZyk6IENvbnRhaW5lckltYWdlIHtcbiAgICByZXR1cm4gQ29udGFpbmVySW1hZ2UuZnJvbUVjclJlcG9zaXRvcnkoXG4gICAgICB0aGlzLmltcG9ydFJlcG9Gb3Ioc2NvcGUsIHJlZ2lvbiksXG4gICAgICB0aGlzLmltYWdlVGFnLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogSW1wb3J0IHRoZSByZXBsaWNhdGVkIHJlcG9zaXRvcnkgYXMgYSBMYW1iZGEtY29tcGF0aWJsZVxuICAgKiBgRG9ja2VySW1hZ2VDb2RlYCBpbiBhIGNvbnN1bWVyIHNjb3BlICh0eXBpY2FsbHkgYSBzdGFjayBpbiBgcmVnaW9uYCkuXG4gICAqXG4gICAqIFRoZSBjb25zdW1lcidzIHN0YWNrIG11c3QgaGF2ZSBgY3Jvc3NSZWdpb25SZWZlcmVuY2VzOiB0cnVlYCB3aGVuXG4gICAqIGByZWdpb25gIGRpZmZlcnMgZnJvbSB0aGUgYnVpbGRlcidzIHJlZ2lvbi5cbiAgICovXG4gIHB1YmxpYyBkb2NrZXJJbWFnZUNvZGVGb3Ioc2NvcGU6IENvbnN0cnVjdCwgcmVnaW9uOiBzdHJpbmcpOiBEb2NrZXJJbWFnZUNvZGUge1xuICAgIHJldHVybiBEb2NrZXJJbWFnZUNvZGUuZnJvbUVjcih0aGlzLmltcG9ydFJlcG9Gb3Ioc2NvcGUsIHJlZ2lvbiksIHtcbiAgICAgIHRhZ09yRGlnZXN0OiB0aGlzLmltYWdlVGFnLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBpbXBvcnRSZXBvRm9yKHNjb3BlOiBDb25zdHJ1Y3QsIHJlZ2lvbjogc3RyaW5nKTogUmVwb3NpdG9yeSB7XG4gICAgdGhpcy5hc3NlcnRSZWdpb25Jc0tub3duKHJlZ2lvbik7XG4gICAgaWYgKHJlZ2lvbiA9PT0gdGhpcy5wcmltYXJ5UmVnaW9uKSByZXR1cm4gdGhpcy5lY3JSZXBvc2l0b3J5O1xuXG4gICAgLy8gSW5jbHVkZSB0aGUgYnVpbGRlcidzIG93biBub2RlLmFkZHIgaW4gdGhlIGltcG9ydCBpZCBzbyB0d28gZGlmZmVyZW50XG4gICAgLy8gYnVpbGRlcnMgaW1wb3J0aW5nIHRoZSBzYW1lIHJlZ2lvbiBpbnRvIHRoZSBzYW1lIHNjb3BlIGVhY2ggZ2V0IHRoZWlyXG4gICAgLy8gb3duIFJlcG9zaXRvcnkgY2hpbGQgKG90aGVyd2lzZSB0aGUgc2Vjb25kIGNhbGwgd291bGQgY29sbGlkZSB3aXRoIHRoZVxuICAgIC8vIGZpcnN0IGFuZCByZXR1cm4gdGhlIHdyb25nIGJ1aWxkZXIncyByZXBvKS5cbiAgICBjb25zdCBpbXBvcnRJZCA9IGBJbXBvcnRlZFJlcG8ke3JlZ2lvbn0ke3RoaXMubm9kZS5hZGRyfWA7XG4gICAgY29uc3QgZXhpc3RpbmcgPSBzY29wZS5ub2RlLnRyeUZpbmRDaGlsZChpbXBvcnRJZCk7XG4gICAgaWYgKGV4aXN0aW5nKSByZXR1cm4gZXhpc3RpbmcgYXMgUmVwb3NpdG9yeTtcblxuICAgIHJldHVybiBSZXBvc2l0b3J5LmZyb21SZXBvc2l0b3J5QXR0cmlidXRlcyhzY29wZSwgaW1wb3J0SWQsIHtcbiAgICAgIHJlcG9zaXRvcnlOYW1lOiB0aGlzLnJlcG9zaXRvcnlOYW1lLFxuICAgICAgcmVwb3NpdG9yeUFybjogU3RhY2sub2Yoc2NvcGUpLmZvcm1hdEFybih7XG4gICAgICAgIHNlcnZpY2U6ICdlY3InLFxuICAgICAgICByZXNvdXJjZTogJ3JlcG9zaXRvcnknLFxuICAgICAgICByZXNvdXJjZU5hbWU6IHRoaXMucmVwb3NpdG9yeU5hbWUsXG4gICAgICAgIHJlZ2lvbixcbiAgICAgICAgYWNjb3VudDogdGhpcy5hY2NvdW50SWQsXG4gICAgICB9KSxcbiAgICB9KSBhcyBSZXBvc2l0b3J5O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3NlcnRSZWdpb25Jc0tub3duKHJlZ2lvbjogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHJlZ2lvbiA9PT0gdGhpcy5wcmltYXJ5UmVnaW9uKSByZXR1cm47XG4gICAgaWYgKHRoaXMucmVwbGljYVJlZ2lvbnMuaW5jbHVkZXMocmVnaW9uKSkgcmV0dXJuO1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBSZWdpb24gXCIke3JlZ2lvbn1cIiBpcyBub3QgdGhlIHByaW1hcnkgcmVnaW9uICgke3RoaXMucHJpbWFyeVJlZ2lvbn0pIGAgK1xuICAgICAgYG9yIG9uZSBvZiB0aGUgY29uZmlndXJlZCByZXBsaWNhUmVnaW9ucyAoJHt0aGlzLnJlcGxpY2FSZWdpb25zLmpvaW4oJywgJykgfHwgJzxub25lPid9KS4gYCArXG4gICAgICAnQWRkIHRoZSByZWdpb24gdG8gdGhlIGJ1aWxkZXJcXCdzIHJlcGxpY2FSZWdpb25zIHByb3AgdG8gbWFrZSBpdCBhdmFpbGFibGUuJyxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZVJlcGxpY2FSZWdpb25zKHJlcGxpY2FSZWdpb25zOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGNvbnN0IHN0YWNrID0gU3RhY2sub2YodGhpcyk7XG4gICAgY29uc3QgcHJpbWFyeVBhcnRpdGlvbiA9IHN0YWNrLnBhcnRpdGlvbjtcbiAgICBmb3IgKGNvbnN0IHJlZ2lvbiBvZiByZXBsaWNhUmVnaW9ucykge1xuICAgICAgaWYgKHJlZ2lvbiA9PT0gdGhpcy5wcmltYXJ5UmVnaW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgcmVwbGljYVJlZ2lvbnMgY2Fubm90IGluY2x1ZGUgdGhlIHByaW1hcnkgcmVnaW9uIFwiJHt0aGlzLnByaW1hcnlSZWdpb259XCIuIGAgK1xuICAgICAgICAgICdSZW1vdmUgaXQgZnJvbSB0aGUgbGlzdC4nLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgLy8gUGFydGl0aW9uIGNhbm5vdCBiZSBjbGVhbmx5IGluZmVycmVkIGZyb20gcmVnaW9uIGFsb25lIGF0IHN5bnRoIHRpbWVcbiAgICAgIC8vIChpdCdzIGEgQ0RLIHBzZXVkby1wYXJhbWV0ZXIgYW5kIG1heSBiZSBhIHRva2VuKS4gV2UgZG8gdGhlIGJlc3QtZWZmb3J0XG4gICAgICAvLyBjaGVjazogaWYgYm90aCBwYXJ0aXRpb24gdmFsdWVzIGFyZSBjb25jcmV0ZSBhbmQgdGhleSBkaWZmZXIsIGZhaWwuXG4gICAgICAvLyBDcm9zcy1wYXJ0aXRpb24gcmVwbGljYXRpb24gaXMgdW5zdXBwb3J0ZWQgYnkgRUNSLlxuICAgICAgaWYgKCFUb2tlbi5pc1VucmVzb2x2ZWQocHJpbWFyeVBhcnRpdGlvbikpIHtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWRQYXJ0aXRpb24gPSBpbmZlclBhcnRpdGlvbihyZWdpb24pO1xuICAgICAgICBpZiAoZXhwZWN0ZWRQYXJ0aXRpb24gJiYgZXhwZWN0ZWRQYXJ0aXRpb24gIT09IHByaW1hcnlQYXJ0aXRpb24pIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAnQ3Jvc3MtcGFydGl0aW9uIEVDUiByZXBsaWNhdGlvbiBpcyBub3Qgc3VwcG9ydGVkLiAnICtcbiAgICAgICAgICAgIGBQcmltYXJ5IHBhcnRpdGlvbiBpcyBcIiR7cHJpbWFyeVBhcnRpdGlvbn1cIiBidXQgcmVwbGljYSByZWdpb24gYCArXG4gICAgICAgICAgICBgXCIke3JlZ2lvbn1cIiBhcHBlYXJzIHRvIGJlIGluIHBhcnRpdGlvbiBcIiR7ZXhwZWN0ZWRQYXJ0aXRpb259XCIuYCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBncmFudEVjckFjY2Vzcyhwcm9qZWN0OiBQcm9qZWN0KTogdm9pZCB7XG4gICAgdGhpcy5lY3JSZXBvc2l0b3J5LmdyYW50UHVsbFB1c2gocHJvamVjdCk7XG4gICAgcHJvamVjdC5hZGRUb1JvbGVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICdlY3I6R2V0QXV0aG9yaXphdGlvblRva2VuJyxcbiAgICAgICAgICAnZWNyOkdldERvd25sb2FkVXJsRm9yTGF5ZXInLFxuICAgICAgICAgICdlY3I6QmF0Y2hDaGVja0xheWVyQXZhaWxhYmlsaXR5JyxcbiAgICAgICAgICAnZWNyOkJhdGNoR2V0SW1hZ2UnLFxuICAgICAgICBdLFxuICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ3JhbnRQdWxsVGhyb3VnaENhY2hlQWNjZXNzKHByb2plY3Q6IFByb2plY3QsIHByZWZpeGVzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICAgIGlmICghcHJlZml4ZXMgfHwgcHJlZml4ZXMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgY29uc3Qgc3RhY2sgPSBTdGFjay5vZih0aGlzKTtcbiAgICBwcm9qZWN0LmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgJ2VjcjpCYXRjaEdldEltYWdlJyxcbiAgICAgICAgICAnZWNyOkdldERvd25sb2FkVXJsRm9yTGF5ZXInLFxuICAgICAgICAgICdlY3I6QmF0Y2hDaGVja0xheWVyQXZhaWxhYmlsaXR5JyxcbiAgICAgICAgICAnZWNyOkJhdGNoSW1wb3J0VXBzdHJlYW1JbWFnZScsXG4gICAgICAgICAgJ2VjcjpDcmVhdGVSZXBvc2l0b3J5JyxcbiAgICAgICAgXSxcbiAgICAgICAgcmVzb3VyY2VzOiBwcmVmaXhlcy5tYXAoXG4gICAgICAgICAgKHByZWZpeCkgPT4gYGFybjphd3M6ZWNyOiR7c3RhY2sucmVnaW9ufToke3N0YWNrLmFjY291bnR9OnJlcG9zaXRvcnkvJHtwcmVmaXh9LypgLFxuICAgICAgICApLFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ3JhbnRCdWlsZExvZ3NBY2Nlc3MocHJvamVjdDogUHJvamVjdCwgcmV0YWluQnVpbGRMb2dzOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKCFyZXRhaW5CdWlsZExvZ3MpIHJldHVybjtcbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHRoaXMpO1xuICAgIHByb2plY3QuYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFsnbG9nczpDcmVhdGVMb2dHcm91cCcsICdsb2dzOkNyZWF0ZUxvZ1N0cmVhbScsICdsb2dzOlB1dExvZ0V2ZW50cyddLFxuICAgICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgICBgYXJuOmF3czpsb2dzOiR7c3RhY2sucmVnaW9ufToke3N0YWNrLmFjY291bnR9OmxvZy1ncm91cDoke0JVSUxEX0xPR19HUk9VUF9QUkVGSVh9JHtwcm9qZWN0LnByb2plY3ROYW1lfWAsXG4gICAgICAgICAgYGFybjphd3M6bG9nczoke3N0YWNrLnJlZ2lvbn06JHtzdGFjay5hY2NvdW50fTpsb2ctZ3JvdXA6JHtCVUlMRF9MT0dfR1JPVVBfUFJFRklYfSR7cHJvamVjdC5wcm9qZWN0TmFtZX06KmAsXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogQmVzdC1lZmZvcnQgcGFydGl0aW9uIGluZmVyZW5jZSBmcm9tIGFuIEFXUyByZWdpb24gbmFtZS4gUmV0dXJuc1xuICogdW5kZWZpbmVkIGlmIHRoZSByZWdpb24gZG9lc24ndCBsb29rIGxpa2UgYSBrbm93biBwYXJ0aXRpb24gcHJlZml4IOKAlFxuICogY2FsbGVycyBzaG91bGQgdHJlYXQgdGhhdCBhcyBcInNraXAgdGhlIHBhcnRpdGlvbiBjaGVja1wiLlxuICovXG5mdW5jdGlvbiBpbmZlclBhcnRpdGlvbihyZWdpb246IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmIChyZWdpb24uc3RhcnRzV2l0aCgnY24tJykpIHJldHVybiAnYXdzLWNuJztcbiAgaWYgKHJlZ2lvbi5zdGFydHNXaXRoKCd1cy1nb3YtJykpIHJldHVybiAnYXdzLXVzLWdvdic7XG4gIGlmIChyZWdpb24uc3RhcnRzV2l0aCgndXMtaXNvLScpKSByZXR1cm4gJ2F3cy1pc28nO1xuICBpZiAocmVnaW9uLnN0YXJ0c1dpdGgoJ3VzLWlzb2ItJykpIHJldHVybiAnYXdzLWlzby1iJztcbiAgaWYgKC9eW2Etel17Mn0tW2Etel0rLVxcZCskLy50ZXN0KHJlZ2lvbikpIHJldHVybiAnYXdzJztcbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbiJdfQ==
@@ -0,0 +1,7 @@
1
+ import { Duration } from 'aws-cdk-lib';
2
+ import { Runtime } from 'aws-cdk-lib/aws-lambda';
3
+ export declare const LAMBDA_RUNTIME: Runtime;
4
+ export declare const LAMBDA_TIMEOUT: Duration;
5
+ export declare const DEFAULT_QUERY_INTERVAL: Duration;
6
+ export declare const BUILD_LOG_GROUP_PREFIX = "/docker-builder/";
7
+ export declare const PROVIDER_SINGLETON_ID = "TokenInjectableDockerBuilderProvider";
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PROVIDER_SINGLETON_ID = exports.BUILD_LOG_GROUP_PREFIX = exports.DEFAULT_QUERY_INTERVAL = exports.LAMBDA_TIMEOUT = exports.LAMBDA_RUNTIME = void 0;
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
6
+ exports.LAMBDA_RUNTIME = aws_lambda_1.Runtime.NODEJS_22_X;
7
+ exports.LAMBDA_TIMEOUT = aws_cdk_lib_1.Duration.minutes(15);
8
+ exports.DEFAULT_QUERY_INTERVAL = aws_cdk_lib_1.Duration.seconds(30);
9
+ exports.BUILD_LOG_GROUP_PREFIX = '/docker-builder/';
10
+ exports.PROVIDER_SINGLETON_ID = 'TokenInjectableDockerBuilderProvider';
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbnN0YW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBdUM7QUFDdkMsdURBQWlEO0FBRXBDLFFBQUEsY0FBYyxHQUFHLG9CQUFPLENBQUMsV0FBVyxDQUFDO0FBQ3JDLFFBQUEsY0FBYyxHQUFHLHNCQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3RDLFFBQUEsc0JBQXNCLEdBQUcsc0JBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDOUMsUUFBQSxzQkFBc0IsR0FBRyxrQkFBa0IsQ0FBQztBQUM1QyxRQUFBLHFCQUFxQixHQUFHLHNDQUFzQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRHVyYXRpb24gfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBSdW50aW1lIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5cbmV4cG9ydCBjb25zdCBMQU1CREFfUlVOVElNRSA9IFJ1bnRpbWUuTk9ERUpTXzIyX1g7XG5leHBvcnQgY29uc3QgTEFNQkRBX1RJTUVPVVQgPSBEdXJhdGlvbi5taW51dGVzKDE1KTtcbmV4cG9ydCBjb25zdCBERUZBVUxUX1FVRVJZX0lOVEVSVkFMID0gRHVyYXRpb24uc2Vjb25kcygzMCk7XG5leHBvcnQgY29uc3QgQlVJTERfTE9HX0dST1VQX1BSRUZJWCA9ICcvZG9ja2VyLWJ1aWxkZXIvJztcbmV4cG9ydCBjb25zdCBQUk9WSURFUl9TSU5HTEVUT05fSUQgPSAnVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlclByb3ZpZGVyJztcbiJdfQ==
package/lib/ecr.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { Repository } from 'aws-cdk-lib/aws-ecr';
2
+ import { Key } from 'aws-cdk-lib/aws-kms';
3
+ import { Construct } from 'constructs';
4
+ export interface BuilderEcrRepositoryOptions {
5
+ readonly kmsEncryption: boolean;
6
+ readonly encryptionKey?: Key;
7
+ }
8
+ /**
9
+ * Create an ECR repository for a builder.
10
+ *
11
+ * SAFETY: tagged images are never deleted. Lambda pins images by digest
12
+ * internally, so deleting an in-use tagged image would make the next Lambda
13
+ * config update fail with "Image ID cannot be found". Untagged images are
14
+ * cleaned up after 30 days.
15
+ */
16
+ export declare function createBuilderEcrRepository(scope: Construct, id: string, options: BuilderEcrRepositoryOptions): Repository;
package/lib/ecr.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createBuilderEcrRepository = createBuilderEcrRepository;
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ const aws_ecr_1 = require("aws-cdk-lib/aws-ecr");
6
+ /**
7
+ * Create an ECR repository for a builder.
8
+ *
9
+ * SAFETY: tagged images are never deleted. Lambda pins images by digest
10
+ * internally, so deleting an in-use tagged image would make the next Lambda
11
+ * config update fail with "Image ID cannot be found". Untagged images are
12
+ * cleaned up after 30 days.
13
+ */
14
+ function createBuilderEcrRepository(scope, id, options) {
15
+ const { kmsEncryption, encryptionKey } = options;
16
+ return new aws_ecr_1.Repository(scope, id, {
17
+ lifecycleRules: [
18
+ {
19
+ rulePriority: 1,
20
+ description: 'Remove untagged images after 30 days',
21
+ tagStatus: aws_ecr_1.TagStatus.UNTAGGED,
22
+ maxImageAge: aws_cdk_lib_1.Duration.days(30),
23
+ },
24
+ ],
25
+ encryption: kmsEncryption ? aws_ecr_1.RepositoryEncryption.KMS : aws_ecr_1.RepositoryEncryption.AES_256,
26
+ encryptionKey: kmsEncryption ? encryptionKey : undefined,
27
+ imageScanOnPush: true,
28
+ });
29
+ }
30
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Vjci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWtCQSxnRUFvQkM7QUF0Q0QsNkNBQXVDO0FBQ3ZDLGlEQUFrRjtBQVNsRjs7Ozs7OztHQU9HO0FBQ0gsU0FBZ0IsMEJBQTBCLENBQ3hDLEtBQWdCLEVBQ2hCLEVBQVUsRUFDVixPQUFvQztJQUVwQyxNQUFNLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxHQUFHLE9BQU8sQ0FBQztJQUVqRCxPQUFPLElBQUksb0JBQVUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1FBQy9CLGNBQWMsRUFBRTtZQUNkO2dCQUNFLFlBQVksRUFBRSxDQUFDO2dCQUNmLFdBQVcsRUFBRSxzQ0FBc0M7Z0JBQ25ELFNBQVMsRUFBRSxtQkFBUyxDQUFDLFFBQVE7Z0JBQzdCLFdBQVcsRUFBRSxzQkFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7YUFDL0I7U0FDRjtRQUNELFVBQVUsRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDLDhCQUFvQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsOEJBQW9CLENBQUMsT0FBTztRQUNuRixhQUFhLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLFNBQVM7UUFDeEQsZUFBZSxFQUFFLElBQUk7S0FDdEIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IER1cmF0aW9uIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSwgUmVwb3NpdG9yeUVuY3J5cHRpb24sIFRhZ1N0YXR1cyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1lY3InO1xuaW1wb3J0IHsgS2V5IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWttcyc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuZXhwb3J0IGludGVyZmFjZSBCdWlsZGVyRWNyUmVwb3NpdG9yeU9wdGlvbnMge1xuICByZWFkb25seSBrbXNFbmNyeXB0aW9uOiBib29sZWFuO1xuICByZWFkb25seSBlbmNyeXB0aW9uS2V5PzogS2V5O1xufVxuXG4vKipcbiAqIENyZWF0ZSBhbiBFQ1IgcmVwb3NpdG9yeSBmb3IgYSBidWlsZGVyLlxuICpcbiAqIFNBRkVUWTogdGFnZ2VkIGltYWdlcyBhcmUgbmV2ZXIgZGVsZXRlZC4gTGFtYmRhIHBpbnMgaW1hZ2VzIGJ5IGRpZ2VzdFxuICogaW50ZXJuYWxseSwgc28gZGVsZXRpbmcgYW4gaW4tdXNlIHRhZ2dlZCBpbWFnZSB3b3VsZCBtYWtlIHRoZSBuZXh0IExhbWJkYVxuICogY29uZmlnIHVwZGF0ZSBmYWlsIHdpdGggXCJJbWFnZSBJRCBjYW5ub3QgYmUgZm91bmRcIi4gVW50YWdnZWQgaW1hZ2VzIGFyZVxuICogY2xlYW5lZCB1cCBhZnRlciAzMCBkYXlzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQnVpbGRlckVjclJlcG9zaXRvcnkoXG4gIHNjb3BlOiBDb25zdHJ1Y3QsXG4gIGlkOiBzdHJpbmcsXG4gIG9wdGlvbnM6IEJ1aWxkZXJFY3JSZXBvc2l0b3J5T3B0aW9ucyxcbik6IFJlcG9zaXRvcnkge1xuICBjb25zdCB7IGttc0VuY3J5cHRpb24sIGVuY3J5cHRpb25LZXkgfSA9IG9wdGlvbnM7XG5cbiAgcmV0dXJuIG5ldyBSZXBvc2l0b3J5KHNjb3BlLCBpZCwge1xuICAgIGxpZmVjeWNsZVJ1bGVzOiBbXG4gICAgICB7XG4gICAgICAgIHJ1bGVQcmlvcml0eTogMSxcbiAgICAgICAgZGVzY3JpcHRpb246ICdSZW1vdmUgdW50YWdnZWQgaW1hZ2VzIGFmdGVyIDMwIGRheXMnLFxuICAgICAgICB0YWdTdGF0dXM6IFRhZ1N0YXR1cy5VTlRBR0dFRCxcbiAgICAgICAgbWF4SW1hZ2VBZ2U6IER1cmF0aW9uLmRheXMoMzApLFxuICAgICAgfSxcbiAgICBdLFxuICAgIGVuY3J5cHRpb246IGttc0VuY3J5cHRpb24gPyBSZXBvc2l0b3J5RW5jcnlwdGlvbi5LTVMgOiBSZXBvc2l0b3J5RW5jcnlwdGlvbi5BRVNfMjU2LFxuICAgIGVuY3J5cHRpb25LZXk6IGttc0VuY3J5cHRpb24gPyBlbmNyeXB0aW9uS2V5IDogdW5kZWZpbmVkLFxuICAgIGltYWdlU2Nhbk9uUHVzaDogdHJ1ZSxcbiAgfSk7XG59XG4iXX0=