@aws/pdk
Version:
All documentation is located at: https://aws.github.io/aws-pdk
195 lines • 30.2 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CloudfrontWebAcl = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0 */
const path = require("path");
const pdk_nag_1 = require("../pdk-nag");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
const custom_resources_1 = require("aws-cdk-lib/custom-resources");
const cdk_nag_1 = require("cdk-nag");
const constructs_1 = require("constructs");
/**
* This construct creates a WAFv2 Web ACL for cloudfront in the us-east-1 region (required for cloudfront) no matter the
* region of the parent cdk stack.
*/
class CloudfrontWebAcl extends constructs_1.Construct {
constructor(scope, id, props) {
super(scope, id);
const stack = aws_cdk_lib_1.Stack.of(this);
const aclName = `${stack.stackName}-${id}-${this.node.addr.slice(-4)}`;
const onEventHandler = this.createOnEventHandler(stack, aclName);
const customResource = this.createAclCustomResource(stack, aclName, onEventHandler, props);
this.webAclId = customResource.getAttString("WebAclId");
this.webAclArn = customResource.getAttString("WebAclArn");
}
/**
* Creates an event handler for managing an ACL in us-east-1.
*
* @param stack containing Stack instance.
* @param aclName name of the ACL to manage.
* @private
*/
createOnEventHandler(stack, aclName) {
// NB without manually defining a name, the cdk generated name for the Provider function can become too long and
// deployments fail. This is because the Provider's name references the onEvent handler name and appends "-Provider"
// rather than being generated by cdk and truncated appropriately
const onEventHandlerName = `${pdk_nag_1.PDKNag.getStackPrefix(stack)
.split("/")
.join("-")}AclEvent-${this.node.addr.slice(-6)}`;
const onEventHandlerRole = new aws_iam_1.Role(this, "OnEventHandlerRole", {
assumedBy: new aws_iam_1.ServicePrincipal("lambda.amazonaws.com"),
inlinePolicies: {
logs: new aws_iam_1.PolicyDocument({
statements: [
new aws_iam_1.PolicyStatement({
effect: aws_iam_1.Effect.ALLOW,
actions: [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
],
resources: [
`arn:aws:logs:${stack.region}:${stack.account}:log-group:/aws/lambda/${onEventHandlerName}`,
`arn:aws:logs:${stack.region}:${stack.account}:log-group:/aws/lambda/${onEventHandlerName}:*`,
],
}),
],
}),
wafv2: new aws_iam_1.PolicyDocument({
statements: [
new aws_iam_1.PolicyStatement({
effect: aws_iam_1.Effect.ALLOW,
actions: [
"wafv2:CreateWebACL",
"wafv2:DeleteWebACL",
"wafv2:UpdateWebACL",
"wafv2:GetWebACL",
],
resources: [
`arn:aws:wafv2:us-east-1:${stack.account}:global/ipset/${aclName}-IPSet/*`,
`arn:aws:wafv2:us-east-1:${stack.account}:global/webacl/${aclName}/*`,
`arn:aws:wafv2:us-east-1:${stack.account}:global/managedruleset/*/*`,
],
}),
new aws_iam_1.PolicyStatement({
effect: aws_iam_1.Effect.ALLOW,
actions: [
"wafv2:CreateIPSet",
"wafv2:DeleteIPSet",
"wafv2:UpdateIPSet",
"wafv2:GetIPSet",
],
resources: [
`arn:aws:wafv2:us-east-1:${stack.account}:global/ipset/${aclName}-IPSet/*`,
],
}),
],
}),
},
});
const onEventHandler = new aws_lambda_1.Function(this, "CloudfrontWebAclOnEventHandler", {
code: aws_lambda_1.Code.fromAsset(path.join(__dirname, "./webacl_event_handler")),
role: onEventHandlerRole,
functionName: onEventHandlerName,
handler: "index.onEvent",
runtime: aws_lambda_1.Runtime.NODEJS_18_X,
timeout: aws_cdk_lib_1.Duration.seconds(300),
});
["AwsSolutions-IAM5", "AwsPrototyping-IAMNoWildcardPermissions"].forEach((RuleId) => {
cdk_nag_1.NagSuppressions.addResourceSuppressions(onEventHandlerRole, [
{
id: RuleId,
reason: "WafV2 resources have been scoped down to the ACL/IPSet level, however * is still needed as resource id's are created just in time.",
appliesTo: [
{
regex: `/^Resource::arn:aws:wafv2:us-east-1:${pdk_nag_1.PDKNag.getStackAccountRegex(stack)}:global/(.*)$/g`,
},
],
},
{
id: RuleId,
reason: "Cloudwatch resources have been scoped down to the LogGroup level, however * is still needed as stream names are created just in time.",
appliesTo: [
{
regex: `/^Resource::arn:aws:logs:${pdk_nag_1.PDKNag.getStackRegionRegex(stack)}:${pdk_nag_1.PDKNag.getStackAccountRegex(stack)}:log-group:/aws/lambda/${onEventHandlerName}:\*/g`,
},
],
},
], true);
});
return onEventHandler;
}
/**
* Creates a Custom resource to manage the deployment of the ACL.
*
* @param stack containing Stack instance.
* @param aclName name of the ACL to manage.
* @param onEventHandler event handler to use for deployment.
* @param props user provided properties for configuring the ACL.
* @private
*/
createAclCustomResource(stack, aclName, onEventHandler, props) {
const providerFunctionName = `${onEventHandler.functionName}-Provider`;
const providerRole = new aws_iam_1.Role(this, "CloudfrontWebAclProviderRole", {
assumedBy: new aws_iam_1.ServicePrincipal("lambda.amazonaws.com"),
inlinePolicies: {
logs: new aws_iam_1.PolicyDocument({
statements: [
new aws_iam_1.PolicyStatement({
effect: aws_iam_1.Effect.ALLOW,
actions: [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
],
resources: [
`arn:aws:logs:${stack.region}:${stack.account}:log-group:/aws/lambda/${providerFunctionName}`,
`arn:aws:logs:${stack.region}:${stack.account}:log-group:/aws/lambda/${providerFunctionName}:*`,
],
}),
],
}),
},
});
const provider = new custom_resources_1.Provider(this, "CloudfrontAclProvider", {
onEventHandler,
role: providerRole,
providerFunctionName,
});
["AwsSolutions-IAM5", "AwsPrototyping-IAMNoWildcardPermissions"].forEach((RuleId) => {
cdk_nag_1.NagSuppressions.addResourceSuppressions(providerRole, [
{
id: RuleId,
reason: "Cloudwatch resources have been scoped down to the LogGroup level, however * is still needed as stream names are created just in time.",
},
], true);
});
["AwsSolutions-L1", "AwsPrototyping-LambdaLatestVersion"].forEach((RuleId) => {
cdk_nag_1.NagSuppressions.addResourceSuppressions(provider, [
{
id: RuleId,
reason: "Latest runtime cannot be configured. CDK will need to upgrade the Provider construct accordingly.",
},
], true);
});
return new aws_cdk_lib_1.CustomResource(this, "CFAclCustomResource", {
serviceToken: provider.serviceToken,
properties: {
ID: aclName,
MANAGED_RULES: props?.managedRules ?? [
{ vendor: "AWS", name: "AWSManagedRulesCommonRuleSet" },
],
CIDR_ALLOW_LIST: props?.cidrAllowList,
},
});
}
}
exports.CloudfrontWebAcl = CloudfrontWebAcl;
_a = JSII_RTTI_SYMBOL_1;
CloudfrontWebAcl[_a] = { fqn: "@aws/pdk.static_website.CloudfrontWebAcl", version: "0.26.14" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWRmcm9udC13ZWItYWNsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY2xvdWRmcm9udC13ZWItYWNsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUE7c0NBQ3NDO0FBQ3RDLDZCQUE2QjtBQUM3QiwwQ0FBc0M7QUFDdEMsNkNBQThEO0FBQzlELGlEQU02QjtBQUM3Qix1REFBaUU7QUFDakUsbUVBQXdEO0FBQ3hELHFDQUEwQztBQUMxQywyQ0FBdUM7QUFzRXZDOzs7R0FHRztBQUNILE1BQWEsZ0JBQWlCLFNBQVEsc0JBQVM7SUFJN0MsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUE2QjtRQUNyRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLE1BQU0sS0FBSyxHQUFHLG1CQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdCLE1BQU0sT0FBTyxHQUFHLEdBQUcsS0FBSyxDQUFDLFNBQVMsSUFBSSxFQUFFLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN2RSxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FDakQsS0FBSyxFQUNMLE9BQU8sRUFDUCxjQUFjLEVBQ2QsS0FBSyxDQUNOLENBQUM7UUFFRixJQUFJLENBQUMsUUFBUSxHQUFHLGNBQWMsQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDeEQsSUFBSSxDQUFDLFNBQVMsR0FBRyxjQUFjLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSyxvQkFBb0IsQ0FBQyxLQUFZLEVBQUUsT0FBZTtRQUN4RCxnSEFBZ0g7UUFDaEgsb0hBQW9I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aHQgW0FtYXpvbi5jb21dKGh0dHA6Ly9hbWF6b24uY29tLyksIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMCAqL1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgUERLTmFnIH0gZnJvbSBcIkBhd3MvcGRrLW5hZ1wiO1xuaW1wb3J0IHsgQ3VzdG9tUmVzb3VyY2UsIER1cmF0aW9uLCBTdGFjayB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHtcbiAgRWZmZWN0LFxuICBQb2xpY3lEb2N1bWVudCxcbiAgUG9saWN5U3RhdGVtZW50LFxuICBSb2xlLFxuICBTZXJ2aWNlUHJpbmNpcGFsLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWlhbVwiO1xuaW1wb3J0IHsgQ29kZSwgRnVuY3Rpb24sIFJ1bnRpbWUgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYVwiO1xuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tIFwiYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlc1wiO1xuaW1wb3J0IHsgTmFnU3VwcHJlc3Npb25zIH0gZnJvbSBcImNkay1uYWdcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIFdBRiBWMiBtYW5hZ2VkIHJ1bGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWFuYWdlZFJ1bGUge1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIG1hbmFnZWQgcnVsZSBncm91cCB2ZW5kb3IuIFlvdSB1c2UgdGhpcywgYWxvbmcgd2l0aCB0aGUgcnVsZSBncm91cCBuYW1lLCB0byBpZGVudGlmeSB0aGUgcnVsZSBncm91cC5cbiAgICovXG4gIHJlYWRvbmx5IHZlbmRvcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgbWFuYWdlZCBydWxlIGdyb3VwLiBZb3UgdXNlIHRoaXMsIGFsb25nIHdpdGggdGhlIHZlbmRvciBuYW1lLCB0byBpZGVudGlmeSB0aGUgcnVsZSBncm91cC5cbiAgICovXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBUeXBlIG9mIENpZHIuXG4gKi9cbmV4cG9ydCB0eXBlIENpZHJUeXBlID0gXCJJUFY0XCIgfCBcIklQVjZcIjtcblxuLyoqXG4gKiBSZXByZXNlbnRhdGlvbiBvZiBhIENJRFIgcmFuZ2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2lkckFsbG93TGlzdCB7XG4gIC8qKlxuICAgKiBUeXBlIG9mIENJRFIgcmFuZ2UuXG4gICAqL1xuICByZWFkb25seSBjaWRyVHlwZTogQ2lkclR5cGU7XG5cbiAgLyoqXG4gICAqIFNwZWNpZnkgYW4gSVB2NCBhZGRyZXNzIGJ5IHVzaW5nIENJRFIgbm90YXRpb24uIEZvciBleGFtcGxlOlxuICAgKiBUbyBjb25maWd1cmUgQVdTIFdBRiB0byBhbGxvdywgYmxvY2ssIG9yIGNvdW50IHJlcXVlc3RzIHRoYXQgb3JpZ2luYXRlZCBmcm9tIHRoZSBJUCBhZGRyZXNzIDE5Mi4wLjIuNDQsIHNwZWNpZnkgMTkyLjAuMi40NC8zMiAuXG4gICAqIFRvIGNvbmZpZ3VyZSBBV1MgV0FGIHRvIGFsbG93LCBibG9jaywgb3IgY291bnQgcmVxdWVzdHMgdGhhdCBvcmlnaW5hdGVkIGZyb20gSVAgYWRkcmVzc2VzIGZyb20gMTkyLjAuMi4wIHRvIDE5Mi4wLjIuMjU1LCBzcGVjaWZ5IDE5Mi4wLjIuMC8yNCAuXG4gICAqXG4gICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IENJRFIgbm90YXRpb24sIHNlZSB0aGUgV2lraXBlZGlhIGVudHJ5IENsYXNzbGVzcyBJbnRlci1Eb21haW4gUm91dGluZyAuXG4gICAqXG4gICAqIFNwZWNpZnkgYW4gSVB2NiBhZGRyZXNzIGJ5IHVzaW5nIENJRFIgbm90YXRpb24uIEZvciBleGFtcGxlOlxuICAgKiBUbyBjb25maWd1cmUgQVdTIFdBRiB0byBhbGxvdywgYmxvY2ssIG9yIGNvdW50IHJlcXVlc3RzIHRoYXQgb3JpZ2luYXRlZCBmcm9tIHRoZSBJUCBhZGRyZXNzIDExMTE6MDAwMDowMDAwOjAwMDA6MDAwMDowMDAwOjAwMDA6MDExMSwgc3BlY2lmeSAxMTExOjAwMDA6MDAwMDowMDAwOjAwMDA6MDAwMDowMDAwOjAxMTEvMTI4IC5cbiAgICogVG8gY29uZmlndXJlIEFXUyBXQUYgdG8gYWxsb3csIGJsb2NrLCBvciBjb3VudCByZXF1ZXN0cyB0aGF0IG9yaWdpbmF0ZWQgZnJvbSBJUCBhZGRyZXNzZXMgMTExMTowMDAwOjAwMDA6MDAwMDowMDAwOjAwMDA6MDAwMDowMDAwIHRvIDExMTE6MDAwMDowMDAwOjAwMDA6ZmZmZjpmZmZmOmZmZmY6ZmZmZiwgc3BlY2lmeSAxMTExOjAwMDA6MDAwMDowMDAwOjAwMDA6MDAwMDowMDAwOjAwMDAvNjQgLlxuICAgKi9cbiAgcmVhZG9ubHkgY2lkclJhbmdlczogc3RyaW5nW107XG59XG5cbi8qKlxuICogUHJvcGVydGllcyB0byBjb25maWd1cmUgdGhlIHdlYiBhY2wuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2xvdWRGcm9udFdlYkFjbFByb3BzIHtcbiAgLyoqXG4gICAqIExpc3Qgb2YgbWFuYWdlZCBydWxlcyB0byBhcHBseSB0byB0aGUgd2ViIGFjbC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBbeyB2ZW5kb3I6IFwiQVdTXCIsIG5hbWU6IFwiQVdTTWFuYWdlZFJ1bGVzQ29tbW9uUnVsZVNldFwiIH1dXG4gICAqL1xuICByZWFkb25seSBtYW5hZ2VkUnVsZXM/OiBNYW5hZ2VkUnVsZVtdO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIGNpZHIgcmFuZ2VzIHRvIGFsbG93LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHVuZGVmaW5lZFxuICAgKi9cbiAgcmVhZG9ubHkgY2lkckFsbG93TGlzdD86IENpZHJBbGxvd0xpc3Q7XG5cbiAgLyoqXG4gICAqIFNldCB0byB0cnVlIHRvIHByZXZlbnQgY3JlYXRpb24gb2YgYSB3ZWIgYWNsIGZvciB0aGUgc3RhdGljIHdlYnNpdGVcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGRpc2FibGU/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFRoaXMgY29uc3RydWN0IGNyZWF0ZXMgYSBXQUZ2MiBXZWIgQUNMIGZvciBjbG91ZGZyb250IGluIHRoZSB1cy1lYXN0LTEgcmVnaW9uIChyZXF1aXJlZCBmb3IgY2xvdWRmcm9udCkgbm8gbWF0dGVyIHRoZVxuICogcmVnaW9uIG9mIHRoZSBwYXJlbnQgY2RrIHN0YWNrLlxuICovXG5leHBvcnQgY2xhc3MgQ2xvdWRmcm9udFdlYkFjbCBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHB1YmxpYyByZWFkb25seSB3ZWJBY2xJZDogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgd2ViQWNsQXJuOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM/OiBDbG91ZEZyb250V2ViQWNsUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3Qgc3RhY2sgPSBTdGFjay5vZih0aGlzKTtcbiAgICBjb25zdCBhY2xOYW1lID0gYCR7c3RhY2suc3RhY2tOYW1lfS0ke2lkfS0ke3RoaXMubm9kZS5hZGRyLnNsaWNlKC00KX1gO1xuICAgIGNvbnN0IG9uRXZlbnRIYW5kbGVyID0gdGhpcy5jcmVhdGVPbkV2ZW50SGFuZGxlcihzdGFjaywgYWNsTmFtZSk7XG4gICAgY29uc3QgY3VzdG9tUmVzb3VyY2UgPSB0aGlzLmNyZWF0ZUFjbEN1c3RvbVJlc291cmNlKFxuICAgICAgc3RhY2ssXG4gICAgICBhY2xOYW1lLFxuICAgICAgb25FdmVudEhhbmRsZXIsXG4gICAgICBwcm9wc1xuICAgICk7XG5cbiAgICB0aGlzLndlYkFjbElkID0gY3VzdG9tUmVzb3VyY2UuZ2V0QXR0U3RyaW5nKFwiV2ViQWNsSWRcIik7XG4gICAgdGhpcy53ZWJBY2xBcm4gPSBjdXN0b21SZXNvdXJjZS5nZXRBdHRTdHJpbmcoXCJXZWJBY2xBcm5cIik7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBldmVudCBoYW5kbGVyIGZvciBtYW5hZ2luZyBhbiBBQ0wgaW4gdXMtZWFzdC0xLlxuICAgKlxuICAgKiBAcGFyYW0gc3RhY2sgY29udGFpbmluZyBTdGFjayBpbnN0YW5jZS5cbiAgICogQHBhcmFtIGFjbE5hbWUgbmFtZSBvZiB0aGUgQUNMIHRvIG1hbmFnZS5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgY3JlYXRlT25FdmVudEhhbmRsZXIoc3RhY2s6IFN0YWNrLCBhY2xOYW1lOiBzdHJpbmcpOiBGdW5jdGlvbiB7XG4gICAgLy8gTkIgd2l0aG91dCBtYW51YWxseSBkZWZpbmluZyBhIG5hbWUsIHRoZSBjZGsgZ2VuZXJhdGVkIG5hbWUgZm9yIHRoZSBQcm92aWRlciBmdW5jdGlvbiBjYW4gYmVjb21lIHRvbyBsb25nIGFuZFxuICAgIC8vIGRlcGxveW1lbnRzIGZhaWwuIFRoaXMgaXMgYmVjYXVzZSB0aGUgUHJvdmlkZXIncyBuYW1lIHJlZmVyZW5jZXMgdGhlIG9uRXZlbnQgaGFuZGxlciBuYW1lIGFuZCBhcHBlbmRzIFwiLVByb3ZpZGVyXCJcbiAgICAvLyByYXRoZXIgdGhhbiBiZWluZyBnZW5lcmF0ZWQgYnkgY2RrIGFuZCB0cnVuY2F0ZWQgYXBwcm9wcmlhdGVseVxuICAgIGNvbnN0IG9uRXZlbnRIYW5kbGVyTmFtZSA9IGAke1BES05hZy5nZXRTdGFja1ByZWZpeChzdGFjaylcbiAgICAgIC5zcGxpdChcIi9cIilcbiAgICAgIC5qb2luKFwiLVwiKX1BY2xFdmVudC0ke3RoaXMubm9kZS5hZGRyLnNsaWNlKC02KX1gO1xuICAgIGNvbnN0IG9uRXZlbnRIYW5kbGVyUm9sZSA9IG5ldyBSb2xlKHRoaXMsIFwiT25FdmVudEhhbmRsZXJSb2xlXCIsIHtcbiAgICAgIGFzc3VtZWRCeTogbmV3IFNlcnZpY2VQcmluY2lwYWwoXCJsYW1iZGEuYW1hem9uYXdzLmNvbVwiKSxcbiAgICAgIGlubGluZVBvbGljaWVzOiB7XG4gICAgICAgIGxvZ3M6IG5ldyBQb2xpY3lEb2N1bWVudCh7XG4gICAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICAgIGVmZmVjdDogRWZmZWN0LkFMTE9XLFxuICAgICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICAgXCJsb2dzOkNyZWF0ZUxvZ0dyb3VwXCIsXG4gICAgICAgICAgICAgICAgXCJsb2dzOkNyZWF0ZUxvZ1N0cmVhbVwiLFxuICAgICAgICAgICAgICAgIFwibG9nczpQdXRMb2dFdmVudHNcIixcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgICAgICAgYGFybjphd3M6bG9nczoke3N0YWNrLnJlZ2lvbn06JHtzdGFjay5hY2NvdW50fTpsb2ctZ3JvdXA6L2F3cy9sYW1iZGEvJHtvbkV2ZW50SGFuZGxlck5hbWV9YCxcbiAgICAgICAgICAgICAgICBgYXJuOmF3czpsb2dzOiR7c3RhY2sucmVnaW9ufToke3N0YWNrLmFjY291bnR9OmxvZy1ncm91cDovYXdzL2xhbWJkYS8ke29uRXZlbnRIYW5kbGVyTmFtZX06KmAsXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KSxcbiAgICAgICAgd2FmdjI6IG5ldyBQb2xpY3lEb2N1bWVudCh7XG4gICAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICAgIGVmZmVjdDogRWZmZWN0LkFMTE9XLFxuICAgICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICAgXCJ3YWZ2MjpDcmVhdGVXZWJBQ0xcIixcbiAgICAgICAgICAgICAgICBcIndhZnYyOkRlbGV0ZVdlYkFDTFwiLFxuICAgICAgICAgICAgICAgIFwid2FmdjI6VXBkYXRlV2ViQUNMXCIsXG4gICAgICAgICAgICAgICAgXCJ3YWZ2MjpHZXRXZWJBQ0xcIixcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgICAgICAgYGFybjphd3M6d2FmdjI6dXMtZWFzdC0xOiR7c3RhY2suYWNjb3VudH06Z2xvYmFsL2lwc2V0LyR7YWNsTmFtZX0tSVBTZXQvKmAsXG4gICAgICAgICAgICAgICAgYGFybjphd3M6d2FmdjI6dXMtZWFzdC0xOiR7c3RhY2suYWNjb3VudH06Z2xvYmFsL3dlYmFjbC8ke2FjbE5hbWV9LypgLFxuICAgICAgICAgICAgICAgIGBhcm46YXdzOndhZnYyOnVzLWVhc3QtMToke3N0YWNrLmFjY291bnR9Omdsb2JhbC9tYW5hZ2VkcnVsZXNldC8qLypgLFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1csXG4gICAgICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgICAgICBcIndhZnYyOkNyZWF0ZUlQU2V0XCIsXG4gICAgICAgICAgICAgICAgXCJ3YWZ2MjpEZWxldGVJUFNldFwiLFxuICAgICAgICAgICAgICAgIFwid2FmdjI6VXBkYXRlSVBTZXRcIixcbiAgICAgICAgICAgICAgICBcIndhZnYyOkdldElQU2V0XCIsXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICAgIGBhcm46YXdzOndhZnYyOnVzLWVhc3QtMToke3N0YWNrLmFjY291bnR9Omdsb2JhbC9pcHNldC8ke2FjbE5hbWV9LUlQU2V0LypgLFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgXSxcbiAgICAgICAgfSksXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3Qgb25FdmVudEhhbmRsZXIgPSBuZXcgRnVuY3Rpb24oXG4gICAgICB0aGlzLFxuICAgICAgXCJDbG91ZGZyb250V2ViQWNsT25FdmVudEhhbmRsZXJcIixcbiAgICAgIHtcbiAgICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQocGF0aC5qb2luKF9fZGlybmFtZSwgXCIuL3dlYmFjbF9ldmVudF9oYW5kbGVyXCIpKSxcbiAgICAgICAgcm9sZTogb25FdmVudEhhbmRsZXJSb2xlLFxuICAgICAgICBmdW5jdGlvbk5hbWU6IG9uRXZlbnRIYW5kbGVyTmFtZSxcbiAgICAgICAgaGFuZGxlcjogXCJpbmRleC5vbkV2ZW50XCIsXG4gICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzE4X1gsXG4gICAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoMzAwKSxcbiAgICAgIH1cbiAgICApO1xuXG4gICAgW1wiQXdzU29sdXRpb25zLUlBTTVcIiwgXCJBd3NQcm90b3R5cGluZy1JQU1Ob1dpbGRjYXJkUGVybWlzc2lvbnNcIl0uZm9yRWFjaChcbiAgICAgIChSdWxlSWQpID0+IHtcbiAgICAgICAgTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKFxuICAgICAgICAgIG9uRXZlbnRIYW5kbGVyUm9sZSxcbiAgICAgICAgICBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiBSdWxlSWQsXG4gICAgICAgICAgICAgIHJlYXNvbjpcbiAgICAgICAgICAgICAgICBcIldhZlYyIHJlc291cmNlcyBoYXZlIGJlZW4gc2NvcGVkIGRvd24gdG8gdGhlIEFDTC9JUFNldCBsZXZlbCwgaG93ZXZlciAqIGlzIHN0aWxsIG5lZWRlZCBhcyByZXNvdXJjZSBpZCdzIGFyZSBjcmVhdGVkIGp1c3QgaW4gdGltZS5cIixcbiAgICAgICAgICAgICAgYXBwbGllc1RvOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgcmVnZXg6IGAvXlJlc291cmNlOjphcm46YXdzOndhZnYyOnVzLWVhc3QtMToke1BES05hZy5nZXRTdGFja0FjY291bnRSZWdleChcbiAgICAgICAgICAgICAgICAgICAgc3RhY2tcbiAgICAgICAgICAgICAgICAgICl9Omdsb2JhbC8oLiopJC9nYCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6IFJ1bGVJZCxcbiAgICAgICAgICAgICAgcmVhc29uOlxuICAgICAgICAgICAgICAgIFwiQ2xvdWR3YXRjaCByZXNvdXJjZXMgaGF2ZSBiZWVuIHNjb3BlZCBkb3duIHRvIHRoZSBMb2dHcm91cCBsZXZlbCwgaG93ZXZlciAqIGlzIHN0aWxsIG5lZWRlZCBhcyBzdHJlYW0gbmFtZXMgYXJlIGNyZWF0ZWQganVzdCBpbiB0aW1lLlwiLFxuICAgICAgICAgICAgICBhcHBsaWVzVG86IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICByZWdleDogYC9eUmVzb3VyY2U6OmFybjphd3M6bG9nczoke1BES05hZy5nZXRTdGFja1JlZ2lvblJlZ2V4KFxuICAgICAgICAgICAgICAgICAgICBzdGFja1xuICAgICAgICAgICAgICAgICAgKX06JHtQREtOYWcuZ2V0U3RhY2tBY2NvdW50UmVnZXgoXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrXG4gICAgICAgICAgICAgICAgICApfTpsb2ctZ3JvdXA6L2F3cy9sYW1iZGEvJHtvbkV2ZW50SGFuZGxlck5hbWV9OlxcKi9nYCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHRydWVcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgcmV0dXJuIG9uRXZlbnRIYW5kbGVyO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBDdXN0b20gcmVzb3VyY2UgdG8gbWFuYWdlIHRoZSBkZXBsb3ltZW50IG9mIHRoZSBBQ0wuXG4gICAqXG4gICAqIEBwYXJhbSBzdGFjayBjb250YWluaW5nIFN0YWNrIGluc3RhbmNlLlxuICAgKiBAcGFyYW0gYWNsTmFtZSBuYW1lIG9mIHRoZSBBQ0wgdG8gbWFuYWdlLlxuICAgKiBAcGFyYW0gb25FdmVudEhhbmRsZXIgZXZlbnQgaGFuZGxlciB0byB1c2UgZm9yIGRlcGxveW1lbnQuXG4gICAqIEBwYXJhbSBwcm9wcyB1c2VyIHByb3ZpZGVkIHByb3BlcnRpZXMgZm9yIGNvbmZpZ3VyaW5nIHRoZSBBQ0wuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZUFjbEN1c3RvbVJlc291cmNlKFxuICAgIHN0YWNrOiBTdGFjayxcbiAgICBhY2xOYW1lOiBzdHJpbmcsXG4gICAgb25FdmVudEhhbmRsZXI6IEZ1bmN0aW9uLFxuICAgIHByb3BzPzogQ2xvdWRGcm9udFdlYkFjbFByb3BzXG4gICk6IEN1c3RvbVJlc291cmNlIHtcbiAgICBjb25zdCBwcm92aWRlckZ1bmN0aW9uTmFtZSA9IGAke29uRXZlbnRIYW5kbGVyLmZ1bmN0aW9uTmFtZX0tUHJvdmlkZXJgO1xuICAgIGNvbnN0IHByb3ZpZGVyUm9sZSA9IG5ldyBSb2xlKHRoaXMsIFwiQ2xvdWRmcm9udFdlYkFjbFByb3ZpZGVyUm9sZVwiLCB7XG4gICAgICBhc3N1bWVkQnk6IG5ldyBTZXJ2aWNlUHJpbmNpcGFsKFwibGFtYmRhLmFtYXpvbmF3cy5jb21cIiksXG4gICAgICBpbmxpbmVQb2xpY2llczoge1xuICAgICAgICBsb2dzOiBuZXcgUG9saWN5RG9jdW1lbnQoe1xuICAgICAgICAgIHN0YXRlbWVudHM6IFtcbiAgICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC5BTExPVyxcbiAgICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAgIFwibG9nczpDcmVhdGVMb2dHcm91cFwiLFxuICAgICAgICAgICAgICAgIFwibG9nczpDcmVhdGVMb2dTdHJlYW1cIixcbiAgICAgICAgICAgICAgICBcImxvZ3M6UHV0TG9nRXZlbnRzXCIsXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICAgIGBhcm46YXdzOmxvZ3M6JHtzdGFjay5yZWdpb259OiR7c3RhY2suYWNjb3VudH06bG9nLWdyb3VwOi9hd3MvbGFtYmRhLyR7cHJvdmlkZXJGdW5jdGlvbk5hbWV9YCxcbiAgICAgICAgICAgICAgICBgYXJuOmF3czpsb2dzOiR7c3RhY2sucmVnaW9ufToke3N0YWNrLmFjY291bnR9OmxvZy1ncm91cDovYXdzL2xhbWJkYS8ke3Byb3ZpZGVyRnVuY3Rpb25OYW1lfToqYCxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBjb25zdCBwcm92aWRlciA9IG5ldyBQcm92aWRlcih0aGlzLCBcIkNsb3VkZnJvbnRBY2xQcm92aWRlclwiLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcixcbiAgICAgIHJvbGU6IHByb3ZpZGVyUm9sZSxcbiAgICAgIHByb3ZpZGVyRnVuY3Rpb25OYW1lLFxuICAgIH0pO1xuXG4gICAgW1wiQXdzU29sdXRpb25zLUlBTTVcIiwgXCJBd3NQcm90b3R5cGluZy1JQU1Ob1dpbGRjYXJkUGVybWlzc2lvbnNcIl0uZm9yRWFjaChcbiAgICAgIChSdWxlSWQpID0+IHtcbiAgICAgICAgTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKFxuICAgICAgICAgIHByb3ZpZGVyUm9sZSxcbiAgICAgICAgICBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiBSdWxlSWQsXG4gICAgICAgICAgICAgIHJlYXNvbjpcbiAgICAgICAgICAgICAgICBcIkNsb3Vkd2F0Y2ggcmVzb3VyY2VzIGhhdmUgYmVlbiBzY29wZWQgZG93biB0byB0aGUgTG9nR3JvdXAgbGV2ZWwsIGhvd2V2ZXIgKiBpcyBzdGlsbCBuZWVkZWQgYXMgc3RyZWFtIG5hbWVzIGFyZSBjcmVhdGVkIGp1c3QgaW4gdGltZS5cIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICB0cnVlXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgKTtcblxuICAgIFtcIkF3c1NvbHV0aW9ucy1MMVwiLCBcIkF3c1Byb3RvdHlwaW5nLUxhbWJkYUxhdGVzdFZlcnNpb25cIl0uZm9yRWFjaChcbiAgICAgIChSdWxlSWQpID0+IHtcbiAgICAgICAgTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKFxuICAgICAgICAgIHByb3ZpZGVyLFxuICAgICAgICAgIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6IFJ1bGVJZCxcbiAgICAgICAgICAgICAgcmVhc29uOlxuICAgICAgICAgICAgICAgIFwiTGF0ZXN0IHJ1bnRpbWUgY2Fubm90IGJlIGNvbmZpZ3VyZWQuIENESyB3aWxsIG5lZWQgdG8gdXBncmFkZSB0aGUgUHJvdmlkZXIgY29uc3RydWN0IGFjY29yZGluZ2x5LlwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHRydWVcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgcmV0dXJuIG5ldyBDdXN0b21SZXNvdXJjZSh0aGlzLCBcIkNGQWNsQ3VzdG9tUmVzb3VyY2VcIiwge1xuICAgICAgc2VydmljZVRva2VuOiBwcm92aWRlci5zZXJ2aWNlVG9rZW4sXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIElEOiBhY2xOYW1lLFxuICAgICAgICBNQU5BR0VEX1JVTEVTOiBwcm9wcz8ubWFuYWdlZFJ1bGVzID8/IFtcbiAgICAgICAgICB7IHZlbmRvcjogXCJBV1NcIiwgbmFtZTogXCJBV1NNYW5hZ2VkUnVsZXNDb21tb25SdWxlU2V0XCIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgQ0lEUl9BTExPV19MSVNUOiBwcm9wcz8uY2lkckFsbG93TGlzdCxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==