@aws/pdk
Version:
All documentation is located at: https://aws.github.io/aws-pdk
219 lines • 25 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0 */
const client_wafv2_1 = require("@aws-sdk/client-wafv2"); // eslint-disable-line
const DELIMITER = ":";
const SCOPE = "CLOUDFRONT";
const client = new client_wafv2_1.WAFV2({
region: "us-east-1",
customUserAgent: "aws-pdk/static-website/waf",
});
const MAX_CREATE_RETRY = 10;
const RETRY_INTERVAL = 2000;
/**
* Handler for creating a WAF V2 ACL in US-EAST-1.
*/
exports.onEvent = async (event) => {
const { ID, MANAGED_RULES, CIDR_ALLOW_LIST } = event.ResourceProperties;
const [WEB_ACL_ID, IP_SET_ID] = event.PhysicalResourceId
? event.PhysicalResourceId.split(DELIMITER)
: [];
let response = {};
switch (event.RequestType) {
case "Create":
response = await createWaf(ID, MANAGED_RULES, CIDR_ALLOW_LIST);
break;
case "Update":
response = await updateWaf(WEB_ACL_ID, IP_SET_ID, ID, getIpSetName(ID), MANAGED_RULES, CIDR_ALLOW_LIST);
break;
case "Delete":
response = await deleteWaf(WEB_ACL_ID, IP_SET_ID, ID, getIpSetName(ID));
break;
default:
throw new Error(`Invalid RequestType: ${event.RequestType}`);
}
return response;
};
/**
* Generates the name of the IP Set.
*
* @param id param passed in.
* @returns name of IP Set.
*/
const getIpSetName = (id) => `${id}-IPSet`;
/**
* Returns a set of rules to apply.
*
* @param ipSetArn ip set arn
* @param ipSetName ip set name
* @param managedRules managed rules
* @param cidrAllowList cidr allow list
* @returns set of rules to apply.
*/
const getWafRules = (ipSetArn, ipSetName, managedRules, cidrAllowList) => {
const rules = [];
if (cidrAllowList) {
rules.push({
Name: ipSetName,
Priority: 1,
VisibilityConfig: {
MetricName: ipSetName,
CloudWatchMetricsEnabled: true,
SampledRequestsEnabled: true,
},
Action: {
Block: {},
},
Statement: {
NotStatement: {
Statement: {
IPSetReferenceStatement: {
ARN: ipSetArn,
},
},
},
},
});
}
if (managedRules) {
rules.push(...managedRules
.map((r) => ({ VendorName: r.vendor, Name: r.name }))
.map((rule, Priority) => ({
Name: `${rule.VendorName}-${rule.Name}`,
Priority,
Statement: { ManagedRuleGroupStatement: rule },
OverrideAction: { None: {} },
VisibilityConfig: {
MetricName: `${rule.VendorName}-${rule.Name}`,
CloudWatchMetricsEnabled: true,
SampledRequestsEnabled: true,
},
})));
}
return rules;
};
const createWaf = async (id, managedRules, cidrAllowList) => {
const ipSetName = getIpSetName(id);
const createIpSetResponse = await client.createIPSet({
Name: ipSetName,
Scope: SCOPE,
Addresses: cidrAllowList?.cidrRanges ?? [],
IPAddressVersion: cidrAllowList?.cidrType ?? "IPV4",
});
const createWebAclResponse = await createWafAcl(id, ipSetName, createIpSetResponse, managedRules, cidrAllowList);
return {
PhysicalResourceId: `${createWebAclResponse.Summary?.Id}${DELIMITER}${createIpSetResponse.Summary?.Id}`,
Data: {
WebAclArn: createWebAclResponse.Summary?.ARN,
WebAclId: createWebAclResponse.Summary?.Id,
IPSetArn: createIpSetResponse.Summary?.ARN,
IPSetId: createIpSetResponse.Summary?.Id,
},
};
};
const createWafAcl = async (id, ipSetName, createIpSetResponse, managedRules, cidrAllowList) => {
let counter = 0;
while (true) {
try {
const createWebAclResponse = await client.createWebACL({
Name: id,
DefaultAction: { Allow: {} },
Scope: SCOPE,
VisibilityConfig: {
CloudWatchMetricsEnabled: true,
MetricName: id,
SampledRequestsEnabled: true,
},
Rules: getWafRules(createIpSetResponse.Summary.ARN, ipSetName, managedRules, cidrAllowList),
});
return createWebAclResponse;
}
catch (e) {
if (e instanceof client_wafv2_1.WAFUnavailableEntityException &&
counter < MAX_CREATE_RETRY) {
counter++;
console.log(`Received error: ${e.message}; Waiting for retrying ${counter}`);
await sleep(RETRY_INTERVAL);
continue;
}
throw e;
}
}
};
const updateWaf = async (webAclId, ipSetId, id, ipSetName, managedRules, cidrAllowList) => {
const getIpSetResponse = await client.getIPSet({
Id: ipSetId,
Name: ipSetName,
Scope: SCOPE,
});
await client.updateIPSet({
Id: ipSetId,
Name: ipSetName,
Addresses: cidrAllowList?.cidrRanges ?? [],
Scope: SCOPE,
LockToken: getIpSetResponse.LockToken,
});
const getWebAclResponse = await client.getWebACL({
Id: webAclId,
Name: id,
Scope: SCOPE,
});
await client.updateWebACL({
Name: id,
DefaultAction: { Allow: {} },
Scope: SCOPE,
VisibilityConfig: {
CloudWatchMetricsEnabled: true,
MetricName: id,
SampledRequestsEnabled: true,
},
Rules: getWafRules(getIpSetResponse.IPSet?.ARN, ipSetName, managedRules, cidrAllowList),
Id: getWebAclResponse.WebACL?.Id,
LockToken: getWebAclResponse.LockToken,
});
return {
Data: {
WebAclArn: getWebAclResponse.WebACL?.ARN,
WebAclId: getWebAclResponse.WebACL?.Id,
IPSetArn: getIpSetResponse.IPSet?.ARN,
IPSetId: getIpSetResponse.IPSet?.Id,
},
};
};
const deleteWaf = async (webAclId, ipSetId, id, ipSetName) => {
const getWebAclResponse = await client.getWebACL({
Id: webAclId,
Name: id,
Scope: SCOPE,
});
await client.deleteWebACL({
Id: webAclId,
Name: id,
Scope: SCOPE,
LockToken: getWebAclResponse.LockToken,
});
const getIpSetResponse = await client.getIPSet({
Id: ipSetId,
Name: ipSetName,
Scope: SCOPE,
});
await client.deleteIPSet({
Id: ipSetId,
Name: ipSetName,
Scope: SCOPE,
LockToken: getIpSetResponse.LockToken,
});
return {
Data: {
WebAclArn: getWebAclResponse.WebACL?.ARN,
WebAclId: getWebAclResponse.WebACL?.Id,
IPSetArn: getIpSetResponse.IPSet?.ARN,
IPSetId: getIpSetResponse.IPSet?.Id,
},
};
};
const sleep = async (duration) => {
return new Promise((resolve) => setTimeout(resolve, duration));
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBO3NDQUNzQztBQUN0Qyx3REFBNkcsQ0FBQyxzQkFBc0I7QUFFcEksTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDO0FBQ3RCLE1BQU0sS0FBSyxHQUFHLFlBQVksQ0FBQztBQUMzQixNQUFNLE1BQU0sR0FBRyxJQUFJLG9CQUFLLENBQUM7SUFDdkIsTUFBTSxFQUFFLFdBQVc7SUFDbkIsZUFBZSxFQUFFLDRCQUE0QjtDQUM5QyxDQUFDLENBQUM7QUFFSCxNQUFNLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztBQUM1QixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUM7QUFFNUI7O0dBRUc7QUFDSCxPQUFPLENBQUMsT0FBTyxHQUFHLEtBQUssRUFBRSxLQUFVLEVBQUUsRUFBRTtJQUNyQyxNQUFNLEVBQUUsRUFBRSxFQUFFLGFBQWEsRUFBRSxlQUFlLEVBQUUsR0FBRyxLQUFLLENBQUMsa0JBQWtCLENBQUM7SUFDeEUsTUFBTSxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsR0FBRyxLQUFLLENBQUMsa0JBQWtCO1FBQ3RELENBQUMsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztRQUMzQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ1AsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDO0lBRWxCLFFBQVEsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzFCLEtBQUssUUFBUTtZQUNYLFFBQVEsR0FBRyxNQUFNLFNBQVMsQ0FBQyxFQUFFLEVBQUUsYUFBYSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1lBQy9ELE1BQU07UUFDUixLQUFLLFFBQVE7WUFDWCxRQUFRLEdBQUcsTUFBTSxTQUFTLENBQ3hCLFVBQVUsRUFDVixTQUFTLEVBQ1QsRUFBRSxFQUNGLFlBQVksQ0FBQyxFQUFFLENBQUMsRUFDaEIsYUFBYSxFQUNi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N0MsRUFBRSxFQUFFLE9BQU87UUFDWCxJQUFJLEVBQUUsU0FBUztRQUNmLEtBQUssRUFBRSxLQUFLO0tBQ2IsQ0FBQyxDQUFDO0lBRUgsTUFBTSxNQUFNLENBQUMsV0FBVyxDQUFDO1FBQ3ZCLEVBQUUsRUFBRSxPQUFPO1FBQ1gsSUFBSSxFQUFFLFNBQVM7UUFDZixLQUFLLEVBQUUsS0FBSztRQUNaLFNBQVMsRUFBRSxnQkFBZ0IsQ0FBQyxTQUFVO0tBQ3ZDLENBQUMsQ0FBQztJQUVILE9BQU87UUFDTCxJQUFJLEVBQUU7WUFDSixTQUFTLEVBQUUsaUJBQWlCLENBQUMsTUFBTSxFQUFFLEdBQUc7WUFDeEMsUUFBUSxFQUFFLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ3RDLFFBQVEsRUFBRSxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsR0FBRztZQUNyQyxPQUFPLEVBQUUsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLEVBQUU7U0FDcEM7S0FDRixDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBRUYsTUFBTSxLQUFLLEdBQUcsS0FBSyxFQUFFLFFBQWdCLEVBQUUsRUFBRTtJQUN2QyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFDakUsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyohIENvcHlyaWdodCBbQW1hem9uLmNvbV0oaHR0cDovL2FtYXpvbi5jb20vKSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wICovXG5pbXBvcnQgeyBDcmVhdGVJUFNldENvbW1hbmRPdXRwdXQsIFJ1bGUsIFdBRlVuYXZhaWxhYmxlRW50aXR5RXhjZXB0aW9uLCBXQUZWMiB9IGZyb20gXCJAYXdzLXNkay9jbGllbnQtd2FmdjJcIjsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXG5jb25zdCBERUxJTUlURVIgPSBcIjpcIjtcbmNvbnN0IFNDT1BFID0gXCJDTE9VREZST05UXCI7XG5jb25zdCBjbGllbnQgPSBuZXcgV0FGVjIoe1xuICByZWdpb246IFwidXMtZWFzdC0xXCIsXG4gIGN1c3RvbVVzZXJBZ2VudDogXCJhd3MtcGRrL3N0YXRpYy13ZWJzaXRlL3dhZlwiLFxufSk7XG5cbmNvbnN0IE1BWF9DUkVBVEVfUkVUUlkgPSAxMDtcbmNvbnN0IFJFVFJZX0lOVEVSVkFMID0gMjAwMDtcblxuLyoqXG4gKiBIYW5kbGVyIGZvciBjcmVhdGluZyBhIFdBRiBWMiBBQ0wgaW4gVVMtRUFTVC0xLlxuICovXG5leHBvcnRzLm9uRXZlbnQgPSBhc3luYyAoZXZlbnQ6IGFueSkgPT4ge1xuICBjb25zdCB7IElELCBNQU5BR0VEX1JVTEVTLCBDSURSX0FMTE9XX0xJU1QgfSA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcztcbiAgY29uc3QgW1dFQl9BQ0xfSUQsIElQX1NFVF9JRF0gPSBldmVudC5QaHlzaWNhbFJlc291cmNlSWRcbiAgICA/IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZC5zcGxpdChERUxJTUlURVIpXG4gICAgOiBbXTtcbiAgbGV0IHJlc3BvbnNlID0ge307XG5cbiAgc3dpdGNoIChldmVudC5SZXF1ZXN0VHlwZSkge1xuICAgIGNhc2UgXCJDcmVhdGVcIjpcbiAgICAgIHJlc3BvbnNlID0gYXdhaXQgY3JlYXRlV2FmKElELCBNQU5BR0VEX1JVTEVTLCBDSURSX0FMTE9XX0xJU1QpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBcIlVwZGF0ZVwiOlxuICAgICAgcmVzcG9uc2UgPSBhd2FpdCB1cGRhdGVXYWYoXG4gICAgICAgIFdFQl9BQ0xfSUQsXG4gICAgICAgIElQX1NFVF9JRCxcbiAgICAgICAgSUQsXG4gICAgICAgIGdldElwU2V0TmFtZShJRCksXG4gICAgICAgIE1BTkFHRURfUlVMRVMsXG4gICAgICAgIENJRFJfQUxMT1dfTElTVFxuICAgICAgKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgXCJEZWxldGVcIjpcbiAgICAgIHJlc3BvbnNlID0gYXdhaXQgZGVsZXRlV2FmKFdFQl9BQ0xfSUQsIElQX1NFVF9JRCwgSUQsIGdldElwU2V0TmFtZShJRCkpO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBSZXF1ZXN0VHlwZTogJHtldmVudC5SZXF1ZXN0VHlwZX1gKTtcbiAgfVxuXG4gIHJldHVybiByZXNwb25zZTtcbn07XG5cbi8qKlxuICogR2VuZXJhdGVzIHRoZSBuYW1lIG9mIHRoZSBJUCBTZXQuXG4gKlxuICogQHBhcmFtIGlkIHBhcmFtIHBhc3NlZCBpbi5cbiAqIEByZXR1cm5zIG5hbWUgb2YgSVAgU2V0LlxuICovXG5jb25zdCBnZXRJcFNldE5hbWUgPSAoaWQ6IHN0cmluZykgPT4gYCR7aWR9LUlQU2V0YDtcblxuLyoqXG4gKiBSZXR1cm5zIGEgc2V0IG9mIHJ1bGVzIHRvIGFwcGx5LlxuICpcbiAqIEBwYXJhbSBpcFNldEFybiBpcCBzZXQgYXJuXG4gKiBAcGFyYW0gaXBTZXROYW1lICBpcCBzZXQgbmFtZVxuICogQHBhcmFtIG1hbmFnZWRSdWxlcyAgbWFuYWdlZCBydWxlc1xuICogQHBhcmFtIGNpZHJBbGxvd0xpc3QgY2lkciBhbGxvdyBsaXN0XG4gKiBAcmV0dXJucyBzZXQgb2YgcnVsZXMgdG8gYXBwbHkuXG4gKi9cbmNvbnN0IGdldFdhZlJ1bGVzID0gKFxuICBpcFNldEFybjogc3RyaW5nLFxuICBpcFNldE5hbWU6IHN0cmluZyxcbiAgbWFuYWdlZFJ1bGVzPzogYW55LFxuICBjaWRyQWxsb3dMaXN0PzogYW55XG4pOiBBcnJheTxSdWxlPiA9PiB7XG4gIGNvbnN0IHJ1bGVzOiBBcnJheTxSdWxlPiA9IFtdO1xuXG4gIGlmIChjaWRyQWxsb3dMaXN0KSB7XG4gICAgcnVsZXMucHVzaCh7XG4gICAgICBOYW1lOiBpcFNldE5hbWUsXG4gICAgICBQcmlvcml0eTogMSxcbiAgICAgIFZpc2liaWxpdHlDb25maWc6IHtcbiAgICAgICAgTWV0cmljTmFtZTogaXBTZXROYW1lLFxuICAgICAgICBDbG91ZFdhdGNoTWV0cmljc0VuYWJsZWQ6IHRydWUsXG4gICAgICAgIFNhbXBsZWRSZXF1ZXN0c0VuYWJsZWQ6IHRydWUsXG4gICAgICB9LFxuICAgICAgQWN0aW9uOiB7XG4gICAgICAgIEJsb2NrOiB7fSxcbiAgICAgIH0sXG4gICAgICBTdGF0ZW1lbnQ6IHtcbiAgICAgICAgTm90U3RhdGVtZW50OiB7XG4gICAgICAgICAgU3RhdGVtZW50OiB7XG4gICAgICAgICAgICBJUFNldFJlZmVyZW5jZVN0YXRlbWVudDoge1xuICAgICAgICAgICAgICBBUk46IGlwU2V0QXJuLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChtYW5hZ2VkUnVsZXMpIHtcbiAgICBydWxlcy5wdXNoKFxuICAgICAgLi4ubWFuYWdlZFJ1bGVzXG4gICAgICAgIC5tYXAoKHI6IGFueSkgPT4gKHsgVmVuZG9yTmFtZTogci52ZW5kb3IsIE5hbWU6IHIubmFtZSB9KSlcbiAgICAgICAgLm1hcCgocnVsZTogYW55LCBQcmlvcml0eTogYW55KSA9PiAoe1xuICAgICAgICAgIE5hbWU6IGAke3J1bGUuVmVuZG9yTmFtZX0tJHtydWxlLk5hbWV9YCxcbiAgICAgICAgICBQcmlvcml0eSxcbiAgICAgICAgICBTdGF0ZW1lbnQ6IHsgTWFuYWdlZFJ1bGVHcm91cFN0YXRlbWVudDogcnVsZSB9LFxuICAgICAgICAgIE92ZXJyaWRlQWN0aW9uOiB7IE5vbmU6IHt9IH0sXG4gICAgICAgICAgVmlzaWJpbGl0eUNvbmZpZzoge1xuICAgICAgICAgICAgTWV0cmljTmFtZTogYCR7cnVsZS5WZW5kb3JOYW1lfS0ke3J1bGUuTmFtZX1gLFxuICAgICAgICAgICAgQ2xvdWRXYXRjaE1ldHJpY3NFbmFibGVkOiB0cnVlLFxuICAgICAgICAgICAgU2FtcGxlZFJlcXVlc3RzRW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSlcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIHJ1bGVzO1xufTtcblxuY29uc3QgY3JlYXRlV2FmID0gYXN5bmMgKFxuICBpZDogc3RyaW5nLFxuICBtYW5hZ2VkUnVsZXM/OiBhbnksXG4gIGNpZHJBbGxvd0xpc3Q/OiBhbnlcbikgPT4ge1xuICBjb25zdCBpcFNldE5hbWUgPSBnZXRJcFNldE5hbWUoaWQpO1xuICBjb25zdCBjcmVhdGVJcFNldFJlc3BvbnNlID0gYXdhaXQgY2xpZW50LmNyZWF0ZUlQU2V0KHtcbiAgICBOYW1lOiBpcFNldE5hbWUsXG4gICAgU2NvcGU6IFNDT1BFLFxuICAgIEFkZHJlc3NlczogY2lkckFsbG93TGlzdD8uY2lkclJhbmdlcyA/PyBbXSxcbiAgICBJUEFkZHJlc3NWZXJzaW9uOiBjaWRyQWxsb3dMaXN0Py5jaWRyVHlwZSA/PyBcIklQVjRcIixcbiAgfSk7XG5cbiAgY29uc3QgY3JlYXRlV2ViQWNsUmVzcG9uc2UgPSBhd2FpdCBjcmVhdGVXYWZBY2woXG4gICAgaWQsXG4gICAgaXBTZXROYW1lLFxuICAgIGNyZWF0ZUlwU2V0UmVzcG9uc2UsXG4gICAgbWFuYWdlZFJ1bGVzLFxuICAgIGNpZHJBbGxvd0xpc3RcbiAgKTtcblxuICByZXR1cm4ge1xuICAgIFBoeXNpY2FsUmVzb3VyY2VJZDogYCR7Y3JlYXRlV2ViQWNsUmVzcG9uc2UuU3VtbWFyeT8uSWR9JHtERUxJTUlURVJ9JHtjcmVhdGVJcFNldFJlc3BvbnNlLlN1bW1hcnk/LklkfWAsXG4gICAgRGF0YToge1xuICAgICAgV2ViQWNsQXJuOiBjcmVhdGVXZWJBY2xSZXNwb25zZS5TdW1tYXJ5Py5BUk4sXG4gICAgICBXZWJBY2xJZDogY3JlYXRlV2ViQWNsUmVzcG9uc2UuU3VtbWFyeT8uSWQsXG4gICAgICBJUFNldEFybjogY3JlYXRlSXBTZXRSZXNwb25zZS5TdW1tYXJ5Py5BUk4sXG4gICAgICBJUFNldElkOiBjcmVhdGVJcFNldFJlc3BvbnNlLlN1bW1hcnk/LklkLFxuICAgIH0sXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVXYWZBY2wgPSBhc3luYyAoXG4gIGlkOiBzdHJpbmcsXG4gIGlwU2V0TmFtZTogc3RyaW5nLFxuICBjcmVhdGVJcFNldFJlc3BvbnNlOiBDcmVhdGVJUFNldENvbW1hbmRPdXRwdXQsXG4gIG1hbmFnZWRSdWxlcz86IGFueSxcbiAgY2lkckFsbG93TGlzdD86IGFueVxuKSA9PiB7XG4gIGxldCBjb3VudGVyID0gMDtcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjcmVhdGVXZWJBY2xSZXNwb25zZSA9IGF3YWl0IGNsaWVudC5jcmVhdGVXZWJBQ0woe1xuICAgICAgICBOYW1lOiBpZCxcbiAgICAgICAgRGVmYXVsdEFjdGlvbjogeyBBbGxvdzoge30gfSxcbiAgICAgICAgU2NvcGU6IFNDT1BFLFxuICAgICAgICBWaXNpYmlsaXR5Q29uZmlnOiB7XG4gICAgICAgICAgQ2xvdWRXYXRjaE1ldHJpY3NFbmFibGVkOiB0cnVlLFxuICAgICAgICAgIE1ldHJpY05hbWU6IGlkLFxuICAgICAgICAgIFNhbXBsZWRSZXF1ZXN0c0VuYWJsZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIFJ1bGVzOiBnZXRXYWZSdWxlcyhcbiAgICAgICAgICBjcmVhdGVJcFNldFJlc3BvbnNlLlN1bW1hcnkhLkFSTiEsXG4gICAgICAgICAgaXBTZXROYW1lLFxuICAgICAgICAgIG1hbmFnZWRSdWxlcyxcbiAgICAgICAgICBjaWRyQWxsb3dMaXN0XG4gICAgICAgICksXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGNyZWF0ZVdlYkFjbFJlc3BvbnNlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChcbiAgICAgICAgZSBpbnN0YW5jZW9mIFdBRlVuYXZhaWxhYmxlRW50aXR5RXhjZXB0aW9uICYmXG4gICAgICAgIGNvdW50ZXIgPCBNQVhfQ1JFQVRFX1JFVFJZXG4gICAgICApIHtcbiAgICAgICAgY291bnRlcisrO1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICBgUmVjZWl2ZWQgZXJyb3I6ICR7ZS5tZXNzYWdlfTsgV2FpdGluZyBmb3IgcmV0cnlpbmcgJHtjb3VudGVyfWBcbiAgICAgICAgKTtcbiAgICAgICAgYXdhaXQgc2xlZXAoUkVUUllfSU5URVJWQUwpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gIH1cbn07XG5cbmNvbnN0IHVwZGF0ZVdhZiA9IGFzeW5jIChcbiAgd2ViQWNsSWQ6IHN0cmluZyxcbiAgaXBTZXRJZDogc3RyaW5nLFxuICBpZDogc3RyaW5nLFxuICBpcFNldE5hbWU6IHN0cmluZyxcbiAgbWFuYWdlZFJ1bGVzPzogYW55LFxuICBjaWRyQWxsb3dMaXN0PzogYW55XG4pID0+IHtcbiAgY29uc3QgZ2V0SXBTZXRSZXNwb25zZSA9IGF3YWl0IGNsaWVudC5nZXRJUFNldCh7XG4gICAgSWQ6IGlwU2V0SWQsXG4gICAgTmFtZTogaXBTZXROYW1lLFxuICAgIFNjb3BlOiBTQ09QRSxcbiAgfSk7XG5cbiAgYXdhaXQgY2xpZW50LnVwZGF0ZUlQU2V0KHtcbiAgICBJZDogaXBTZXRJZCxcbiAgICBOYW1lOiBpcFNldE5hbWUsXG4gICAgQWRkcmVzc2VzOiBjaWRyQWxsb3dMaXN0Py5jaWRyUmFuZ2VzID8/IFtdLFxuICAgIFNjb3BlOiBTQ09QRSxcbiAgICBMb2NrVG9rZW46IGdldElwU2V0UmVzcG9uc2UuTG9ja1Rva2VuISxcbiAgfSk7XG5cbiAgY29uc3QgZ2V0V2ViQWNsUmVzcG9uc2UgPSBhd2FpdCBjbGllbnQuZ2V0V2ViQUNMKHtcbiAgICBJZDogd2ViQWNsSWQsXG4gICAgTmFtZTogaWQsXG4gICAgU2NvcGU6IFNDT1BFLFxuICB9KTtcblxuICBhd2FpdCBjbGllbnQudXBkYXRlV2ViQUNMKHtcbiAgICBOYW1lOiBpZCxcbiAgICBEZWZhdWx0QWN0aW9uOiB7IEFsbG93OiB7fSB9LFxuICAgIFNjb3BlOiBTQ09QRSxcbiAgICBWaXNpYmlsaXR5Q29uZmlnOiB7XG4gICAgICBDbG91ZFdhdGNoTWV0cmljc0VuYWJsZWQ6IHRydWUsXG4gICAgICBNZXRyaWNOYW1lOiBpZCxcbiAgICAgIFNhbXBsZWRSZXF1ZXN0c0VuYWJsZWQ6IHRydWUsXG4gICAgfSxcbiAgICBSdWxlczogZ2V0V2FmUnVsZXMoXG4gICAgICBnZXRJcFNldFJlc3BvbnNlLklQU2V0Py5BUk4hLFxuICAgICAgaXBTZXROYW1lLFxuICAgICAgbWFuYWdlZFJ1bGVzLFxuICAgICAgY2lkckFsbG93TGlzdFxuICAgICksXG4gICAgSWQ6IGdldFdlYkFjbFJlc3BvbnNlLldlYkFDTD8uSWQhLFxuICAgIExvY2tUb2tlbjogZ2V0V2ViQWNsUmVzcG9uc2UuTG9ja1Rva2VuISxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBEYXRhOiB7XG4gICAgICBXZWJBY2xBcm46IGdldFdlYkFjbFJlc3BvbnNlLldlYkFDTD8uQVJOLFxuICAgICAgV2ViQWNsSWQ6IGdldFdlYkFjbFJlc3BvbnNlLldlYkFDTD8uSWQsXG4gICAgICBJUFNldEFybjogZ2V0SXBTZXRSZXNwb25zZS5JUFNldD8uQVJOLFxuICAgICAgSVBTZXRJZDogZ2V0SXBTZXRSZXNwb25zZS5JUFNldD8uSWQsXG4gICAgfSxcbiAgfTtcbn07XG5cbmNvbnN0IGRlbGV0ZVdhZiA9IGFzeW5jIChcbiAgd2ViQWNsSWQ6IHN0cmluZyxcbiAgaXBTZXRJZDogc3RyaW5nLFxuICBpZDogc3RyaW5nLFxuICBpcFNldE5hbWU6IHN0cmluZ1xuKSA9PiB7XG4gIGNvbnN0IGdldFdlYkFjbFJlc3BvbnNlID0gYXdhaXQgY2xpZW50LmdldFdlYkFDTCh7XG4gICAgSWQ6IHdlYkFjbElkLFxuICAgIE5hbWU6IGlkLFxuICAgIFNjb3BlOiBTQ09QRSxcbiAgfSk7XG5cbiAgYXdhaXQgY2xpZW50LmRlbGV0ZVdlYkFDTCh7XG4gICAgSWQ6IHdlYkFjbElkLFxuICAgIE5hbWU6IGlkLFxuICAgIFNjb3BlOiBTQ09QRSxcbiAgICBMb2NrVG9rZW46IGdldFdlYkFjbFJlc3BvbnNlLkxvY2tUb2tlbiEsXG4gIH0pO1xuXG4gIGNvbnN0IGdldElwU2V0UmVzcG9uc2UgPSBhd2FpdCBjbGllbnQuZ2V0SVBTZXQoe1xuICAgIElkOiBpcFNldElkLFxuICAgIE5hbWU6IGlwU2V0TmFtZSxcbiAgICBTY29wZTogU0NPUEUsXG4gIH0pO1xuXG4gIGF3YWl0IGNsaWVudC5kZWxldGVJUFNldCh7XG4gICAgSWQ6IGlwU2V0SWQsXG4gICAgTmFtZTogaXBTZXROYW1lLFxuICAgIFNjb3BlOiBTQ09QRSxcbiAgICBMb2NrVG9rZW46IGdldElwU2V0UmVzcG9uc2UuTG9ja1Rva2VuISxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBEYXRhOiB7XG4gICAgICBXZWJBY2xBcm46IGdldFdlYkFjbFJlc3BvbnNlLldlYkFDTD8uQVJOLFxuICAgICAgV2ViQWNsSWQ6IGdldFdlYkFjbFJlc3BvbnNlLldlYkFDTD8uSWQsXG4gICAgICBJUFNldEFybjogZ2V0SXBTZXRSZXNwb25zZS5JUFNldD8uQVJOLFxuICAgICAgSVBTZXRJZDogZ2V0SXBTZXRSZXNwb25zZS5JUFNldD8uSWQsXG4gICAgfSxcbiAgfTtcbn07XG5cbmNvbnN0IHNsZWVwID0gYXN5bmMgKGR1cmF0aW9uOiBudW1iZXIpID0+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIGR1cmF0aW9uKSk7XG59O1xuIl19