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/.jsii +260 -143
- package/API.md +196 -136
- package/README.md +156 -71
- package/ecrReplication/ecrReplication.js +156 -0
- package/isComplete/isComplete.js +45 -1
- package/lib/build-spec.d.ts +24 -0
- package/lib/build-spec.js +104 -0
- package/lib/builder.d.ts +206 -0
- package/lib/builder.js +289 -0
- package/lib/constants.d.ts +7 -0
- package/lib/constants.js +11 -0
- package/lib/ecr.d.ts +16 -0
- package/lib/ecr.js +30 -0
- package/lib/index.d.ts +2 -261
- package/lib/index.js +6 -402
- package/lib/provider.d.ts +63 -0
- package/lib/provider.js +212 -0
- package/package.json +10 -5
package/lib/provider.js
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.TokenInjectableDockerBuilderProvider = void 0;
|
|
5
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
8
|
+
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
|
9
|
+
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
|
10
|
+
const custom_resources_1 = require("aws-cdk-lib/custom-resources");
|
|
11
|
+
const constructs_1 = require("constructs");
|
|
12
|
+
const constants_1 = require("./constants");
|
|
13
|
+
const REPLICATION_TOTAL_TIMEOUT = aws_cdk_lib_1.Duration.hours(1);
|
|
14
|
+
const REPLICATION_CR_ID = 'ReplicationConfig';
|
|
15
|
+
const REPLICATION_FN_ID = 'ReplicationConfigHandler';
|
|
16
|
+
// ECR registry replication caps (per registry / per AWS account):
|
|
17
|
+
// https://docs.aws.amazon.com/AmazonECR/latest/userguide/replication.html
|
|
18
|
+
const MAX_UNIQUE_DESTINATIONS = 25;
|
|
19
|
+
const MAX_RULES = 10;
|
|
20
|
+
/**
|
|
21
|
+
* Shared provider for `TokenInjectableDockerBuilder` instances.
|
|
22
|
+
*
|
|
23
|
+
* Creates the onEvent and isComplete Lambda functions once per stack.
|
|
24
|
+
* Each builder instance registers its CodeBuild project ARN so the
|
|
25
|
+
* shared Lambdas have permission to start builds and read logs.
|
|
26
|
+
*/
|
|
27
|
+
class TokenInjectableDockerBuilderProvider extends constructs_1.Construct {
|
|
28
|
+
/**
|
|
29
|
+
* Get or create the singleton provider for this stack.
|
|
30
|
+
* All `TokenInjectableDockerBuilder` instances in the same stack
|
|
31
|
+
* share a single pair of Lambda functions.
|
|
32
|
+
*/
|
|
33
|
+
static getOrCreate(scope, props) {
|
|
34
|
+
const stack = aws_cdk_lib_1.Stack.of(scope);
|
|
35
|
+
const existing = stack.node.tryFindChild(constants_1.PROVIDER_SINGLETON_ID);
|
|
36
|
+
if (existing)
|
|
37
|
+
return existing;
|
|
38
|
+
return new TokenInjectableDockerBuilderProvider(stack, constants_1.PROVIDER_SINGLETON_ID, props);
|
|
39
|
+
}
|
|
40
|
+
constructor(scope, id, props) {
|
|
41
|
+
super(scope, id);
|
|
42
|
+
this.replicationSpecs = [];
|
|
43
|
+
this.onEventHandlerFunction = new aws_lambda_1.Function(this, 'OnEventHandler', {
|
|
44
|
+
runtime: constants_1.LAMBDA_RUNTIME,
|
|
45
|
+
code: aws_lambda_1.Code.fromAsset(path.resolve(__dirname, '../onEvent')),
|
|
46
|
+
handler: 'onEvent.handler',
|
|
47
|
+
timeout: constants_1.LAMBDA_TIMEOUT,
|
|
48
|
+
});
|
|
49
|
+
this.onEventHandlerFunction.addToRolePolicy(new aws_iam_1.PolicyStatement({
|
|
50
|
+
actions: [
|
|
51
|
+
'logs:CreateLogGroup',
|
|
52
|
+
'logs:PutRetentionPolicy',
|
|
53
|
+
'logs:DeleteLogGroup',
|
|
54
|
+
],
|
|
55
|
+
resources: [`arn:aws:logs:*:*:log-group:${constants_1.BUILD_LOG_GROUP_PREFIX}*`],
|
|
56
|
+
}));
|
|
57
|
+
this.isCompleteHandlerFunction = new aws_lambda_1.Function(this, 'IsCompleteHandler', {
|
|
58
|
+
runtime: constants_1.LAMBDA_RUNTIME,
|
|
59
|
+
code: aws_lambda_1.Code.fromAsset(path.resolve(__dirname, '../isComplete')),
|
|
60
|
+
handler: 'isComplete.handler',
|
|
61
|
+
timeout: constants_1.LAMBDA_TIMEOUT,
|
|
62
|
+
});
|
|
63
|
+
this.isCompleteHandlerFunction.addToRolePolicy(new aws_iam_1.PolicyStatement({
|
|
64
|
+
actions: [
|
|
65
|
+
'codebuild:BatchGetBuilds',
|
|
66
|
+
'codebuild:ListBuildsForProject',
|
|
67
|
+
'logs:GetLogEvents',
|
|
68
|
+
'logs:DescribeLogStreams',
|
|
69
|
+
'logs:DescribeLogGroups',
|
|
70
|
+
],
|
|
71
|
+
resources: ['*'],
|
|
72
|
+
}));
|
|
73
|
+
const provider = new custom_resources_1.Provider(this, 'Provider', {
|
|
74
|
+
onEventHandler: this.onEventHandlerFunction,
|
|
75
|
+
isCompleteHandler: this.isCompleteHandlerFunction,
|
|
76
|
+
queryInterval: props?.queryInterval ?? constants_1.DEFAULT_QUERY_INTERVAL,
|
|
77
|
+
// ECR cross-region replication can take up to 30 min in rare cases.
|
|
78
|
+
// The default 30 min totalTimeout is too tight when a builder uses
|
|
79
|
+
// replicaRegions and isComplete is waiting for replicas to land.
|
|
80
|
+
totalTimeout: REPLICATION_TOTAL_TIMEOUT,
|
|
81
|
+
});
|
|
82
|
+
this.serviceToken = provider.serviceToken;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Grant the shared Lambdas permission to start builds for a specific
|
|
86
|
+
* CodeBuild project and pull/push to its ECR repository.
|
|
87
|
+
*/
|
|
88
|
+
registerProject(project, ecrRepo, encryptionKey) {
|
|
89
|
+
this.onEventHandlerFunction.addToRolePolicy(new aws_iam_1.PolicyStatement({
|
|
90
|
+
actions: ['codebuild:StartBuild'],
|
|
91
|
+
resources: [project.projectArn],
|
|
92
|
+
}));
|
|
93
|
+
ecrRepo.grantPullPush(this.onEventHandlerFunction);
|
|
94
|
+
ecrRepo.grantPullPush(this.isCompleteHandlerFunction);
|
|
95
|
+
if (encryptionKey) {
|
|
96
|
+
encryptionKey.grantEncryptDecrypt(this.onEventHandlerFunction);
|
|
97
|
+
encryptionKey.grantEncryptDecrypt(this.isCompleteHandlerFunction);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Register a builder's replica regions with the singleton's replication-config
|
|
102
|
+
* custom resource. Multiple builders contribute specs; the CR merges them into
|
|
103
|
+
* a single registry-wide configuration on every deploy.
|
|
104
|
+
*
|
|
105
|
+
* Also grants the `isComplete` Lambda permission to BatchGetImage on each
|
|
106
|
+
* replica region's repo so it can poll for replication availability.
|
|
107
|
+
*/
|
|
108
|
+
registerReplication(repoName, replicaRegions) {
|
|
109
|
+
if (replicaRegions.length === 0)
|
|
110
|
+
return;
|
|
111
|
+
const stack = aws_cdk_lib_1.Stack.of(this);
|
|
112
|
+
const destinations = replicaRegions.map((r) => ({ region: r, registryId: stack.account }));
|
|
113
|
+
this.replicationSpecs.push({ repositoryName: repoName, destinations });
|
|
114
|
+
this.assertReplicationCapsWithinLimits();
|
|
115
|
+
// Grant isComplete BatchGetImage on every replica repo ARN so it can
|
|
116
|
+
// poll for the replicated image to appear.
|
|
117
|
+
this.isCompleteHandlerFunction.addToRolePolicy(new aws_iam_1.PolicyStatement({
|
|
118
|
+
actions: ['ecr:BatchGetImage', 'ecr:DescribeImages'],
|
|
119
|
+
resources: replicaRegions.map((r) => `arn:aws:ecr:${r}:${stack.account}:repository/${repoName}`),
|
|
120
|
+
}));
|
|
121
|
+
this.ensureReplicationCr();
|
|
122
|
+
// Refresh the CR's ManagedSpecs every time a builder registers. Custom
|
|
123
|
+
// resource update detection diffs ResourceProperties — a new value here
|
|
124
|
+
// triggers a CR update, which re-runs the merge in the replication Lambda.
|
|
125
|
+
if (this.replicationCr) {
|
|
126
|
+
const properties = this.replicationCr.node.defaultChild;
|
|
127
|
+
// CDK doesn't expose a public API to mutate CustomResource properties
|
|
128
|
+
// after creation. Instead we use addPropertyOverride to write the
|
|
129
|
+
// serialized state of all registered specs to date.
|
|
130
|
+
properties.addPropertyOverride('ManagedSpecs', JSON.stringify(this.replicationSpecs));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
ensureReplicationCr() {
|
|
134
|
+
if (this.replicationCr)
|
|
135
|
+
return;
|
|
136
|
+
this.replicationFn = new aws_lambda_1.Function(this, REPLICATION_FN_ID, {
|
|
137
|
+
runtime: constants_1.LAMBDA_RUNTIME,
|
|
138
|
+
code: aws_lambda_1.Code.fromAsset(path.resolve(__dirname, '../ecrReplication')),
|
|
139
|
+
handler: 'ecrReplication.handler',
|
|
140
|
+
timeout: constants_1.LAMBDA_TIMEOUT,
|
|
141
|
+
});
|
|
142
|
+
this.replicationFn.addToRolePolicy(new aws_iam_1.PolicyStatement({
|
|
143
|
+
actions: [
|
|
144
|
+
'ecr:DescribeRegistry',
|
|
145
|
+
'ecr:PutReplicationConfiguration',
|
|
146
|
+
],
|
|
147
|
+
resources: ['*'],
|
|
148
|
+
}));
|
|
149
|
+
// First-ever PutReplicationConfiguration in an account creates a
|
|
150
|
+
// service-linked role; idempotent if it already exists.
|
|
151
|
+
this.replicationFn.addToRolePolicy(new aws_iam_1.PolicyStatement({
|
|
152
|
+
actions: ['iam:CreateServiceLinkedRole'],
|
|
153
|
+
resources: ['*'],
|
|
154
|
+
conditions: {
|
|
155
|
+
StringEquals: {
|
|
156
|
+
'iam:AWSServiceName': 'replication.ecr.amazonaws.com',
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
}));
|
|
160
|
+
const replicationProvider = new custom_resources_1.Provider(this, 'ReplicationProvider', {
|
|
161
|
+
onEventHandler: this.replicationFn,
|
|
162
|
+
});
|
|
163
|
+
this.replicationCr = new aws_cdk_lib_1.CustomResource(this, REPLICATION_CR_ID, {
|
|
164
|
+
serviceToken: replicationProvider.serviceToken,
|
|
165
|
+
resourceType: 'Custom::TidbReplicationConfig',
|
|
166
|
+
properties: {
|
|
167
|
+
ManagedSpecs: JSON.stringify(this.replicationSpecs),
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Enforce ECR registry replication caps at synth time so users get a clear
|
|
173
|
+
* error before deploy. Caps are per-registry (per AWS account), not
|
|
174
|
+
* per-stack — but this construct can only see specs registered through
|
|
175
|
+
* its own singletons. Cross-stack/cross-app rules outside this construct
|
|
176
|
+
* are invisible here; the replication CR will still surface those at
|
|
177
|
+
* deploy time via the ECR API's own error.
|
|
178
|
+
*/
|
|
179
|
+
assertReplicationCapsWithinLimits() {
|
|
180
|
+
const uniqueDestinations = new Set();
|
|
181
|
+
const uniqueDestinationSets = new Set();
|
|
182
|
+
for (const spec of this.replicationSpecs) {
|
|
183
|
+
for (const dest of spec.destinations) {
|
|
184
|
+
uniqueDestinations.add(`${dest.region}:${dest.registryId}`);
|
|
185
|
+
}
|
|
186
|
+
const setKey = spec.destinations
|
|
187
|
+
.map((d) => `${d.region}:${d.registryId}`)
|
|
188
|
+
.sort()
|
|
189
|
+
.join('|');
|
|
190
|
+
uniqueDestinationSets.add(setKey);
|
|
191
|
+
}
|
|
192
|
+
if (uniqueDestinations.size > MAX_UNIQUE_DESTINATIONS) {
|
|
193
|
+
throw new Error(`ECR registry replication supports at most ${MAX_UNIQUE_DESTINATIONS} unique ` +
|
|
194
|
+
'destinations across all rules per AWS account, but this stack would create ' +
|
|
195
|
+
`${uniqueDestinations.size}. Reduce the union of replicaRegions across all ` +
|
|
196
|
+
'TokenInjectableDockerBuilder instances. (Limit is per-registry / per-account, ' +
|
|
197
|
+
'so other stacks in the same account count too — but only specs registered ' +
|
|
198
|
+
'through this construct are visible at synth time.)');
|
|
199
|
+
}
|
|
200
|
+
if (uniqueDestinationSets.size > MAX_RULES) {
|
|
201
|
+
throw new Error(`ECR registry replication supports at most ${MAX_RULES} rules per registry. ` +
|
|
202
|
+
'The construct groups builders by their destination set into one rule each, ' +
|
|
203
|
+
`but this stack has ${uniqueDestinationSets.size} unique destination sets. ` +
|
|
204
|
+
'Consolidate builders to share destination sets (i.e. give them the same ' +
|
|
205
|
+
'replicaRegions) so they share a rule.');
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
exports.TokenInjectableDockerBuilderProvider = TokenInjectableDockerBuilderProvider;
|
|
210
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
211
|
+
TokenInjectableDockerBuilderProvider[_a] = { fqn: "token-injectable-docker-builder.TokenInjectableDockerBuilderProvider", version: "2.0.0" };
|
|
212
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2QkFBNkI7QUFFN0IsNkNBQThEO0FBRzlELGlEQUFzRDtBQUV0RCx1REFBd0Q7QUFDeEQsbUVBQXdEO0FBQ3hELDJDQUF1QztBQUV2QywyQ0FNcUI7QUFFckIsTUFBTSx5QkFBeUIsR0FBRyxzQkFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwRCxNQUFNLGlCQUFpQixHQUFHLG1CQUFtQixDQUFDO0FBQzlDLE1BQU0saUJBQWlCLEdBQUcsMEJBQTBCLENBQUM7QUFFckQsa0VBQWtFO0FBQ2xFLDBFQUEwRTtBQUMxRSxNQUFNLHVCQUF1QixHQUFHLEVBQUUsQ0FBQztBQUNuQyxNQUFNLFNBQVMsR0FBRyxFQUFFLENBQUM7QUFjckI7Ozs7OztHQU1HO0FBQ0gsTUFBYSxvQ0FBcUMsU0FBUSxzQkFBUztJQUNqRTs7OztPQUlHO0lBQ0ksTUFBTSxDQUFDLFdBQVcsQ0FDdkIsS0FBZ0IsRUFDaEIsS0FBaUQ7UUFFakQsTUFBTSxLQUFLLEdBQUcsbUJBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUIsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsaUNBQXFCLENBRWpELENBQUM7UUFDZCxJQUFJLFFBQVE7WUFBRSxPQUFPLFFBQVEsQ0FBQztRQUM5QixPQUFPLElBQUksb0NBQW9DLENBQUMsS0FBSyxFQUFFLGlDQUFxQixFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3ZGLENBQUM7SUFhRCxZQUNFLEtBQWdCLEVBQ2hCLEVBQVUsRUFDVixLQUFpRDtRQUVqRCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBUEYscUJBQWdCLEdBQW1HLEVBQUUsQ0FBQztRQVNySSxJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxxQkFBUSxDQUFDLElBQUksRUFBRSxnQkFBZ0IsRUFBRTtZQUNqRSxPQUFPLEVBQUUsMEJBQWM7WUFDdkIsSUFBSSxFQUFFLGlCQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDO1lBQzNELE9BQU8sRUFBRSxpQkFBaUI7WUFDMUIsT0FBTyxFQUFFLDBCQUFjO1NBQ3hCLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxlQUFlLENBQ3pDLElBQUkseUJBQWUsQ0FBQztZQUNsQixPQUFPLEVBQUU7Z0JBQ1AscUJBQXFCO2dCQUNyQix5QkFBeUI7Z0JBQ3pCLHFCQUFxQjthQUN0QjtZQUNELFNBQVMsRUFBRSxDQUFDLDhCQUE4QixrQ0FBc0IsR0FBRyxDQUFDO1NBQ3JFLENBQUMsQ0FDSCxDQUFDO1FBRUYsSUFBSSxDQUFDLHlCQUF5QixHQUFHLElBQUkscUJBQVEsQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLEVBQUU7WUFDdkUsT0FBTyxFQUFFLDBCQUFjO1lBQ3ZCLElBQUksRUFBRSxpQkFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxlQUFlLENBQUMsQ0FBQztZQUM5RCxPQUFPLEVBQUUsb0JBQW9CO1lBQzdCLE9BQU8sRUFBRSwwQkFBYztTQUN4QixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMseUJBQXlCLENBQUMsZUFBZSxDQUM1QyxJQUFJLHlCQUFlLENBQUM7WUFDbEIsT0FBTyxFQUFFO2dCQUNQLDBCQUEwQjtnQkFDMUIsZ0NBQWdDO2dCQUNoQyxtQkFBbUI7Z0JBQ25CLHlCQUF5QjtnQkFDekIsd0JBQXdCO2FBQ3pCO1lBQ0QsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO1NBQ2pCLENBQUMsQ0FDSCxDQUFDO1FBRUYsTUFBTSxRQUFRLEdBQUcsSUFBSSwyQkFBUSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDOUMsY0FBYyxFQUFFLElBQUksQ0FBQyxzQkFBc0I7WUFDM0MsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLHlCQUF5QjtZQUNqRCxhQUFhLEVBQUUsS0FBSyxFQUFFLGFBQWEsSUFBSSxrQ0FBc0I7WUFDN0Qsb0VBQW9FO1lBQ3BFLG1FQUFtRTtZQUNuRSxpRUFBaUU7WUFDakUsWUFBWSxFQUFFLHlCQUF5QjtTQUN4QyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUM7SUFDNUMsQ0FBQztJQUVEOzs7T0FHRztJQUNJLGVBQWUsQ0FBQyxPQUFnQixFQUFFLE9BQW1CLEVBQUUsYUFBbUI7UUFDL0UsSUFBSSxDQUFDLHNCQUFzQixDQUFDLGVBQWUsQ0FDekMsSUFBSSx5QkFBZSxDQUFDO1lBQ2xCLE9BQU8sRUFBRSxDQUFDLHNCQUFzQixDQUFDO1lBQ2pDLFNBQVMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUM7U0FDaEMsQ0FBQyxDQUNILENBQUM7UUFDRixPQUFPLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ25ELE9BQU8sQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFFdEQsSUFBSSxhQUFhLEVBQUUsQ0FBQztZQUNsQixhQUFhLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUM7WUFDL0QsYUFBYSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLG1CQUFtQixDQUFDLFFBQWdCLEVBQUUsY0FBd0I7UUFDbkUsSUFBSSxjQUFjLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPO1FBQ3hDLE1BQU0sS0FBSyxHQUFHLG1CQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdCLE1BQU0sWUFBWSxHQUFHLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzNGLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7UUFFdkUsSUFBSSxDQUFDLGlDQUFpQyxFQUFFLENBQUM7UUFFekMscUVBQXFFO1FBQ3JFLDJDQUEyQztRQUMzQyxJQUFJLENBQUMseUJBQXlCLENBQUMsZUFBZSxDQUM1QyxJQUFJLHlCQUFlLENBQUM7WUFDbEIsT0FBTyxFQUFFLENBQUMsbUJBQW1CLEVBQUUsb0JBQW9CLENBQUM7WUFDcEQsU0FBUyxFQUFFLGNBQWMsQ0FBQyxHQUFHLENBQzNCLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxlQUFlLENBQUMsSUFBSSxLQUFLLENBQUMsT0FBTyxlQUFlLFFBQVEsRUFBRSxDQUNsRTtTQUNGLENBQUMsQ0FDSCxDQUFDO1FBRUYsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFFM0IsdUVBQXVFO1FBQ3ZFLHdFQUF3RTtRQUN4RSwyRUFBMkU7UUFDM0UsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDdkIsTUFBTSxVQUFVLEdBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsWUFBb0IsQ0FBQztZQUNqRSxzRUFBc0U7WUFDdEUsa0VBQWtFO1lBQ2xFLG9EQUFvRDtZQUNwRCxVQUFVLENBQUMsbUJBQW1CLENBQzVCLGNBQWMsRUFDZCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUN0QyxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFTyxtQkFBbUI7UUFDekIsSUFBSSxJQUFJLENBQUMsYUFBYTtZQUFFLE9BQU87UUFFL0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLHFCQUFRLENBQUMsSUFBSSxFQUFFLGlCQUFpQixFQUFFO1lBQ3pELE9BQU8sRUFBRSwwQkFBYztZQUN2QixJQUFJLEVBQUUsaUJBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztZQUNsRSxPQUFPLEVBQUUsd0JBQXdCO1lBQ2pDLE9BQU8sRUFBRSwwQkFBYztTQUN4QixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsYUFBYSxDQUFDLGVBQWUsQ0FDaEMsSUFBSSx5QkFBZSxDQUFDO1lBQ2xCLE9BQU8sRUFBRTtnQkFDUCxzQkFBc0I7Z0JBQ3RCLGlDQUFpQzthQUNsQztZQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztTQUNqQixDQUFDLENBQ0gsQ0FBQztRQUNGLGlFQUFpRTtRQUNqRSx3REFBd0Q7UUFDeEQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQ2hDLElBQUkseUJBQWUsQ0FBQztZQUNsQixPQUFPLEVBQUUsQ0FBQyw2QkFBNkIsQ0FBQztZQUN4QyxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7WUFDaEIsVUFBVSxFQUFFO2dCQUNWLFlBQVksRUFBRTtvQkFDWixvQkFBb0IsRUFBRSwrQkFBK0I7aUJBQ3REO2FBQ0Y7U0FDRixDQUFDLENBQ0gsQ0FBQztRQUVGLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSwyQkFBUSxDQUFDLElBQUksRUFBRSxxQkFBcUIsRUFBRTtZQUNwRSxjQUFjLEVBQUUsSUFBSSxDQUFDLGFBQWE7U0FDbkMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLDRCQUFjLENBQUMsSUFBSSxFQUFFLGlCQUFpQixFQUFFO1lBQy9ELFlBQVksRUFBRSxtQkFBbUIsQ0FBQyxZQUFZO1lBQzlDLFlBQVksRUFBRSwrQkFBK0I7WUFDN0MsVUFBVSxFQUFFO2dCQUNWLFlBQVksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQzthQUNwRDtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0ssaUNBQWlDO1FBQ3ZDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztRQUM3QyxNQUFNLHFCQUFxQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDaEQsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUN6QyxLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDckMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUM5RCxDQUFDO1lBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVk7aUJBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztpQkFDekMsSUFBSSxFQUFFO2lCQUNOLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNiLHFCQUFxQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNwQyxDQUFDO1FBRUQsSUFBSSxrQkFBa0IsQ0FBQyxJQUFJLEdBQUcsdUJBQXVCLEVBQUUsQ0FBQztZQUN0RCxNQUFNLElBQUksS0FBSyxDQUNiLDZDQUE2Qyx1QkFBdUIsVUFBVTtnQkFDOUUsNkVBQTZFO2dCQUM3RSxHQUFHLGtCQUFrQixDQUFDLElBQUksa0RBQWtEO2dCQUM1RSxnRkFBZ0Y7Z0JBQ2hGLDRFQUE0RTtnQkFDNUUsb0RBQW9ELENBQ3JELENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxxQkFBcUIsQ0FBQyxJQUFJLEdBQUcsU0FBUyxFQUFFLENBQUM7WUFDM0MsTUFBTSxJQUFJLEtBQUssQ0FDYiw2Q0FBNkMsU0FBUyx1QkFBdUI7Z0JBQzdFLDZFQUE2RTtnQkFDN0Usc0JBQXNCLHFCQUFxQixDQUFDLElBQUksNEJBQTRCO2dCQUM1RSwwRUFBMEU7Z0JBQzFFLHVDQUF1QyxDQUN4QyxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7O0FBNU9ILG9GQTZPQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5cbmltcG9ydCB7IEN1c3RvbVJlc291cmNlLCBEdXJhdGlvbiwgU3RhY2sgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBQcm9qZWN0IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWNvZGVidWlsZCc7XG5pbXBvcnQgeyBSZXBvc2l0b3J5IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWVjcic7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7IEtleSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1rbXMnO1xuaW1wb3J0IHsgQ29kZSwgRnVuY3Rpb24gfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCB7IFByb3ZpZGVyIH0gZnJvbSAnYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlcyc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuaW1wb3J0IHtcbiAgQlVJTERfTE9HX0dST1VQX1BSRUZJWCxcbiAgREVGQVVMVF9RVUVSWV9JTlRFUlZBTCxcbiAgTEFNQkRBX1JVTlRJTUUsXG4gIExBTUJEQV9USU1FT1VULFxuICBQUk9WSURFUl9TSU5HTEVUT05fSUQsXG59IGZyb20gJy4vY29uc3RhbnRzJztcblxuY29uc3QgUkVQTElDQVRJT05fVE9UQUxfVElNRU9VVCA9IER1cmF0aW9uLmhvdXJzKDEpO1xuY29uc3QgUkVQTElDQVRJT05fQ1JfSUQgPSAnUmVwbGljYXRpb25Db25maWcnO1xuY29uc3QgUkVQTElDQVRJT05fRk5fSUQgPSAnUmVwbGljYXRpb25Db25maWdIYW5kbGVyJztcblxuLy8gRUNSIHJlZ2lzdHJ5IHJlcGxpY2F0aW9uIGNhcHMgKHBlciByZWdpc3RyeSAvIHBlciBBV1MgYWNjb3VudCk6XG4vLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNSL2xhdGVzdC91c2VyZ3VpZGUvcmVwbGljYXRpb24uaHRtbFxuY29uc3QgTUFYX1VOSVFVRV9ERVNUSU5BVElPTlMgPSAyNTtcbmNvbnN0IE1BWF9SVUxFUyA9IDEwO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGNyZWF0aW5nIGEgYFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXJQcm92aWRlcmAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlclByb3ZpZGVyUHJvcHMge1xuICAvKipcbiAgICogSG93IG9mdGVuIHRoZSBwcm92aWRlciBwb2xscyBmb3IgYnVpbGQgY29tcGxldGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgRHVyYXRpb24uc2Vjb25kcygzMClcbiAgICovXG4gIHJlYWRvbmx5IHF1ZXJ5SW50ZXJ2YWw/OiBEdXJhdGlvbjtcbn1cblxuLyoqXG4gKiBTaGFyZWQgcHJvdmlkZXIgZm9yIGBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyYCBpbnN0YW5jZXMuXG4gKlxuICogQ3JlYXRlcyB0aGUgb25FdmVudCBhbmQgaXNDb21wbGV0ZSBMYW1iZGEgZnVuY3Rpb25zIG9uY2UgcGVyIHN0YWNrLlxuICogRWFjaCBidWlsZGVyIGluc3RhbmNlIHJlZ2lzdGVycyBpdHMgQ29kZUJ1aWxkIHByb2plY3QgQVJOIHNvIHRoZVxuICogc2hhcmVkIExhbWJkYXMgaGF2ZSBwZXJtaXNzaW9uIHRvIHN0YXJ0IGJ1aWxkcyBhbmQgcmVhZCBsb2dzLlxuICovXG5leHBvcnQgY2xhc3MgVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlclByb3ZpZGVyIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgLyoqXG4gICAqIEdldCBvciBjcmVhdGUgdGhlIHNpbmdsZXRvbiBwcm92aWRlciBmb3IgdGhpcyBzdGFjay5cbiAgICogQWxsIGBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyYCBpbnN0YW5jZXMgaW4gdGhlIHNhbWUgc3RhY2tcbiAgICogc2hhcmUgYSBzaW5nbGUgcGFpciBvZiBMYW1iZGEgZnVuY3Rpb25zLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBnZXRPckNyZWF0ZShcbiAgICBzY29wZTogQ29uc3RydWN0LFxuICAgIHByb3BzPzogVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlclByb3ZpZGVyUHJvcHMsXG4gICk6IFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXJQcm92aWRlciB7XG4gICAgY29uc3Qgc3RhY2sgPSBTdGFjay5vZihzY29wZSk7XG4gICAgY29uc3QgZXhpc3RpbmcgPSBzdGFjay5ub2RlLnRyeUZpbmRDaGlsZChQUk9WSURFUl9TSU5HTEVUT05fSUQpIGFzXG4gICAgICB8IFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXJQcm92aWRlclxuICAgICAgfCB1bmRlZmluZWQ7XG4gICAgaWYgKGV4aXN0aW5nKSByZXR1cm4gZXhpc3Rpbmc7XG4gICAgcmV0dXJuIG5ldyBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyUHJvdmlkZXIoc3RhY2ssIFBST1ZJREVSX1NJTkdMRVRPTl9JRCwgcHJvcHMpO1xuICB9XG5cbiAgLyoqIFRoZSBzZXJ2aWNlIHRva2VuIHVzZWQgYnkgQ3VzdG9tUmVzb3VyY2UgaW5zdGFuY2VzLiAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2VydmljZVRva2VuOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvbkV2ZW50SGFuZGxlckZ1bmN0aW9uOiBGdW5jdGlvbjtcbiAgcHJpdmF0ZSByZWFkb25seSBpc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uOiBGdW5jdGlvbjtcblxuICAvLyBSZXBsaWNhdGlvbi1jb25maWcgQ1IgaXMgY3JlYXRlZCBsYXppbHkgb24gZmlyc3QgcmVnaXN0ZXJSZXBsaWNhdGlvbiBjYWxsLlxuICBwcml2YXRlIHJlcGxpY2F0aW9uRm4/OiBGdW5jdGlvbjtcbiAgcHJpdmF0ZSByZXBsaWNhdGlvbkNyPzogQ3VzdG9tUmVzb3VyY2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVwbGljYXRpb25TcGVjczogQXJyYXk8eyByZXBvc2l0b3J5TmFtZTogc3RyaW5nOyBkZXN0aW5hdGlvbnM6IEFycmF5PHsgcmVnaW9uOiBzdHJpbmc7IHJlZ2lzdHJ5SWQ6IHN0cmluZyB9PiB9PiA9IFtdO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IENvbnN0cnVjdCxcbiAgICBpZDogc3RyaW5nLFxuICAgIHByb3BzPzogVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlclByb3ZpZGVyUHJvcHMsXG4gICkge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICB0aGlzLm9uRXZlbnRIYW5kbGVyRnVuY3Rpb24gPSBuZXcgRnVuY3Rpb24odGhpcywgJ09uRXZlbnRIYW5kbGVyJywge1xuICAgICAgcnVudGltZTogTEFNQkRBX1JVTlRJTUUsXG4gICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldChwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vb25FdmVudCcpKSxcbiAgICAgIGhhbmRsZXI6ICdvbkV2ZW50LmhhbmRsZXInLFxuICAgICAgdGltZW91dDogTEFNQkRBX1RJTUVPVVQsXG4gICAgfSk7XG4gICAgdGhpcy5vbkV2ZW50SGFuZGxlckZ1bmN0aW9uLmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgJ2xvZ3M6Q3JlYXRlTG9nR3JvdXAnLFxuICAgICAgICAgICdsb2dzOlB1dFJldGVudGlvblBvbGljeScsXG4gICAgICAgICAgJ2xvZ3M6RGVsZXRlTG9nR3JvdXAnLFxuICAgICAgICBdLFxuICAgICAgICByZXNvdXJjZXM6IFtgYXJuOmF3czpsb2dzOio6Kjpsb2ctZ3JvdXA6JHtCVUlMRF9MT0dfR1JPVVBfUFJFRklYfSpgXSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICB0aGlzLmlzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24gPSBuZXcgRnVuY3Rpb24odGhpcywgJ0lzQ29tcGxldGVIYW5kbGVyJywge1xuICAgICAgcnVudGltZTogTEFNQkRBX1JVTlRJTUUsXG4gICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldChwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vaXNDb21wbGV0ZScpKSxcbiAgICAgIGhhbmRsZXI6ICdpc0NvbXBsZXRlLmhhbmRsZXInLFxuICAgICAgdGltZW91dDogTEFNQkRBX1RJTUVPVVQsXG4gICAgfSk7XG4gICAgdGhpcy5pc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uLmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgJ2NvZGVidWlsZDpCYXRjaEdldEJ1aWxkcycsXG4gICAgICAgICAgJ2NvZGVidWlsZDpMaXN0QnVpbGRzRm9yUHJvamVjdCcsXG4gICAgICAgICAgJ2xvZ3M6R2V0TG9nRXZlbnRzJyxcbiAgICAgICAgICAnbG9nczpEZXNjcmliZUxvZ1N0cmVhbXMnLFxuICAgICAgICAgICdsb2dzOkRlc2NyaWJlTG9nR3JvdXBzJyxcbiAgICAgICAgXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBjb25zdCBwcm92aWRlciA9IG5ldyBQcm92aWRlcih0aGlzLCAnUHJvdmlkZXInLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcjogdGhpcy5vbkV2ZW50SGFuZGxlckZ1bmN0aW9uLFxuICAgICAgaXNDb21wbGV0ZUhhbmRsZXI6IHRoaXMuaXNDb21wbGV0ZUhhbmRsZXJGdW5jdGlvbixcbiAgICAgIHF1ZXJ5SW50ZXJ2YWw6IHByb3BzPy5xdWVyeUludGVydmFsID8/IERFRkFVTFRfUVVFUllfSU5URVJWQUwsXG4gICAgICAvLyBFQ1IgY3Jvc3MtcmVnaW9uIHJlcGxpY2F0aW9uIGNhbiB0YWtlIHVwIHRvIDMwIG1pbiBpbiByYXJlIGNhc2VzLlxuICAgICAgLy8gVGhlIGRlZmF1bHQgMzAgbWluIHRvdGFsVGltZW91dCBpcyB0b28gdGlnaHQgd2hlbiBhIGJ1aWxkZXIgdXNlc1xuICAgICAgLy8gcmVwbGljYVJlZ2lvbnMgYW5kIGlzQ29tcGxldGUgaXMgd2FpdGluZyBmb3IgcmVwbGljYXMgdG8gbGFuZC5cbiAgICAgIHRvdGFsVGltZW91dDogUkVQTElDQVRJT05fVE9UQUxfVElNRU9VVCxcbiAgICB9KTtcblxuICAgIHRoaXMuc2VydmljZVRva2VuID0gcHJvdmlkZXIuc2VydmljZVRva2VuO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50IHRoZSBzaGFyZWQgTGFtYmRhcyBwZXJtaXNzaW9uIHRvIHN0YXJ0IGJ1aWxkcyBmb3IgYSBzcGVjaWZpY1xuICAgKiBDb2RlQnVpbGQgcHJvamVjdCBhbmQgcHVsbC9wdXNoIHRvIGl0cyBFQ1IgcmVwb3NpdG9yeS5cbiAgICovXG4gIHB1YmxpYyByZWdpc3RlclByb2plY3QocHJvamVjdDogUHJvamVjdCwgZWNyUmVwbzogUmVwb3NpdG9yeSwgZW5jcnlwdGlvbktleT86IEtleSk6IHZvaWQge1xuICAgIHRoaXMub25FdmVudEhhbmRsZXJGdW5jdGlvbi5hZGRUb1JvbGVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogWydjb2RlYnVpbGQ6U3RhcnRCdWlsZCddLFxuICAgICAgICByZXNvdXJjZXM6IFtwcm9qZWN0LnByb2plY3RBcm5dLFxuICAgICAgfSksXG4gICAgKTtcbiAgICBlY3JSZXBvLmdyYW50UHVsbFB1c2godGhpcy5vbkV2ZW50SGFuZGxlckZ1bmN0aW9uKTtcbiAgICBlY3JSZXBvLmdyYW50UHVsbFB1c2godGhpcy5pc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uKTtcblxuICAgIGlmIChlbmNyeXB0aW9uS2V5KSB7XG4gICAgICBlbmNyeXB0aW9uS2V5LmdyYW50RW5jcnlwdERlY3J5cHQodGhpcy5vbkV2ZW50SGFuZGxlckZ1bmN0aW9uKTtcbiAgICAgIGVuY3J5cHRpb25LZXkuZ3JhbnRFbmNyeXB0RGVjcnlwdCh0aGlzLmlzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBhIGJ1aWxkZXIncyByZXBsaWNhIHJlZ2lvbnMgd2l0aCB0aGUgc2luZ2xldG9uJ3MgcmVwbGljYXRpb24tY29uZmlnXG4gICAqIGN1c3RvbSByZXNvdXJjZS4gTXVsdGlwbGUgYnVpbGRlcnMgY29udHJpYnV0ZSBzcGVjczsgdGhlIENSIG1lcmdlcyB0aGVtIGludG9cbiAgICogYSBzaW5nbGUgcmVnaXN0cnktd2lkZSBjb25maWd1cmF0aW9uIG9uIGV2ZXJ5IGRlcGxveS5cbiAgICpcbiAgICogQWxzbyBncmFudHMgdGhlIGBpc0NvbXBsZXRlYCBMYW1iZGEgcGVybWlzc2lvbiB0byBCYXRjaEdldEltYWdlIG9uIGVhY2hcbiAgICogcmVwbGljYSByZWdpb24ncyByZXBvIHNvIGl0IGNhbiBwb2xsIGZvciByZXBsaWNhdGlvbiBhdmFpbGFiaWxpdHkuXG4gICAqL1xuICBwdWJsaWMgcmVnaXN0ZXJSZXBsaWNhdGlvbihyZXBvTmFtZTogc3RyaW5nLCByZXBsaWNhUmVnaW9uczogc3RyaW5nW10pOiB2b2lkIHtcbiAgICBpZiAocmVwbGljYVJlZ2lvbnMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgY29uc3Qgc3RhY2sgPSBTdGFjay5vZih0aGlzKTtcbiAgICBjb25zdCBkZXN0aW5hdGlvbnMgPSByZXBsaWNhUmVnaW9ucy5tYXAoKHIpID0+ICh7IHJlZ2lvbjogciwgcmVnaXN0cnlJZDogc3RhY2suYWNjb3VudCB9KSk7XG4gICAgdGhpcy5yZXBsaWNhdGlvblNwZWNzLnB1c2goeyByZXBvc2l0b3J5TmFtZTogcmVwb05hbWUsIGRlc3RpbmF0aW9ucyB9KTtcblxuICAgIHRoaXMuYXNzZXJ0UmVwbGljYXRpb25DYXBzV2l0aGluTGltaXRzKCk7XG5cbiAgICAvLyBHcmFudCBpc0NvbXBsZXRlIEJhdGNoR2V0SW1hZ2Ugb24gZXZlcnkgcmVwbGljYSByZXBvIEFSTiBzbyBpdCBjYW5cbiAgICAvLyBwb2xsIGZvciB0aGUgcmVwbGljYXRlZCBpbWFnZSB0byBhcHBlYXIuXG4gICAgdGhpcy5pc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uLmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbJ2VjcjpCYXRjaEdldEltYWdlJywgJ2VjcjpEZXNjcmliZUltYWdlcyddLFxuICAgICAgICByZXNvdXJjZXM6IHJlcGxpY2FSZWdpb25zLm1hcChcbiAgICAgICAgICAocikgPT4gYGFybjphd3M6ZWNyOiR7cn06JHtzdGFjay5hY2NvdW50fTpyZXBvc2l0b3J5LyR7cmVwb05hbWV9YCxcbiAgICAgICAgKSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICB0aGlzLmVuc3VyZVJlcGxpY2F0aW9uQ3IoKTtcblxuICAgIC8vIFJlZnJlc2ggdGhlIENSJ3MgTWFuYWdlZFNwZWNzIGV2ZXJ5IHRpbWUgYSBidWlsZGVyIHJlZ2lzdGVycy4gQ3VzdG9tXG4gICAgLy8gcmVzb3VyY2UgdXBkYXRlIGRldGVjdGlvbiBkaWZmcyBSZXNvdXJjZVByb3BlcnRpZXMg4oCUIGEgbmV3IHZhbHVlIGhlcmVcbiAgICAvLyB0cmlnZ2VycyBhIENSIHVwZGF0ZSwgd2hpY2ggcmUtcnVucyB0aGUgbWVyZ2UgaW4gdGhlIHJlcGxpY2F0aW9uIExhbWJkYS5cbiAgICBpZiAodGhpcy5yZXBsaWNhdGlvbkNyKSB7XG4gICAgICBjb25zdCBwcm9wZXJ0aWVzID0gKHRoaXMucmVwbGljYXRpb25Dci5ub2RlLmRlZmF1bHRDaGlsZCBhcyBhbnkpO1xuICAgICAgLy8gQ0RLIGRvZXNuJ3QgZXhwb3NlIGEgcHVibGljIEFQSSB0byBtdXRhdGUgQ3VzdG9tUmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAgLy8gYWZ0ZXIgY3JlYXRpb24uIEluc3RlYWQgd2UgdXNlIGFkZFByb3BlcnR5T3ZlcnJpZGUgdG8gd3JpdGUgdGhlXG4gICAgICAvLyBzZXJpYWxpemVkIHN0YXRlIG9mIGFsbCByZWdpc3RlcmVkIHNwZWNzIHRvIGRhdGUuXG4gICAgICBwcm9wZXJ0aWVzLmFkZFByb3BlcnR5T3ZlcnJpZGUoXG4gICAgICAgICdNYW5hZ2VkU3BlY3MnLFxuICAgICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLnJlcGxpY2F0aW9uU3BlY3MpLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZVJlcGxpY2F0aW9uQ3IoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVwbGljYXRpb25DcikgcmV0dXJuO1xuXG4gICAgdGhpcy5yZXBsaWNhdGlvbkZuID0gbmV3IEZ1bmN0aW9uKHRoaXMsIFJFUExJQ0FUSU9OX0ZOX0lELCB7XG4gICAgICBydW50aW1lOiBMQU1CREFfUlVOVElNRSxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUFzc2V0KHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLi9lY3JSZXBsaWNhdGlvbicpKSxcbiAgICAgIGhhbmRsZXI6ICdlY3JSZXBsaWNhdGlvbi5oYW5kbGVyJyxcbiAgICAgIHRpbWVvdXQ6IExBTUJEQV9USU1FT1VULFxuICAgIH0pO1xuICAgIHRoaXMucmVwbGljYXRpb25Gbi5hZGRUb1JvbGVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICdlY3I6RGVzY3JpYmVSZWdpc3RyeScsXG4gICAgICAgICAgJ2VjcjpQdXRSZXBsaWNhdGlvbkNvbmZpZ3VyYXRpb24nLFxuICAgICAgICBdLFxuICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgfSksXG4gICAgKTtcbiAgICAvLyBGaXJzdC1ldmVyIFB1dFJlcGxpY2F0aW9uQ29uZmlndXJhdGlvbiBpbiBhbiBhY2NvdW50IGNyZWF0ZXMgYVxuICAgIC8vIHNlcnZpY2UtbGlua2VkIHJvbGU7IGlkZW1wb3RlbnQgaWYgaXQgYWxyZWFkeSBleGlzdHMuXG4gICAgdGhpcy5yZXBsaWNhdGlvbkZuLmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbJ2lhbTpDcmVhdGVTZXJ2aWNlTGlua2VkUm9sZSddLFxuICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICBjb25kaXRpb25zOiB7XG4gICAgICAgICAgU3RyaW5nRXF1YWxzOiB7XG4gICAgICAgICAgICAnaWFtOkFXU1NlcnZpY2VOYW1lJzogJ3JlcGxpY2F0aW9uLmVjci5hbWF6b25hd3MuY29tJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIGNvbnN0IHJlcGxpY2F0aW9uUHJvdmlkZXIgPSBuZXcgUHJvdmlkZXIodGhpcywgJ1JlcGxpY2F0aW9uUHJvdmlkZXInLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcjogdGhpcy5yZXBsaWNhdGlvbkZuLFxuICAgIH0pO1xuXG4gICAgdGhpcy5yZXBsaWNhdGlvbkNyID0gbmV3IEN1c3RvbVJlc291cmNlKHRoaXMsIFJFUExJQ0FUSU9OX0NSX0lELCB7XG4gICAgICBzZXJ2aWNlVG9rZW46IHJlcGxpY2F0aW9uUHJvdmlkZXIuc2VydmljZVRva2VuLFxuICAgICAgcmVzb3VyY2VUeXBlOiAnQ3VzdG9tOjpUaWRiUmVwbGljYXRpb25Db25maWcnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBNYW5hZ2VkU3BlY3M6IEpTT04uc3RyaW5naWZ5KHRoaXMucmVwbGljYXRpb25TcGVjcyksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuZm9yY2UgRUNSIHJlZ2lzdHJ5IHJlcGxpY2F0aW9uIGNhcHMgYXQgc3ludGggdGltZSBzbyB1c2VycyBnZXQgYSBjbGVhclxuICAgKiBlcnJvciBiZWZvcmUgZGVwbG95LiBDYXBzIGFyZSBwZXItcmVnaXN0cnkgKHBlciBBV1MgYWNjb3VudCksIG5vdFxuICAgKiBwZXItc3RhY2sg4oCUIGJ1dCB0aGlzIGNvbnN0cnVjdCBjYW4gb25seSBzZWUgc3BlY3MgcmVnaXN0ZXJlZCB0aHJvdWdoXG4gICAqIGl0cyBvd24gc2luZ2xldG9ucy4gQ3Jvc3Mtc3RhY2svY3Jvc3MtYXBwIHJ1bGVzIG91dHNpZGUgdGhpcyBjb25zdHJ1Y3RcbiAgICogYXJlIGludmlzaWJsZSBoZXJlOyB0aGUgcmVwbGljYXRpb24gQ1Igd2lsbCBzdGlsbCBzdXJmYWNlIHRob3NlIGF0XG4gICAqIGRlcGxveSB0aW1lIHZpYSB0aGUgRUNSIEFQSSdzIG93biBlcnJvci5cbiAgICovXG4gIHByaXZhdGUgYXNzZXJ0UmVwbGljYXRpb25DYXBzV2l0aGluTGltaXRzKCk6IHZvaWQge1xuICAgIGNvbnN0IHVuaXF1ZURlc3RpbmF0aW9ucyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IHVuaXF1ZURlc3RpbmF0aW9uU2V0cyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGZvciAoY29uc3Qgc3BlYyBvZiB0aGlzLnJlcGxpY2F0aW9uU3BlY3MpIHtcbiAgICAgIGZvciAoY29uc3QgZGVzdCBvZiBzcGVjLmRlc3RpbmF0aW9ucykge1xuICAgICAgICB1bmlxdWVEZXN0aW5hdGlvbnMuYWRkKGAke2Rlc3QucmVnaW9ufToke2Rlc3QucmVnaXN0cnlJZH1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNldEtleSA9IHNwZWMuZGVzdGluYXRpb25zXG4gICAgICAgIC5tYXAoKGQpID0+IGAke2QucmVnaW9ufToke2QucmVnaXN0cnlJZH1gKVxuICAgICAgICAuc29ydCgpXG4gICAgICAgIC5qb2luKCd8Jyk7XG4gICAgICB1bmlxdWVEZXN0aW5hdGlvblNldHMuYWRkKHNldEtleSk7XG4gICAgfVxuXG4gICAgaWYgKHVuaXF1ZURlc3RpbmF0aW9ucy5zaXplID4gTUFYX1VOSVFVRV9ERVNUSU5BVElPTlMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEVDUiByZWdpc3RyeSByZXBsaWNhdGlvbiBzdXBwb3J0cyBhdCBtb3N0ICR7TUFYX1VOSVFVRV9ERVNUSU5BVElPTlN9IHVuaXF1ZSBgICtcbiAgICAgICAgJ2Rlc3RpbmF0aW9ucyBhY3Jvc3MgYWxsIHJ1bGVzIHBlciBBV1MgYWNjb3VudCwgYnV0IHRoaXMgc3RhY2sgd291bGQgY3JlYXRlICcgK1xuICAgICAgICBgJHt1bmlxdWVEZXN0aW5hdGlvbnMuc2l6ZX0uIFJlZHVjZSB0aGUgdW5pb24gb2YgcmVwbGljYVJlZ2lvbnMgYWNyb3NzIGFsbCBgICtcbiAgICAgICAgJ1Rva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXIgaW5zdGFuY2VzLiAoTGltaXQgaXMgcGVyLXJlZ2lzdHJ5IC8gcGVyLWFjY291bnQsICcgK1xuICAgICAgICAnc28gb3RoZXIgc3RhY2tzIGluIHRoZSBzYW1lIGFjY291bnQgY291bnQgdG9vIOKAlCBidXQgb25seSBzcGVjcyByZWdpc3RlcmVkICcgK1xuICAgICAgICAndGhyb3VnaCB0aGlzIGNvbnN0cnVjdCBhcmUgdmlzaWJsZSBhdCBzeW50aCB0aW1lLiknLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAodW5pcXVlRGVzdGluYXRpb25TZXRzLnNpemUgPiBNQVhfUlVMRVMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEVDUiByZWdpc3RyeSByZXBsaWNhdGlvbiBzdXBwb3J0cyBhdCBtb3N0ICR7TUFYX1JVTEVTfSBydWxlcyBwZXIgcmVnaXN0cnkuIGAgK1xuICAgICAgICAnVGhlIGNvbnN0cnVjdCBncm91cHMgYnVpbGRlcnMgYnkgdGhlaXIgZGVzdGluYXRpb24gc2V0IGludG8gb25lIHJ1bGUgZWFjaCwgJyArXG4gICAgICAgIGBidXQgdGhpcyBzdGFjayBoYXMgJHt1bmlxdWVEZXN0aW5hdGlvblNldHMuc2l6ZX0gdW5pcXVlIGRlc3RpbmF0aW9uIHNldHMuIGAgK1xuICAgICAgICAnQ29uc29saWRhdGUgYnVpbGRlcnMgdG8gc2hhcmUgZGVzdGluYXRpb24gc2V0cyAoaS5lLiBnaXZlIHRoZW0gdGhlIHNhbWUgJyArXG4gICAgICAgICdyZXBsaWNhUmVnaW9ucykgc28gdGhleSBzaGFyZSBhIHJ1bGUuJyxcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG4iXX0=
|
package/package.json
CHANGED
|
@@ -29,10 +29,12 @@
|
|
|
29
29
|
"upgrade": "npx projen upgrade",
|
|
30
30
|
"watch": "npx projen watch",
|
|
31
31
|
"projen": "npx projen",
|
|
32
|
-
"local-deploy": "npx cdk deploy --app \"npx ts-node
|
|
33
|
-
"local-deploy-no-rollback": "npx cdk deploy --no-rollback --app \"npx ts-node
|
|
34
|
-
"local-destroy": "npx cdk destroy --app \"npx ts-node
|
|
35
|
-
"local-synth": "npx cdk synth --app \"npx ts-node
|
|
32
|
+
"local-deploy": "npx cdk deploy --all --app \"npx ts-node test/integ.default.ts\"",
|
|
33
|
+
"local-deploy-no-rollback": "npx cdk deploy --all --no-rollback --app \"npx ts-node test/integ.default.ts\"",
|
|
34
|
+
"local-destroy": "npx cdk destroy --all --app \"npx ts-node test/integ.default.ts\"",
|
|
35
|
+
"local-synth": "npx cdk synth --app \"npx ts-node test/integ.default.ts\"",
|
|
36
|
+
"integ": "npx integ-runner --update-on-failed --directory test",
|
|
37
|
+
"integ-migration": "npx cdk deploy TidbMigrationStack --app \"npx ts-node test/migration/before-v1.ts\" --require-approval=never && npx cdk deploy TidbMigrationStack --app \"npx ts-node test/migration/after-v2.ts\" --require-approval=never && npx cdk destroy TidbMigrationStack --app \"npx ts-node test/migration/after-v2.ts\" --force"
|
|
36
38
|
},
|
|
37
39
|
"author": {
|
|
38
40
|
"name": "AlexTech314",
|
|
@@ -40,6 +42,8 @@
|
|
|
40
42
|
"organization": false
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
45
|
+
"@aws-cdk/integ-runner": "^2.197.0",
|
|
46
|
+
"@aws-cdk/integ-tests-alpha": "2.238.0-alpha.0",
|
|
43
47
|
"@stylistic/eslint-plugin": "^2",
|
|
44
48
|
"@types/jest": "^29.5.14",
|
|
45
49
|
"@types/node": "^22.19.15",
|
|
@@ -59,6 +63,7 @@
|
|
|
59
63
|
"jsii-pacmak": "^1.127.0",
|
|
60
64
|
"jsii-rosetta": "~5.9.27",
|
|
61
65
|
"projen": "^0.99.25",
|
|
66
|
+
"token-injectable-docker-builder-v1": "npm:token-injectable-docker-builder@^1.13.0",
|
|
62
67
|
"ts-jest": "^29.4.6",
|
|
63
68
|
"ts-node": "^10.9.2",
|
|
64
69
|
"typescript": "^5.9.3"
|
|
@@ -98,7 +103,7 @@
|
|
|
98
103
|
"publishConfig": {
|
|
99
104
|
"access": "public"
|
|
100
105
|
},
|
|
101
|
-
"version": "
|
|
106
|
+
"version": "2.0.0",
|
|
102
107
|
"jest": {
|
|
103
108
|
"coverageProvider": "v8",
|
|
104
109
|
"testMatch": [
|