raindancers-network
Version:
Extensions to the ec2.Vpc Constructs
245 lines • 35.9 kB
JavaScript
"use strict";
var _a, _b;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CrowdStrikeNLB = exports.CrowdStrikeExtendedEndpoint = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const path = require("path");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const cdk = require("aws-cdk-lib");
const constructs = require("constructs");
const crowdstrike_1 = require("./crowdstrike");
const enterprisevpc_1 = require("../evpc/enterprisevpc");
/**
* This will
*/
class CrowdStrikeExtendedEndpoint extends constructs.Construct {
constructor(scope, id, props) {
super(scope, id);
// default to 192.168.255.0 if not supplied
let cidr;
if (props.vpccidr) {
cidr = props.vpccidr;
}
else {
cidr = '192.168.255.0/24';
}
const crowdstrikeVPC = new enterprisevpc_1.EnterpriseVpc(this, 'EVPC', {
vpc: new aws_cdk_lib_1.aws_ec2.Vpc(this, 'VPC', {
ipAddresses: aws_cdk_lib_1.aws_ec2.IpAddresses.cidr(cidr),
maxAzs: 2,
vpcName: 'CrowdstrikeVPC' + props.crowdstrikeCloud,
subnetConfiguration: [
{
name: 'inside',
subnetType: aws_cdk_lib_1.aws_ec2.SubnetType.PRIVATE_ISOLATED,
cidrMask: 27,
},
],
}),
});
// peer this vpc to the other vpc.
const endPoints = new crowdstrike_1.CrowdStrikePrivateLinkEndpoint(this, 'endpoints', {
vpc: crowdstrikeVPC.vpc,
crowdStrikeCloud: props.crowdstrikeCloud,
subnets: { subnetGroupName: 'inside' },
peeredwithNLB: true,
});
this.proxy = endPoints.proxy;
this.download = endPoints.download;
this.proxyZone = endPoints.proxyhostedZone;
this.proxyZoneName = endPoints.proxyhostedZoneName;
this.downloadZone = endPoints.downloadhostedZone;
this.downloadZoneName = endPoints.downloadhostedZoneName;
if (props.peeringVpc) {
new aws_cdk_lib_1.aws_ec2.CfnVPCPeeringConnection(this, 'MyCfnVPCPeeringConnection', {
peerVpcId: props.peeringVpc.peeringVpcId,
vpcId: crowdstrikeVPC.vpc.vpcId,
peerRegion: props.peeringVpc.peerVpcRegion,
});
// associate the new hosted zone with the peered vpc
new aws_cdk_lib_1.custom_resources.AwsCustomResource(this, 'associateproxyzone', {
onCreate: {
service: 'Route53',
action: 'associateVPCWithHostedZone',
parameters: {
HostedZoneId: endPoints.proxyhostedZone,
VPC: {
VPCId: props.peeringVpc.peeringVpcId,
VPCRegion: props.peeringVpc.peerVpcRegion,
},
},
physicalResourceId: aws_cdk_lib_1.custom_resources.PhysicalResourceId.of(endPoints.proxyhostedZone),
},
onDelete: {
service: 'Route53',
action: 'disassociateVPCFromHostedZone',
parameters: {
HostedZoneId: endPoints.proxyhostedZone,
VPC: {
VPCId: props.peeringVpc.peeringVpcId,
VPCRegion: props.peeringVpc.peerVpcRegion,
},
},
},
logRetention: aws_cdk_lib_1.aws_logs.RetentionDays.ONE_DAY,
policy: aws_cdk_lib_1.custom_resources.AwsCustomResourcePolicy.fromSdkCalls({
resources: aws_cdk_lib_1.custom_resources.AwsCustomResourcePolicy.ANY_RESOURCE,
}),
});
// downloadzoneassoication.
new aws_cdk_lib_1.custom_resources.AwsCustomResource(this, 'associatedownloadzone', {
onCreate: {
service: 'Route53',
action: 'associateVPCWithHostedZone',
parameters: {
HostedZoneId: endPoints.downloadhostedZone,
VPC: {
VPCId: props.peeringVpc.peeringVpcId,
VPCRegion: props.peeringVpc.peerVpcRegion,
},
},
physicalResourceId: aws_cdk_lib_1.custom_resources.PhysicalResourceId.of(endPoints.downloadhostedZone),
},
onDelete: {
service: 'Route53',
action: 'disassociateVPCFromHostedZone',
parameters: {
HostedZoneId: endPoints.downloadhostedZone,
VPC: {
VPCId: props.peeringVpc.peeringVpcId,
VPCRegion: props.peeringVpc.peerVpcRegion,
},
},
},
logRetention: aws_cdk_lib_1.aws_logs.RetentionDays.ONE_DAY,
policy: aws_cdk_lib_1.custom_resources.AwsCustomResourcePolicy.fromStatements([
new aws_cdk_lib_1.aws_iam.PolicyStatement({
actions: [
'route53:DisassociateVPCFromHostedZone',
'ec2:DescribeVpcs',
'route53:AssociateVPCWithHostedZone',
],
effect: aws_cdk_lib_1.aws_iam.Effect.ALLOW,
resources: ['*'],
}),
]),
});
}
}
}
exports.CrowdStrikeExtendedEndpoint = CrowdStrikeExtendedEndpoint;
_a = JSII_RTTI_SYMBOL_1;
CrowdStrikeExtendedEndpoint[_a] = { fqn: "raindancers-network.crowdstrike.CrowdStrikeExtendedEndpoint", version: "1.29.3" };
class CrowdStrikeNLB extends constructs.Construct {
constructor(scope, id, props) {
super(scope, id);
const getTargetsFn = new aws_cdk_lib_1.aws_lambda.SingletonFunction(this, 'GetTargetsLambda', {
uuid: 'FFEEFF00',
runtime: aws_cdk_lib_1.aws_lambda.Runtime.PYTHON_3_9,
handler: 'getTargets.on_event',
code: aws_cdk_lib_1.aws_lambda.Code.fromAsset(path.join(__dirname, '../../lambda/crowdstrike')),
});
getTargetsFn.addToRolePolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({
effect: aws_cdk_lib_1.aws_iam.Effect.ALLOW,
resources: ['*'],
actions: ['ec2:Describe*'],
}));
const getTargetsToken = new aws_cdk_lib_1.custom_resources.Provider(this, 'NetworkManagerProvider', {
onEventHandler: getTargetsFn,
});
const proxyEndpointIP = new cdk.CustomResource(this, 'proxytargets', {
properties: {
EndpointId: props.proxy,
Region: props.region,
},
serviceToken: getTargetsToken.serviceToken,
});
const downloadEndpointIP = new cdk.CustomResource(this, 'downloadtargets', {
properties: {
EndpointId: props.download,
Region: props.region,
},
serviceToken: getTargetsToken.serviceToken,
});
let proxyTargets = [];
proxyTargets.push(new aws_cdk_lib_1.aws_elasticloadbalancingv2_targets.IpTarget(proxyEndpointIP.getAttString('Target1'), undefined, 'all'));
proxyTargets.push(new aws_cdk_lib_1.aws_elasticloadbalancingv2_targets.IpTarget(proxyEndpointIP.getAttString('Target2'), undefined, 'all'));
let downloadTargets = [];
downloadTargets.push(new aws_cdk_lib_1.aws_elasticloadbalancingv2_targets.IpTarget(downloadEndpointIP.getAttString('Target1'), undefined, 'all'));
downloadTargets.push(new aws_cdk_lib_1.aws_elasticloadbalancingv2_targets.IpTarget(downloadEndpointIP.getAttString('Target2'), undefined, 'all'));
const Proxyloadbalancer = new aws_cdk_lib_1.aws_elasticloadbalancingv2.NetworkLoadBalancer(this, 'csProxyLB', {
vpc: props.vpc,
vpcSubnets: { subnetGroupName: props.subnetGroupName },
internetFacing: false,
crossZoneEnabled: true,
});
const proxyListener = Proxyloadbalancer.addListener('proxylistener', {
port: 443,
protocol: aws_cdk_lib_1.aws_elasticloadbalancingv2.Protocol.TCP,
});
proxyListener.addTargets('proxyTargets', {
port: 443,
protocol: aws_cdk_lib_1.aws_elasticloadbalancingv2.Protocol.TCP,
targets: proxyTargets,
});
new aws_cdk_lib_1.aws_route53.ARecord(this, 'proxyarecord', {
zone: aws_cdk_lib_1.aws_route53.PrivateHostedZone.fromHostedZoneAttributes(this, 'proxyzone', {
hostedZoneId: props.proxyhostedZone,
zoneName: props.proxyhostedZoneName,
}),
target: aws_cdk_lib_1.aws_route53.RecordTarget.fromAlias(new aws_cdk_lib_1.aws_route53_targets.LoadBalancerTarget(Proxyloadbalancer)),
});
const downloadbalancer = new aws_cdk_lib_1.aws_elasticloadbalancingv2.NetworkLoadBalancer(this, 'downloadLB', {
vpc: props.vpc,
vpcSubnets: { subnetGroupName: props.subnetGroupName },
internetFacing: false,
crossZoneEnabled: true,
});
const downloadListener = downloadbalancer.addListener('downloadlistener', {
port: 443,
protocol: aws_cdk_lib_1.aws_elasticloadbalancingv2.Protocol.TCP,
});
downloadListener.addTargets('downloadTargets', {
port: 443,
protocol: aws_cdk_lib_1.aws_elasticloadbalancingv2.Protocol.TCP,
targets: downloadTargets,
});
new aws_cdk_lib_1.aws_route53.ARecord(this, 'downloadarecord', {
zone: aws_cdk_lib_1.aws_route53.PrivateHostedZone.fromHostedZoneAttributes(this, 'downloadzone', {
hostedZoneId: props.downloadhostedZone,
zoneName: props.downloadhostedZoneName,
}),
target: aws_cdk_lib_1.aws_route53.RecordTarget.fromAlias(new aws_cdk_lib_1.aws_route53_targets.LoadBalancerTarget(Proxyloadbalancer)),
});
// create a forwarding rule, and share to the org
// create a master zone sharing rule
const cloudsinkZone = 'cloudsink.net';
var zoneName = cloudsinkZone.replace(/\./gi, 'dot');
zoneName = zoneName.replace(/-/gi, 'dash');
const resolverRuleCloudSink = new aws_cdk_lib_1.aws_route53resolver.CfnResolverRule(this, `${cloudsinkZone}SharedResolverRule`, {
domainName: cloudsinkZone,
ruleType: 'FORWARD',
name: zoneName,
resolverEndpointId: props.routeresolverEndpoints.outboundResolver.attrResolverEndpointId,
targetIps: props.routeresolverEndpoints.inboundResolversIp,
tags: [{
key: 'r53rrule',
value: 'cloudsink.net',
}],
});
new aws_cdk_lib_1.aws_ram.CfnResourceShare(this, `ResolverRuleShare${cloudsinkZone}`, {
name: zoneName,
principals: [this.node.tryGetContext('orgArn')],
resourceArns: [resolverRuleCloudSink.attrArn],
allowExternalPrincipals: false,
tags: [{
key: 'r53rshare',
value: 'cloudsink.net',
}],
});
}
}
exports.CrowdStrikeNLB = CrowdStrikeNLB;
_b = JSII_RTTI_SYMBOL_1;
CrowdStrikeNLB[_b] = { fqn: "raindancers-network.crowdstrike.CrowdStrikeNLB", version: "1.29.3" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3Jvd2RzdHJpa2VOTEJlbmRwb2ludC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jcm93ZHN0cmlrZS9jcm93ZHN0cmlrZU5MQmVuZHBvaW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNkJBQTZCO0FBQzdCLDZDQWFxQjtBQUVyQixtQ0FBbUM7QUFHbkMseUNBQXlDO0FBQ3pDLCtDQUErRDtBQUcvRCx5REFBc0Q7QUFpQnREOztHQUVHO0FBQ0gsTUFBYSwyQkFBNEIsU0FBUSxVQUFVLENBQUMsU0FBUztJQVNuRSxZQUFZLEtBQTJCLEVBQUUsRUFBVSxFQUFFLEtBQXVDO1FBQzFGLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsNENBQTRDO1FBQzVDLElBQUksSUFBWSxDQUFDO1FBQ2pCLElBQUksS0FBSyxDQUFDLE9BQU8sRUFBRTtZQUNqQixJQUFJLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztTQUN0QjthQUFNO1lBQ0wsSUFBSSxHQUFHLGtCQUFrQixDQUFDO1NBQzNCO1FBRUQsTUFBTSxjQUFjLEdBQUcsSUFBSSw2QkFBYSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUU7WUFDckQsR0FBRyxFQUFFLElBQUkscUJBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRTtnQkFDNUIsV0FBVyxFQUFFLHFCQUFHLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ3ZDLE1BQU0sRUFBRSxDQUFDO2dCQUNULE9BQU8sRUFBRSxnQkFBZ0IsR0FBRyxLQUFLLENBQUMsZ0JBQWdCO2dCQUNsRCxtQkFBbUIsRUFBRTtvQkFDbkI7d0JBQ0UsSUFBSSxFQUFFLFFBQVE7d0JBQ2QsVUFBVSxFQUFFLHFCQUFHLENBQUMsVUFBVSxDQUFDLGdCQUFnQjt3QkFDM0MsUUFBUSxFQUFFLEVBQUU7cUJBQ2I7aUJBQ0Y7YUFDRixDQUFDO1NBQ0gsQ0FBQyxDQUFDO1FB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Q0FBQztZQUM3Qyx1QkFBdUIsRUFBRSxLQUFLO1lBQzlCLElBQUksRUFBRSxDQUFDO29CQUNMLEdBQUcsRUFBRSxXQUFXO29CQUNoQixLQUFLLEVBQUUsZUFBZTtpQkFDdkIsQ0FBQztTQUNILENBQUMsQ0FBQztJQUdMLENBQUM7O0FBeklILHdDQTBJQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQge1xuICBhd3NfZWMyIGFzIGVjMixcbiAgY3VzdG9tX3Jlc291cmNlcyBhcyBjcixcbiAgYXdzX2xvZ3MgYXMgbG9ncyxcbiAgYXdzX2VsYXN0aWNsb2FkYmFsYW5jaW5ndjIgYXMgZWxidjIsXG4gIGF3c19lbGFzdGljbG9hZGJhbGFuY2luZ3YyX3RhcmdldHMgYXMgZWxidjJfdGFyZ2V0cyxcbiAgYXdzX3JvdXRlNTMgYXMgcjUzLFxuICBhd3Nfcm91dGU1M190YXJnZXRzIGFzIHI1M3RhcmdldHMsXG4gIGF3c19yb3V0ZTUzcmVzb2x2ZXIgYXMgcjUzcixcbiAgYXdzX2lhbSBhcyBpYW0sXG4gIGF3c19yYW0gYXMgcmFtLFxuICBhd3NfbGFtYmRhLFxufVxuICBmcm9tICdhd3MtY2RrLWxpYic7XG5cbmltcG9ydCAqIGFzIGNkayBmcm9tICdhd3MtY2RrLWxpYic7XG5cblxuaW1wb3J0ICogYXMgY29uc3RydWN0cyBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IENyb3dkU3RyaWtlUHJpdmF0ZUxpbmtFbmRwb2ludCB9IGZyb20gJy4vY3Jvd2RzdHJpa2UnO1xuaW1wb3J0IHsgQ3Jvd2RTdHJpa2VDbG91ZCB9IGZyb20gJy4vY3Jvd2RzdHJpa2VSZWdpb25JbmZvJztcbmltcG9ydCB7IFI1M1Jlc29sdmVyZW5kcG9pbnRzIH0gZnJvbSAnLi4vZG5zL2Ruc1Jlc29sdmVycyc7XG5pbXBvcnQgeyBFbnRlcnByaXNlVnBjIH0gZnJvbSAnLi4vZXZwYy9lbnRlcnByaXNldnBjJztcblxuZXhwb3J0IGludGVyZmFjZSBWcGNSZWdpb25JZCB7XG4gIHJlYWRvbmx5IHBlZXJpbmdWcGNJZDogc3RyaW5nO1xuICByZWFkb25seSBwZWVyVnBjUmVnaW9uOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3Jvd2RTdHJpa2VFeHRlbmRlZEVuZHBvaW50UHJvcHMge1xuICAvKiphd3NcbiAgICogVGhlIEVDMiBJbnN0YW5jZSB0aGF0IHdpbGwgYmUgdWRwYXRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGNyb3dkc3RyaWtlQ2xvdWQ6IENyb3dkU3RyaWtlQ2xvdWQ7XG4gIHJlYWRvbmx5IHZwY2NpZHI/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIHJlYWRvbmx5IHBlZXJpbmdWcGM/OiBWcGNSZWdpb25JZDtcbiAgcmVhZG9ubHkgdXNlRUxCSW5QZWVyZWRWcGM/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFRoaXMgd2lsbFxuICovXG5leHBvcnQgY2xhc3MgQ3Jvd2RTdHJpa2VFeHRlbmRlZEVuZHBvaW50IGV4dGVuZHMgY29uc3RydWN0cy5Db25zdHJ1Y3Qge1xuXG4gIHB1YmxpYyByZWFkb25seSBwcm94eTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgZG93bmxvYWQ6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHByb3h5Wm9uZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcHJveHlab25lTmFtZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgZG93bmxvYWRab25lOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBkb3dubG9hZFpvbmVOYW1lOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IGNvbnN0cnVjdHMuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ3Jvd2RTdHJpa2VFeHRlbmRlZEVuZHBvaW50UHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgLy8gIGRlZmF1bHQgdG8gMTkyLjE2OC4yNTUuMCBpZiBub3Qgc3VwcGxpZWRcbiAgICBsZXQgY2lkcjogc3RyaW5nO1xuICAgIGlmIChwcm9wcy52cGNjaWRyKSB7XG4gICAgICBjaWRyID0gcHJvcHMudnBjY2lkcjtcbiAgICB9IGVsc2Uge1xuICAgICAgY2lkciA9ICcxOTIuMTY4LjI1NS4wLzI0JztcbiAgICB9XG5cbiAgICBjb25zdCBjcm93ZHN0cmlrZVZQQyA9IG5ldyBFbnRlcnByaXNlVnBjKHRoaXMsICdFVlBDJywge1xuICAgICAgdnBjOiBuZXcgZWMyLlZwYyh0aGlzLCAnVlBDJywge1xuICAgICAgICBpcEFkZHJlc3NlczogZWMyLklwQWRkcmVzc2VzLmNpZHIoY2lkciksXG4gICAgICAgIG1heEF6czogMixcbiAgICAgICAgdnBjTmFtZTogJ0Nyb3dkc3RyaWtlVlBDJyArIHByb3BzLmNyb3dkc3RyaWtlQ2xvdWQsXG4gICAgICAgIHN1Ym5ldENvbmZpZ3VyYXRpb246IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiAnaW5zaWRlJyxcbiAgICAgICAgICAgIHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBSSVZBVEVfSVNPTEFURUQsXG4gICAgICAgICAgICBjaWRyTWFzazogMjcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgIH0pO1xuXG4gICAgLy8gcGVlciB0aGlzIHZwYyB0byB0aGUgb3RoZXIgdnBjLlxuXG5cbiAgICBjb25zdCBlbmRQb2ludHMgPSBuZXcgQ3Jvd2RTdHJpa2VQcml2YXRlTGlua0VuZHBvaW50KHRoaXMsICdlbmRwb2ludHMnLCB7XG4gICAgICB2cGM6IGNyb3dkc3RyaWtlVlBDLnZwYyxcbiAgICAgIGNyb3dkU3RyaWtlQ2xvdWQ6IHByb3BzLmNyb3dkc3RyaWtlQ2xvdWQsXG4gICAgICBzdWJuZXRzOiB7IHN1Ym5ldEdyb3VwTmFtZTogJ2luc2lkZScgfSxcbiAgICAgIHBlZXJlZHdpdGhOTEI6IHRydWUsXG4gICAgfSk7XG5cbiAgICB0aGlzLnByb3h5ID0gZW5kUG9pbnRzLnByb3h5O1xuICAgIHRoaXMuZG93bmxvYWQgPSBlbmRQb2ludHMuZG93bmxvYWQ7XG4gICAgdGhpcy5wcm94eVpvbmUgPSBlbmRQb2ludHMucHJveHlob3N0ZWRab25lO1xuICAgIHRoaXMucHJveHlab25lTmFtZSA9IGVuZFBvaW50cy5wcm94eWhvc3RlZFpvbmVOYW1lO1xuICAgIHRoaXMuZG93bmxvYWRab25lID0gZW5kUG9pbnRzLmRvd25sb2FkaG9zdGVkWm9uZTtcbiAgICB0aGlzLmRvd25sb2FkWm9uZU5hbWUgPSBlbmRQb2ludHMuZG93bmxvYWRob3N0ZWRab25lTmFtZTtcblxuICAgIGlmIChwcm9wcy5wZWVyaW5nVnBjKSB7XG5cbiAgICAgIG5ldyBlYzIuQ2ZuVlBDUGVlcmluZ0Nvbm5lY3Rpb24odGhpcywgJ015Q2ZuVlBDUGVlcmluZ0Nvbm5lY3Rpb24nLCB7XG4gICAgICAgIHBlZXJWcGNJZDogcHJvcHMucGVlcmluZ1ZwYy5wZWVyaW5nVnBjSWQsXG4gICAgICAgIHZwY0lkOiBjcm93ZHN0cmlrZVZQQy52cGMudnBjSWQsXG4gICAgICAgIHBlZXJSZWdpb246IHByb3BzLnBlZXJpbmdWcGMucGVlclZwY1JlZ2lvbixcbiAgICAgIH0pO1xuXG4gICAgICAvLyBhc3NvY2lhdGUgdGhlIG5ldyBob3N0ZWQgem9uZSB3aXRoIHRoZSBwZWVyZWQgdnBjXG4gICAgICBuZXcgY3IuQXdzQ3VzdG9tUmVzb3VyY2UodGhpcywgJ2Fzc29jaWF0ZXByb3h5em9uZScsIHtcbiAgICAgICAgb25DcmVhdGU6IHtcbiAgICAgICAgICBzZXJ2aWNlOiAnUm91dGU1MycsXG4gICAgICAgICAgYWN0aW9uOiAnYXNzb2NpYXRlVlBDV2l0aEhvc3RlZFpvbmUnLFxuICAgICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgIEhvc3RlZFpvbmVJZDogZW5kUG9pbnRzLnByb3h5aG9zdGVkWm9uZSxcbiAgICAgICAgICAgIFZQQzoge1xuICAgICAgICAgICAgICBWUENJZDogcHJvcHMucGVlcmluZ1ZwYy5wZWVyaW5nVnBjSWQsXG4gICAgICAgICAgICAgIFZQQ1JlZ2lvbjogcHJvcHMucGVlcmluZ1ZwYy5wZWVyVnBjUmVnaW9uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZDogY3IuUGh5c2ljYWxSZXNvdXJjZUlkLm9mKGVuZFBvaW50cy5wcm94eWhvc3RlZFpvbmUpLFxuICAgICAgICB9LFxuICAgICAgICBvbkRlbGV0ZToge1xuICAgICAgICAgIHNlcnZpY2U6ICdSb3V0ZTUzJyxcbiAgICAgICAgICBhY3Rpb246ICdkaXNhc3NvY2lhdGVWUENGcm9tSG9zdGVkWm9uZScsXG4gICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgSG9zdGVkWm9uZUlkOiBlbmRQb2ludHMucHJveHlob3N0ZWRab25lLFxuICAgICAgICAgICAgVlBDOiB7XG4gICAgICAgICAgICAgIFZQQ0lkOiBwcm9wcy5wZWVyaW5nVnBjLnBlZXJpbmdWcGNJZCxcbiAgICAgICAgICAgICAgVlBDUmVnaW9uOiBwcm9wcy5wZWVyaW5nVnBjLnBlZXJWcGNSZWdpb24sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGxvZ1JldGVudGlvbjogbG9ncy5SZXRlbnRpb25EYXlzLk9ORV9EQVksXG4gICAgICAgIHBvbGljeTogY3IuQXdzQ3VzdG9tUmVzb3VyY2VQb2xpY3kuZnJvbVNka0NhbGxzKHtcbiAgICAgICAgICByZXNvdXJjZXM6IGNyLkF3c0N1c3RvbVJlc291cmNlUG9saWN5LkFOWV9SRVNPVVJDRSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcblxuICAgICAgLy8gZG93bmxvYWR6b25lYXNzb2ljYXRpb24uXG4gICAgICBuZXcgY3IuQXdzQ3VzdG9tUmVzb3VyY2UodGhpcywgJ2Fzc29jaWF0ZWRvd25sb2Fkem9uZScsIHtcbiAgICAgICAgb25DcmVhdGU6IHtcbiAgICAgICAgICBzZXJ2aWNlOiAnUm91dGU1MycsXG4gICAgICAgICAgYWN0aW9uOiAnYXNzb2NpYXRlVlBDV2l0aEhvc3RlZFpvbmUnLFxuICAgICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgIEhvc3RlZFpvbmVJZDogZW5kUG9pbnRzLmRvd25sb2FkaG9zdGVkWm9uZSxcbiAgICAgICAgICAgIFZQQzoge1xuICAgICAgICAgICAgICBWUENJZDogcHJvcHMucGVlcmluZ1ZwYy5wZWVyaW5nVnBjSWQsXG4gICAgICAgICAgICAgIFZQQ1JlZ2lvbjogcHJvcHMucGVlcmluZ1ZwYy5wZWVyVnBjUmVnaW9uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZDogY3IuUGh5c2ljYWxSZXNvdXJjZUlkLm9mKGVuZFBvaW50cy5kb3dubG9hZGhvc3RlZFpvbmUpLFxuICAgICAgICB9LFxuICAgICAgICBvbkRlbGV0ZToge1xuICAgICAgICAgIHNlcnZpY2U6ICdSb3V0ZTUzJyxcbiAgICAgICAgICBhY3Rpb246ICdkaXNhc3NvY2lhdGVWUENGcm9tSG9zdGVkWm9uZScsXG4gICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgSG9zdGVkWm9uZUlkOiBlbmRQb2ludHMuZG93bmxvYWRob3N0ZWRab25lLFxuICAgICAgICAgICAgVlBDOiB7XG4gICAgICAgICAgICAgIFZQQ0lkOiBwcm9wcy5wZWVyaW5nVnBjLnBlZXJpbmdWcGNJZCxcbiAgICAgICAgICAgICAgVlBDUmVnaW9uOiBwcm9wcy5wZWVyaW5nVnBjLnBlZXJWcGNSZWdpb24sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGxvZ1JldGVudGlvbjogbG9ncy5SZXRlbnRpb25EYXlzLk9ORV9EQVksXG4gICAgICAgIHBvbGljeTogY3IuQXdzQ3VzdG9tUmVzb3VyY2VQb2xpY3kuZnJvbVN0YXRlbWVudHMoXG4gICAgICAgICAgW1xuICAgICAgICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICAgJ3JvdXRlNTM6RGlzYXNzb2NpYXRlVlBDRnJvbUhvc3RlZFpvbmUnLFxuICAgICAgICAgICAgICAgICdlYzI6RGVzY3JpYmVWcGNzJyxcbiAgICAgICAgICAgICAgICAncm91dGU1MzpBc3NvY2lhdGVWUENXaXRoSG9zdGVkWm9uZScsXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVyxcbiAgICAgICAgICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIF0sXG4gICAgICAgICksXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBDcm93ZFN0cmlrZU5MQlByb3BzIHtcbiAgcmVhZG9ubHkgdnBjOiBlYzIuVnBjO1xuICByZWFkb25seSBzdWJuZXRHcm91cE5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgcHJveHk6IHN0cmluZztcbiAgcmVhZG9ubHkgZG93bmxvYWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgcHJveHlob3N0ZWRab25lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHByb3h5aG9zdGVkWm9uZU5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgZG93bmxvYWRob3N0ZWRab25lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRvd25sb2FkaG9zdGVkWm9uZU5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgcmVnaW9uOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNyb3dkc3RyaWtlUmVnaW9uOiBDcm93ZFN0cmlrZUNsb3VkO1xuICByZWFkb25seSByb3V0ZXJlc29sdmVyRW5kcG9pbnRzOiBSNTNSZXNvbHZlcmVuZHBvaW50cztcbn1cblxuXG5leHBvcnQgY2xhc3MgQ3Jvd2RTdHJpa2VOTEIgZXh0ZW5kcyBjb25zdHJ1Y3RzLkNvbnN0cnVjdCB7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IGNvbnN0cnVjdHMuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ3Jvd2RTdHJpa2VOTEJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBjb25zdCBnZXRUYXJnZXRzRm4gPSBuZXcgYXdzX2xhbWJkYS5TaW5nbGV0b25GdW5jdGlvbih0aGlzLCAnR2V0VGFyZ2V0c0xhbWJkYScsIHtcbiAgICAgIHV1aWQ6ICdGRkVFRkYwMCcsXG4gICAgICBydW50aW1lOiBhd3NfbGFtYmRhLlJ1bnRpbWUuUFlUSE9OXzNfOSxcblx0ICAgIGhhbmRsZXI6ICdnZXRUYXJnZXRzLm9uX2V2ZW50Jyxcblx0ICAgIGNvZGU6IGF3c19sYW1iZGEuQ29kZS5mcm9tQXNzZXQocGF0aC5qb2luKF9fZGlybmFtZSwgJy4uLy4uL2xhbWJkYS9jcm93ZHN0cmlrZScpKSxcbiAgICB9KTtcblxuICAgIGdldFRhcmdldHNGbi5hZGRUb1JvbGVQb2xpY3koXG5cdCAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG5cdCAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVyxcblx0ICAgICAgcmVzb3VyY2VzOiBbJyonXSxcblx0ICAgICAgYWN0aW9uczogWydlYzI6RGVzY3JpYmUqJ10sXG5cdCAgICB9KSxcblx0ICApO1xuXG4gICAgY29uc3QgZ2V0VGFyZ2V0c1Rva2VuID0gbmV3IGNyLlByb3ZpZGVyKHRoaXMsICdOZXR3b3JrTWFuYWdlclByb3ZpZGVyJywge1xuXHQgICAgb25FdmVudEhhbmRsZXI6IGdldFRhcmdldHNGbixcblx0ICB9KTtcblxuICAgIGNvbnN0IHByb3h5RW5kcG9pbnRJUCA9IG5ldyBjZGsuQ3VzdG9tUmVzb3VyY2UodGhpcywgJ3Byb3h5dGFyZ2V0cycsIHtcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgRW5kcG9pbnRJZDogcHJvcHMucHJveHksXG4gICAgICAgIFJlZ2lvbjogcHJvcHMucmVnaW9uLFxuICAgICAgfSxcbiAgICAgIHNlcnZpY2VUb2tlbjogZ2V0VGFyZ2V0c1Rva2VuLnNlcnZpY2VUb2tlbixcbiAgICB9KTtcblxuICAgIGNvbnN0IGRvd25sb2FkRW5kcG9pbnRJUCA9IG5ldyBjZGsuQ3VzdG9tUmVzb3VyY2UodGhpcywgJ2Rvd25sb2FkdGFyZ2V0cycsIHtcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgRW5kcG9pbnRJZDogcHJvcHMuZG93bmxvYWQsXG4gICAgICAgIFJlZ2lvbjogcHJvcHMucmVnaW9uLFxuICAgICAgfSxcbiAgICAgIHNlcnZpY2VUb2tlbjogZ2V0VGFyZ2V0c1Rva2VuLnNlcnZpY2VUb2tlbixcbiAgICB9KTtcblxuXG4gICAgbGV0IHByb3h5VGFyZ2V0czogZWxidjJfdGFyZ2V0cy5JcFRhcmdldFtdID0gW107XG4gICAgcHJveHlUYXJnZXRzLnB1c2gobmV3IGVsYnYyX3RhcmdldHMuSXBUYXJnZXQocHJveHlFbmRwb2ludElQLmdldEF0dFN0cmluZygnVGFyZ2V0MScpLCB1bmRlZmluZWQsICdhbGwnKSk7XG4gICAgcHJveHlUYXJnZXRzLnB1c2gobmV3IGVsYnYyX3RhcmdldHMuSXBUYXJnZXQocHJveHlFbmRwb2ludElQLmdldEF0dFN0cmluZygnVGFyZ2V0MicpLCB1bmRlZmluZWQsICdhbGwnKSk7XG4gICAgbGV0IGRvd25sb2FkVGFyZ2V0czogZWxidjJfdGFyZ2V0cy5JcFRhcmdldFtdID0gW107XG4gICAgZG93bmxvYWRUYXJnZXRzLnB1c2gobmV3IGVsYnYyX3RhcmdldHMuSXBUYXJnZXQoZG93bmxvYWRFbmRwb2ludElQLmdldEF0dFN0cmluZygnVGFyZ2V0MScpLCB1bmRlZmluZWQsICdhbGwnKSk7XG4gICAgZG93bmxvYWRUYXJnZXRzLnB1c2gobmV3IGVsYnYyX3RhcmdldHMuSXBUYXJnZXQoZG93bmxvYWRFbmRwb2ludElQLmdldEF0dFN0cmluZygnVGFyZ2V0MicpLCB1bmRlZmluZWQsICdhbGwnKSk7XG5cblxuICAgIGNvbnN0IFByb3h5bG9hZGJhbGFuY2VyID0gbmV3IGVsYnYyLk5ldHdvcmtMb2FkQmFsYW5jZXIodGhpcywgJ2NzUHJveHlMQicsIHtcbiAgICAgIHZwYzogcHJvcHMudnBjLFxuICAgICAgdnBjU3VibmV0czogeyBzdWJuZXRHcm91cE5hbWU6IHByb3BzLnN1Ym5ldEdyb3VwTmFtZSB9LFxuICAgICAgaW50ZXJuZXRGYWNpbmc6IGZhbHNlLFxuICAgICAgY3Jvc3Nab25lRW5hYmxlZDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHByb3h5TGlzdGVuZXIgPSBQcm94eWxvYWRiYWxhbmNlci5hZGRMaXN0ZW5lcigncHJveHlsaXN0ZW5lcicsIHtcbiAgICAgIHBvcnQ6IDQ0MyxcbiAgICAgIHByb3RvY29sOiBlbGJ2Mi5Qcm90b2NvbC5UQ1AsXG4gICAgfSk7XG5cbiAgICBwcm94eUxpc3RlbmVyLmFkZFRhcmdldHMoJ3Byb3h5VGFyZ2V0cycsIHtcbiAgICAgIHBvcnQ6IDQ0MyxcbiAgICAgIHByb3RvY29sOiBlbGJ2Mi5Qcm90b2NvbC5UQ1AsXG4gICAgICB0YXJnZXRzOiBwcm94eVRhcmdldHMsXG5cbiAgICB9KTtcblxuXG4gICAgbmV3IHI1My5BUmVjb3JkKHRoaXMsICdwcm94eWFyZWNvcmQnLCB7XG4gICAgICB6b25lOiByNTMuUHJpdmF0ZUhvc3RlZFpvbmUuZnJvbUhvc3RlZFpvbmVBdHRyaWJ1dGVzKHRoaXMsICdwcm94eXpvbmUnLCB7XG4gICAgICAgIGhvc3RlZFpvbmVJZDogcHJvcHMucHJveHlob3N0ZWRab25lLFxuICAgICAgICB6b25lTmFtZTogcHJvcHMucHJveHlob3N0ZWRab25lTmFtZSxcbiAgICAgIH0pLFxuICAgICAgdGFyZ2V0OiByNTMuUmVjb3JkVGFyZ2V0LmZyb21BbGlhcyhuZXcgcjUzdGFyZ2V0cy5Mb2FkQmFsYW5jZXJUYXJnZXQoUHJveHlsb2FkYmFsYW5jZXIpKSxcbiAgICB9KTtcblxuXG4gICAgY29uc3QgZG93bmxvYWRiYWxhbmNlciA9IG5ldyBlbGJ2Mi5OZXR3b3JrTG9hZEJhbGFuY2VyKHRoaXMsICdkb3dubG9hZExCJywge1xuICAgICAgdnBjOiBwcm9wcy52cGMsXG4gICAgICB2cGNTdWJuZXRzOiB7IHN1Ym5ldEdyb3VwTmFtZTogcHJvcHMuc3VibmV0R3JvdXBOYW1lIH0sXG4gICAgICBpbnRlcm5ldEZhY2luZzogZmFsc2UsXG4gICAgICBjcm9zc1pvbmVFbmFibGVkOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgZG93bmxvYWRMaXN0ZW5lciA9IGRvd25sb2FkYmFsYW5jZXIuYWRkTGlzdGVuZXIoJ2Rvd25sb2FkbGlzdGVuZXInLCB7XG4gICAgICBwb3J0OiA0NDMsXG4gICAgICBwcm90b2NvbDogZWxidjIuUHJvdG9jb2wuVENQLFxuICAgIH0pO1xuXG4gICAgZG93bmxvYWRMaXN0ZW5lci5hZGRUYXJnZXRzKCdkb3dubG9hZFRhcmdldHMnLCB7XG4gICAgICBwb3J0OiA0NDMsXG4gICAgICBwcm90b2NvbDogZWxidjIuUHJvdG9jb2wuVENQLFxuICAgICAgdGFyZ2V0czogZG93bmxvYWRUYXJnZXRzLFxuICAgIH0pO1xuXG5cbiAgICBuZXcgcjUzLkFSZWNvcmQodGhpcywgJ2Rvd25sb2FkYXJlY29yZCcsIHtcbiAgICAgIHpvbmU6IHI1My5Qcml2YXRlSG9zdGVkWm9uZS5mcm9tSG9zdGVkWm9uZUF0dHJpYnV0ZXModGhpcywgJ2Rvd25sb2Fkem9uZScsIHtcbiAgICAgICAgaG9zdGVkWm9uZUlkOiBwcm9wcy5kb3dubG9hZGhvc3RlZFpvbmUsXG4gICAgICAgIHpvbmVOYW1lOiBwcm9wcy5kb3dubG9hZGhvc3RlZFpvbmVOYW1lLFxuICAgICAgfSksXG4gICAgICB0YXJnZXQ6IHI1My5SZWNvcmRUYXJnZXQuZnJvbUFsaWFzKG5ldyByNTN0YXJnZXRzLkxvYWRCYWxhbmNlclRhcmdldChQcm94eWxvYWRiYWxhbmNlcikpLFxuICAgIH0pO1xuXG4gICAgLy8gY3JlYXRlIGEgZm9yd2FyZGluZyBydWxlLCBhbmQgc2hhcmUgdG8gdGhlIG9yZ1xuXG4gICAgLy8gY3JlYXRlIGEgbWFzdGVyIHpvbmUgc2hhcmluZyBydWxlXG4gICAgY29uc3QgY2xvdWRzaW5rWm9uZSA9ICdjbG91ZHNpbmsubmV0JztcbiAgICB2YXIgem9uZU5hbWUgPSBjbG91ZHNpbmtab25lLnJlcGxhY2UoL1xcLi9naSwgJ2RvdCcpO1xuICAgIHpvbmVOYW1lID0gem9uZU5hbWUucmVwbGFjZSgvLS9naSwgJ2Rhc2gnKTtcblxuXG4gICAgY29uc3QgcmVzb2x2ZXJSdWxlQ2xvdWRTaW5rID0gbmV3IHI1M3IuQ2ZuUmVzb2x2ZXJSdWxlKHRoaXMsIGAke2Nsb3Vkc2lua1pvbmV9U2hhcmVkUmVzb2x2ZXJSdWxlYCwge1xuICAgICAgZG9tYWluTmFtZTogY2xvdWRzaW5rWm9uZSxcbiAgICAgIHJ1bGVUeXBlOiAnRk9SV0FSRCcsXG4gICAgICBuYW1lOiB6b25lTmFtZSxcbiAgICAgIHJlc29sdmVyRW5kcG9pbnRJZDogcHJvcHMucm91dGVyZXNvbHZlckVuZHBvaW50cy5vdXRib3VuZFJlc29sdmVyLmF0dHJSZXNvbHZlckVuZHBvaW50SWQsXG4gICAgICB0YXJnZXRJcHM6IHByb3BzLnJvdXRlcmVzb2x2ZXJFbmRwb2ludHMuaW5ib3VuZFJlc29sdmVyc0lwLCAvLyBkbnMgc2VydmVyc1xuICAgICAgdGFnczogW3tcbiAgICAgICAga2V5OiAncjUzcnJ1bGUnLFxuICAgICAgICB2YWx1ZTogJ2Nsb3Vkc2luay5uZXQnLFxuICAgICAgfV0sXG4gICAgfSk7XG5cbiAgICBuZXcgcmFtLkNmblJlc291cmNlU2hhcmUodGhpcywgYFJlc29sdmVyUnVsZVNoYXJlJHtjbG91ZHNpbmtab25lfWAsIHtcbiAgICAgIG5hbWU6IHpvbmVOYW1lLFxuICAgICAgcHJpbmNpcGFsczogW3RoaXMubm9kZS50cnlHZXRDb250ZXh0KCdvcmdBcm4nKV0sXG4gICAgICByZXNvdXJjZUFybnM6IFtyZXNvbHZlclJ1bGVDbG91ZFNpbmsuYXR0ckFybl0sXG4gICAgICBhbGxvd0V4dGVybmFsUHJpbmNpcGFsczogZmFsc2UsXG4gICAgICB0YWdzOiBbe1xuICAgICAgICBrZXk6ICdyNTNyc2hhcmUnLFxuICAgICAgICB2YWx1ZTogJ2Nsb3Vkc2luay5uZXQnLFxuICAgICAgfV0sXG4gICAgfSk7XG5cblxuICB9XG59Il19