UNPKG

@cdklabs/cdk-hyperledger-fabric-network

Version:

CDK construct to deploy a Hyperledger Fabric network running on Amazon Managed Blockchain

132 lines 20.2 kB
"use strict"; // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: MIT-0 Object.defineProperty(exports, "__esModule", { value: true }); exports.HyperledgerFabricIdentity = void 0; const child_process_1 = require("child_process"); const path = require("path"); const cdk = require("aws-cdk-lib"); const ec2 = require("aws-cdk-lib/aws-ec2"); const iam = require("aws-cdk-lib/aws-iam"); const lambda = require("aws-cdk-lib/aws-lambda"); const logs = require("aws-cdk-lib/aws-logs"); const customresources = require("aws-cdk-lib/custom-resources"); const constructs = require("constructs"); const utilities = require("./utilities"); /** * Creates custom resources to enroll admin and register user * identities with the CA using the fabric-ca-client SDK. * Admin identity is enrolled by default. User identities are * registered and enrolled, if provided. */ class HyperledgerFabricIdentity extends constructs.Construct { constructor(scope, id) { super(scope, id); // Collect metadata on the stack const partition = cdk.Stack.of(this).partition; const region = cdk.Stack.of(this).region; // Retrieve the S3 Bucket and key that contains the TLS cert file const tlsBucketData = utilities.getTlsBucket(region); const adminPasswordArn = scope.adminPasswordSecret.secretArn; const adminPrivateKeyArn = scope.adminPrivateKeySecret.secretArn; const adminSignedCertArn = scope.adminSignedCertSecret.secretArn; const caEndpoint = scope.caEndpoint; const client = scope.client; const memberName = scope.memberName; // Role for the custom resource lambda functions const customResourceRole = new iam.Role(this, 'CustomResourceRole', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com') }); // Policies for the custom resource lambda to enroll and register users customResourceRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole')); customResourceRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaVPCAccessExecutionRole')); customResourceRole.addToPolicy(new iam.PolicyStatement({ actions: ['s3:GetObject', 'secretsmanager:CreateSecret', 'secretsmanager:GetSecretValue', 'secretsmanager:PutSecretValue'], resources: [ `arn:${partition}:s3:::${tlsBucketData.bucketName}/*`, adminPasswordArn, adminPrivateKeyArn, adminSignedCertArn, ], })); const lambdaDirectory = '../lambdas/fabric'; // Have to use docker local bundling as esbuild doesn't resolve the path on the fabric-proto package const codeProp = { bundling: { image: lambda.Runtime.NODEJS_14_X.bundlingImage, command: [ 'bash', '-c', 'cp -a . /asset-output', 'npm install --prefix /asset-output', ], local: { tryBundle(outputDir) { try { (0, child_process_1.execSync)('npm --version'); (0, child_process_1.execSync)(`cp -a ${path.join(__dirname, lambdaDirectory)}/. ${outputDir}`); (0, child_process_1.execSync)(`npm install --prefix ${outputDir}`); } catch { return false; } return true; }, }, }, }; // Lambda function to enroll the admin and import credentials to secrets manager. const adminFunction = new lambda.Function(this, 'AdminFunction', { runtime: lambda.Runtime.NODEJS_14_X, handler: 'enroll-admin.handler', code: lambda.Code.fromAsset(path.join(__dirname, lambdaDirectory), codeProp), environment: { ADMIN_PASSWORD_ARN: adminPasswordArn, CA_ENDPOINT: caEndpoint, PRIVATE_KEY_ARN: adminPrivateKeyArn, SIGNED_CERT_ARN: adminSignedCertArn, TLS_CERT_BUCKET: tlsBucketData.bucketName, TLS_CERT_KEY: tlsBucketData.key, }, role: customResourceRole, vpc: client.vpc, vpcSubnets: client.vpc.selectSubnets(), timeout: cdk.Duration.minutes(1), }); // Port range to access the Network const ledgerPortRange = ec2.Port.tcpRange(utilities.STARTING_PORT, utilities.ENDING_PORT); // Add access to the lambda for the Network ports client.vpcEndpoint.connections.allowFrom(adminFunction, ledgerPortRange); // Custom Resource provider this.adminProvider = new customresources.Provider(this, 'AdminProvider', { onEventHandler: adminFunction, logRetention: logs.RetentionDays.ONE_DAY, }); // Lambda function to register and enroll users and // import credentials to secrets manager. const userFunction = new lambda.Function(scope, 'UserFunction', { runtime: lambda.Runtime.NODEJS_14_X, handler: 'register-user.handler', code: lambda.Code.fromAsset(path.join(__dirname, lambdaDirectory), codeProp), environment: { CA_ENDPOINT: caEndpoint, MEMBER_NAME: memberName, PRIVATE_KEY_ARN: adminPrivateKeyArn, SIGNED_CERT_ARN: adminSignedCertArn, TLS_CERT_BUCKET: tlsBucketData.bucketName, TLS_CERT_KEY: tlsBucketData.key, }, role: customResourceRole, vpc: client.vpc, vpcSubnets: client.vpc.selectSubnets(), timeout: cdk.Duration.minutes(1), }); // Add access to the lambda for the Network ports scope.client.vpcEndpoint.connections.allowFrom(userFunction, ledgerPortRange); // Custom Resource provider HyperledgerFabricIdentity.userProvider = new customresources.Provider(scope, 'UserProvider', { onEventHandler: userFunction, logRetention: logs.RetentionDays.ONE_DAY, }); // Populate the custom role static variable HyperledgerFabricIdentity.customRole = customResourceRole; } } exports.HyperledgerFabricIdentity = HyperledgerFabricIdentity; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWRlbnRpdHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaWRlbnRpdHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHFFQUFxRTtBQUNyRSxpQ0FBaUM7OztBQUVqQyxpREFBeUM7QUFDekMsNkJBQTZCO0FBQzdCLG1DQUFtQztBQUNuQywyQ0FBMkM7QUFDM0MsMkNBQTJDO0FBQzNDLGlEQUFpRDtBQUNqRCw2Q0FBNkM7QUFDN0MsZ0VBQWdFO0FBQ2hFLHlDQUF5QztBQUd6Qyx5Q0FBeUM7QUFFekM7Ozs7O0dBS0c7QUFDSCxNQUFhLHlCQUEwQixTQUFRLFVBQVUsQ0FBQyxTQUFTO0lBa0JqRSxZQUFZLEtBQXVDLEVBQUUsRUFBVTtRQUM3RCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLGdDQUFnQztRQUNoQyxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDL0MsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDO1FBRXpDLGlFQUFpRTtRQUNqRSxNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXJELE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLG1CQUFtQixDQUFDLFNBQVMsQ0FBQztRQUM3RCxNQUFNLGtCQUFrQixHQUFHLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxTQUFTLENBQUM7UUFDakUsTUFBTSxrQkFBa0IsR0FBRyxLQUFLLENBQUMscUJBQXFCLENBQUMsU0FBUyxDQUFDO1FBQ2pFLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUM7UUFDcEMsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUM1QixNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsVUFB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QUNqRCxLQUFLLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxlQUFlLENBQUMsQ0FBQztRQUU5RSwyQkFBMkI7UUFDM0IseUJBQXlCLENBQUMsWUFBWSxHQUFHLElBQUksZUFBZSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsY0FBYyxFQUFFO1lBQzNGLGNBQWMsRUFBRSxZQUFZO1lBQzVCLFlBQVksRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU87U0FDekMsQ0FBQyxDQUFDO1FBRUgsMkNBQTJDO1FBQzNDLHlCQUF5QixDQUFDLFVBQVUsR0FBRyxrQkFBa0IsQ0FBQztJQUU1RCxDQUFDO0NBRUY7QUE3SUQsOERBNklDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlULTBcblxuaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyBjZGsgZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0ICogYXMgZWMyIGZyb20gJ2F3cy1jZGstbGliL2F3cy1lYzInO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0ICogYXMgbG9ncyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbG9ncyc7XG5pbXBvcnQgKiBhcyBjdXN0b21yZXNvdXJjZXMgZnJvbSAnYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlcyc7XG5pbXBvcnQgKiBhcyBjb25zdHJ1Y3RzIGZyb20gJ2NvbnN0cnVjdHMnO1xuXG5pbXBvcnQgKiBhcyBuZXR3b3JrIGZyb20gJy4vbmV0d29yayc7XG5pbXBvcnQgKiBhcyB1dGlsaXRpZXMgZnJvbSAnLi91dGlsaXRpZXMnO1xuXG4vKipcbiAqIENyZWF0ZXMgY3VzdG9tIHJlc291cmNlcyB0byBlbnJvbGwgYWRtaW4gYW5kIHJlZ2lzdGVyIHVzZXJcbiAqIGlkZW50aXRpZXMgd2l0aCB0aGUgQ0EgdXNpbmcgdGhlIGZhYnJpYy1jYS1jbGllbnQgU0RLLlxuICogQWRtaW4gaWRlbnRpdHkgaXMgZW5yb2xsZWQgYnkgZGVmYXVsdC4gVXNlciBpZGVudGl0aWVzIGFyZVxuICogcmVnaXN0ZXJlZCBhbmQgZW5yb2xsZWQsIGlmIHByb3ZpZGVkLlxuICovXG5leHBvcnQgY2xhc3MgSHlwZXJsZWRnZXJGYWJyaWNJZGVudGl0eSBleHRlbmRzIGNvbnN0cnVjdHMuQ29uc3RydWN0IHtcblxuICAvKipcbiAgICogUm9sZSBmb3IgY3VzdG9tIHJlc291cmNlIGxhbWJkYSB0byBhc3N1bWVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY3VzdG9tUm9sZTogaWFtLlJvbGU7XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBwcm92aWRlciB0byByZWdpc3RlciB1c2VyIGlkZW50aXR5XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHVzZXJQcm92aWRlcjogY3VzdG9tcmVzb3VyY2VzLlByb3ZpZGVyO1xuXG4gIC8qKlxuICAgKiBDdXN0b20gcHJvdmlkZXIgdG8gZW5yb2xsIGFkbWluIGlkZW50aXR5XG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYWRtaW5Qcm92aWRlcjogY3VzdG9tcmVzb3VyY2VzLlByb3ZpZGVyO1xuXG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IG5ldHdvcmsuSHlwZXJsZWRnZXJGYWJyaWNOZXR3b3JrLCBpZDogc3RyaW5nKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIC8vIENvbGxlY3QgbWV0YWRhdGEgb24gdGhlIHN0YWNrXG4gICAgY29uc3QgcGFydGl0aW9uID0gY2RrLlN0YWNrLm9mKHRoaXMpLnBhcnRpdGlvbjtcbiAgICBjb25zdCByZWdpb24gPSBjZGsuU3RhY2sub2YodGhpcykucmVnaW9uO1xuXG4gICAgLy8gUmV0cmlldmUgdGhlIFMzIEJ1Y2tldCBhbmQga2V5IHRoYXQgY29udGFpbnMgdGhlIFRMUyBjZXJ0IGZpbGVcbiAgICBjb25zdCB0bHNCdWNrZXREYXRhID0gdXRpbGl0aWVzLmdldFRsc0J1Y2tldChyZWdpb24pO1xuXG4gICAgY29uc3QgYWRtaW5QYXNzd29yZEFybiA9IHNjb3BlLmFkbWluUGFzc3dvcmRTZWNyZXQuc2VjcmV0QXJuO1xuICAgIGNvbnN0IGFkbWluUHJpdmF0ZUtleUFybiA9IHNjb3BlLmFkbWluUHJpdmF0ZUtleVNlY3JldC5zZWNyZXRBcm47XG4gICAgY29uc3QgYWRtaW5TaWduZWRDZXJ0QXJuID0gc2NvcGUuYWRtaW5TaWduZWRDZXJ0U2VjcmV0LnNlY3JldEFybjtcbiAgICBjb25zdCBjYUVuZHBvaW50ID0gc2NvcGUuY2FFbmRwb2ludDtcbiAgICBjb25zdCBjbGllbnQgPSBzY29wZS5jbGllbnQ7XG4gICAgY29uc3QgbWVtYmVyTmFtZSA9IHNjb3BlLm1lbWJlck5hbWU7XG5cbiAgICAvLyBSb2xlIGZvciB0aGUgY3VzdG9tIHJlc291cmNlIGxhbWJkYSBmdW5jdGlvbnNcbiAgICBjb25zdCBjdXN0b21SZXNvdXJjZVJvbGUgPSBuZXcgaWFtLlJvbGUodGhpcywgJ0N1c3RvbVJlc291cmNlUm9sZScsIHsgYXNzdW1lZEJ5OiBuZXcgaWFtLlNlcnZpY2VQcmluY2lwYWwoJ2xhbWJkYS5hbWF6b25hd3MuY29tJykgfSk7XG5cbiAgICAvLyBQb2xpY2llcyBmb3IgdGhlIGN1c3RvbSByZXNvdXJjZSBsYW1iZGEgdG8gZW5yb2xsIGFuZCByZWdpc3RlciB1c2Vyc1xuICAgIGN1c3RvbVJlc291cmNlUm9sZS5hZGRNYW5hZ2VkUG9saWN5KGlhbS5NYW5hZ2VkUG9saWN5LmZyb21Bd3NNYW5hZ2VkUG9saWN5TmFtZSgnc2VydmljZS1yb2xlL0FXU0xhbWJkYUJhc2ljRXhlY3V0aW9uUm9sZScpKTtcbiAgICBjdXN0b21SZXNvdXJjZVJvbGUuYWRkTWFuYWdlZFBvbGljeShpYW0uTWFuYWdlZFBvbGljeS5mcm9tQXdzTWFuYWdlZFBvbGljeU5hbWUoJ3NlcnZpY2Utcm9sZS9BV1NMYW1iZGFWUENBY2Nlc3NFeGVjdXRpb25Sb2xlJykpO1xuICAgIGN1c3RvbVJlc291cmNlUm9sZS5hZGRUb1BvbGljeSggbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgYWN0aW9uczogWydzMzpHZXRPYmplY3QnLCAnc2VjcmV0c21hbmFnZXI6Q3JlYXRlU2VjcmV0JywgJ3NlY3JldHNtYW5hZ2VyOkdldFNlY3JldFZhbHVlJywgJ3NlY3JldHNtYW5hZ2VyOlB1dFNlY3JldFZhbHVlJ10sXG4gICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgYGFybjoke3BhcnRpdGlvbn06czM6Ojoke3Rsc0J1Y2tldERhdGEuYnVja2V0TmFtZX0vKmAsXG4gICAgICAgIGFkbWluUGFzc3dvcmRBcm4sXG4gICAgICAgIGFkbWluUHJpdmF0ZUtleUFybixcbiAgICAgICAgYWRtaW5TaWduZWRDZXJ0QXJuLFxuICAgICAgXSxcbiAgICB9KSk7XG5cbiAgICBjb25zdCBsYW1iZGFEaXJlY3RvcnkgPSAnLi4vbGFtYmRhcy9mYWJyaWMnO1xuXG4gICAgLy8gSGF2ZSB0byB1c2UgZG9ja2VyIGxvY2FsIGJ1bmRsaW5nIGFzIGVzYnVpbGQgZG9lc24ndCByZXNvbHZlIHRoZSBwYXRoIG9uIHRoZSBmYWJyaWMtcHJvdG8gcGFja2FnZVxuICAgIGNvbnN0IGNvZGVQcm9wID0ge1xuICAgICAgYnVuZGxpbmc6IHtcbiAgICAgICAgaW1hZ2U6IGxhbWJkYS5SdW50aW1lLk5PREVKU18xNF9YLmJ1bmRsaW5nSW1hZ2UsXG4gICAgICAgIGNvbW1hbmQ6IFtcbiAgICAgICAgICAnYmFzaCcsICctYycsICdjcCAtYSAuIC9hc3NldC1vdXRwdXQnLFxuICAgICAgICAgICducG0gaW5zdGFsbCAtLXByZWZpeCAvYXNzZXQtb3V0cHV0JyxcbiAgICAgICAgXSxcbiAgICAgICAgbG9jYWw6IHtcbiAgICAgICAgICB0cnlCdW5kbGUob3V0cHV0RGlyOiBzdHJpbmcpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGV4ZWNTeW5jKCducG0gLS12ZXJzaW9uJyk7XG4gICAgICAgICAgICAgIGV4ZWNTeW5jKGBjcCAtYSAke3BhdGguam9pbihfX2Rpcm5hbWUsIGxhbWJkYURpcmVjdG9yeSl9Ly4gJHtvdXRwdXREaXJ9YCk7XG4gICAgICAgICAgICAgIGV4ZWNTeW5jKGBucG0gaW5zdGFsbCAtLXByZWZpeCAke291dHB1dERpcn1gKTtcbiAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgLy8gTGFtYmRhIGZ1bmN0aW9uIHRvIGVucm9sbCB0aGUgYWRtaW4gYW5kIGltcG9ydCBjcmVkZW50aWFscyB0byBzZWNyZXRzIG1hbmFnZXIuXG4gICAgY29uc3QgYWRtaW5GdW5jdGlvbiA9IG5ldyBsYW1iZGEuRnVuY3Rpb24odGhpcywgJ0FkbWluRnVuY3Rpb24nLCB7XG4gICAgICBydW50aW1lOiBsYW1iZGEuUnVudGltZS5OT0RFSlNfMTRfWCxcbiAgICAgIGhhbmRsZXI6ICdlbnJvbGwtYWRtaW4uaGFuZGxlcicsXG4gICAgICBjb2RlOiBsYW1iZGEuQ29kZS5mcm9tQXNzZXQocGF0aC5qb2luKF9fZGlybmFtZSwgbGFtYmRhRGlyZWN0b3J5KSwgY29kZVByb3ApLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgQURNSU5fUEFTU1dPUkRfQVJOOiBhZG1pblBhc3N3b3JkQXJuLFxuICAgICAgICBDQV9FTkRQT0lOVDogY2FFbmRwb2ludCxcbiAgICAgICAgUFJJVkFURV9LRVlfQVJOOiBhZG1pblByaXZhdGVLZXlBcm4sXG4gICAgICAgIFNJR05FRF9DRVJUX0FSTjogYWRtaW5TaWduZWRDZXJ0QXJuLFxuICAgICAgICBUTFNfQ0VSVF9CVUNLRVQ6IHRsc0J1Y2tldERhdGEuYnVja2V0TmFtZSxcbiAgICAgICAgVExTX0NFUlRfS0VZOiB0bHNCdWNrZXREYXRhLmtleSxcbiAgICAgIH0sXG4gICAgICByb2xlOiBjdXN0b21SZXNvdXJjZVJvbGUsXG4gICAgICB2cGM6IGNsaWVudC52cGMsXG4gICAgICB2cGNTdWJuZXRzOiBjbGllbnQudnBjLnNlbGVjdFN1Ym5ldHMoKSxcbiAgICAgIHRpbWVvdXQ6IGNkay5EdXJhdGlvbi5taW51dGVzKDEpLFxuICAgIH0pO1xuXG4gICAgLy8gUG9ydCByYW5nZSB0byBhY2Nlc3MgdGhlIE5ldHdvcmtcbiAgICBjb25zdCBsZWRnZXJQb3J0UmFuZ2UgPSBlYzIuUG9ydC50Y3BSYW5nZSh1dGlsaXRpZXMuU1RBUlRJTkdfUE9SVCwgdXRpbGl0aWVzLkVORElOR19QT1JUKTtcblxuICAgIC8vIEFkZCBhY2Nlc3MgdG8gdGhlIGxhbWJkYSBmb3IgdGhlIE5ldHdvcmsgcG9ydHNcbiAgICBjbGllbnQudnBjRW5kcG9pbnQuY29ubmVjdGlvbnMuYWxsb3dGcm9tKGFkbWluRnVuY3Rpb24sIGxlZGdlclBvcnRSYW5nZSk7XG5cbiAgICAvLyBDdXN0b20gUmVzb3VyY2UgcHJvdmlkZXJcbiAgICB0aGlzLmFkbWluUHJvdmlkZXIgPSBuZXcgY3VzdG9tcmVzb3VyY2VzLlByb3ZpZGVyKHRoaXMsICdBZG1pblByb3ZpZGVyJywge1xuICAgICAgb25FdmVudEhhbmRsZXI6IGFkbWluRnVuY3Rpb24sXG4gICAgICBsb2dSZXRlbnRpb246IGxvZ3MuUmV0ZW50aW9uRGF5cy5PTkVfREFZLFxuICAgIH0pO1xuXG4gICAgLy8gTGFtYmRhIGZ1bmN0aW9uIHRvIHJlZ2lzdGVyIGFuZCBlbnJvbGwgdXNlcnMgYW5kXG4gICAgLy8gaW1wb3J0IGNyZWRlbnRpYWxzIHRvIHNlY3JldHMgbWFuYWdlci5cbiAgICBjb25zdCB1c2VyRnVuY3Rpb24gPSBuZXcgbGFtYmRhLkZ1bmN0aW9uKHNjb3BlLCAnVXNlckZ1bmN0aW9uJywge1xuICAgICAgcnVudGltZTogbGFtYmRhLlJ1bnRpbWUuTk9ERUpTXzE0X1gsXG4gICAgICBoYW5kbGVyOiAncmVnaXN0ZXItdXNlci5oYW5kbGVyJyxcbiAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChwYXRoLmpvaW4oX19kaXJuYW1lLCBsYW1iZGFEaXJlY3RvcnkpLCBjb2RlUHJvcCksXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBDQV9FTkRQT0lOVDogY2FFbmRwb2ludCxcbiAgICAgICAgTUVNQkVSX05BTUU6IG1lbWJlck5hbWUsXG4gICAgICAgIFBSSVZBVEVfS0VZX0FSTjogYWRtaW5Qcml2YXRlS2V5QXJuLFxuICAgICAgICBTSUdORURfQ0VSVF9BUk46IGFkbWluU2lnbmVkQ2VydEFybixcbiAgICAgICAgVExTX0NFUlRfQlVDS0VUOiB0bHNCdWNrZXREYXRhLmJ1Y2tldE5hbWUsXG4gICAgICAgIFRMU19DRVJUX0tFWTogdGxzQnVja2V0RGF0YS5rZXksXG4gICAgICB9LFxuICAgICAgcm9sZTogY3VzdG9tUmVzb3VyY2VSb2xlLFxuICAgICAgdnBjOiBjbGllbnQudnBjLFxuICAgICAgdnBjU3VibmV0czogY2xpZW50LnZwYy5zZWxlY3RTdWJuZXRzKCksXG4gICAgICB0aW1lb3V0OiBjZGsuRHVyYXRpb24ubWludXRlcygxKSxcbiAgICB9KTtcblxuICAgIC8vIEFkZCBhY2Nlc3MgdG8gdGhlIGxhbWJkYSBmb3IgdGhlIE5ldHdvcmsgcG9ydHNcbiAgICBzY29wZS5jbGllbnQudnBjRW5kcG9pbnQuY29ubmVjdGlvbnMuYWxsb3dGcm9tKHVzZXJGdW5jdGlvbiwgbGVkZ2VyUG9ydFJhbmdlKTtcblxuICAgIC8vIEN1c3RvbSBSZXNvdXJjZSBwcm92aWRlclxuICAgIEh5cGVybGVkZ2VyRmFicmljSWRlbnRpdHkudXNlclByb3ZpZGVyID0gbmV3IGN1c3RvbXJlc291cmNlcy5Qcm92aWRlcihzY29wZSwgJ1VzZXJQcm92aWRlcicsIHtcbiAgICAgIG9uRXZlbnRIYW5kbGVyOiB1c2VyRnVuY3Rpb24sXG4gICAgICBsb2dSZXRlbnRpb246IGxvZ3MuUmV0ZW50aW9uRGF5cy5PTkVfREFZLFxuICAgIH0pO1xuXG4gICAgLy8gUG9wdWxhdGUgdGhlIGN1c3RvbSByb2xlIHN0YXRpYyB2YXJpYWJsZVxuICAgIEh5cGVybGVkZ2VyRmFicmljSWRlbnRpdHkuY3VzdG9tUm9sZSA9IGN1c3RvbVJlc291cmNlUm9sZTtcblxuICB9XG5cbn0iXX0=