UNPKG

@aws/pdk

Version:

All documentation is located at: https://aws.github.io/aws-pdk

219 lines 25 kB
"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