@aws-solutions-constructs/aws-wafwebacl-appsync 2.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
6
+ * with the License. A copy of the License is located at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
11
+ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
12
+ * and limitations under the License.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ // Imports
16
+ const cdk = require("aws-cdk-lib");
17
+ const lib_1 = require("../lib");
18
+ const waf = require("aws-cdk-lib/aws-wafv2");
19
+ const defaults = require("@aws-solutions-constructs/core");
20
+ const appsync = require("aws-cdk-lib/aws-appsync");
21
+ require("@aws-cdk/assert/jest");
22
+ function deployAppsyncGraphqlApi(stack) {
23
+ return new appsync.CfnGraphQLApi(stack, "new-api", {
24
+ name: "api",
25
+ authenticationType: "API_KEY",
26
+ });
27
+ }
28
+ function deployConstruct(stack, webaclProps, existingWebaclObj) {
29
+ const api = deployAppsyncGraphqlApi(stack);
30
+ return new lib_1.WafwebaclToAppsync(stack, "test-waf-appsync", {
31
+ existingAppsyncApi: api,
32
+ webaclProps,
33
+ existingWebaclObj,
34
+ });
35
+ }
36
+ // --------------------------------------------------------------
37
+ // Test error handling for existing WAF web ACL and user provided web ACL props
38
+ // --------------------------------------------------------------
39
+ test("Test error handling for existing WAF web ACL and user provider web ACL props", () => {
40
+ const stack = new cdk.Stack();
41
+ const props = {
42
+ defaultAction: {
43
+ allow: {},
44
+ },
45
+ scope: "REGIONAL",
46
+ visibilityConfig: {
47
+ cloudWatchMetricsEnabled: false,
48
+ metricName: "webACL",
49
+ sampledRequestsEnabled: true,
50
+ },
51
+ };
52
+ const wafAcl = new waf.CfnWebACL(stack, "test-waf", props);
53
+ const api = deployAppsyncGraphqlApi(stack);
54
+ expect(() => {
55
+ new lib_1.WafwebaclToAppsync(stack, "test-waf-appsync", {
56
+ existingAppsyncApi: api,
57
+ existingWebaclObj: wafAcl,
58
+ webaclProps: props,
59
+ });
60
+ }).toThrowError();
61
+ });
62
+ // --------------------------------------------------------------
63
+ // Test default deployment
64
+ // --------------------------------------------------------------
65
+ test("Test default deployment", () => {
66
+ const stack = new cdk.Stack();
67
+ const construct = deployConstruct(stack);
68
+ expect(construct.webacl !== null);
69
+ expect(construct.appsyncApi !== null);
70
+ expect(stack).toHaveResource("AWS::WAFv2::WebACL", {
71
+ Rules: [
72
+ {
73
+ Name: "AWS-AWSManagedRulesBotControlRuleSet",
74
+ OverrideAction: {
75
+ None: {},
76
+ },
77
+ Priority: 0,
78
+ Statement: {
79
+ ManagedRuleGroupStatement: {
80
+ Name: "AWSManagedRulesBotControlRuleSet",
81
+ VendorName: "AWS",
82
+ },
83
+ },
84
+ VisibilityConfig: {
85
+ CloudWatchMetricsEnabled: true,
86
+ MetricName: "AWSManagedRulesBotControlRuleSet",
87
+ SampledRequestsEnabled: true,
88
+ },
89
+ },
90
+ {
91
+ Name: "AWS-AWSManagedRulesKnownBadInputsRuleSet",
92
+ OverrideAction: {
93
+ None: {},
94
+ },
95
+ Priority: 1,
96
+ Statement: {
97
+ ManagedRuleGroupStatement: {
98
+ Name: "AWSManagedRulesKnownBadInputsRuleSet",
99
+ VendorName: "AWS",
100
+ },
101
+ },
102
+ VisibilityConfig: {
103
+ CloudWatchMetricsEnabled: true,
104
+ MetricName: "AWSManagedRulesKnownBadInputsRuleSet",
105
+ SampledRequestsEnabled: true,
106
+ },
107
+ },
108
+ {
109
+ Name: "AWS-AWSManagedRulesCommonRuleSet",
110
+ OverrideAction: {
111
+ None: {},
112
+ },
113
+ Priority: 2,
114
+ Statement: {
115
+ ManagedRuleGroupStatement: {
116
+ Name: "AWSManagedRulesCommonRuleSet",
117
+ VendorName: "AWS",
118
+ },
119
+ },
120
+ VisibilityConfig: {
121
+ CloudWatchMetricsEnabled: true,
122
+ MetricName: "AWSManagedRulesCommonRuleSet",
123
+ SampledRequestsEnabled: true,
124
+ },
125
+ },
126
+ {
127
+ Name: "AWS-AWSManagedRulesAnonymousIpList",
128
+ OverrideAction: {
129
+ None: {},
130
+ },
131
+ Priority: 3,
132
+ Statement: {
133
+ ManagedRuleGroupStatement: {
134
+ Name: "AWSManagedRulesAnonymousIpList",
135
+ VendorName: "AWS",
136
+ },
137
+ },
138
+ VisibilityConfig: {
139
+ CloudWatchMetricsEnabled: true,
140
+ MetricName: "AWSManagedRulesAnonymousIpList",
141
+ SampledRequestsEnabled: true,
142
+ },
143
+ },
144
+ {
145
+ Name: "AWS-AWSManagedRulesAmazonIpReputationList",
146
+ OverrideAction: {
147
+ None: {},
148
+ },
149
+ Priority: 4,
150
+ Statement: {
151
+ ManagedRuleGroupStatement: {
152
+ Name: "AWSManagedRulesAmazonIpReputationList",
153
+ VendorName: "AWS",
154
+ },
155
+ },
156
+ VisibilityConfig: {
157
+ CloudWatchMetricsEnabled: true,
158
+ MetricName: "AWSManagedRulesAmazonIpReputationList",
159
+ SampledRequestsEnabled: true,
160
+ },
161
+ },
162
+ {
163
+ Name: "AWS-AWSManagedRulesAdminProtectionRuleSet",
164
+ OverrideAction: {
165
+ None: {},
166
+ },
167
+ Priority: 5,
168
+ Statement: {
169
+ ManagedRuleGroupStatement: {
170
+ Name: "AWSManagedRulesAdminProtectionRuleSet",
171
+ VendorName: "AWS",
172
+ },
173
+ },
174
+ VisibilityConfig: {
175
+ CloudWatchMetricsEnabled: true,
176
+ MetricName: "AWSManagedRulesAdminProtectionRuleSet",
177
+ SampledRequestsEnabled: true,
178
+ },
179
+ },
180
+ {
181
+ Name: "AWS-AWSManagedRulesSQLiRuleSet",
182
+ OverrideAction: {
183
+ None: {},
184
+ },
185
+ Priority: 6,
186
+ Statement: {
187
+ ManagedRuleGroupStatement: {
188
+ Name: "AWSManagedRulesSQLiRuleSet",
189
+ VendorName: "AWS",
190
+ },
191
+ },
192
+ VisibilityConfig: {
193
+ CloudWatchMetricsEnabled: true,
194
+ MetricName: "AWSManagedRulesSQLiRuleSet",
195
+ SampledRequestsEnabled: true,
196
+ },
197
+ },
198
+ ],
199
+ });
200
+ });
201
+ // --------------------------------------------------------------
202
+ // Test web acl with user provided acl props
203
+ // --------------------------------------------------------------
204
+ test("Test user provided acl props", () => {
205
+ const stack = new cdk.Stack();
206
+ const webaclProps = {
207
+ defaultAction: {
208
+ allow: {},
209
+ },
210
+ scope: "REGIONAL",
211
+ visibilityConfig: {
212
+ cloudWatchMetricsEnabled: false,
213
+ metricName: "webACL",
214
+ sampledRequestsEnabled: true,
215
+ },
216
+ rules: [
217
+ defaults.wrapManagedRuleSet("AWSManagedRulesCommonRuleSet", "AWS", 0),
218
+ defaults.wrapManagedRuleSet("AWSManagedRulesWordPressRuleSet", "AWS", 1),
219
+ ],
220
+ };
221
+ deployConstruct(stack, webaclProps);
222
+ expect(stack).toHaveResource("AWS::WAFv2::WebACL", {
223
+ VisibilityConfig: {
224
+ CloudWatchMetricsEnabled: false,
225
+ MetricName: "webACL",
226
+ SampledRequestsEnabled: true,
227
+ },
228
+ Rules: [
229
+ {
230
+ Name: "AWS-AWSManagedRulesCommonRuleSet",
231
+ OverrideAction: {
232
+ None: {},
233
+ },
234
+ Priority: 0,
235
+ Statement: {
236
+ ManagedRuleGroupStatement: {
237
+ Name: "AWSManagedRulesCommonRuleSet",
238
+ VendorName: "AWS",
239
+ },
240
+ },
241
+ VisibilityConfig: {
242
+ CloudWatchMetricsEnabled: true,
243
+ MetricName: "AWSManagedRulesCommonRuleSet",
244
+ SampledRequestsEnabled: true,
245
+ },
246
+ },
247
+ {
248
+ Name: "AWS-AWSManagedRulesWordPressRuleSet",
249
+ OverrideAction: {
250
+ None: {},
251
+ },
252
+ Priority: 1,
253
+ Statement: {
254
+ ManagedRuleGroupStatement: {
255
+ Name: "AWSManagedRulesWordPressRuleSet",
256
+ VendorName: "AWS",
257
+ },
258
+ },
259
+ VisibilityConfig: {
260
+ CloudWatchMetricsEnabled: true,
261
+ MetricName: "AWSManagedRulesWordPressRuleSet",
262
+ SampledRequestsEnabled: true,
263
+ },
264
+ },
265
+ ],
266
+ });
267
+ });
268
+ // --------------------------------------------------------------
269
+ // Test existing web ACL
270
+ // --------------------------------------------------------------
271
+ test("Test existing web ACL", () => {
272
+ const stack = new cdk.Stack();
273
+ const webacl = new waf.CfnWebACL(stack, "test-webacl", {
274
+ defaultAction: {
275
+ allow: {},
276
+ },
277
+ scope: "REGIONAL",
278
+ visibilityConfig: {
279
+ cloudWatchMetricsEnabled: true,
280
+ metricName: "webACL",
281
+ sampledRequestsEnabled: true,
282
+ },
283
+ });
284
+ deployConstruct(stack, undefined, webacl);
285
+ expect(stack).toHaveResource("AWS::WAFv2::WebACL", {
286
+ VisibilityConfig: {
287
+ CloudWatchMetricsEnabled: true,
288
+ MetricName: "webACL",
289
+ SampledRequestsEnabled: true,
290
+ },
291
+ });
292
+ expect(stack).toCountResources("AWS::WAFv2::WebACL", 1);
293
+ });
294
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC53YWZ3ZWJhY2wtYXBwc3luYy50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidGVzdC53YWZ3ZWJhY2wtYXBwc3luYy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7R0FXRzs7QUFFSCxVQUFVO0FBQ1YsbUNBQW1DO0FBQ25DLGdDQUE0QztBQUM1Qyw2Q0FBNkM7QUFDN0MsMkRBQTJEO0FBQzNELG1EQUFtRDtBQUNuRCxnQ0FBOEI7QUFFOUIsU0FBUyx1QkFBdUIsQ0FBQyxLQUFnQjtJQUMvQyxPQUFPLElBQUksT0FBTyxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFO1FBQ2pELElBQUksRUFBRSxLQUFLO1FBQ1gsa0JBQWtCLEVBQUUsU0FBUztLQUM5QixDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsU0FBUyxlQUFlLENBQ3RCLEtBQWdCLEVBQ2hCLFdBQWdDLEVBQ2hDLGlCQUFpQztJQUVqQyxNQUFNLEdBQUcsR0FBRyx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUUzQyxPQUFPLElBQUksd0JBQWtCLENBQUMsS0FBSyxFQUFFLGtCQUFrQixFQUFFO1FBQ3ZELGtCQUFrQixFQUFFLEdBQUc7UUFDdkIsV0FBVztRQUNYLGlCQUFpQjtLQUNsQixDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsaUVBQWlFO0FBQ2pFLCtFQUErRTtBQUMvRSxpRUFBaUU7QUFDakUsSUFBSSxDQUFDLDhFQUE4RSxFQUFFLEdBQUcsRUFBRTtJQUN4RixNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUM5QixNQUFNLEtBQUssR0FBdUI7UUFDaEMsYUFBYSxFQUFFO1lBQ2IsS0FBSyxFQUFFLEVBQUU7U0FDVjtRQUNELEtBQUssRUFBRSxVQUFVO1FBQ2pCLGdCQUFnQixFQUFFO1lBQ2hCLHdCQUF3QixFQUFFLEtBQUs7WUFDL0IsVUFBVSxFQUFFLFFBQVE7WUFDcEIs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UUFDakQsZ0JBQWdCLEVBQUU7WUFDaEIsd0JBQXdCLEVBQUUsSUFBSTtZQUM5QixVQUFVLEVBQUUsUUFBUTtZQUNwQixzQkFBc0IsRUFBRSxJQUFJO1NBQzdCO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLGdCQUFnQixDQUFDLG9CQUFvQixFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzFELENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgQ29weXJpZ2h0IDIwMjIgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKS4gWW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogIHdpdGggdGhlIExpY2Vuc2UuIEEgY29weSBvZiB0aGUgTGljZW5zZSBpcyBsb2NhdGVkIGF0XG4gKlxuICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiAgb3IgaW4gdGhlICdsaWNlbnNlJyBmaWxlIGFjY29tcGFueWluZyB0aGlzIGZpbGUuIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAnQVMgSVMnIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVNcbiAqICBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9uc1xuICogIGFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG4vLyBJbXBvcnRzXG5pbXBvcnQgKiBhcyBjZGsgZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBXYWZ3ZWJhY2xUb0FwcHN5bmMgfSBmcm9tIFwiLi4vbGliXCI7XG5pbXBvcnQgKiBhcyB3YWYgZnJvbSBcImF3cy1jZGstbGliL2F3cy13YWZ2MlwiO1xuaW1wb3J0ICogYXMgZGVmYXVsdHMgZnJvbSBcIkBhd3Mtc29sdXRpb25zLWNvbnN0cnVjdHMvY29yZVwiO1xuaW1wb3J0ICogYXMgYXBwc3luYyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWFwcHN5bmNcIjtcbmltcG9ydCBcIkBhd3MtY2RrL2Fzc2VydC9qZXN0XCI7XG5cbmZ1bmN0aW9uIGRlcGxveUFwcHN5bmNHcmFwaHFsQXBpKHN0YWNrOiBjZGsuU3RhY2spIHtcbiAgcmV0dXJuIG5ldyBhcHBzeW5jLkNmbkdyYXBoUUxBcGkoc3RhY2ssIFwibmV3LWFwaVwiLCB7XG4gICAgbmFtZTogXCJhcGlcIixcbiAgICBhdXRoZW50aWNhdGlvblR5cGU6IFwiQVBJX0tFWVwiLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGVwbG95Q29uc3RydWN0KFxuICBzdGFjazogY2RrLlN0YWNrLFxuICB3ZWJhY2xQcm9wcz86IHdhZi5DZm5XZWJBQ0xQcm9wcyxcbiAgZXhpc3RpbmdXZWJhY2xPYmo/OiB3YWYuQ2ZuV2ViQUNMXG4pIHtcbiAgY29uc3QgYXBpID0gZGVwbG95QXBwc3luY0dyYXBocWxBcGkoc3RhY2spO1xuXG4gIHJldHVybiBuZXcgV2Fmd2ViYWNsVG9BcHBzeW5jKHN0YWNrLCBcInRlc3Qtd2FmLWFwcHN5bmNcIiwge1xuICAgIGV4aXN0aW5nQXBwc3luY0FwaTogYXBpLFxuICAgIHdlYmFjbFByb3BzLFxuICAgIGV4aXN0aW5nV2ViYWNsT2JqLFxuICB9KTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRlc3QgZXJyb3IgaGFuZGxpbmcgZm9yIGV4aXN0aW5nIFdBRiB3ZWIgQUNMIGFuZCB1c2VyIHByb3ZpZGVkIHdlYiBBQ0wgcHJvcHNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG50ZXN0KFwiVGVzdCBlcnJvciBoYW5kbGluZyBmb3IgZXhpc3RpbmcgV0FGIHdlYiBBQ0wgYW5kIHVzZXIgcHJvdmlkZXIgd2ViIEFDTCBwcm9wc1wiLCAoKSA9PiB7XG4gIGNvbnN0IHN0YWNrID0gbmV3IGNkay5TdGFjaygpO1xuICBjb25zdCBwcm9wczogd2FmLkNmbldlYkFDTFByb3BzID0ge1xuICAgIGRlZmF1bHRBY3Rpb246IHtcbiAgICAgIGFsbG93OiB7fSxcbiAgICB9LFxuICAgIHNjb3BlOiBcIlJFR0lPTkFMXCIsXG4gICAgdmlzaWJpbGl0eUNvbmZpZzoge1xuICAgICAgY2xvdWRXYXRjaE1ldHJpY3NFbmFibGVkOiBmYWxzZSxcbiAgICAgIG1ldHJpY05hbWU6IFwid2ViQUNMXCIsXG4gICAgICBzYW1wbGVkUmVxdWVzdHNFbmFibGVkOiB0cnVlLFxuICAgIH0sXG4gIH07XG5cbiAgY29uc3Qgd2FmQWNsID0gbmV3IHdhZi5DZm5XZWJBQ0woc3RhY2ssIFwidGVzdC13YWZcIiwgcHJvcHMpO1xuICBjb25zdCBhcGkgPSBkZXBsb3lBcHBzeW5jR3JhcGhxbEFwaShzdGFjayk7XG5cbiAgZXhwZWN0KCgpID0+IHtcbiAgICBuZXcgV2Fmd2ViYWNsVG9BcHBzeW5jKHN0YWNrLCBcInRlc3Qtd2FmLWFwcHN5bmNcIiwge1xuICAgICAgZXhpc3RpbmdBcHBzeW5jQXBpOiBhcGksXG4gICAgICBleGlzdGluZ1dlYmFjbE9iajogd2FmQWNsLFxuICAgICAgd2ViYWNsUHJvcHM6IHByb3BzLFxuICAgIH0pO1xuICB9KS50b1Rocm93RXJyb3IoKTtcbn0pO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVGVzdCBkZWZhdWx0IGRlcGxveW1lbnRcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG50ZXN0KFwiVGVzdCBkZWZhdWx0IGRlcGxveW1lbnRcIiwgKCkgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBjZGsuU3RhY2soKTtcbiAgY29uc3QgY29uc3RydWN0ID0gZGVwbG95Q29uc3RydWN0KHN0YWNrKTtcblxuICBleHBlY3QoY29uc3RydWN0LndlYmFjbCAhPT0gbnVsbCk7XG4gIGV4cGVjdChjb25zdHJ1Y3QuYXBwc3luY0FwaSAhPT0gbnVsbCk7XG5cbiAgZXhwZWN0KHN0YWNrKS50b0hhdmVSZXNvdXJjZShcIkFXUzo6V0FGdjI6OldlYkFDTFwiLCB7XG4gICAgUnVsZXM6IFtcbiAgICAgIHtcbiAgICAgICAgTmFtZTogXCJBV1MtQVdTTWFuYWdlZFJ1bGVzQm90Q29udHJvbFJ1bGVTZXRcIixcbiAgICAgICAgT3ZlcnJpZGVBY3Rpb246IHtcbiAgICAgICAgICBOb25lOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgUHJpb3JpdHk6IDAsXG4gICAgICAgIFN0YXRlbWVudDoge1xuICAgICAgICAgIE1hbmFnZWRSdWxlR3JvdXBTdGF0ZW1lbnQ6IHtcbiAgICAgICAgICAgIE5hbWU6IFwiQVdTTWFuYWdlZFJ1bGVzQm90Q29udHJvbFJ1bGVTZXRcIixcbiAgICAgICAgICAgIFZlbmRvck5hbWU6IFwiQVdTXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgVmlzaWJpbGl0eUNvbmZpZzoge1xuICAgICAgICAgIENsb3VkV2F0Y2hNZXRyaWNzRW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICBNZXRyaWNOYW1lOiBcIkFXU01hbmFnZWRSdWxlc0JvdENvbnRyb2xSdWxlU2V0XCIsXG4gICAgICAgICAgU2FtcGxlZFJlcXVlc3RzRW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIE5hbWU6IFwiQVdTLUFXU01hbmFnZWRSdWxlc0tub3duQmFkSW5wdXRzUnVsZVNldFwiLFxuICAgICAgICBPdmVycmlkZUFjdGlvbjoge1xuICAgICAgICAgIE5vbmU6IHt9LFxuICAgICAgICB9LFxuICAgICAgICBQcmlvcml0eTogMSxcbiAgICAgICAgU3RhdGVtZW50OiB7XG4gICAgICAgICAgTWFuYWdlZFJ1bGVHcm91cFN0YXRlbWVudDoge1xuICAgICAgICAgICAgTmFtZTogXCJBV1NNYW5hZ2VkUnVsZXNLbm93bkJhZElucHV0c1J1bGVTZXRcIixcbiAgICAgICAgICAgIFZlbmRvck5hbWU6IFwiQVdTXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgVmlzaWJpbGl0eUNvbmZpZzoge1xuICAgICAgICAgIENsb3VkV2F0Y2hNZXRyaWNzRW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICBNZXRyaWNOYW1lOiBcIkFXU01hbmFnZWRSdWxlc0tub3duQmFkSW5wdXRzUnVsZVNldFwiLFxuICAgICAgICAgIFNhbXBsZWRSZXF1ZXN0c0VuYWJsZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBOYW1lOiBcIkFXUy1BV1NNYW5hZ2VkUnVsZXNDb21tb25SdWxlU2V0XCIsXG4gICAgICAgIE92ZXJyaWRlQWN0aW9uOiB7XG4gICAgICAgICAgTm9uZToge30sXG4gICAgICAgIH0sXG4gICAgICAgIFByaW9yaXR5OiAyLFxuICAgICAgICBTdGF0ZW1lbnQ6IHtcbiAgICAgICAgICBNYW5hZ2VkUnVsZUdyb3VwU3RhdGVtZW50OiB7XG4gICAgICAgICAgICBOYW1lOiBcIkFXU01hbmFnZWRSdWxlc0NvbW1vblJ1bGVTZXRcIixcbiAgICAgICAgICAgIFZlbmRvck5hbWU6IFwiQVdTXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgVmlzaWJpbGl0eUNvbmZpZzoge1xuICAgICAgICAgIENsb3VkV2F0Y2hNZXRyaWNzRW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICBNZXRyaWNOYW1lOiBcIkFXU01hbmFnZWRSdWxlc0NvbW1vblJ1bGVTZXRcIixcbiAgICAgICAgICBTYW1wbGVkUmVxdWVzdHNFbmFibGVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgTmFtZTogXCJBV1MtQVdTTWFuYWdlZFJ1bGVzQW5vbnltb3VzSXBMaXN0XCIsXG4gICAgICAgIE92ZXJyaWRlQWN0aW9uOiB7XG4gICAgICAgICAgTm9uZToge30sXG4gICAgICAgIH0sXG4gICAgICAgIFByaW9yaXR5OiAzLFxuICAgICAgICBTdGF0ZW1lbnQ6IHtcbiAgICAgICAgICBNYW5hZ2VkUnVsZUdyb3VwU3RhdGVtZW50OiB7XG4gICAgICAgICAgICBOYW1lOiBcIkFXU01hbmFnZWRSdWxlc0Fub255bW91c0lwTGlzdFwiLFxuICAgICAgICAgICAgVmVuZG9yTmFtZTogXCJBV1NcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBWaXNpYmlsaXR5Q29uZmlnOiB7XG4gICAgICAgICAgQ2xvdWRXYXRjaE1ldHJpY3NFbmFibGVkOiB0cnVlLFxuICAgICAgICAgIE1ldHJpY05hbWU6IFwiQVdTTWFuYWdlZFJ1bGVzQW5vbnltb3VzSXBMaXN0XCIsXG4gICAgICAgICAgU2FtcGxlZFJlcXVlc3RzRW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIE5hbWU6IFwiQVdTLUFXU01hbmFnZWRSdWxlc0FtYXpvbklwUmVwdXRhdGlvbkxpc3RcIixcbiAgICAgICAgT3ZlcnJpZGVBY3Rpb246IHtcbiAgICAgICAgICBOb25lOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgUHJpb3JpdHk6IDQsXG4gICAgICAgIFN0YXRlbWVudDoge1xuICAgICAgICAgIE1hbmFnZWRSdWxlR3JvdXBTdGF0ZW1lbnQ6IHtcbiAgICAgICAgICAgIE5hbWU6IFwiQVdTTWFuYWdlZFJ1bGVzQW1hem9uSXBSZXB1dGF0aW9uTGlzdFwiLFxuICAgICAgICAgICAgVmVuZG9yTmFtZTogXCJBV1NcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBWaXNpYmlsaXR5Q29uZmlnOiB7XG4gICAgICAgICAgQ2xvdWRXYXRjaE1ldHJpY3NFbmFibGVkOiB0cnVlLFxuICAgICAgICAgIE1ldHJpY05hbWU6IFwiQVdTTWFuYWdlZFJ1bGVzQW1hem9uSXBSZXB1dGF0aW9uTGlzdFwiLFxuICAgICAgICAgIFNhbXBsZWRSZXF1ZXN0c0VuYWJsZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBOYW1lOiBcIkFXUy1BV1NNYW5hZ2VkUnVsZXNBZG1pblByb3RlY3Rpb25SdWxlU2V0XCIsXG4gICAgICAgIE92ZXJyaWRlQWN0aW9uOiB7XG4gICAgICAgICAgTm9uZToge30sXG4gICAgICAgIH0sXG4gICAgICAgIFByaW9yaXR5OiA1LFxuICAgICAgICBTdGF0ZW1lbnQ6IHtcbiAgICAgICAgICBNYW5hZ2VkUnVsZUdyb3VwU3RhdGVtZW50OiB7XG4gICAgICAgICAgICBOYW1lOiBcIkFXU01hbmFnZWRSdWxlc0FkbWluUHJvdGVjdGlvblJ1bGVTZXRcIixcbiAgICAgICAgICAgIFZlbmRvck5hbWU6IFwiQVdTXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgVmlzaWJpbGl0eUNvbmZpZzoge1xuICAgICAgICAgIENsb3VkV2F0Y2hNZXRyaWNzRW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICBNZXRyaWNOYW1lOiBcIkFXU01hbmFnZWRSdWxlc0FkbWluUHJvdGVjdGlvblJ1bGVTZXRcIixcbiAgICAgICAgICBTYW1wbGVkUmVxdWVzdHNFbmFibGVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgTmFtZTogXCJBV1MtQVdTTWFuYWdlZFJ1bGVzU1FMaVJ1bGVTZXRcIixcbiAgICAgICAgT3ZlcnJpZGVBY3Rpb246IHtcbiAgICAgICAgICBOb25lOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgUHJpb3JpdHk6IDYsXG4gICAgICAgIFN0YXRlbWVudDoge1xuICAgICAgICAgIE1hbmFnZWRSdWxlR3JvdXBTdGF0ZW1lbnQ6IHtcbiAgICAgICAgICAgIE5hbWU6IFwiQVdTTWFuYWdlZFJ1bGVzU1FMaVJ1bGVTZXRcIixcbiAgICAgICAgICAgIFZlbmRvck5hbWU6IFwiQVdTXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgVmlzaWJpbGl0eUNvbmZpZzoge1xuICAgICAgICAgIENsb3VkV2F0Y2hNZXRyaWNzRW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICBNZXRyaWNOYW1lOiBcIkFXU01hbmFnZWRSdWxlc1NRTGlSdWxlU2V0XCIsXG4gICAgICAgICAgU2FtcGxlZFJlcXVlc3RzRW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSk7XG59KTtcblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRlc3Qgd2ViIGFjbCB3aXRoIHVzZXIgcHJvdmlkZWQgYWNsIHByb3BzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxudGVzdChcIlRlc3QgdXNlciBwcm92aWRlZCBhY2wgcHJvcHNcIiwgKCkgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBjZGsuU3RhY2soKTtcbiAgY29uc3Qgd2ViYWNsUHJvcHM6IHdhZi5DZm5XZWJBQ0xQcm9wcyA9IHtcbiAgICBkZWZhdWx0QWN0aW9uOiB7XG4gICAgICBhbGxvdzoge30sXG4gICAgfSxcbiAgICBzY29wZTogXCJSRUdJT05BTFwiLFxuICAgIHZpc2liaWxpdHlDb25maWc6IHtcbiAgICAgIGNsb3VkV2F0Y2hNZXRyaWNzRW5hYmxlZDogZmFsc2UsXG4gICAgICBtZXRyaWNOYW1lOiBcIndlYkFDTFwiLFxuICAgICAgc2FtcGxlZFJlcXVlc3RzRW5hYmxlZDogdHJ1ZSxcbiAgICB9LFxuICAgIHJ1bGVzOiBbXG4gICAgICBkZWZhdWx0cy53cmFwTWFuYWdlZFJ1bGVTZXQoXCJBV1NNYW5hZ2VkUnVsZXNDb21tb25SdWxlU2V0XCIsIFwiQVdTXCIsIDApLFxuICAgICAgZGVmYXVsdHMud3JhcE1hbmFnZWRSdWxlU2V0KFwiQVdTTWFuYWdlZFJ1bGVzV29yZFByZXNzUnVsZVNldFwiLCBcIkFXU1wiLCAxKSxcbiAgICBdLFxuICB9O1xuXG4gIGRlcGxveUNvbnN0cnVjdChzdGFjaywgd2ViYWNsUHJvcHMpO1xuXG4gIGV4cGVjdChzdGFjaykudG9IYXZlUmVzb3VyY2UoXCJBV1M6OldBRnYyOjpXZWJBQ0xcIiwge1xuICAgIFZpc2liaWxpdHlDb25maWc6IHtcbiAgICAgIENsb3VkV2F0Y2hNZXRyaWNzRW5hYmxlZDogZmFsc2UsXG4gICAgICBNZXRyaWNOYW1lOiBcIndlYkFDTFwiLFxuICAgICAgU2FtcGxlZFJlcXVlc3RzRW5hYmxlZDogdHJ1ZSxcbiAgICB9LFxuICAgIFJ1bGVzOiBbXG4gICAgICB7XG4gICAgICAgIE5hbWU6IFwiQVdTLUFXU01hbmFnZWRSdWxlc0NvbW1vblJ1bGVTZXRcIixcbiAgICAgICAgT3ZlcnJpZGVBY3Rpb246IHtcbiAgICAgICAgICBOb25lOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgUHJpb3JpdHk6IDAsXG4gICAgICAgIFN0YXRlbWVudDoge1xuICAgICAgICAgIE1hbmFnZWRSdWxlR3JvdXBTdGF0ZW1lbnQ6IHtcbiAgICAgICAgICAgIE5hbWU6IFwiQVdTTWFuYWdlZFJ1bGVzQ29tbW9uUnVsZVNldFwiLFxuICAgICAgICAgICAgVmVuZG9yTmFtZTogXCJBV1NcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBWaXNpYmlsaXR5Q29uZmlnOiB7XG4gICAgICAgICAgQ2xvdWRXYXRjaE1ldHJpY3NFbmFibGVkOiB0cnVlLFxuICAgICAgICAgIE1ldHJpY05hbWU6IFwiQVdTTWFuYWdlZFJ1bGVzQ29tbW9uUnVsZVNldFwiLFxuICAgICAgICAgIFNhbXBsZWRSZXF1ZXN0c0VuYWJsZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBOYW1lOiBcIkFXUy1BV1NNYW5hZ2VkUnVsZXNXb3JkUHJlc3NSdWxlU2V0XCIsXG4gICAgICAgIE92ZXJyaWRlQWN0aW9uOiB7XG4gICAgICAgICAgTm9uZToge30sXG4gICAgICAgIH0sXG4gICAgICAgIFByaW9yaXR5OiAxLFxuICAgICAgICBTdGF0ZW1lbnQ6IHtcbiAgICAgICAgICBNYW5hZ2VkUnVsZUdyb3VwU3RhdGVtZW50OiB7XG4gICAgICAgICAgICBOYW1lOiBcIkFXU01hbmFnZWRSdWxlc1dvcmRQcmVzc1J1bGVTZXRcIixcbiAgICAgICAgICAgIFZlbmRvck5hbWU6IFwiQVdTXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgVmlzaWJpbGl0eUNvbmZpZzoge1xuICAgICAgICAgIENsb3VkV2F0Y2hNZXRyaWNzRW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICBNZXRyaWNOYW1lOiBcIkFXU01hbmFnZWRSdWxlc1dvcmRQcmVzc1J1bGVTZXRcIixcbiAgICAgICAgICBTYW1wbGVkUmVxdWVzdHNFbmFibGVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICBdLFxuICB9KTtcbn0pO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVGVzdCBleGlzdGluZyB3ZWIgQUNMXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxudGVzdChcIlRlc3QgZXhpc3Rpbmcgd2ViIEFDTFwiLCAoKSA9PiB7XG4gIGNvbnN0IHN0YWNrID0gbmV3IGNkay5TdGFjaygpO1xuICBjb25zdCB3ZWJhY2w6IHdhZi5DZm5XZWJBQ0wgPSBuZXcgd2FmLkNmbldlYkFDTChzdGFjaywgXCJ0ZXN0LXdlYmFjbFwiLCB7XG4gICAgZGVmYXVsdEFjdGlvbjoge1xuICAgICAgYWxsb3c6IHt9LFxuICAgIH0sXG4gICAgc2NvcGU6IFwiUkVHSU9OQUxcIixcbiAgICB2aXNpYmlsaXR5Q29uZmlnOiB7XG4gICAgICBjbG91ZFdhdGNoTWV0cmljc0VuYWJsZWQ6IHRydWUsXG4gICAgICBtZXRyaWNOYW1lOiBcIndlYkFDTFwiLFxuICAgICAgc2FtcGxlZFJlcXVlc3RzRW5hYmxlZDogdHJ1ZSxcbiAgICB9LFxuICB9KTtcblxuICBkZXBsb3lDb25zdHJ1Y3Qoc3RhY2ssIHVuZGVmaW5lZCwgd2ViYWNsKTtcblxuICBleHBlY3Qoc3RhY2spLnRvSGF2ZVJlc291cmNlKFwiQVdTOjpXQUZ2Mjo6V2ViQUNMXCIsIHtcbiAgICBWaXNpYmlsaXR5Q29uZmlnOiB7XG4gICAgICBDbG91ZFdhdGNoTWV0cmljc0VuYWJsZWQ6IHRydWUsXG4gICAgICBNZXRyaWNOYW1lOiBcIndlYkFDTFwiLFxuICAgICAgU2FtcGxlZFJlcXVlc3RzRW5hYmxlZDogdHJ1ZSxcbiAgICB9LFxuICB9KTtcblxuICBleHBlY3Qoc3RhY2spLnRvQ291bnRSZXNvdXJjZXMoXCJBV1M6OldBRnYyOjpXZWJBQ0xcIiwgMSk7XG59KTtcbiJdfQ==