@aws-solutions-constructs/core
Version:
Core CDK Construct for patterns library
240 lines • 31.7 kB
JavaScript
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServiceEndpointTypes = void 0;
exports.buildVpc = buildVpc;
exports.AddAwsServiceEndpoint = AddAwsServiceEndpoint;
exports.retrievePrivateSubnetIds = retrievePrivateSubnetIds;
exports.CheckVpcProps = CheckVpcProps;
/*
* The functions found here in the core library are for internal use and can be changed
* or removed outside of a major release. We recommend against calling them directly from client code.
*/
const ec2 = require("aws-cdk-lib/aws-ec2");
const security_group_helper_1 = require("./security-group-helper");
const utils_1 = require("./utils");
const cdk = require("aws-cdk-lib");
/**
* @internal This is an internal core function and should not be called directly by Solutions Constructs clients.
*/
function buildVpc(scope, props) {
if (props?.existingVpc) {
return props?.existingVpc;
}
let cumulativeProps = props?.defaultVpcProps;
cumulativeProps = (0, utils_1.consolidateProps)(cumulativeProps, props?.userVpcProps, props?.constructVpcProps);
const vpc = new ec2.Vpc(scope, "Vpc", cumulativeProps);
// Add VPC FlowLogs with the default setting of trafficType:ALL and destination: CloudWatch Logs
const flowLog = vpc.addFlowLog("FlowLog");
SuppressMapPublicIpWarnings(vpc);
SuppressEncryptedLogWarnings(flowLog);
(0, utils_1.suppressVpcCustomerHandlerRoleWarnings)(cdk.Stack.of(scope));
return vpc;
}
var ServiceEndpointTypes;
(function (ServiceEndpointTypes) {
ServiceEndpointTypes["DYNAMODB"] = "DDB";
ServiceEndpointTypes["SNS"] = "SNS";
ServiceEndpointTypes["SQS"] = "SQS";
ServiceEndpointTypes["S3"] = "S3";
ServiceEndpointTypes["STEP_FUNCTIONS"] = "STEP_FUNCTIONS";
ServiceEndpointTypes["SAGEMAKER_RUNTIME"] = "SAGEMAKER_RUNTIME";
ServiceEndpointTypes["SECRETS_MANAGER"] = "SECRETS_MANAGER";
ServiceEndpointTypes["SSM"] = "SSM";
ServiceEndpointTypes["ECR_API"] = "ECR_API";
ServiceEndpointTypes["ECR_DKR"] = "ECR_DKR";
ServiceEndpointTypes["EVENTS"] = "CLOUDWATCH_EVENTS";
ServiceEndpointTypes["KINESIS_FIREHOSE"] = "KINESIS_FIREHOSE";
ServiceEndpointTypes["KINESIS_STREAMS"] = "KINESIS_STREAMS";
ServiceEndpointTypes["BEDROCK"] = "BEDROCK";
ServiceEndpointTypes["BEDROCK_RUNTIME"] = "BEDROCK_RUNTIME";
ServiceEndpointTypes["KENDRA"] = "KENDRA";
})(ServiceEndpointTypes || (exports.ServiceEndpointTypes = ServiceEndpointTypes = {}));
var EndpointTypes;
(function (EndpointTypes) {
EndpointTypes["GATEWAY"] = "Gateway";
EndpointTypes["INTERFACE"] = "Interface";
})(EndpointTypes || (EndpointTypes = {}));
const endpointSettings = [
{
endpointName: ServiceEndpointTypes.DYNAMODB,
endpointType: EndpointTypes.GATEWAY,
endpointGatewayService: ec2.GatewayVpcEndpointAwsService.DYNAMODB,
},
{
endpointName: ServiceEndpointTypes.S3,
endpointType: EndpointTypes.GATEWAY,
endpointGatewayService: ec2.GatewayVpcEndpointAwsService.S3,
},
{
endpointName: ServiceEndpointTypes.STEP_FUNCTIONS,
endpointType: EndpointTypes.INTERFACE,
endpointInterfaceService: ec2.InterfaceVpcEndpointAwsService.STEP_FUNCTIONS,
},
{
endpointName: ServiceEndpointTypes.SNS,
endpointType: EndpointTypes.INTERFACE,
endpointInterfaceService: ec2.InterfaceVpcEndpointAwsService.SNS,
},
{
endpointName: ServiceEndpointTypes.SQS,
endpointType: EndpointTypes.INTERFACE,
endpointInterfaceService: ec2.InterfaceVpcEndpointAwsService.SQS,
},
{
endpointName: ServiceEndpointTypes.SAGEMAKER_RUNTIME,
endpointType: EndpointTypes.INTERFACE,
endpointInterfaceService: ec2.InterfaceVpcEndpointAwsService.SAGEMAKER_RUNTIME,
},
{
endpointName: ServiceEndpointTypes.SECRETS_MANAGER,
endpointType: EndpointTypes.INTERFACE,
endpointInterfaceService: ec2.InterfaceVpcEndpointAwsService.SECRETS_MANAGER,
},
{
endpointName: ServiceEndpointTypes.SSM,
endpointType: EndpointTypes.INTERFACE,
endpointInterfaceService: ec2.InterfaceVpcEndpointAwsService.SSM,
},
{
endpointName: ServiceEndpointTypes.ECR_API,
endpointType: EndpointTypes.INTERFACE,
endpointInterfaceService: ec2.InterfaceVpcEndpointAwsService.ECR
},
{
endpointName: ServiceEndpointTypes.ECR_DKR,
endpointType: EndpointTypes.INTERFACE,
endpointInterfaceService: ec2.InterfaceVpcEndpointAwsService.ECR_DOCKER
},
{
endpointName: ServiceEndpointTypes.EVENTS,
endpointType: EndpointTypes.INTERFACE,
endpointInterfaceService: ec2.InterfaceVpcEndpointAwsService.CLOUDWATCH_EVENTS
},
{
endpointName: ServiceEndpointTypes.KINESIS_FIREHOSE,
endpointType: EndpointTypes.INTERFACE,
endpointInterfaceService: ec2.InterfaceVpcEndpointAwsService.KINESIS_FIREHOSE
},
{
endpointName: ServiceEndpointTypes.KINESIS_STREAMS,
endpointType: EndpointTypes.INTERFACE,
endpointInterfaceService: ec2.InterfaceVpcEndpointAwsService.KINESIS_STREAMS
},
{
endpointName: ServiceEndpointTypes.KENDRA,
endpointType: EndpointTypes.INTERFACE,
endpointInterfaceService: ec2.InterfaceVpcEndpointAwsService.KENDRA
},
{
endpointName: ServiceEndpointTypes.BEDROCK,
endpointType: EndpointTypes.INTERFACE,
endpointInterfaceService: ec2.InterfaceVpcEndpointAwsService.BEDROCK
},
{
endpointName: ServiceEndpointTypes.BEDROCK_RUNTIME,
endpointType: EndpointTypes.INTERFACE,
endpointInterfaceService: ec2.InterfaceVpcEndpointAwsService.BEDROCK_RUNTIME
}
];
/**
* @internal This is an internal core function and should not be called directly by Solutions Constructs clients.
*/
function AddAwsServiceEndpoint(scope, vpc, interfaceTag) {
if (CheckIfEndpointAlreadyExists(vpc, interfaceTag)) {
return;
}
const service = endpointSettings.find((endpoint) => endpoint.endpointName === interfaceTag);
if (!service) {
throw new Error("Unsupported Service sent to AddServiceEndpoint");
}
if (service.endpointType === EndpointTypes.GATEWAY) {
AddGatewayEndpoint(vpc, service, interfaceTag);
}
if (service.endpointType === EndpointTypes.INTERFACE) {
AddInterfaceEndpoint(scope, vpc, service, interfaceTag);
}
}
function CheckIfEndpointAlreadyExists(vpc, interfaceTag) {
return vpc.node.children.some((child) => child.node.id === interfaceTag);
}
function SuppressMapPublicIpWarnings(vpc) {
// Add Cfn Nag suppression for PUBLIC subnets to suppress WARN W33: EC2 Subnet should not have MapPublicIpOnLaunch set to true
vpc.publicSubnets.forEach((subnet) => {
const cfnSubnet = subnet.node.defaultChild;
(0, utils_1.addCfnSuppressRules)(cfnSubnet, [
{
id: 'W33',
reason: 'Allow Public Subnets to have MapPublicIpOnLaunch set to true'
}
]);
});
}
function SuppressEncryptedLogWarnings(flowLog) {
// Add Cfn Nag suppression for CloudWatchLogs LogGroups data is encrypted
const cfnLogGroup = flowLog.logGroup?.node.defaultChild;
(0, utils_1.addCfnSuppressRules)(cfnLogGroup, [
{
id: 'W84',
reason: 'By default CloudWatchLogs LogGroups data is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)'
}
]);
}
function AddInterfaceEndpoint(scope, vpc, service, interfaceTag) {
const endpointDefaultSecurityGroup = (0, security_group_helper_1.buildSecurityGroup)(scope, `${scope.node.id}-${service.endpointName}`, {
vpc,
allowAllOutbound: true,
}, [{ peer: ec2.Peer.ipv4(vpc.vpcCidrBlock), connection: ec2.Port.tcp(443) }], []);
vpc.addInterfaceEndpoint(interfaceTag, {
service: service.endpointInterfaceService,
securityGroups: [endpointDefaultSecurityGroup],
});
}
function AddGatewayEndpoint(vpc, service, interfaceTag) {
vpc.addGatewayEndpoint(interfaceTag, {
service: service.endpointGatewayService,
});
}
/**
* @internal This is an internal core function and should not be called directly by Solutions Constructs clients.
*/
function retrievePrivateSubnetIds(vpc) {
let targetSubnetType;
if (vpc.isolatedSubnets.length) {
targetSubnetType = ec2.SubnetType.PRIVATE_ISOLATED;
}
else if (vpc.privateSubnets.length) {
targetSubnetType = ec2.SubnetType.PRIVATE_WITH_EGRESS;
}
else {
throw new Error('Error - No isolated or private subnets available in VPC');
}
const subnetSelector = {
onePerAz: true,
subnetType: targetSubnetType
};
return vpc.selectSubnets(subnetSelector).subnetIds;
}
function CheckVpcProps(propsObject) {
let errorMessages = '';
let errorFound = false;
if ((propsObject.deployVpc || propsObject.vpcProps) && propsObject.existingVpc) {
errorMessages += 'Error - Either provide an existingVpc or some combination of deployVpc and vpcProps, but not both.\n';
errorFound = true;
}
if (errorFound) {
throw new Error(errorMessages);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidnBjLWhlbHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInZwYy1oZWxwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7OztHQVdHOzs7QUFxQ0gsNEJBbUJDO0FBdUhELHNEQXVCQztBQXlERCw0REFpQkM7QUFRRCxzQ0FZQztBQWxTRDs7O0dBR0c7QUFFSCwyQ0FBMkM7QUFHM0MsbUVBQTZEO0FBQzdELG1DQUF3RztBQUN4RyxtQ0FBbUM7QUFzQm5DOztHQUVHO0FBQ0gsU0FBZ0IsUUFBUSxDQUFDLEtBQWdCLEVBQUUsS0FBb0I7SUFDN0QsSUFBSSxLQUFLLEVBQUUsV0FBVyxFQUFFLENBQUM7UUFDdkIsT0FBTyxLQUFLLEVBQUUsV0FBVyxDQUFDO0lBQzVCLENBQUM7SUFFRCxJQUFJLGVBQWUsR0FBaUIsS0FBSyxFQUFFLGVBQWUsQ0FBQztJQUUzRCxlQUFlLEdBQUcsSUFBQSx3QkFBZ0IsRUFBQyxlQUFlLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUVuRyxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxlQUFlLENBQUMsQ0FBQztJQUV2RCxnR0FBZ0c7SUFDaEcsTUFBTSxPQUFPLEdBQWdCLEdBQUcsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFdkQsMkJBQTJCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDakMsNEJBQTRCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEMsSUFBQSw4Q0FBc0MsRUFBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBRTVELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVELElBQVksb0JBaUJYO0FBakJELFdBQVksb0JBQW9CO0lBQzlCLHdDQUFnQixDQUFBO0lBQ2hCLG1DQUFXLENBQUE7SUFDWCxtQ0FB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QUM7U0FBTSxDQUFDO1FBQ04sTUFBTSxJQUFJLEtBQUssQ0FBQyx5REFBeUQsQ0FBQyxDQUFDO0lBQzdFLENBQUM7SUFFRCxNQUFNLGNBQWMsR0FBRztRQUNyQixRQUFRLEVBQUUsSUFBSTtRQUNkLFVBQVUsRUFBRSxnQkFBZ0I7S0FDN0IsQ0FBQztJQUVGLE9BQU8sR0FBRyxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDckQsQ0FBQztBQVFELFNBQWdCLGFBQWEsQ0FBQyxXQUE4QjtJQUMxRCxJQUFJLGFBQWEsR0FBRyxFQUFFLENBQUM7SUFDdkIsSUFBSSxVQUFVLEdBQUcsS0FBSyxDQUFDO0lBRXZCLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxJQUFJLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxXQUFXLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDL0UsYUFBYSxJQUFJLHNHQUFzRyxDQUFDO1FBQ3hILFVBQVUsR0FBRyxJQUFJLENBQUM7SUFDcEIsQ0FBQztJQUVELElBQUksVUFBVSxFQUFFLENBQUM7UUFDZixNQUFNLElBQUksS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgQ29weXJpZ2h0IEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIikuIFlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcbiAqICB3aXRoIHRoZSBMaWNlbnNlLiBBIGNvcHkgb2YgdGhlIExpY2Vuc2UgaXMgbG9jYXRlZCBhdFxuICpcbiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogIG9yIGluIHRoZSAnbGljZW5zZScgZmlsZSBhY2NvbXBhbnlpbmcgdGhpcyBmaWxlLiBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgb24gYW4gJ0FTIElTJyBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTXG4gKiAgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnNcbiAqICBhbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuLypcbiAqICBUaGUgZnVuY3Rpb25zIGZvdW5kIGhlcmUgaW4gdGhlIGNvcmUgbGlicmFyeSBhcmUgZm9yIGludGVybmFsIHVzZSBhbmQgY2FuIGJlIGNoYW5nZWRcbiAqICBvciByZW1vdmVkIG91dHNpZGUgb2YgYSBtYWpvciByZWxlYXNlLiBXZSByZWNvbW1lbmQgYWdhaW5zdCBjYWxsaW5nIHRoZW0gZGlyZWN0bHkgZnJvbSBjbGllbnQgY29kZS5cbiAqL1xuXG5pbXBvcnQgKiBhcyBlYzIgZnJvbSBcImF3cy1jZGstbGliL2F3cy1lYzJcIjtcbmltcG9ydCB7IENmbkxvZ0dyb3VwIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sb2dzXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHsgYnVpbGRTZWN1cml0eUdyb3VwIH0gZnJvbSBcIi4vc2VjdXJpdHktZ3JvdXAtaGVscGVyXCI7XG5pbXBvcnQgeyBjb25zb2xpZGF0ZVByb3BzLCBhZGRDZm5TdXBwcmVzc1J1bGVzLCBzdXBwcmVzc1ZwY0N1c3RvbWVySGFuZGxlclJvbGVXYXJuaW5ncyB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgKiBhcyBjZGsgZnJvbSAnYXdzLWNkay1saWInO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkVnBjUHJvcHMge1xuICAvKipcbiAgICogRXhpc3RpbmcgaW5zdGFuY2Ugb2YgYSBWUEMsIGlmIHRoaXMgaXMgc2V0IHRoZW4gdGhlIGFsbCBQcm9wcyBhcmUgaWdub3JlZFxuICAgKi9cbiAgcmVhZG9ubHkgZXhpc3RpbmdWcGM/OiBlYzIuSVZwYztcbiAgLyoqXG4gICAqIE9uZSBvZiB0aGUgZGVmYXVsdCBWUEMgY29uZmlndXJhdGlvbnMgYXZhaWxhYmxlIGluIHZwYy1kZWZhdWx0c1xuICAgKi9cbiAgcmVhZG9ubHkgZGVmYXVsdFZwY1Byb3BzOiBlYzIuVnBjUHJvcHM7XG4gIC8qKlxuICAgKiBVc2VyIHByb3ZpZGVkIHByb3BzIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IHByb3BzIGZvciB0aGUgVlBDLlxuICAgKi9cbiAgcmVhZG9ubHkgdXNlclZwY1Byb3BzPzogZWMyLlZwY1Byb3BzO1xuICAvKipcbiAgICogQ29uc3RydWN0IHNwZWNpZmllZCBwcm9wcyB0aGF0IG92ZXJyaWRlIGJvdGggdGhlIGRlZmF1bHQgcHJvcHNcbiAgICogYW5kIHVzZXIgcHJvcHMgZm9yIHRoZSBWUEMuXG4gICAqL1xuICByZWFkb25seSBjb25zdHJ1Y3RWcGNQcm9wcz86IGVjMi5WcGNQcm9wcztcbn1cblxuLyoqXG4gKiBAaW50ZXJuYWwgVGhpcyBpcyBhbiBpbnRlcm5hbCBjb3JlIGZ1bmN0aW9uIGFuZCBzaG91bGQgbm90IGJlIGNhbGxlZCBkaXJlY3RseSBieSBTb2x1dGlvbnMgQ29uc3RydWN0cyBjbGllbnRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRWcGMoc2NvcGU6IENvbnN0cnVjdCwgcHJvcHM6IEJ1aWxkVnBjUHJvcHMpOiBlYzIuSVZwYyB7XG4gIGlmIChwcm9wcz8uZXhpc3RpbmdWcGMpIHtcbiAgICByZXR1cm4gcHJvcHM/LmV4aXN0aW5nVnBjO1xuICB9XG5cbiAgbGV0IGN1bXVsYXRpdmVQcm9wczogZWMyLlZwY1Byb3BzID0gcHJvcHM/LmRlZmF1bHRWcGNQcm9wcztcblxuICBjdW11bGF0aXZlUHJvcHMgPSBjb25zb2xpZGF0ZVByb3BzKGN1bXVsYXRpdmVQcm9wcywgcHJvcHM/LnVzZXJWcGNQcm9wcywgcHJvcHM/LmNvbnN0cnVjdFZwY1Byb3BzKTtcblxuICBjb25zdCB2cGMgPSBuZXcgZWMyLlZwYyhzY29wZSwgXCJWcGNcIiwgY3VtdWxhdGl2ZVByb3BzKTtcblxuICAvLyBBZGQgVlBDIEZsb3dMb2dzIHdpdGggdGhlIGRlZmF1bHQgc2V0dGluZyBvZiB0cmFmZmljVHlwZTpBTEwgYW5kIGRlc3RpbmF0aW9uOiBDbG91ZFdhdGNoIExvZ3NcbiAgY29uc3QgZmxvd0xvZzogZWMyLkZsb3dMb2cgPSB2cGMuYWRkRmxvd0xvZyhcIkZsb3dMb2dcIik7XG5cbiAgU3VwcHJlc3NNYXBQdWJsaWNJcFdhcm5pbmdzKHZwYyk7XG4gIFN1cHByZXNzRW5jcnlwdGVkTG9nV2FybmluZ3MoZmxvd0xvZyk7XG4gIHN1cHByZXNzVnBjQ3VzdG9tZXJIYW5kbGVyUm9sZVdhcm5pbmdzKGNkay5TdGFjay5vZihzY29wZSkpO1xuXG4gIHJldHVybiB2cGM7XG59XG5cbmV4cG9ydCBlbnVtIFNlcnZpY2VFbmRwb2ludFR5cGVzIHtcbiAgRFlOQU1PREIgPSBcIkREQlwiLFxuICBTTlMgPSBcIlNOU1wiLFxuICBTUVMgPSBcIlNRU1wiLFxuICBTMyA9IFwiUzNcIixcbiAgU1RFUF9GVU5DVElPTlMgPSBcIlNURVBfRlVOQ1RJT05TXCIsXG4gIFNBR0VNQUtFUl9SVU5USU1FID0gXCJTQUdFTUFLRVJfUlVOVElNRVwiLFxuICBTRUNSRVRTX01BTkFHRVIgPSBcIlNFQ1JFVFNfTUFOQUdFUlwiLFxuICBTU00gPSBcIlNTTVwiLFxuICBFQ1JfQVBJID0gXCJFQ1JfQVBJXCIsXG4gIEVDUl9ES1IgPSBcIkVDUl9ES1JcIixcbiAgRVZFTlRTID0gXCJDTE9VRFdBVENIX0VWRU5UU1wiLFxuICBLSU5FU0lTX0ZJUkVIT1NFID0gXCJLSU5FU0lTX0ZJUkVIT1NFXCIsXG4gIEtJTkVTSVNfU1RSRUFNUyA9IFwiS0lORVNJU19TVFJFQU1TXCIsXG4gIEJFRFJPQ0sgPSBcIkJFRFJPQ0tcIixcbiAgQkVEUk9DS19SVU5USU1FID0gXCJCRURST0NLX1JVTlRJTUVcIixcbiAgS0VORFJBID0gXCJLRU5EUkFcIlxufVxuXG5lbnVtIEVuZHBvaW50VHlwZXMge1xuICBHQVRFV0FZID0gXCJHYXRld2F5XCIsXG4gIElOVEVSRkFDRSA9IFwiSW50ZXJmYWNlXCIsXG59XG5cbmludGVyZmFjZSBFbmRwb2ludERlZmluaXRpb24ge1xuICBlbmRwb2ludE5hbWU6IFNlcnZpY2VFbmRwb2ludFR5cGVzO1xuICBlbmRwb2ludFR5cGU6IEVuZHBvaW50VHlwZXM7XG4gIGVuZHBvaW50R2F0ZXdheVNlcnZpY2U/OiBlYzIuR2F0ZXdheVZwY0VuZHBvaW50QXdzU2VydmljZTtcbiAgZW5kcG9pbnRJbnRlcmZhY2VTZXJ2aWNlPzogZWMyLkludGVyZmFjZVZwY0VuZHBvaW50QXdzU2VydmljZTtcbn1cblxuY29uc3QgZW5kcG9pbnRTZXR0aW5nczogRW5kcG9pbnREZWZpbml0aW9uW10gPSBbXG4gIHtcbiAgICBlbmRwb2ludE5hbWU6IFNlcnZpY2VFbmRwb2ludFR5cGVzLkRZTkFNT0RCLFxuICAgIGVuZHBvaW50VHlwZTogRW5kcG9pbnRUeXBlcy5HQVRFV0FZLFxuICAgIGVuZHBvaW50R2F0ZXdheVNlcnZpY2U6IGVjMi5HYXRld2F5VnBjRW5kcG9pbnRBd3NTZXJ2aWNlLkRZTkFNT0RCLFxuICB9LFxuICB7XG4gICAgZW5kcG9pbnROYW1lOiBTZXJ2aWNlRW5kcG9pbnRUeXBlcy5TMyxcbiAgICBlbmRwb2ludFR5cGU6IEVuZHBvaW50VHlwZXMuR0FURVdBWSxcbiAgICBlbmRwb2ludEdhdGV3YXlTZXJ2aWNlOiBlYzIuR2F0ZXdheVZwY0VuZHBvaW50QXdzU2VydmljZS5TMyxcbiAgfSxcbiAge1xuICAgIGVuZHBvaW50TmFtZTogU2VydmljZUVuZHBvaW50VHlwZXMuU1RFUF9GVU5DVElPTlMsXG4gICAgZW5kcG9pbnRUeXBlOiBFbmRwb2ludFR5cGVzLklOVEVSRkFDRSxcbiAgICBlbmRwb2ludEludGVyZmFjZVNlcnZpY2U6IGVjMi5JbnRlcmZhY2VWcGNFbmRwb2ludEF3c1NlcnZpY2UuU1RFUF9GVU5DVElPTlMsXG4gIH0sXG4gIHtcbiAgICBlbmRwb2ludE5hbWU6IFNlcnZpY2VFbmRwb2ludFR5cGVzLlNOUyxcbiAgICBlbmRwb2ludFR5cGU6IEVuZHBvaW50VHlwZXMuSU5URVJGQUNFLFxuICAgIGVuZHBvaW50SW50ZXJmYWNlU2VydmljZTogZWMyLkludGVyZmFjZVZwY0VuZHBvaW50QXdzU2VydmljZS5TTlMsXG4gIH0sXG4gIHtcbiAgICBlbmRwb2ludE5hbWU6IFNlcnZpY2VFbmRwb2ludFR5cGVzLlNRUyxcbiAgICBlbmRwb2ludFR5cGU6IEVuZHBvaW50VHlwZXMuSU5URVJGQUNFLFxuICAgIGVuZHBvaW50SW50ZXJmYWNlU2VydmljZTogZWMyLkludGVyZmFjZVZwY0VuZHBvaW50QXdzU2VydmljZS5TUVMsXG4gIH0sXG4gIHtcbiAgICBlbmRwb2ludE5hbWU6IFNlcnZpY2VFbmRwb2ludFR5cGVzLlNBR0VNQUtFUl9SVU5USU1FLFxuICAgIGVuZHBvaW50VHlwZTogRW5kcG9pbnRUeXBlcy5JTlRFUkZBQ0UsXG4gICAgZW5kcG9pbnRJbnRlcmZhY2VTZXJ2aWNlOiBlYzIuSW50ZXJmYWNlVnBjRW5kcG9pbnRBd3NTZXJ2aWNlLlNBR0VNQUtFUl9SVU5USU1FLFxuICB9LFxuICB7XG4gICAgZW5kcG9pbnROYW1lOiBTZXJ2aWNlRW5kcG9pbnRUeXBlcy5TRUNSRVRTX01BTkFHRVIsXG4gICAgZW5kcG9pbnRUeXBlOiBFbmRwb2ludFR5cGVzLklOVEVSRkFDRSxcbiAgICBlbmRwb2ludEludGVyZmFjZVNlcnZpY2U6IGVjMi5JbnRlcmZhY2VWcGNFbmRwb2ludEF3c1NlcnZpY2UuU0VDUkVUU19NQU5BR0VSLFxuICB9LFxuICB7XG4gICAgZW5kcG9pbnROYW1lOiBTZXJ2aWNlRW5kcG9pbnRUeXBlcy5TU00sXG4gICAgZW5kcG9pbnRUeXBlOiBFbmRwb2ludFR5cGVzLklOVEVSRkFDRSxcbiAgICBlbmRwb2ludEludGVyZmFjZVNlcnZpY2U6IGVjMi5JbnRlcmZhY2VWcGNFbmRwb2ludEF3c1NlcnZpY2UuU1NNLFxuICB9LFxuICB7XG4gICAgZW5kcG9pbnROYW1lOiBTZXJ2aWNlRW5kcG9pbnRUeXBlcy5FQ1JfQVBJLFxuICAgIGVuZHBvaW50VHlwZTogRW5kcG9pbnRUeXBlcy5JTlRFUkZBQ0UsXG4gICAgZW5kcG9pbnRJbnRlcmZhY2VTZXJ2aWNlOiBlYzIuSW50ZXJmYWNlVnBjRW5kcG9pbnRBd3NTZXJ2aWNlLkVDUlxuICB9LFxuICB7XG4gICAgZW5kcG9pbnROYW1lOiBTZXJ2aWNlRW5kcG9pbnRUeXBlcy5FQ1JfREtSLFxuICAgIGVuZHBvaW50VHlwZTogRW5kcG9pbnRUeXBlcy5JTlRFUkZBQ0UsXG4gICAgZW5kcG9pbnRJbnRlcmZhY2VTZXJ2aWNlOiBlYzIuSW50ZXJmYWNlVnBjRW5kcG9pbnRBd3NTZXJ2aWNlLkVDUl9ET0NLRVJcbiAgfSxcbiAge1xuICAgIGVuZHBvaW50TmFtZTogU2VydmljZUVuZHBvaW50VHlwZXMuRVZFTlRTLFxuICAgIGVuZHBvaW50VHlwZTogRW5kcG9pbnRUeXBlcy5JTlRFUkZBQ0UsXG4gICAgZW5kcG9pbnRJbnRlcmZhY2VTZXJ2aWNlOiBlYzIuSW50ZXJmYWNlVnBjRW5kcG9pbnRBd3NTZXJ2aWNlLkNMT1VEV0FUQ0hfRVZFTlRTXG4gIH0sXG4gIHtcbiAgICBlbmRwb2ludE5hbWU6IFNlcnZpY2VFbmRwb2ludFR5cGVzLktJTkVTSVNfRklSRUhPU0UsXG4gICAgZW5kcG9pbnRUeXBlOiBFbmRwb2ludFR5cGVzLklOVEVSRkFDRSxcbiAgICBlbmRwb2ludEludGVyZmFjZVNlcnZpY2U6IGVjMi5JbnRlcmZhY2VWcGNFbmRwb2ludEF3c1NlcnZpY2UuS0lORVNJU19GSVJFSE9TRVxuICB9LFxuICB7XG4gICAgZW5kcG9pbnROYW1lOiBTZXJ2aWNlRW5kcG9pbnRUeXBlcy5LSU5FU0lTX1NUUkVBTVMsXG4gICAgZW5kcG9pbnRUeXBlOiBFbmRwb2ludFR5cGVzLklOVEVSRkFDRSxcbiAgICBlbmRwb2ludEludGVyZmFjZVNlcnZpY2U6IGVjMi5JbnRlcmZhY2VWcGNFbmRwb2ludEF3c1NlcnZpY2UuS0lORVNJU19TVFJFQU1TXG4gIH0sXG4gIHtcbiAgICBlbmRwb2ludE5hbWU6IFNlcnZpY2VFbmRwb2ludFR5cGVzLktFTkRSQSxcbiAgICBlbmRwb2ludFR5cGU6IEVuZHBvaW50VHlwZXMuSU5URVJGQUNFLFxuICAgIGVuZHBvaW50SW50ZXJmYWNlU2VydmljZTogZWMyLkludGVyZmFjZVZwY0VuZHBvaW50QXdzU2VydmljZS5LRU5EUkFcbiAgfSxcbiAge1xuICAgIGVuZHBvaW50TmFtZTogU2VydmljZUVuZHBvaW50VHlwZXMuQkVEUk9DSyxcbiAgICBlbmRwb2ludFR5cGU6IEVuZHBvaW50VHlwZXMuSU5URVJGQUNFLFxuICAgIGVuZHBvaW50SW50ZXJmYWNlU2VydmljZTogZWMyLkludGVyZmFjZVZwY0VuZHBvaW50QXdzU2VydmljZS5CRURST0NLXG4gIH0sXG4gIHtcbiAgICBlbmRwb2ludE5hbWU6IFNlcnZpY2VFbmRwb2ludFR5cGVzLkJFRFJPQ0tfUlVOVElNRSxcbiAgICBlbmRwb2ludFR5cGU6IEVuZHBvaW50VHlwZXMuSU5URVJGQUNFLFxuICAgIGVuZHBvaW50SW50ZXJmYWNlU2VydmljZTogZWMyLkludGVyZmFjZVZwY0VuZHBvaW50QXdzU2VydmljZS5CRURST0NLX1JVTlRJTUVcbiAgfVxuXTtcblxuLyoqXG4gKiBAaW50ZXJuYWwgVGhpcyBpcyBhbiBpbnRlcm5hbCBjb3JlIGZ1bmN0aW9uIGFuZCBzaG91bGQgbm90IGJlIGNhbGxlZCBkaXJlY3RseSBieSBTb2x1dGlvbnMgQ29uc3RydWN0cyBjbGllbnRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gQWRkQXdzU2VydmljZUVuZHBvaW50KFxuICBzY29wZTogQ29uc3RydWN0LFxuICB2cGM6IGVjMi5JVnBjLFxuICBpbnRlcmZhY2VUYWc6IFNlcnZpY2VFbmRwb2ludFR5cGVzXG4pIHtcbiAgaWYgKENoZWNrSWZFbmRwb2ludEFscmVhZHlFeGlzdHModnBjLCBpbnRlcmZhY2VUYWcpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qgc2VydmljZSA9IGVuZHBvaW50U2V0dGluZ3MuZmluZChcbiAgICAoZW5kcG9pbnQpID0+IGVuZHBvaW50LmVuZHBvaW50TmFtZSA9PT0gaW50ZXJmYWNlVGFnXG4gICk7XG5cbiAgaWYgKCFzZXJ2aWNlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgU2VydmljZSBzZW50IHRvIEFkZFNlcnZpY2VFbmRwb2ludFwiKTtcbiAgfVxuXG4gIGlmIChzZXJ2aWNlLmVuZHBvaW50VHlwZSA9PT0gRW5kcG9pbnRUeXBlcy5HQVRFV0FZKSB7XG4gICAgQWRkR2F0ZXdheUVuZHBvaW50KHZwYywgc2VydmljZSwgaW50ZXJmYWNlVGFnKTtcbiAgfVxuICBpZiAoc2VydmljZS5lbmRwb2ludFR5cGUgPT09IEVuZHBvaW50VHlwZXMuSU5URVJGQUNFKSB7XG4gICAgQWRkSW50ZXJmYWNlRW5kcG9pbnQoc2NvcGUsIHZwYywgc2VydmljZSwgaW50ZXJmYWNlVGFnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBDaGVja0lmRW5kcG9pbnRBbHJlYWR5RXhpc3RzKHZwYzogZWMyLklWcGMsIGludGVyZmFjZVRhZzogU2VydmljZUVuZHBvaW50VHlwZXMpOiBib29sZWFuIHtcbiAgcmV0dXJuIHZwYy5ub2RlLmNoaWxkcmVuLnNvbWUoKGNoaWxkKSA9PiBjaGlsZC5ub2RlLmlkID09PSBpbnRlcmZhY2VUYWcpO1xufVxuXG5mdW5jdGlvbiBTdXBwcmVzc01hcFB1YmxpY0lwV2FybmluZ3ModnBjOiBlYzIuVnBjKSB7XG4gIC8vIEFkZCBDZm4gTmFnIHN1cHByZXNzaW9uIGZvciBQVUJMSUMgc3VibmV0cyB0byBzdXBwcmVzcyBXQVJOIFczMzogRUMyIFN1Ym5ldCBzaG91bGQgbm90IGhhdmUgTWFwUHVibGljSXBPbkxhdW5jaCBzZXQgdG8gdHJ1ZVxuICB2cGMucHVibGljU3VibmV0cy5mb3JFYWNoKChzdWJuZXQpID0+IHtcbiAgICBjb25zdCBjZm5TdWJuZXQgPSBzdWJuZXQubm9kZS5kZWZhdWx0Q2hpbGQgYXMgZWMyLkNmblN1Ym5ldDtcbiAgICBhZGRDZm5TdXBwcmVzc1J1bGVzKGNmblN1Ym5ldCwgW1xuICAgICAge1xuICAgICAgICBpZDogJ1czMycsXG4gICAgICAgIHJlYXNvbjogJ0FsbG93IFB1YmxpYyBTdWJuZXRzIHRvIGhhdmUgTWFwUHVibGljSXBPbkxhdW5jaCBzZXQgdG8gdHJ1ZSdcbiAgICAgIH1cbiAgICBdKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIFN1cHByZXNzRW5jcnlwdGVkTG9nV2FybmluZ3MoZmxvd0xvZzogZWMyLkZsb3dMb2cpIHtcbiAgLy8gQWRkIENmbiBOYWcgc3VwcHJlc3Npb24gZm9yIENsb3VkV2F0Y2hMb2dzIExvZ0dyb3VwcyBkYXRhIGlzIGVuY3J5cHRlZFxuICBjb25zdCBjZm5Mb2dHcm91cDogQ2ZuTG9nR3JvdXAgPSBmbG93TG9nLmxvZ0dyb3VwPy5ub2RlLmRlZmF1bHRDaGlsZCBhcyBDZm5Mb2dHcm91cDtcbiAgYWRkQ2ZuU3VwcHJlc3NSdWxlcyhjZm5Mb2dHcm91cCwgW1xuICAgIHtcbiAgICAgIGlkOiAnVzg0JyxcbiAgICAgIHJlYXNvbjogJ0J5IGRlZmF1bHQgQ2xvdWRXYXRjaExvZ3MgTG9nR3JvdXBzIGRhdGEgaXMgZW5jcnlwdGVkIHVzaW5nIHRoZSBDbG91ZFdhdGNoIHNlcnZlci1zaWRlIGVuY3J5cHRpb24ga2V5cyAoQVdTIE1hbmFnZWQgS2V5cyknXG4gICAgfVxuICBdKTtcbn1cblxuZnVuY3Rpb24gQWRkSW50ZXJmYWNlRW5kcG9pbnQoc2NvcGU6IENvbnN0cnVjdCwgdnBjOiBlYzIuSVZwYywgc2VydmljZTogRW5kcG9pbnREZWZpbml0aW9uLCBpbnRlcmZhY2VUYWc6IFNlcnZpY2VFbmRwb2ludFR5cGVzKSB7XG4gIGNvbnN0IGVuZHBvaW50RGVmYXVsdFNlY3VyaXR5R3JvdXAgPSBidWlsZFNlY3VyaXR5R3JvdXAoXG4gICAgc2NvcGUsXG4gICAgYCR7c2NvcGUubm9kZS5pZH0tJHtzZXJ2aWNlLmVuZHBvaW50TmFtZX1gLFxuICAgIHtcbiAgICAgIHZwYyxcbiAgICAgIGFsbG93QWxsT3V0Ym91bmQ6IHRydWUsXG4gICAgfSxcbiAgICBbeyBwZWVyOiBlYzIuUGVlci5pcHY0KHZwYy52cGNDaWRyQmxvY2spLCBjb25uZWN0aW9uOiBlYzIuUG9ydC50Y3AoNDQzKSB9XSxcbiAgICBbXVxuICApO1xuXG4gIHZwYy5hZGRJbnRlcmZhY2VFbmRwb2ludChpbnRlcmZhY2VUYWcsIHtcbiAgICBzZXJ2aWNlOiBzZXJ2aWNlLmVuZHBvaW50SW50ZXJmYWNlU2VydmljZSBhcyBlYzIuSW50ZXJmYWNlVnBjRW5kcG9pbnRBd3NTZXJ2aWNlLFxuICAgIHNlY3VyaXR5R3JvdXBzOiBbZW5kcG9pbnREZWZhdWx0U2VjdXJpdHlHcm91cF0sXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBBZGRHYXRld2F5RW5kcG9pbnQodnBjOiBlYzIuSVZwYywgc2VydmljZTogRW5kcG9pbnREZWZpbml0aW9uLCBpbnRlcmZhY2VUYWc6IFNlcnZpY2VFbmRwb2ludFR5cGVzKSB7XG4gIHZwYy5hZGRHYXRld2F5RW5kcG9pbnQoaW50ZXJmYWNlVGFnLCB7XG4gICAgc2VydmljZTogc2VydmljZS5lbmRwb2ludEdhdGV3YXlTZXJ2aWNlIGFzIGVjMi5HYXRld2F5VnBjRW5kcG9pbnRBd3NTZXJ2aWNlLFxuICB9KTtcbn1cblxuLyoqXG4gKiBAaW50ZXJuYWwgVGhpcyBpcyBhbiBpbnRlcm5hbCBjb3JlIGZ1bmN0aW9uIGFuZCBzaG91bGQgbm90IGJlIGNhbGxlZCBkaXJlY3RseSBieSBTb2x1dGlvbnMgQ29uc3RydWN0cyBjbGllbnRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmV0cmlldmVQcml2YXRlU3VibmV0SWRzKHZwYzogZWMyLklWcGMpIHtcbiAgbGV0IHRhcmdldFN1Ym5ldFR5cGU7XG5cbiAgaWYgKHZwYy5pc29sYXRlZFN1Ym5ldHMubGVuZ3RoKSB7XG4gICAgdGFyZ2V0U3VibmV0VHlwZSA9IGVjMi5TdWJuZXRUeXBlLlBSSVZBVEVfSVNPTEFURUQ7XG4gIH0gZWxzZSBpZiAodnBjLnByaXZhdGVTdWJuZXRzLmxlbmd0aCkge1xuICAgIHRhcmdldFN1Ym5ldFR5cGUgPSBlYzIuU3VibmV0VHlwZS5QUklWQVRFX1dJVEhfRUdSRVNTO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignRXJyb3IgLSBObyBpc29sYXRlZCBvciBwcml2YXRlIHN1Ym5ldHMgYXZhaWxhYmxlIGluIFZQQycpO1xuICB9XG5cbiAgY29uc3Qgc3VibmV0U2VsZWN0b3IgPSB7XG4gICAgb25lUGVyQXo6IHRydWUsXG4gICAgc3VibmV0VHlwZTogdGFyZ2V0U3VibmV0VHlwZVxuICB9O1xuXG4gIHJldHVybiB2cGMuc2VsZWN0U3VibmV0cyhzdWJuZXRTZWxlY3Rvcikuc3VibmV0SWRzO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZwY1Byb3BzU2V0IHtcbiAgcmVhZG9ubHkgZXhpc3RpbmdWcGM/OiBlYzIuSVZwYztcbiAgcmVhZG9ubHkgdnBjUHJvcHM/OiBlYzIuVnBjUHJvcHM7XG4gIHJlYWRvbmx5IGRlcGxveVZwYz86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBDaGVja1ZwY1Byb3BzKHByb3BzT2JqZWN0OiBWcGNQcm9wc1NldCB8IGFueSkge1xuICBsZXQgZXJyb3JNZXNzYWdlcyA9ICcnO1xuICBsZXQgZXJyb3JGb3VuZCA9IGZhbHNlO1xuXG4gIGlmICgocHJvcHNPYmplY3QuZGVwbG95VnBjIHx8IHByb3BzT2JqZWN0LnZwY1Byb3BzKSAmJiBwcm9wc09iamVjdC5leGlzdGluZ1ZwYykge1xuICAgIGVycm9yTWVzc2FnZXMgKz0gJ0Vycm9yIC0gRWl0aGVyIHByb3ZpZGUgYW4gZXhpc3RpbmdWcGMgb3Igc29tZSBjb21iaW5hdGlvbiBvZiBkZXBsb3lWcGMgYW5kIHZwY1Byb3BzLCBidXQgbm90IGJvdGguXFxuJztcbiAgICBlcnJvckZvdW5kID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChlcnJvckZvdW5kKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTWVzc2FnZXMpO1xuICB9XG59XG4iXX0=
;