aws-cdk 2.1.0 → 2.5.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/LICENSE +1 -1
- package/NOTICE +1 -1
- package/README.md +5 -1
- package/build-info.json +2 -2
- package/lib/api/aws-auth/sdk-provider.js +11 -21
- package/lib/api/aws-auth/sdk.d.ts +2 -0
- package/lib/api/aws-auth/sdk.js +4 -1
- package/lib/api/bootstrap/bootstrap-template.yaml +3 -1
- package/lib/api/deploy-stack.js +7 -1
- package/lib/api/hotswap/code-build-projects.d.ts +3 -0
- package/lib/api/hotswap/code-build-projects.js +53 -0
- package/lib/api/hotswap/common.d.ts +17 -1
- package/lib/api/hotswap/common.js +30 -6
- package/lib/api/hotswap/ecs-services.js +4 -18
- package/lib/api/hotswap/evaluate-cloudformation-template.d.ts +1 -0
- package/lib/api/hotswap/evaluate-cloudformation-template.js +6 -1
- package/lib/api/hotswap/lambda-functions.d.ts +2 -2
- package/lib/api/hotswap/lambda-functions.js +171 -46
- package/lib/api/hotswap/s3-bucket-deployments.d.ts +8 -0
- package/lib/api/hotswap/s3-bucket-deployments.js +106 -0
- package/lib/api/hotswap/stepfunctions-state-machines.js +11 -7
- package/lib/api/hotswap-deployments.d.ts +0 -7
- package/lib/api/hotswap-deployments.js +86 -12
- package/lib/cdk-toolkit.js +50 -16
- package/lib/commands/docs.js +2 -2
- package/lib/context-providers/index.d.ts +10 -5
- package/lib/context-providers/index.js +32 -19
- package/lib/context-providers/provider.d.ts +1 -0
- package/lib/context-providers/provider.js +6 -1
- package/lib/init.js +2 -1
- package/lib/plugin.d.ts +20 -0
- package/lib/plugin.js +28 -1
- package/lib/util/asset-publishing.js +9 -2
- package/lib/util/npm.d.ts +1 -0
- package/lib/util/npm.js +21 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +22 -19
- package/npm-shrinkwrap.json +176 -43
- package/package.json +16 -16
- package/test/api/cloud-executable.test.js +3 -3
- package/test/api/hotswap/{lambda-hotswap-deployments.test.d.ts → code-build-projects-hotswap-deployments.test.d.ts} +0 -0
- package/test/api/hotswap/code-build-projects-hotswap-deployments.test.js +576 -0
- package/test/api/hotswap/hotswap-deployments.test.js +4 -2
- package/test/api/hotswap/hotswap-test-setup.d.ts +4 -1
- package/test/api/hotswap/hotswap-test-setup.js +13 -4
- package/test/api/hotswap/lambda-functions-hotswap-deployments.test.d.ts +1 -0
- package/test/api/hotswap/lambda-functions-hotswap-deployments.test.js +502 -0
- package/test/api/hotswap/lambda-versions-aliases-hotswap-deployments.test.d.ts +1 -0
- package/test/api/hotswap/lambda-versions-aliases-hotswap-deployments.test.js +197 -0
- package/test/api/hotswap/s3-bucket-hotswap-deployments.test.d.ts +1 -0
- package/test/api/hotswap/s3-bucket-hotswap-deployments.test.js +678 -0
- package/test/api/hotswap/state-machine-hotswap-deployments.test.js +12 -11
- package/test/cdk-toolkit.test.js +11 -4
- package/test/context-providers/generic.test.js +40 -7
- package/test/init.test.js +5 -4
- package/test/integ/cli/app/app.js +17 -2
- package/test/integ/cli/cli.integtest.js +13 -1
- package/test/integ/helpers/cdk.js +2 -1
- package/test/util/mock-sdk.d.ts +2 -0
- package/test/util/mock-sdk.js +5 -1
- package/test/version.test.js +45 -3
- package/test/api/hotswap/lambda-hotswap-deployments.test.js +0 -418
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const setup = require("./hotswap-test-setup");
|
|
4
|
+
let hotswapMockSdkProvider;
|
|
5
|
+
let mockUpdateProject;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
hotswapMockSdkProvider = setup.setupHotswapTests();
|
|
8
|
+
mockUpdateProject = jest.fn();
|
|
9
|
+
hotswapMockSdkProvider.setUpdateProjectMock(mockUpdateProject);
|
|
10
|
+
});
|
|
11
|
+
test('returns undefined when a new CodeBuild Project is added to the Stack', async () => {
|
|
12
|
+
// GIVEN
|
|
13
|
+
const cdkStackArtifact = setup.cdkStackArtifactOf({
|
|
14
|
+
template: {
|
|
15
|
+
Resources: {
|
|
16
|
+
CodeBuildProject: {
|
|
17
|
+
Type: 'AWS::CodeBuild::Project',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
// WHEN
|
|
23
|
+
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(cdkStackArtifact);
|
|
24
|
+
// THEN
|
|
25
|
+
expect(deployStackResult).toBeUndefined();
|
|
26
|
+
});
|
|
27
|
+
test('calls the updateProject() API when it receives only a source difference in a CodeBuild project', async () => {
|
|
28
|
+
// GIVEN
|
|
29
|
+
setup.setCurrentCfnStackTemplate({
|
|
30
|
+
Resources: {
|
|
31
|
+
CodeBuildProject: {
|
|
32
|
+
Type: 'AWS::CodeBuild::Project',
|
|
33
|
+
Properties: {
|
|
34
|
+
Source: {
|
|
35
|
+
BuildSpec: 'current-spec',
|
|
36
|
+
Type: 'NO_SOURCE',
|
|
37
|
+
},
|
|
38
|
+
Name: 'my-project',
|
|
39
|
+
},
|
|
40
|
+
Metadata: {
|
|
41
|
+
'aws:asset:path': 'old-path',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
const cdkStackArtifact = setup.cdkStackArtifactOf({
|
|
47
|
+
template: {
|
|
48
|
+
Resources: {
|
|
49
|
+
CodeBuildProject: {
|
|
50
|
+
Type: 'AWS::CodeBuild::Project',
|
|
51
|
+
Properties: {
|
|
52
|
+
Source: {
|
|
53
|
+
BuildSpec: 'new-spec',
|
|
54
|
+
Type: 'NO_SOURCE',
|
|
55
|
+
},
|
|
56
|
+
Name: 'my-project',
|
|
57
|
+
},
|
|
58
|
+
Metadata: {
|
|
59
|
+
'aws:asset:path': 'new-path',
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
// WHEN
|
|
66
|
+
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(cdkStackArtifact);
|
|
67
|
+
// THEN
|
|
68
|
+
expect(deployStackResult).not.toBeUndefined();
|
|
69
|
+
expect(mockUpdateProject).toHaveBeenCalledWith({
|
|
70
|
+
name: 'my-project',
|
|
71
|
+
source: {
|
|
72
|
+
type: 'NO_SOURCE',
|
|
73
|
+
buildspec: 'new-spec',
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
test('calls the updateProject() API when it receives only a source version difference in a CodeBuild project', async () => {
|
|
78
|
+
// GIVEN
|
|
79
|
+
setup.setCurrentCfnStackTemplate({
|
|
80
|
+
Resources: {
|
|
81
|
+
CodeBuildProject: {
|
|
82
|
+
Type: 'AWS::CodeBuild::Project',
|
|
83
|
+
Properties: {
|
|
84
|
+
Source: {
|
|
85
|
+
BuildSpec: 'current-spec',
|
|
86
|
+
Type: 'NO_SOURCE',
|
|
87
|
+
},
|
|
88
|
+
Name: 'my-project',
|
|
89
|
+
SourceVersion: 'v1',
|
|
90
|
+
},
|
|
91
|
+
Metadata: {
|
|
92
|
+
'aws:asset:path': 'old-path',
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
const cdkStackArtifact = setup.cdkStackArtifactOf({
|
|
98
|
+
template: {
|
|
99
|
+
Resources: {
|
|
100
|
+
CodeBuildProject: {
|
|
101
|
+
Type: 'AWS::CodeBuild::Project',
|
|
102
|
+
Properties: {
|
|
103
|
+
Source: {
|
|
104
|
+
BuildSpec: 'current-spec',
|
|
105
|
+
Type: 'NO_SOURCE',
|
|
106
|
+
},
|
|
107
|
+
Name: 'my-project',
|
|
108
|
+
SourceVersion: 'v2',
|
|
109
|
+
},
|
|
110
|
+
Metadata: {
|
|
111
|
+
'aws:asset:path': 'new-path',
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
// WHEN
|
|
118
|
+
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(cdkStackArtifact);
|
|
119
|
+
// THEN
|
|
120
|
+
expect(deployStackResult).not.toBeUndefined();
|
|
121
|
+
expect(mockUpdateProject).toHaveBeenCalledWith({
|
|
122
|
+
name: 'my-project',
|
|
123
|
+
sourceVersion: 'v2',
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
test('calls the updateProject() API when it receives only an environment difference in a CodeBuild project', async () => {
|
|
127
|
+
// GIVEN
|
|
128
|
+
setup.setCurrentCfnStackTemplate({
|
|
129
|
+
Resources: {
|
|
130
|
+
CodeBuildProject: {
|
|
131
|
+
Type: 'AWS::CodeBuild::Project',
|
|
132
|
+
Properties: {
|
|
133
|
+
Source: {
|
|
134
|
+
BuildSpec: 'current-spec',
|
|
135
|
+
Type: 'NO_SOURCE',
|
|
136
|
+
},
|
|
137
|
+
Name: 'my-project',
|
|
138
|
+
Environment: {
|
|
139
|
+
ComputeType: 'BUILD_GENERAL1_SMALL',
|
|
140
|
+
EnvironmentVariables: [
|
|
141
|
+
{
|
|
142
|
+
Name: 'SUPER_IMPORTANT_ENV_VAR',
|
|
143
|
+
Type: 'PLAINTEXT',
|
|
144
|
+
Value: 'super cool value',
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
Name: 'SECOND_IMPORTANT_ENV_VAR',
|
|
148
|
+
Type: 'PLAINTEXT',
|
|
149
|
+
Value: 'yet another super cool value',
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
Image: 'aws/codebuild/standard:1.0',
|
|
153
|
+
ImagePullCredentialsType: 'CODEBUILD',
|
|
154
|
+
PrivilegedMode: false,
|
|
155
|
+
Type: 'LINUX_CONTAINER',
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
Metadata: {
|
|
159
|
+
'aws:asset:path': 'old-path',
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
const cdkStackArtifact = setup.cdkStackArtifactOf({
|
|
165
|
+
template: {
|
|
166
|
+
Resources: {
|
|
167
|
+
CodeBuildProject: {
|
|
168
|
+
Type: 'AWS::CodeBuild::Project',
|
|
169
|
+
Properties: {
|
|
170
|
+
Source: {
|
|
171
|
+
BuildSpec: 'current-spec',
|
|
172
|
+
Type: 'NO_SOURCE',
|
|
173
|
+
},
|
|
174
|
+
Name: 'my-project',
|
|
175
|
+
Environment: {
|
|
176
|
+
ComputeType: 'BUILD_GENERAL1_SMALL',
|
|
177
|
+
EnvironmentVariables: [
|
|
178
|
+
{
|
|
179
|
+
Name: 'SUPER_IMPORTANT_ENV_VAR',
|
|
180
|
+
Type: 'PLAINTEXT',
|
|
181
|
+
Value: 'changed value',
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
Name: 'NEW_IMPORTANT_ENV_VAR',
|
|
185
|
+
Type: 'PLAINTEXT',
|
|
186
|
+
Value: 'new value',
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
Image: 'aws/codebuild/standard:1.0',
|
|
190
|
+
ImagePullCredentialsType: 'CODEBUILD',
|
|
191
|
+
PrivilegedMode: false,
|
|
192
|
+
Type: 'LINUX_CONTAINER',
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
Metadata: {
|
|
196
|
+
'aws:asset:path': 'new-path',
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
// WHEN
|
|
203
|
+
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(cdkStackArtifact);
|
|
204
|
+
// THEN
|
|
205
|
+
expect(deployStackResult).not.toBeUndefined();
|
|
206
|
+
expect(mockUpdateProject).toHaveBeenCalledWith({
|
|
207
|
+
name: 'my-project',
|
|
208
|
+
environment: {
|
|
209
|
+
computeType: 'BUILD_GENERAL1_SMALL',
|
|
210
|
+
environmentVariables: [
|
|
211
|
+
{
|
|
212
|
+
name: 'SUPER_IMPORTANT_ENV_VAR',
|
|
213
|
+
type: 'PLAINTEXT',
|
|
214
|
+
value: 'changed value',
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: 'NEW_IMPORTANT_ENV_VAR',
|
|
218
|
+
type: 'PLAINTEXT',
|
|
219
|
+
value: 'new value',
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
image: 'aws/codebuild/standard:1.0',
|
|
223
|
+
imagePullCredentialsType: 'CODEBUILD',
|
|
224
|
+
privilegedMode: false,
|
|
225
|
+
type: 'LINUX_CONTAINER',
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
test("correctly evaluates the project's name when it references a different resource from the template", async () => {
|
|
230
|
+
// GIVEN
|
|
231
|
+
setup.setCurrentCfnStackTemplate({
|
|
232
|
+
Resources: {
|
|
233
|
+
Bucket: {
|
|
234
|
+
Type: 'AWS::S3::Bucket',
|
|
235
|
+
},
|
|
236
|
+
CodeBuildProject: {
|
|
237
|
+
Type: 'AWS::CodeBuild::Project',
|
|
238
|
+
Properties: {
|
|
239
|
+
Source: {
|
|
240
|
+
BuildSpec: 'current-spec',
|
|
241
|
+
Type: 'NO_SOURCE',
|
|
242
|
+
},
|
|
243
|
+
Name: {
|
|
244
|
+
'Fn::Join': ['-', [
|
|
245
|
+
{ Ref: 'Bucket' },
|
|
246
|
+
'project',
|
|
247
|
+
]],
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
Metadata: {
|
|
251
|
+
'aws:asset:path': 'old-path',
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
setup.pushStackResourceSummaries(setup.stackSummaryOf('Bucket', 'AWS::S3::Bucket', 'mybucket'));
|
|
257
|
+
const cdkStackArtifact = setup.cdkStackArtifactOf({
|
|
258
|
+
template: {
|
|
259
|
+
Resources: {
|
|
260
|
+
Bucket: {
|
|
261
|
+
Type: 'AWS::S3::Bucket',
|
|
262
|
+
},
|
|
263
|
+
CodeBuildProject: {
|
|
264
|
+
Type: 'AWS::CodeBuild::Project',
|
|
265
|
+
Properties: {
|
|
266
|
+
Source: {
|
|
267
|
+
BuildSpec: 'new-spec',
|
|
268
|
+
Type: 'NO_SOURCE',
|
|
269
|
+
},
|
|
270
|
+
Name: {
|
|
271
|
+
'Fn::Join': ['-', [
|
|
272
|
+
{ Ref: 'Bucket' },
|
|
273
|
+
'project',
|
|
274
|
+
]],
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
Metadata: {
|
|
278
|
+
'aws:asset:path': 'old-path',
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
});
|
|
284
|
+
// WHEN
|
|
285
|
+
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(cdkStackArtifact);
|
|
286
|
+
// THEN
|
|
287
|
+
expect(deployStackResult).not.toBeUndefined();
|
|
288
|
+
expect(mockUpdateProject).toHaveBeenCalledWith({
|
|
289
|
+
name: 'mybucket-project',
|
|
290
|
+
source: {
|
|
291
|
+
type: 'NO_SOURCE',
|
|
292
|
+
buildspec: 'new-spec',
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
test("correctly falls back to taking the project's name from the current stack if it can't evaluate it in the template", async () => {
|
|
297
|
+
// GIVEN
|
|
298
|
+
setup.setCurrentCfnStackTemplate({
|
|
299
|
+
Parameters: {
|
|
300
|
+
Param1: { Type: 'String' },
|
|
301
|
+
AssetBucketParam: { Type: 'String' },
|
|
302
|
+
},
|
|
303
|
+
Resources: {
|
|
304
|
+
CodeBuildProject: {
|
|
305
|
+
Type: 'AWS::CodeBuild::Project',
|
|
306
|
+
Properties: {
|
|
307
|
+
Source: {
|
|
308
|
+
BuildSpec: 'current-spec',
|
|
309
|
+
Type: 'NO_SOURCE',
|
|
310
|
+
},
|
|
311
|
+
Name: { Ref: 'Param1' },
|
|
312
|
+
},
|
|
313
|
+
Metadata: {
|
|
314
|
+
'aws:asset:path': 'old-path',
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
});
|
|
319
|
+
setup.pushStackResourceSummaries(setup.stackSummaryOf('CodeBuildProject', 'AWS::CodeBuild::Project', 'my-project'));
|
|
320
|
+
const cdkStackArtifact = setup.cdkStackArtifactOf({
|
|
321
|
+
template: {
|
|
322
|
+
Parameters: {
|
|
323
|
+
Param1: { Type: 'String' },
|
|
324
|
+
AssetBucketParam: { Type: 'String' },
|
|
325
|
+
},
|
|
326
|
+
Resources: {
|
|
327
|
+
CodeBuildProject: {
|
|
328
|
+
Type: 'AWS::CodeBuild::Project',
|
|
329
|
+
Properties: {
|
|
330
|
+
Source: {
|
|
331
|
+
BuildSpec: 'new-spec',
|
|
332
|
+
Type: 'NO_SOURCE',
|
|
333
|
+
},
|
|
334
|
+
Name: { Ref: 'Param1' },
|
|
335
|
+
},
|
|
336
|
+
Metadata: {
|
|
337
|
+
'aws:asset:path': 'new-path',
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
// WHEN
|
|
344
|
+
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(cdkStackArtifact, { AssetBucketParam: 'asset-bucket' });
|
|
345
|
+
// THEN
|
|
346
|
+
expect(deployStackResult).not.toBeUndefined();
|
|
347
|
+
expect(mockUpdateProject).toHaveBeenCalledWith({
|
|
348
|
+
name: 'my-project',
|
|
349
|
+
source: {
|
|
350
|
+
type: 'NO_SOURCE',
|
|
351
|
+
buildspec: 'new-spec',
|
|
352
|
+
},
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
test("will not perform a hotswap deployment if it cannot find a Ref target (outside the project's name)", async () => {
|
|
356
|
+
// GIVEN
|
|
357
|
+
setup.setCurrentCfnStackTemplate({
|
|
358
|
+
Parameters: {
|
|
359
|
+
Param1: { Type: 'String' },
|
|
360
|
+
},
|
|
361
|
+
Resources: {
|
|
362
|
+
CodeBuildProject: {
|
|
363
|
+
Type: 'AWS::CodeBuild::Project',
|
|
364
|
+
Properties: {
|
|
365
|
+
Source: {
|
|
366
|
+
BuildSpec: { 'Fn::Sub': '${Param1}' },
|
|
367
|
+
Type: 'NO_SOURCE',
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
Metadata: {
|
|
371
|
+
'aws:asset:path': 'old-path',
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
});
|
|
376
|
+
setup.pushStackResourceSummaries(setup.stackSummaryOf('CodeBuildProject', 'AWS::CodeBuild::Project', 'my-project'));
|
|
377
|
+
const cdkStackArtifact = setup.cdkStackArtifactOf({
|
|
378
|
+
template: {
|
|
379
|
+
Parameters: {
|
|
380
|
+
Param1: { Type: 'String' },
|
|
381
|
+
},
|
|
382
|
+
Resources: {
|
|
383
|
+
CodeBuildProject: {
|
|
384
|
+
Type: 'AWS::CodeBuild::Project',
|
|
385
|
+
Properties: {
|
|
386
|
+
Source: {
|
|
387
|
+
BuildSpec: { 'Fn::Sub': '${Param1}' },
|
|
388
|
+
Type: 'CODEPIPELINE',
|
|
389
|
+
},
|
|
390
|
+
},
|
|
391
|
+
Metadata: {
|
|
392
|
+
'aws:asset:path': 'new-path',
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
},
|
|
397
|
+
});
|
|
398
|
+
// THEN
|
|
399
|
+
await expect(() => hotswapMockSdkProvider.tryHotswapDeployment(cdkStackArtifact)).rejects.toThrow(/Parameter or resource 'Param1' could not be found for evaluation/);
|
|
400
|
+
});
|
|
401
|
+
test("will not perform a hotswap deployment if it doesn't know how to handle a specific attribute (outside the project's name)", async () => {
|
|
402
|
+
// GIVEN
|
|
403
|
+
setup.setCurrentCfnStackTemplate({
|
|
404
|
+
Resources: {
|
|
405
|
+
Bucket: {
|
|
406
|
+
Type: 'AWS::S3::Bucket',
|
|
407
|
+
},
|
|
408
|
+
CodeBuildProject: {
|
|
409
|
+
Type: 'AWS::CodeBuild::Project',
|
|
410
|
+
Properties: {
|
|
411
|
+
Source: {
|
|
412
|
+
BuildSpec: { 'Fn::GetAtt': ['Bucket', 'UnknownAttribute'] },
|
|
413
|
+
Type: 'NO_SOURCE',
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
Metadata: {
|
|
417
|
+
'aws:asset:path': 'old-path',
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
},
|
|
421
|
+
});
|
|
422
|
+
setup.pushStackResourceSummaries(setup.stackSummaryOf('CodeBuildProject', 'AWS::CodeBuild::Project', 'my-project'), setup.stackSummaryOf('Bucket', 'AWS::S3::Bucket', 'my-bucket'));
|
|
423
|
+
const cdkStackArtifact = setup.cdkStackArtifactOf({
|
|
424
|
+
template: {
|
|
425
|
+
Resources: {
|
|
426
|
+
Bucket: {
|
|
427
|
+
Type: 'AWS::S3::Bucket',
|
|
428
|
+
},
|
|
429
|
+
CodeBuildProject: {
|
|
430
|
+
Type: 'AWS::CodeBuild::Project',
|
|
431
|
+
Properties: {
|
|
432
|
+
Source: {
|
|
433
|
+
BuildSpec: { 'Fn::GetAtt': ['Bucket', 'UnknownAttribute'] },
|
|
434
|
+
Type: 'S3',
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
Metadata: {
|
|
438
|
+
'aws:asset:path': 'new-path',
|
|
439
|
+
},
|
|
440
|
+
},
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
});
|
|
444
|
+
// THEN
|
|
445
|
+
await expect(() => hotswapMockSdkProvider.tryHotswapDeployment(cdkStackArtifact)).rejects.toThrow("We don't support the 'UnknownAttribute' attribute of the 'AWS::S3::Bucket' resource. This is a CDK limitation. Please report it at https://github.com/aws/aws-cdk/issues/new/choose");
|
|
446
|
+
});
|
|
447
|
+
test('calls the updateProject() API when it receives a difference in a CodeBuild project with no name', async () => {
|
|
448
|
+
// GIVEN
|
|
449
|
+
setup.setCurrentCfnStackTemplate({
|
|
450
|
+
Resources: {
|
|
451
|
+
CodeBuildProject: {
|
|
452
|
+
Type: 'AWS::CodeBuild::Project',
|
|
453
|
+
Properties: {
|
|
454
|
+
Source: {
|
|
455
|
+
BuildSpec: 'current-spec',
|
|
456
|
+
Type: 'NO_SOURCE',
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
Metadata: {
|
|
460
|
+
'aws:asset:path': 'current-path',
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
});
|
|
465
|
+
const cdkStackArtifact = setup.cdkStackArtifactOf({
|
|
466
|
+
template: {
|
|
467
|
+
Resources: {
|
|
468
|
+
CodeBuildProject: {
|
|
469
|
+
Type: 'AWS::CodeBuild::Project',
|
|
470
|
+
Properties: {
|
|
471
|
+
Source: {
|
|
472
|
+
BuildSpec: 'new-spec',
|
|
473
|
+
Type: 'NO_SOURCE',
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
Metadata: {
|
|
477
|
+
'aws:asset:path': 'current-path',
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
},
|
|
482
|
+
});
|
|
483
|
+
// WHEN
|
|
484
|
+
setup.pushStackResourceSummaries(setup.stackSummaryOf('CodeBuildProject', 'AWS::CodeBuild::Project', 'mock-project-resource-id'));
|
|
485
|
+
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(cdkStackArtifact);
|
|
486
|
+
// THEN
|
|
487
|
+
expect(deployStackResult).not.toBeUndefined();
|
|
488
|
+
expect(mockUpdateProject).toHaveBeenCalledWith({
|
|
489
|
+
name: 'mock-project-resource-id',
|
|
490
|
+
source: {
|
|
491
|
+
type: 'NO_SOURCE',
|
|
492
|
+
buildspec: 'new-spec',
|
|
493
|
+
},
|
|
494
|
+
});
|
|
495
|
+
});
|
|
496
|
+
test('does not call the updateProject() API when it receives a change that is not Source, SourceVersion, or Environment difference in a CodeBuild project', async () => {
|
|
497
|
+
// GIVEN
|
|
498
|
+
setup.setCurrentCfnStackTemplate({
|
|
499
|
+
Resources: {
|
|
500
|
+
CodeBuildProject: {
|
|
501
|
+
Type: 'AWS::CodeBuild::Project',
|
|
502
|
+
Properties: {
|
|
503
|
+
Source: {
|
|
504
|
+
BuildSpec: 'current-spec',
|
|
505
|
+
Type: 'NO_SOURCE',
|
|
506
|
+
},
|
|
507
|
+
ConcurrentBuildLimit: 1,
|
|
508
|
+
},
|
|
509
|
+
},
|
|
510
|
+
},
|
|
511
|
+
});
|
|
512
|
+
const cdkStackArtifact = setup.cdkStackArtifactOf({
|
|
513
|
+
template: {
|
|
514
|
+
Resources: {
|
|
515
|
+
CodeBuildProject: {
|
|
516
|
+
Type: 'AWS::CodeBuild::Project',
|
|
517
|
+
Properties: {
|
|
518
|
+
Source: {
|
|
519
|
+
BuildSpec: 'current-spec',
|
|
520
|
+
Type: 'NO_SOURCE',
|
|
521
|
+
},
|
|
522
|
+
ConcurrentBuildLimit: 2,
|
|
523
|
+
},
|
|
524
|
+
},
|
|
525
|
+
},
|
|
526
|
+
},
|
|
527
|
+
});
|
|
528
|
+
// WHEN
|
|
529
|
+
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(cdkStackArtifact);
|
|
530
|
+
// THEN
|
|
531
|
+
expect(deployStackResult).toBeUndefined();
|
|
532
|
+
expect(mockUpdateProject).not.toHaveBeenCalled();
|
|
533
|
+
});
|
|
534
|
+
test('does not call the updateProject() API when a resource with type that is not AWS::CodeBuild::Project but has the same properties is changed', async () => {
|
|
535
|
+
// GIVEN
|
|
536
|
+
setup.setCurrentCfnStackTemplate({
|
|
537
|
+
Resources: {
|
|
538
|
+
CodeBuildProject: {
|
|
539
|
+
Type: 'AWS::NotCodeBuild::NotAProject',
|
|
540
|
+
Properties: {
|
|
541
|
+
Source: {
|
|
542
|
+
BuildSpec: 'current-spec',
|
|
543
|
+
Type: 'NO_SOURCE',
|
|
544
|
+
},
|
|
545
|
+
},
|
|
546
|
+
Metadata: {
|
|
547
|
+
'aws:asset:path': 'old-path',
|
|
548
|
+
},
|
|
549
|
+
},
|
|
550
|
+
},
|
|
551
|
+
});
|
|
552
|
+
const cdkStackArtifact = setup.cdkStackArtifactOf({
|
|
553
|
+
template: {
|
|
554
|
+
Resources: {
|
|
555
|
+
CodeBuildProject: {
|
|
556
|
+
Type: 'AWS::NotCodeBuild::NotAProject',
|
|
557
|
+
Properties: {
|
|
558
|
+
Source: {
|
|
559
|
+
BuildSpec: 'new-spec',
|
|
560
|
+
Type: 'NO_SOURCE',
|
|
561
|
+
},
|
|
562
|
+
},
|
|
563
|
+
Metadata: {
|
|
564
|
+
'aws:asset:path': 'old-path',
|
|
565
|
+
},
|
|
566
|
+
},
|
|
567
|
+
},
|
|
568
|
+
},
|
|
569
|
+
});
|
|
570
|
+
// WHEN
|
|
571
|
+
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(cdkStackArtifact);
|
|
572
|
+
// THEN
|
|
573
|
+
expect(deployStackResult).toBeUndefined();
|
|
574
|
+
expect(mockUpdateProject).not.toHaveBeenCalled();
|
|
575
|
+
});
|
|
576
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZS1idWlsZC1wcm9qZWN0cy1ob3Rzd2FwLWRlcGxveW1lbnRzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjb2RlLWJ1aWxkLXByb2plY3RzLWhvdHN3YXAtZGVwbG95bWVudHMudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUNBLDhDQUE4QztBQUU5QyxJQUFJLHNCQUFvRCxDQUFDO0FBQ3pELElBQUksaUJBQTBGLENBQUM7QUFFL0YsVUFBVSxDQUFDLEdBQUcsRUFBRTtJQUNkLHNCQUFzQixHQUFHLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQ25ELGlCQUFpQixHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztJQUM5QixzQkFBc0IsQ0FBQyxvQkFBb0IsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBQ2pFLENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLHNFQUFzRSxFQUFFLEtBQUssSUFBSSxFQUFFO0lBQ3RGLFFBQVE7SUFDUixNQUFNLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztRQUNoRCxRQUFRLEVBQUU7WUFDUixTQUFTLEVBQUU7Z0JBQ1QsZ0JBQWdCLEVBQUU7b0JBQ2hCLElBQUksRUFBRSx5QkFBeUI7aUJBQ2hDO2FBQ0Y7U0FDRjtLQUNGLENBQUMsQ0FBQztJQUVILE9BQU87SUFDUCxNQUFNLGlCQUFpQixHQUFHLE1BQU0sc0JBQXNCLENBQUMsb0JBQW9CLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUU5RixPQUFPO0lBQ1AsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUMsYUFBYSxFQUFFLENBQUM7QUFDNUMsQ0FBQyxDQUFDLENBQUM7QUFFSCxJQUFJLENBQUMsZ0dBQWdHLEVBQUUsS0FBSyxJQUFJLEVBQUU7SUFDaEgsUUFBUTtJQUNSLEtBQUssQ0FBQywwQkFBMEIsQ0FBQztRQUMvQixTQUFTLEVBQUU7WUFDVCxnQkFBZ0IsRUFBRTtnQkFDaEIsSUFBSSxFQUFF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b20gJ2F3cy1zZGsnO1xuaW1wb3J0ICogYXMgc2V0dXAgZnJvbSAnLi9ob3Rzd2FwLXRlc3Qtc2V0dXAnO1xuXG5sZXQgaG90c3dhcE1vY2tTZGtQcm92aWRlcjogc2V0dXAuSG90c3dhcE1vY2tTZGtQcm92aWRlcjtcbmxldCBtb2NrVXBkYXRlUHJvamVjdDogKHBhcmFtczogQ29kZUJ1aWxkLlVwZGF0ZVByb2plY3RJbnB1dCkgPT4gQ29kZUJ1aWxkLlVwZGF0ZVByb2plY3RPdXRwdXQ7XG5cbmJlZm9yZUVhY2goKCkgPT4ge1xuICBob3Rzd2FwTW9ja1Nka1Byb3ZpZGVyID0gc2V0dXAuc2V0dXBIb3Rzd2FwVGVzdHMoKTtcbiAgbW9ja1VwZGF0ZVByb2plY3QgPSBqZXN0LmZuKCk7XG4gIGhvdHN3YXBNb2NrU2RrUHJvdmlkZXIuc2V0VXBkYXRlUHJvamVjdE1vY2sobW9ja1VwZGF0ZVByb2plY3QpO1xufSk7XG5cbnRlc3QoJ3JldHVybnMgdW5kZWZpbmVkIHdoZW4gYSBuZXcgQ29kZUJ1aWxkIFByb2plY3QgaXMgYWRkZWQgdG8gdGhlIFN0YWNrJywgYXN5bmMgKCkgPT4ge1xuICAvLyBHSVZFTlxuICBjb25zdCBjZGtTdGFja0FydGlmYWN0ID0gc2V0dXAuY2RrU3RhY2tBcnRpZmFjdE9mKHtcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgIENvZGVCdWlsZFByb2plY3Q6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpDb2RlQnVpbGQ6OlByb2plY3QnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcblxuICAvLyBXSEVOXG4gIGNvbnN0IGRlcGxveVN0YWNrUmVzdWx0ID0gYXdhaXQgaG90c3dhcE1vY2tTZGtQcm92aWRlci50cnlIb3Rzd2FwRGVwbG95bWVudChjZGtTdGFja0FydGlmYWN0KTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdChkZXBsb3lTdGFja1Jlc3VsdCkudG9CZVVuZGVmaW5lZCgpO1xufSk7XG5cbnRlc3QoJ2NhbGxzIHRoZSB1cGRhdGVQcm9qZWN0KCkgQVBJIHdoZW4gaXQgcmVjZWl2ZXMgb25seSBhIHNvdXJjZSBkaWZmZXJlbmNlIGluIGEgQ29kZUJ1aWxkIHByb2plY3QnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIHNldHVwLnNldEN1cnJlbnRDZm5TdGFja1RlbXBsYXRlKHtcbiAgICBSZXNvdXJjZXM6IHtcbiAgICAgIENvZGVCdWlsZFByb2plY3Q6IHtcbiAgICAgICAgVHlwZTogJ0FXUzo6Q29kZUJ1aWxkOjpQcm9qZWN0JyxcbiAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgIFNvdXJjZToge1xuICAgICAgICAgICAgQnVpbGRTcGVjOiAnY3VycmVudC1zcGVjJyxcbiAgICAgICAgICAgIFR5cGU6ICdOT19TT1VSQ0UnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgTmFtZTogJ215LXByb2plY3QnLFxuICAgICAgICB9LFxuICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICdhd3M6YXNzZXQ6cGF0aCc6ICdvbGQtcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xuICBjb25zdCBjZGtTdGFja0FydGlmYWN0ID0gc2V0dXAuY2RrU3RhY2tBcnRpZmFjdE9mKHtcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgIENvZGVCdWlsZFByb2plY3Q6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpDb2RlQnVpbGQ6OlByb2plY3QnLFxuICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIFNvdXJjZToge1xuICAgICAgICAgICAgICBCdWlsZFNwZWM6ICduZXctc3BlYycsXG4gICAgICAgICAgICAgIFR5cGU6ICdOT19TT1VSQ0UnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIE5hbWU6ICdteS1wcm9qZWN0JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiAnbmV3LXBhdGgnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xuXG4gIC8vIFdIRU5cbiAgY29uc3QgZGVwbG95U3RhY2tSZXN1bHQgPSBhd2FpdCBob3Rzd2FwTW9ja1Nka1Byb3ZpZGVyLnRyeUhvdHN3YXBEZXBsb3ltZW50KGNka1N0YWNrQXJ0aWZhY3QpO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KGRlcGxveVN0YWNrUmVzdWx0KS5ub3QudG9CZVVuZGVmaW5lZCgpO1xuICBleHBlY3QobW9ja1VwZGF0ZVByb2plY3QpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHtcbiAgICBuYW1lOiAnbXktcHJvamVjdCcsXG4gICAgc291cmNlOiB7XG4gICAgICB0eXBlOiAnTk9fU09VUkNFJyxcbiAgICAgIGJ1aWxkc3BlYzogJ25ldy1zcGVjJyxcbiAgICB9LFxuICB9KTtcbn0pO1xuXG50ZXN0KCdjYWxscyB0aGUgdXBkYXRlUHJvamVjdCgpIEFQSSB3aGVuIGl0IHJlY2VpdmVzIG9ubHkgYSBzb3VyY2UgdmVyc2lvbiBkaWZmZXJlbmNlIGluIGEgQ29kZUJ1aWxkIHByb2plY3QnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIHNldHVwLnNldEN1cnJlbnRDZm5TdGFja1RlbXBsYXRlKHtcbiAgICBSZXNvdXJjZXM6IHtcbiAgICAgIENvZGVCdWlsZFByb2plY3Q6IHtcbiAgICAgICAgVHlwZTogJ0FXUzo6Q29kZUJ1aWxkOjpQcm9qZWN0JyxcbiAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgIFNvdXJjZToge1xuICAgICAgICAgICAgQnVpbGRTcGVjOiAnY3VycmVudC1zcGVjJyxcbiAgICAgICAgICAgIFR5cGU6ICdOT19TT1VSQ0UnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgTmFtZTogJ215LXByb2plY3QnLFxuICAgICAgICAgIFNvdXJjZVZlcnNpb246ICd2MScsXG4gICAgICAgIH0sXG4gICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgJ2F3czphc3NldDpwYXRoJzogJ29sZC1wYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG4gIGNvbnN0IGNka1N0YWNrQXJ0aWZhY3QgPSBzZXR1cC5jZGtTdGFja0FydGlmYWN0T2Yoe1xuICAgIHRlbXBsYXRlOiB7XG4gICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgQ29kZUJ1aWxkUHJvamVjdDoge1xuICAgICAgICAgIFR5cGU6ICdBV1M6OkNvZGVCdWlsZDo6UHJvamVjdCcsXG4gICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgU291cmNlOiB7XG4gICAgICAgICAgICAgIEJ1aWxkU3BlYzogJ2N1cnJlbnQtc3BlYycsXG4gICAgICAgICAgICAgIFR5cGU6ICdOT19TT1VSQ0UnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIE5hbWU6ICdteS1wcm9qZWN0JyxcbiAgICAgICAgICAgIFNvdXJjZVZlcnNpb246ICd2MicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICAgJ2F3czphc3NldDpwYXRoJzogJ25ldy1wYXRoJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcblxuICAvLyBXSEVOXG4gIGNvbnN0IGRlcGxveVN0YWNrUmVzdWx0ID0gYXdhaXQgaG90c3dhcE1vY2tTZGtQcm92aWRlci50cnlIb3Rzd2FwRGVwbG95bWVudChjZGtTdGFja0FydGlmYWN0KTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdChkZXBsb3lTdGFja1Jlc3VsdCkubm90LnRvQmVVbmRlZmluZWQoKTtcbiAgZXhwZWN0KG1vY2tVcGRhdGVQcm9qZWN0KS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh7XG4gICAgbmFtZTogJ215LXByb2plY3QnLFxuICAgIHNvdXJjZVZlcnNpb246ICd2MicsXG4gIH0pO1xufSk7XG5cbnRlc3QoJ2NhbGxzIHRoZSB1cGRhdGVQcm9qZWN0KCkgQVBJIHdoZW4gaXQgcmVjZWl2ZXMgb25seSBhbiBlbnZpcm9ubWVudCBkaWZmZXJlbmNlIGluIGEgQ29kZUJ1aWxkIHByb2plY3QnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIHNldHVwLnNldEN1cnJlbnRDZm5TdGFja1RlbXBsYXRlKHtcbiAgICBSZXNvdXJjZXM6IHtcbiAgICAgIENvZGVCdWlsZFByb2plY3Q6IHtcbiAgICAgICAgVHlwZTogJ0FXUzo6Q29kZUJ1aWxkOjpQcm9qZWN0JyxcbiAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgIFNvdXJjZToge1xuICAgICAgICAgICAgQnVpbGRTcGVjOiAnY3VycmVudC1zcGVjJyxcbiAgICAgICAgICAgIFR5cGU6ICdOT19TT1VSQ0UnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgTmFtZTogJ215LXByb2plY3QnLFxuICAgICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgICBDb21wdXRlVHlwZTogJ0JVSUxEX0dFTkVSQUwxX1NNQUxMJyxcbiAgICAgICAgICAgIEVudmlyb25tZW50VmFyaWFibGVzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBOYW1lOiAnU1VQRVJfSU1QT1JUQU5UX0VOVl9WQVInLFxuICAgICAgICAgICAgICAgIFR5cGU6ICdQTEFJTlRFWFQnLFxuICAgICAgICAgICAgICAgIFZhbHVlOiAnc3VwZXIgY29vbCB2YWx1ZScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBOYW1lOiAnU0VDT05EX0lNUE9SVEFOVF9FTlZfVkFSJyxcbiAgICAgICAgICAgICAgICBUeXBlOiAnUExBSU5URVhUJyxcbiAgICAgICAgICAgICAgICBWYWx1ZTogJ3lldCBhbm90aGVyIHN1cGVyIGNvb2wgdmFsdWUnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIEltYWdlOiAnYXdzL2NvZGVidWlsZC9zdGFuZGFyZDoxLjAnLFxuICAgICAgICAgICAgSW1hZ2VQdWxsQ3JlZGVudGlhbHNUeXBlOiAnQ09ERUJVSUxEJyxcbiAgICAgICAgICAgIFByaXZpbGVnZWRNb2RlOiBmYWxzZSxcbiAgICAgICAgICAgIFR5cGU6ICdMSU5VWF9DT05UQUlORVInLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgJ2F3czphc3NldDpwYXRoJzogJ29sZC1wYXRoJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG4gIGNvbnN0IGNka1N0YWNrQXJ0aWZhY3QgPSBzZXR1cC5jZGtTdGFja0FydGlmYWN0T2Yoe1xuICAgIHRlbXBsYXRlOiB7XG4gICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgQ29kZUJ1aWxkUHJvamVjdDoge1xuICAgICAgICAgIFR5cGU6ICdBV1M6OkNvZGVCdWlsZDo6UHJvamVjdCcsXG4gICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgU291cmNlOiB7XG4gICAgICAgICAgICAgIEJ1aWxkU3BlYzogJ2N1cnJlbnQtc3BlYycsXG4gICAgICAgICAgICAgIFR5cGU6ICdOT19TT1VSQ0UnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIE5hbWU6ICdteS1wcm9qZWN0JyxcbiAgICAgICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgICAgIENvbXB1dGVUeXBlOiAnQlVJTERfR0VORVJBTDFfU01BTEwnLFxuICAgICAgICAgICAgICBFbnZpcm9ubWVudFZhcmlhYmxlczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIE5hbWU6ICdTVVBFUl9JTVBPUlRBTlRfRU5WX1ZBUicsXG4gICAgICAgICAgICAgICAgICBUeXBlOiAnUExBSU5URVhUJyxcbiAgICAgICAgICAgICAgICAgIFZhbHVlOiAnY2hhbmdlZCB2YWx1ZScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBOYW1lOiAnTkVXX0lNUE9SVEFOVF9FTlZfVkFSJyxcbiAgICAgICAgICAgICAgICAgIFR5cGU6ICdQTEFJTlRFWFQnLFxuICAgICAgICAgICAgICAgICAgVmFsdWU6ICduZXcgdmFsdWUnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIEltYWdlOiAnYXdzL2NvZGVidWlsZC9zdGFuZGFyZDoxLjAnLFxuICAgICAgICAgICAgICBJbWFnZVB1bGxDcmVkZW50aWFsc1R5cGU6ICdDT0RFQlVJTEQnLFxuICAgICAgICAgICAgICBQcml2aWxlZ2VkTW9kZTogZmFsc2UsXG4gICAgICAgICAgICAgIFR5cGU6ICdMSU5VWF9DT05UQUlORVInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiAnbmV3LXBhdGgnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xuXG4gIC8vIFdIRU5cbiAgY29uc3QgZGVwbG95U3RhY2tSZXN1bHQgPSBhd2FpdCBob3Rzd2FwTW9ja1Nka1Byb3ZpZGVyLnRyeUhvdHN3YXBEZXBsb3ltZW50KGNka1N0YWNrQXJ0aWZhY3QpO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KGRlcGxveVN0YWNrUmVzdWx0KS5ub3QudG9CZVVuZGVmaW5lZCgpO1xuICBleHBlY3QobW9ja1VwZGF0ZVByb2plY3QpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHtcbiAgICBuYW1lOiAnbXktcHJvamVjdCcsXG4gICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgIGNvbXB1dGVUeXBlOiAnQlVJTERfR0VORVJBTDFfU01BTEwnLFxuICAgICAgZW52aXJvbm1lbnRWYXJpYWJsZXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6ICdTVVBFUl9JTVBPUlRBTlRfRU5WX1ZBUicsXG4gICAgICAgICAgdHlwZTogJ1BMQUlOVEVYVCcsXG4gICAgICAgICAgdmFsdWU6ICdjaGFuZ2VkIHZhbHVlJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6ICdORVdfSU1QT1JUQU5UX0VOVl9WQVInLFxuICAgICAgICAgIHR5cGU6ICdQTEFJTlRFWFQnLFxuICAgICAgICAgIHZhbHVlOiAnbmV3IHZhbHVlJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBpbWFnZTogJ2F3cy9jb2RlYnVpbGQvc3RhbmRhcmQ6MS4wJyxcbiAgICAgIGltYWdlUHVsbENyZWRlbnRpYWxzVHlwZTogJ0NPREVCVUlMRCcsXG4gICAgICBwcml2aWxlZ2VkTW9kZTogZmFsc2UsXG4gICAgICB0eXBlOiAnTElOVVhfQ09OVEFJTkVSJyxcbiAgICB9LFxuICB9KTtcbn0pO1xuXG50ZXN0KFwiY29ycmVjdGx5IGV2YWx1YXRlcyB0aGUgcHJvamVjdCdzIG5hbWUgd2hlbiBpdCByZWZlcmVuY2VzIGEgZGlmZmVyZW50IHJlc291cmNlIGZyb20gdGhlIHRlbXBsYXRlXCIsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgc2V0dXAuc2V0Q3VycmVudENmblN0YWNrVGVtcGxhdGUoe1xuICAgIFJlc291cmNlczoge1xuICAgICAgQnVja2V0OiB7XG4gICAgICAgIFR5cGU6ICdBV1M6OlMzOjpCdWNrZXQnLFxuICAgICAgfSxcbiAgICAgIENvZGVCdWlsZFByb2plY3Q6IHtcbiAgICAgICAgVHlwZTogJ0FXUzo6Q29kZUJ1aWxkOjpQcm9qZWN0JyxcbiAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgIFNvdXJjZToge1xuICAgICAgICAgICAgQnVpbGRTcGVjOiAnY3VycmVudC1zcGVjJyxcbiAgICAgICAgICAgIFR5cGU6ICdOT19TT1VSQ0UnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgTmFtZToge1xuICAgICAgICAgICAgJ0ZuOjpKb2luJzogWyctJywgW1xuICAgICAgICAgICAgICB7IFJlZjogJ0J1Y2tldCcgfSxcbiAgICAgICAgICAgICAgJ3Byb2plY3QnLFxuICAgICAgICAgICAgXV0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgTWV0YWRhdGE6IHtcbiAgICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiAnb2xkLXBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbiAgc2V0dXAucHVzaFN0YWNrUmVzb3VyY2VTdW1tYXJpZXMoc2V0dXAuc3RhY2tTdW1tYXJ5T2YoJ0J1Y2tldCcsICdBV1M6OlMzOjpCdWNrZXQnLCAnbXlidWNrZXQnKSk7XG4gIGNvbnN0IGNka1N0YWNrQXJ0aWZhY3QgPSBzZXR1cC5jZGtTdGFja0FydGlmYWN0T2Yoe1xuICAgIHRlbXBsYXRlOiB7XG4gICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgQnVja2V0OiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6UzM6OkJ1Y2tldCcsXG4gICAgICAgIH0sXG4gICAgICAgIENvZGVCdWlsZFByb2plY3Q6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpDb2RlQnVpbGQ6OlByb2plY3QnLFxuICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIFNvdXJjZToge1xuICAgICAgICAgICAgICBCdWlsZFNwZWM6ICduZXctc3BlYycsXG4gICAgICAgICAgICAgIFR5cGU6ICdOT19TT1VSQ0UnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIE5hbWU6IHtcbiAgICAgICAgICAgICAgJ0ZuOjpKb2luJzogWyctJywgW1xuICAgICAgICAgICAgICAgIHsgUmVmOiAnQnVja2V0JyB9LFxuICAgICAgICAgICAgICAgICdwcm9qZWN0JyxcbiAgICAgICAgICAgICAgXV0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgTWV0YWRhdGE6IHtcbiAgICAgICAgICAgICdhd3M6YXNzZXQ6cGF0aCc6ICdvbGQtcGF0aCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG5cbiAgLy8gV0hFTlxuICBjb25zdCBkZXBsb3lTdGFja1Jlc3VsdCA9IGF3YWl0IGhvdHN3YXBNb2NrU2RrUHJvdmlkZXIudHJ5SG90c3dhcERlcGxveW1lbnQoY2RrU3RhY2tBcnRpZmFjdCk7XG5cbiAgLy8gVEhFTlxuICBleHBlY3QoZGVwbG95U3RhY2tSZXN1bHQpLm5vdC50b0JlVW5kZWZpbmVkKCk7XG4gIGV4cGVjdChtb2NrVXBkYXRlUHJvamVjdCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoe1xuICAgIG5hbWU6ICdteWJ1Y2tldC1wcm9qZWN0JyxcbiAgICBzb3VyY2U6IHtcbiAgICAgIHR5cGU6ICdOT19TT1VSQ0UnLFxuICAgICAgYnVpbGRzcGVjOiAnbmV3LXNwZWMnLFxuICAgIH0sXG4gIH0pO1xufSk7XG5cbnRlc3QoXCJjb3JyZWN0bHkgZmFsbHMgYmFjayB0byB0YWtpbmcgdGhlIHByb2plY3QncyBuYW1lIGZyb20gdGhlIGN1cnJlbnQgc3RhY2sgaWYgaXQgY2FuJ3QgZXZhbHVhdGUgaXQgaW4gdGhlIHRlbXBsYXRlXCIsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgc2V0dXAuc2V0Q3VycmVudENmblN0YWNrVGVtcGxhdGUoe1xuICAgIFBhcmFtZXRlcnM6IHtcbiAgICAgIFBhcmFtMTogeyBUeXBlOiAnU3RyaW5nJyB9LFxuICAgICAgQXNzZXRCdWNrZXRQYXJhbTogeyBUeXBlOiAnU3RyaW5nJyB9LFxuICAgIH0sXG4gICAgUmVzb3VyY2VzOiB7XG4gICAgICBDb2RlQnVpbGRQcm9qZWN0OiB7XG4gICAgICAgIFR5cGU6ICdBV1M6OkNvZGVCdWlsZDo6UHJvamVjdCcsXG4gICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICBTb3VyY2U6IHtcbiAgICAgICAgICAgIEJ1aWxkU3BlYzogJ2N1cnJlbnQtc3BlYycsXG4gICAgICAgICAgICBUeXBlOiAnTk9fU09VUkNFJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIE5hbWU6IHsgUmVmOiAnUGFyYW0xJyB9LFxuICAgICAgICB9LFxuICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICdhd3M6YXNzZXQ6cGF0aCc6ICdvbGQtcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xuICBzZXR1cC5wdXNoU3RhY2tSZXNvdXJjZVN1bW1hcmllcyhzZXR1cC5zdGFja1N1bW1hcnlPZignQ29kZUJ1aWxkUHJvamVjdCcsICdBV1M6OkNvZGVCdWlsZDo6UHJvamVjdCcsICdteS1wcm9qZWN0JykpO1xuICBjb25zdCBjZGtTdGFja0FydGlmYWN0ID0gc2V0dXAuY2RrU3RhY2tBcnRpZmFjdE9mKHtcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgUGFyYW1ldGVyczoge1xuICAgICAgICBQYXJhbTE6IHsgVHlwZTogJ1N0cmluZycgfSxcbiAgICAgICAgQXNzZXRCdWNrZXRQYXJhbTogeyBUeXBlOiAnU3RyaW5nJyB9LFxuICAgICAgfSxcbiAgICAgIFJlc291cmNlczoge1xuICAgICAgICBDb2RlQnVpbGRQcm9qZWN0OiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6Q29kZUJ1aWxkOjpQcm9qZWN0JyxcbiAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBTb3VyY2U6IHtcbiAgICAgICAgICAgICAgQnVpbGRTcGVjOiAnbmV3LXNwZWMnLFxuICAgICAgICAgICAgICBUeXBlOiAnTk9fU09VUkNFJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBOYW1lOiB7IFJlZjogJ1BhcmFtMScgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiAnbmV3LXBhdGgnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xuXG4gIC8vIFdIRU5cbiAgY29uc3QgZGVwbG95U3RhY2tSZXN1bHQgPSBhd2FpdCBob3Rzd2FwTW9ja1Nka1Byb3ZpZGVyLnRyeUhvdHN3YXBEZXBsb3ltZW50KGNka1N0YWNrQXJ0aWZhY3QsIHsgQXNzZXRCdWNrZXRQYXJhbTogJ2Fzc2V0LWJ1Y2tldCcgfSk7XG5cbiAgLy8gVEhFTlxuICBleHBlY3QoZGVwbG95U3RhY2tSZXN1bHQpLm5vdC50b0JlVW5kZWZpbmVkKCk7XG4gIGV4cGVjdChtb2NrVXBkYXRlUHJvamVjdCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoe1xuICAgIG5hbWU6ICdteS1wcm9qZWN0JyxcbiAgICBzb3VyY2U6IHtcbiAgICAgIHR5cGU6ICdOT19TT1VSQ0UnLFxuICAgICAgYnVpbGRzcGVjOiAnbmV3LXNwZWMnLFxuICAgIH0sXG4gIH0pO1xufSk7XG5cbnRlc3QoXCJ3aWxsIG5vdCBwZXJmb3JtIGEgaG90c3dhcCBkZXBsb3ltZW50IGlmIGl0IGNhbm5vdCBmaW5kIGEgUmVmIHRhcmdldCAob3V0c2lkZSB0aGUgcHJvamVjdCdzIG5hbWUpXCIsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgc2V0dXAuc2V0Q3VycmVudENmblN0YWNrVGVtcGxhdGUoe1xuICAgIFBhcmFtZXRlcnM6IHtcbiAgICAgIFBhcmFtMTogeyBUeXBlOiAnU3RyaW5nJyB9LFxuICAgIH0sXG4gICAgUmVzb3VyY2VzOiB7XG4gICAgICBDb2RlQnVpbGRQcm9qZWN0OiB7XG4gICAgICAgIFR5cGU6ICdBV1M6OkNvZGVCdWlsZDo6UHJvamVjdCcsXG4gICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICBTb3VyY2U6IHtcbiAgICAgICAgICAgIEJ1aWxkU3BlYzogeyAnRm46OlN1Yic6ICcke1BhcmFtMX0nIH0sXG4gICAgICAgICAgICBUeXBlOiAnTk9fU09VUkNFJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICdhd3M6YXNzZXQ6cGF0aCc6ICdvbGQtcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xuICBzZXR1cC5wdXNoU3RhY2tSZXNvdXJjZVN1bW1hcmllcyhzZXR1cC5zdGFja1N1bW1hcnlPZignQ29kZUJ1aWxkUHJvamVjdCcsICdBV1M6OkNvZGVCdWlsZDo6UHJvamVjdCcsICdteS1wcm9qZWN0JykpO1xuICBjb25zdCBjZGtTdGFja0FydGlmYWN0ID0gc2V0dXAuY2RrU3RhY2tBcnRpZmFjdE9mKHtcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgUGFyYW1ldGVyczoge1xuICAgICAgICBQYXJhbTE6IHsgVHlwZTogJ1N0cmluZycgfSxcbiAgICAgIH0sXG4gICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgQ29kZUJ1aWxkUHJvamVjdDoge1xuICAgICAgICAgIFR5cGU6ICdBV1M6OkNvZGVCdWlsZDo6UHJvamVjdCcsXG4gICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgU291cmNlOiB7XG4gICAgICAgICAgICAgIEJ1aWxkU3BlYzogeyAnRm46OlN1Yic6ICcke1BhcmFtMX0nIH0sXG4gICAgICAgICAgICAgIFR5cGU6ICdDT0RFUElQRUxJTkUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiAnbmV3LXBhdGgnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xuXG4gIC8vIFRIRU5cbiAgYXdhaXQgZXhwZWN0KCgpID0+XG4gICAgaG90c3dhcE1vY2tTZGtQcm92aWRlci50cnlIb3Rzd2FwRGVwbG95bWVudChjZGtTdGFja0FydGlmYWN0KSxcbiAgKS5yZWplY3RzLnRvVGhyb3coL1BhcmFtZXRlciBvciByZXNvdXJjZSAnUGFyYW0xJyBjb3VsZCBub3QgYmUgZm91bmQgZm9yIGV2YWx1YXRpb24vKTtcbn0pO1xuXG50ZXN0KFwid2lsbCBub3QgcGVyZm9ybSBhIGhvdHN3YXAgZGVwbG95bWVudCBpZiBpdCBkb2Vzbid0IGtub3cgaG93IHRvIGhhbmRsZSBhIHNwZWNpZmljIGF0dHJpYnV0ZSAob3V0c2lkZSB0aGUgcHJvamVjdCdzIG5hbWUpXCIsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgc2V0dXAuc2V0Q3VycmVudENmblN0YWNrVGVtcGxhdGUoe1xuICAgIFJlc291cmNlczoge1xuICAgICAgQnVja2V0OiB7XG4gICAgICAgIFR5cGU6ICdBV1M6OlMzOjpCdWNrZXQnLFxuICAgICAgfSxcbiAgICAgIENvZGVCdWlsZFByb2plY3Q6IHtcbiAgICAgICAgVHlwZTogJ0FXUzo6Q29kZUJ1aWxkOjpQcm9qZWN0JyxcbiAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgIFNvdXJjZToge1xuICAgICAgICAgICAgQnVpbGRTcGVjOiB7ICdGbjo6R2V0QXR0JzogWydCdWNrZXQnLCAnVW5rbm93bkF0dHJpYnV0ZSddIH0sXG4gICAgICAgICAgICBUeXBlOiAnTk9fU09VUkNFJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICdhd3M6YXNzZXQ6cGF0aCc6ICdvbGQtcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xuICBzZXR1cC5wdXNoU3RhY2tSZXNvdXJjZVN1bW1hcmllcyhcbiAgICBzZXR1cC5zdGFja1N1bW1hcnlPZignQ29kZUJ1aWxkUHJvamVjdCcsICdBV1M6OkNvZGVCdWlsZDo6UHJvamVjdCcsICdteS1wcm9qZWN0JyksXG4gICAgc2V0dXAuc3RhY2tTdW1tYXJ5T2YoJ0J1Y2tldCcsICdBV1M6OlMzOjpCdWNrZXQnLCAnbXktYnVja2V0JyksXG4gICk7XG4gIGNvbnN0IGNka1N0YWNrQXJ0aWZhY3QgPSBzZXR1cC5jZGtTdGFja0FydGlmYWN0T2Yoe1xuICAgIHRlbXBsYXRlOiB7XG4gICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgQnVja2V0OiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6UzM6OkJ1Y2tldCcsXG4gICAgICAgIH0sXG4gICAgICAgIENvZGVCdWlsZFByb2plY3Q6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpDb2RlQnVpbGQ6OlByb2plY3QnLFxuICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIFNvdXJjZToge1xuICAgICAgICAgICAgICBCdWlsZFNwZWM6IHsgJ0ZuOjpHZXRBdHQnOiBbJ0J1Y2tldCcsICdVbmtub3duQXR0cmlidXRlJ10gfSxcbiAgICAgICAgICAgICAgVHlwZTogJ1MzJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICAgJ2F3czphc3NldDpwYXRoJzogJ25ldy1wYXRoJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcblxuICAvLyBUSEVOXG4gIGF3YWl0IGV4cGVjdCgoKSA9PlxuICAgIGhvdHN3YXBNb2NrU2RrUHJvdmlkZXIudHJ5SG90c3dhcERlcGxveW1lbnQoY2RrU3RhY2tBcnRpZmFjdCksXG4gICkucmVqZWN0cy50b1Rocm93KFwiV2UgZG9uJ3Qgc3VwcG9ydCB0aGUgJ1Vua25vd25BdHRyaWJ1dGUnIGF0dHJpYnV0ZSBvZiB0aGUgJ0FXUzo6UzM6OkJ1Y2tldCcgcmVzb3VyY2UuIFRoaXMgaXMgYSBDREsgbGltaXRhdGlvbi4gUGxlYXNlIHJlcG9ydCBpdCBhdCBodHRwczovL2dpdGh1Yi5jb20vYXdzL2F3cy1jZGsvaXNzdWVzL25ldy9jaG9vc2VcIik7XG59KTtcblxudGVzdCgnY2FsbHMgdGhlIHVwZGF0ZVByb2plY3QoKSBBUEkgd2hlbiBpdCByZWNlaXZlcyBhIGRpZmZlcmVuY2UgaW4gYSBDb2RlQnVpbGQgcHJvamVjdCB3aXRoIG5vIG5hbWUnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIHNldHVwLnNldEN1cnJlbnRDZm5TdGFja1RlbXBsYXRlKHtcbiAgICBSZXNvdXJjZXM6IHtcbiAgICAgIENvZGVCdWlsZFByb2plY3Q6IHtcbiAgICAgICAgVHlwZTogJ0FXUzo6Q29kZUJ1aWxkOjpQcm9qZWN0JyxcbiAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgIFNvdXJjZToge1xuICAgICAgICAgICAgQnVpbGRTcGVjOiAnY3VycmVudC1zcGVjJyxcbiAgICAgICAgICAgIFR5cGU6ICdOT19TT1VSQ0UnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgJ2F3czphc3NldDpwYXRoJzogJ2N1cnJlbnQtcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xuICBjb25zdCBjZGtTdGFja0FydGlmYWN0ID0gc2V0dXAuY2RrU3RhY2tBcnRpZmFjdE9mKHtcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgIENvZGVCdWlsZFByb2plY3Q6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpDb2RlQnVpbGQ6OlByb2plY3QnLFxuICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIFNvdXJjZToge1xuICAgICAgICAgICAgICBCdWlsZFNwZWM6ICduZXctc3BlYycsXG4gICAgICAgICAgICAgIFR5cGU6ICdOT19TT1VSQ0UnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIE1ldGFkYXRhOiB7XG4gICAgICAgICAgICAnYXdzOmFzc2V0OnBhdGgnOiAnY3VycmVudC1wYXRoJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcblxuICAvLyBXSEVOXG4gIHNldHVwLnB1c2hTdGFja1Jlc291cmNlU3VtbWFyaWVzKHNldHVwLnN0YWNrU3VtbWFyeU9mKCdDb2RlQnVpbGRQcm9qZWN0JywgJ0FXUzo6Q29kZUJ1aWxkOjpQcm9qZWN0JywgJ21vY2stcHJvamVjdC1yZXNvdXJjZS1pZCcpKTtcbiAgY29uc3QgZGVwbG95U3RhY2tSZXN1bHQgPSBhd2FpdCBob3Rzd2FwTW9ja1Nka1Byb3ZpZGVyLnRyeUhvdHN3YXBEZXBsb3ltZW50KGNka1N0YWNrQXJ0aWZhY3QpO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KGRlcGxveVN0YWNrUmVzdWx0KS5ub3QudG9CZVVuZGVmaW5lZCgpO1xuICBleHBlY3QobW9ja1VwZGF0ZVByb2plY3QpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHtcbiAgICBuYW1lOiAnbW9jay1wcm9qZWN0LXJlc291cmNlLWlkJyxcbiAgICBzb3VyY2U6IHtcbiAgICAgIHR5cGU6ICdOT19TT1VSQ0UnLFxuICAgICAgYnVpbGRzcGVjOiAnbmV3LXNwZWMnLFxuICAgIH0sXG4gIH0pO1xufSk7XG5cbnRlc3QoJ2RvZXMgbm90IGNhbGwgdGhlIHVwZGF0ZVByb2plY3QoKSBBUEkgd2hlbiBpdCByZWNlaXZlcyBhIGNoYW5nZSB0aGF0IGlzIG5vdCBTb3VyY2UsIFNvdXJjZVZlcnNpb24sIG9yIEVudmlyb25tZW50IGRpZmZlcmVuY2UgaW4gYSBDb2RlQnVpbGQgcHJvamVjdCcsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgc2V0dXAuc2V0Q3VycmVudENmblN0YWNrVGVtcGxhdGUoe1xuICAgIFJlc291cmNlczoge1xuICAgICAgQ29kZUJ1aWxkUHJvamVjdDoge1xuICAgICAgICBUeXBlOiAnQVdTOjpDb2RlQnVpbGQ6OlByb2plY3QnLFxuICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgU291cmNlOiB7XG4gICAgICAgICAgICBCdWlsZFNwZWM6ICdjdXJyZW50LXNwZWMnLFxuICAgICAgICAgICAgVHlwZTogJ05PX1NPVVJDRScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBDb25jdXJyZW50QnVpbGRMaW1pdDogMSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG4gIGNvbnN0IGNka1N0YWNrQXJ0aWZhY3QgPSBzZXR1cC5jZGtTdGFja0FydGlmYWN0T2Yoe1xuICAgIHRlbXBsYXRlOiB7XG4gICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgQ29kZUJ1aWxkUHJvamVjdDoge1xuICAgICAgICAgIFR5cGU6ICdBV1M6OkNvZGVCdWlsZDo6UHJvamVjdCcsXG4gICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgU291cmNlOiB7XG4gICAgICAgICAgICAgIEJ1aWxkU3BlYzogJ2N1cnJlbnQtc3BlYycsXG4gICAgICAgICAgICAgIFR5cGU6ICdOT19TT1VSQ0UnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIENvbmN1cnJlbnRCdWlsZExpbWl0OiAyLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xuXG4gIC8vIFdIRU5cbiAgY29uc3QgZGVwbG95U3RhY2tSZXN1bHQgPSBhd2FpdCBob3Rzd2FwTW9ja1Nka1Byb3ZpZGVyLnRyeUhvdHN3YXBEZXBsb3ltZW50KGNka1N0YWNrQXJ0aWZhY3QpO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KGRlcGxveVN0YWNrUmVzdWx0KS50b0JlVW5kZWZpbmVkKCk7XG4gIGV4cGVjdChtb2NrVXBkYXRlUHJvamVjdCkubm90LnRvSGF2ZUJlZW5DYWxsZWQoKTtcbn0pO1xuXG50ZXN0KCdkb2VzIG5vdCBjYWxsIHRoZSB1cGRhdGVQcm9qZWN0KCkgQVBJIHdoZW4gYSByZXNvdXJjZSB3aXRoIHR5cGUgdGhhdCBpcyBub3QgQVdTOjpDb2RlQnVpbGQ6OlByb2plY3QgYnV0IGhhcyB0aGUgc2FtZSBwcm9wZXJ0aWVzIGlzIGNoYW5nZWQnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIHNldHVwLnNldEN1cnJlbnRDZm5TdGFja1RlbXBsYXRlKHtcbiAgICBSZXNvdXJjZXM6IHtcbiAgICAgIENvZGVCdWlsZFByb2plY3Q6IHtcbiAgICAgICAgVHlwZTogJ0FXUzo6Tm90Q29kZUJ1aWxkOjpOb3RBUHJvamVjdCcsXG4gICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICBTb3VyY2U6IHtcbiAgICAgICAgICAgIEJ1aWxkU3BlYzogJ2N1cnJlbnQtc3BlYycsXG4gICAgICAgICAgICBUeXBlOiAnTk9fU09VUkNFJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICdhd3M6YXNzZXQ6cGF0aCc6ICdvbGQtcGF0aCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xuICBjb25zdCBjZGtTdGFja0FydGlmYWN0ID0gc2V0dXAuY2RrU3RhY2tBcnRpZmFjdE9mKHtcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgIENvZGVCdWlsZFByb2plY3Q6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpOb3RDb2RlQnVpbGQ6Ok5vdEFQcm9qZWN0JyxcbiAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBTb3VyY2U6IHtcbiAgICAgICAgICAgICAgQnVpbGRTcGVjOiAnbmV3LXNwZWMnLFxuICAgICAgICAgICAgICBUeXBlOiAnTk9fU09VUkNFJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBNZXRhZGF0YToge1xuICAgICAgICAgICAgJ2F3czphc3NldDpwYXRoJzogJ29sZC1wYXRoJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcblxuICAvLyBXSEVOXG4gIGNvbnN0IGRlcGxveVN0YWNrUmVzdWx0ID0gYXdhaXQgaG90c3dhcE1vY2tTZGtQcm92aWRlci50cnlIb3Rzd2FwRGVwbG95bWVudChjZGtTdGFja0FydGlmYWN0KTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdChkZXBsb3lTdGFja1Jlc3VsdCkudG9CZVVuZGVmaW5lZCgpO1xuICBleHBlY3QobW9ja1VwZGF0ZVByb2plY3QpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG59KTsiXX0=
|