UNPKG

raindancers-network

Version:
245 lines 35.9 kB
"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