@cdklabs/cdk-hyperledger-fabric-network 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +4508 -0
- package/LICENSE +15 -0
- package/README.md +150 -0
- package/examples/python/hyperledger.py +90 -0
- package/examples/typescript/hyperledger.ts +106 -0
- package/lambdas/fabric/.eslintrc.js +17 -0
- package/lambdas/fabric/enroll-admin.js +33 -0
- package/lambdas/fabric/package.json +14 -0
- package/lambdas/fabric/register-user.js +62 -0
- package/lambdas/fabric/utilities.js +54 -0
- package/lib/client.d.ts +31 -0
- package/lib/client.js +40 -0
- package/lib/identity.d.ts +25 -0
- package/lib/identity.js +107 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +22 -0
- package/lib/network.d.ts +183 -0
- package/lib/network.js +225 -0
- package/lib/node.d.ts +88 -0
- package/lib/node.js +161 -0
- package/lib/user.d.ts +40 -0
- package/lib/user.js +56 -0
- package/lib/utilities.d.ts +12 -0
- package/lib/utilities.js +116 -0
- package/package.json +154 -0
package/lib/identity.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
// SPDX-License-Identifier: MIT-0
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.HyperledgerFabricIdentity = void 0;
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const cdk = require("aws-cdk-lib");
|
|
8
|
+
const ec2 = require("aws-cdk-lib/aws-ec2");
|
|
9
|
+
const iam = require("aws-cdk-lib/aws-iam");
|
|
10
|
+
const lambda = require("aws-cdk-lib/aws-lambda");
|
|
11
|
+
const logs = require("aws-cdk-lib/aws-logs");
|
|
12
|
+
const customresources = require("aws-cdk-lib/custom-resources");
|
|
13
|
+
const constructs = require("constructs");
|
|
14
|
+
const utilities = require("./utilities");
|
|
15
|
+
/**
|
|
16
|
+
* Creates custom resources to enroll admin and register user
|
|
17
|
+
* identities with the CA using the fabric-ca-client SDK.
|
|
18
|
+
* Admin identity is enrolled by default. User identities are
|
|
19
|
+
* registered and enrolled, if provided.
|
|
20
|
+
*/
|
|
21
|
+
class HyperledgerFabricIdentity extends constructs.Construct {
|
|
22
|
+
constructor(scope, id) {
|
|
23
|
+
super(scope, id);
|
|
24
|
+
// Collect metadata on the stack
|
|
25
|
+
const partition = cdk.Stack.of(this).partition;
|
|
26
|
+
const region = cdk.Stack.of(this).region;
|
|
27
|
+
// Retrieve the S3 Bucket and key that contains the TLS cert file
|
|
28
|
+
const tlsBucketData = utilities.getTlsBucket(region);
|
|
29
|
+
const adminPasswordArn = scope.adminPasswordSecret.secretArn;
|
|
30
|
+
const adminPrivateKeyArn = scope.adminPrivateKeySecret.secretArn;
|
|
31
|
+
const adminSignedCertArn = scope.adminSignedCertSecret.secretArn;
|
|
32
|
+
const caEndpoint = scope.caEndpoint;
|
|
33
|
+
const client = scope.client;
|
|
34
|
+
const memberName = scope.memberName;
|
|
35
|
+
// Role for the custom resource lambda functions
|
|
36
|
+
const customResourceRole = new iam.Role(this, 'CustomResourceRole', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com') });
|
|
37
|
+
// Policies for the custom resource lambda to enroll and register users
|
|
38
|
+
customResourceRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'));
|
|
39
|
+
customResourceRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaVPCAccessExecutionRole'));
|
|
40
|
+
customResourceRole.addToPolicy(new iam.PolicyStatement({
|
|
41
|
+
actions: ['s3:GetObject', 'secretsmanager:CreateSecret', 'secretsmanager:GetSecretValue', 'secretsmanager:PutSecretValue'],
|
|
42
|
+
resources: [
|
|
43
|
+
`arn:${partition}:s3:::${tlsBucketData.bucketName}/*`,
|
|
44
|
+
adminPasswordArn,
|
|
45
|
+
adminPrivateKeyArn,
|
|
46
|
+
adminSignedCertArn,
|
|
47
|
+
],
|
|
48
|
+
}));
|
|
49
|
+
// Lambda function to enroll the admin and import credentials to secrets manager
|
|
50
|
+
const adminFunction = new lambda.Function(this, 'AdminFunction', {
|
|
51
|
+
runtime: lambda.Runtime.NODEJS_14_X,
|
|
52
|
+
handler: 'enroll-admin.handler',
|
|
53
|
+
code: lambda.Code.fromAsset(path.join(__dirname, '../lambdas/fabric')),
|
|
54
|
+
environment: {
|
|
55
|
+
ADMIN_PASSWORD_ARN: adminPasswordArn,
|
|
56
|
+
CA_ENDPOINT: caEndpoint,
|
|
57
|
+
PRIVATE_KEY_ARN: adminPrivateKeyArn,
|
|
58
|
+
SIGNED_CERT_ARN: adminSignedCertArn,
|
|
59
|
+
TLS_CERT_BUCKET: tlsBucketData.bucketName,
|
|
60
|
+
TLS_CERT_KEY: tlsBucketData.key,
|
|
61
|
+
},
|
|
62
|
+
role: customResourceRole,
|
|
63
|
+
vpc: client.vpc,
|
|
64
|
+
vpcSubnets: client.vpc.selectSubnets(),
|
|
65
|
+
timeout: cdk.Duration.minutes(1),
|
|
66
|
+
});
|
|
67
|
+
// Port range to access the Network
|
|
68
|
+
const ledgerPortRange = ec2.Port.tcpRange(utilities.STARTING_PORT, utilities.ENDING_PORT);
|
|
69
|
+
// Add access to the lambda for the Network ports
|
|
70
|
+
client.vpcEndpoint.connections.allowFrom(adminFunction, ledgerPortRange);
|
|
71
|
+
// Custom Resource provider
|
|
72
|
+
this.adminProvider = new customresources.Provider(this, 'AdminProvider', {
|
|
73
|
+
onEventHandler: adminFunction,
|
|
74
|
+
logRetention: logs.RetentionDays.ONE_DAY,
|
|
75
|
+
});
|
|
76
|
+
// Lambda function to register and enroll users and
|
|
77
|
+
// import credentials to secrets manager
|
|
78
|
+
const userFunction = new lambda.Function(scope, 'UserFunction', {
|
|
79
|
+
runtime: lambda.Runtime.NODEJS_14_X,
|
|
80
|
+
handler: 'register-user.handler',
|
|
81
|
+
code: lambda.Code.fromAsset(path.join(__dirname, '../lambdas/fabric')),
|
|
82
|
+
environment: {
|
|
83
|
+
CA_ENDPOINT: caEndpoint,
|
|
84
|
+
MEMBER_NAME: memberName,
|
|
85
|
+
PRIVATE_KEY_ARN: adminPrivateKeyArn,
|
|
86
|
+
SIGNED_CERT_ARN: adminSignedCertArn,
|
|
87
|
+
TLS_CERT_BUCKET: tlsBucketData.bucketName,
|
|
88
|
+
TLS_CERT_KEY: tlsBucketData.key,
|
|
89
|
+
},
|
|
90
|
+
role: customResourceRole,
|
|
91
|
+
vpc: client.vpc,
|
|
92
|
+
vpcSubnets: client.vpc.selectSubnets(),
|
|
93
|
+
timeout: cdk.Duration.minutes(1),
|
|
94
|
+
});
|
|
95
|
+
// Add access to the lambda for the Network ports
|
|
96
|
+
scope.client.vpcEndpoint.connections.allowFrom(userFunction, ledgerPortRange);
|
|
97
|
+
// Custom Resource provider
|
|
98
|
+
HyperledgerFabricIdentity.userProvider = new customresources.Provider(scope, 'UserProvider', {
|
|
99
|
+
onEventHandler: userFunction,
|
|
100
|
+
logRetention: logs.RetentionDays.ONE_DAY,
|
|
101
|
+
});
|
|
102
|
+
// Populate the custom role static variable
|
|
103
|
+
HyperledgerFabricIdentity.customRole = customResourceRole;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.HyperledgerFabricIdentity = HyperledgerFabricIdentity;
|
|
107
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWRlbnRpdHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaWRlbnRpdHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHFFQUFxRTtBQUNyRSxpQ0FBaUM7OztBQUVqQyw2QkFBNkI7QUFDN0IsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQywyQ0FBMkM7QUFDM0MsaURBQWlEO0FBQ2pELDZDQUE2QztBQUM3QyxnRUFBZ0U7QUFDaEUseUNBQXlDO0FBR3pDLHlDQUF5QztBQUV6Qzs7Ozs7R0FLRztBQUNILE1BQWEseUJBQTBCLFNBQVEsVUFBVSxDQUFDLFNBQVM7SUFrQmpFLFlBQVksS0FBdUMsRUFBRSxFQUFVO1FBQzdELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsZ0NBQWdDO1FBQ2hDLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUMvQyxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFFekMsaUVBQWlFO1FBQ2pFLE1BQU0sYUFBYSxHQUFHLFNBQVMsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFckQsTUFBTSxnQkFBZ0IsR0FBRyxLQUFLLENBQUMsbUJBQW1CLENBQUMsU0FBUyxDQUFDO1FBQzdELE1BQU0sa0JBQWtCLEdBQUcsS0FBSyxDQUFDLHFCQUFxQixDQUFDLFNBQVMsQ0FBQztRQUNqRSxNQUFNLGtCQUFrQixHQUFHLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxTQUFTLENBQUM7UUFDakUsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUNwQyxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO1FBQzVCLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUM7UUFFcEMs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Q3ZCLFdBQVcsRUFBRSxVQUFVO2dCQUN2QixlQUFlLEVBQUUsa0JBQWtCO2dCQUNuQyxlQUFlLEVBQUUsa0JBQWtCO2dCQUNuQyxlQUFlLEVBQUUsYUFBYSxDQUFDLFVBQVU7Z0JBQ3pDLFlBQVksRUFBRSxhQUFhLENBQUMsR0FBRzthQUNoQztZQUNELElBQUksRUFBRSxrQkFBa0I7WUFDeEIsR0FBRyxFQUFFLE1BQU0sQ0FBQyxHQUFHO1lBQ2YsVUFBVSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFO1lBQ3RDLE9BQU8sRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7U0FDakMsQ0FBQyxDQUFDO1FBRUgsaURBQWlEO1FBQ2pELEtBQUssQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1FBRTlFLDJCQUEyQjtRQUMzQix5QkFBeUIsQ0FBQyxZQUFZLEdBQUcsSUFBSSxlQUFlLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxjQUFjLEVBQUU7WUFDM0YsY0FBYyxFQUFFLFlBQVk7WUFDNUIsWUFBWSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTztTQUN6QyxDQUFDLENBQUM7UUFFSCwyQ0FBMkM7UUFDM0MseUJBQXlCLENBQUMsVUFBVSxHQUFHLGtCQUFrQixDQUFDO0lBRTVELENBQUM7Q0FFRjtBQXBIRCw4REFvSEMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVQtMFxuXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgY2RrIGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGVjMiBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWMyJztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCAqIGFzIGxvZ3MgZnJvbSAnYXdzLWNkay1saWIvYXdzLWxvZ3MnO1xuaW1wb3J0ICogYXMgY3VzdG9tcmVzb3VyY2VzIGZyb20gJ2F3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXMnO1xuaW1wb3J0ICogYXMgY29uc3RydWN0cyBmcm9tICdjb25zdHJ1Y3RzJztcblxuaW1wb3J0ICogYXMgbmV0d29yayBmcm9tICcuL25ldHdvcmsnO1xuaW1wb3J0ICogYXMgdXRpbGl0aWVzIGZyb20gJy4vdXRpbGl0aWVzJztcblxuLyoqXG4gKiBDcmVhdGVzIGN1c3RvbSByZXNvdXJjZXMgdG8gZW5yb2xsIGFkbWluIGFuZCByZWdpc3RlciB1c2VyXG4gKiBpZGVudGl0aWVzIHdpdGggdGhlIENBIHVzaW5nIHRoZSBmYWJyaWMtY2EtY2xpZW50IFNESy5cbiAqIEFkbWluIGlkZW50aXR5IGlzIGVucm9sbGVkIGJ5IGRlZmF1bHQuIFVzZXIgaWRlbnRpdGllcyBhcmVcbiAqIHJlZ2lzdGVyZWQgYW5kIGVucm9sbGVkLCBpZiBwcm92aWRlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIEh5cGVybGVkZ2VyRmFicmljSWRlbnRpdHkgZXh0ZW5kcyBjb25zdHJ1Y3RzLkNvbnN0cnVjdCB7XG5cbiAgLyoqXG4gICAqIFJvbGUgZm9yIGN1c3RvbSByZXNvdXJjZSBsYW1iZGEgdG8gYXNzdW1lXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGN1c3RvbVJvbGU6IGlhbS5Sb2xlO1xuXG4gIC8qKlxuICAgKiBDdXN0b20gcHJvdmlkZXIgdG8gcmVnaXN0ZXIgdXNlciBpZGVudGl0eVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyB1c2VyUHJvdmlkZXI6IGN1c3RvbXJlc291cmNlcy5Qcm92aWRlcjtcblxuICAvKipcbiAgICogQ3VzdG9tIHByb3ZpZGVyIHRvIGVucm9sbCBhZG1pbiBpZGVudGl0eVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFkbWluUHJvdmlkZXI6IGN1c3RvbXJlc291cmNlcy5Qcm92aWRlcjtcblxuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBuZXR3b3JrLkh5cGVybGVkZ2VyRmFicmljTmV0d29yaywgaWQ6IHN0cmluZykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICAvLyBDb2xsZWN0IG1ldGFkYXRhIG9uIHRoZSBzdGFja1xuICAgIGNvbnN0IHBhcnRpdGlvbiA9IGNkay5TdGFjay5vZih0aGlzKS5wYXJ0aXRpb247XG4gICAgY29uc3QgcmVnaW9uID0gY2RrLlN0YWNrLm9mKHRoaXMpLnJlZ2lvbjtcblxuICAgIC8vIFJldHJpZXZlIHRoZSBTMyBCdWNrZXQgYW5kIGtleSB0aGF0IGNvbnRhaW5zIHRoZSBUTFMgY2VydCBmaWxlXG4gICAgY29uc3QgdGxzQnVja2V0RGF0YSA9IHV0aWxpdGllcy5nZXRUbHNCdWNrZXQocmVnaW9uKTtcblxuICAgIGNvbnN0IGFkbWluUGFzc3dvcmRBcm4gPSBzY29wZS5hZG1pblBhc3N3b3JkU2VjcmV0LnNlY3JldEFybjtcbiAgICBjb25zdCBhZG1pblByaXZhdGVLZXlBcm4gPSBzY29wZS5hZG1pblByaXZhdGVLZXlTZWNyZXQuc2VjcmV0QXJuO1xuICAgIGNvbnN0IGFkbWluU2lnbmVkQ2VydEFybiA9IHNjb3BlLmFkbWluU2lnbmVkQ2VydFNlY3JldC5zZWNyZXRBcm47XG4gICAgY29uc3QgY2FFbmRwb2ludCA9IHNjb3BlLmNhRW5kcG9pbnQ7XG4gICAgY29uc3QgY2xpZW50ID0gc2NvcGUuY2xpZW50O1xuICAgIGNvbnN0IG1lbWJlck5hbWUgPSBzY29wZS5tZW1iZXJOYW1lO1xuXG4gICAgLy8gUm9sZSBmb3IgdGhlIGN1c3RvbSByZXNvdXJjZSBsYW1iZGEgZnVuY3Rpb25zXG4gICAgY29uc3QgY3VzdG9tUmVzb3VyY2VSb2xlID0gbmV3IGlhbS5Sb2xlKHRoaXMsICdDdXN0b21SZXNvdXJjZVJvbGUnLCB7IGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdsYW1iZGEuYW1hem9uYXdzLmNvbScpIH0pO1xuXG4gICAgLy8gUG9saWNpZXMgZm9yIHRoZSBjdXN0b20gcmVzb3VyY2UgbGFtYmRhIHRvIGVucm9sbCBhbmQgcmVnaXN0ZXIgdXNlcnNcbiAgICBjdXN0b21SZXNvdXJjZVJvbGUuYWRkTWFuYWdlZFBvbGljeShpYW0uTWFuYWdlZFBvbGljeS5mcm9tQXdzTWFuYWdlZFBvbGljeU5hbWUoJ3NlcnZpY2Utcm9sZS9BV1NMYW1iZGFCYXNpY0V4ZWN1dGlvblJvbGUnKSk7XG4gICAgY3VzdG9tUmVzb3VyY2VSb2xlLmFkZE1hbmFnZWRQb2xpY3koaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKCdzZXJ2aWNlLXJvbGUvQVdTTGFtYmRhVlBDQWNjZXNzRXhlY3V0aW9uUm9sZScpKTtcbiAgICBjdXN0b21SZXNvdXJjZVJvbGUuYWRkVG9Qb2xpY3koIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgIGFjdGlvbnM6IFsnczM6R2V0T2JqZWN0JywgJ3NlY3JldHNtYW5hZ2VyOkNyZWF0ZVNlY3JldCcsICdzZWNyZXRzbWFuYWdlcjpHZXRTZWNyZXRWYWx1ZScsICdzZWNyZXRzbWFuYWdlcjpQdXRTZWNyZXRWYWx1ZSddLFxuICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgIGBhcm46JHtwYXJ0aXRpb259OnMzOjo6JHt0bHNCdWNrZXREYXRhLmJ1Y2tldE5hbWV9LypgLFxuICAgICAgICBhZG1pblBhc3N3b3JkQXJuLFxuICAgICAgICBhZG1pblByaXZhdGVLZXlBcm4sXG4gICAgICAgIGFkbWluU2lnbmVkQ2VydEFybixcbiAgICAgIF0sXG4gICAgfSkpO1xuXG4gICAgLy8gTGFtYmRhIGZ1bmN0aW9uIHRvIGVucm9sbCB0aGUgYWRtaW4gYW5kIGltcG9ydCBjcmVkZW50aWFscyB0byBzZWNyZXRzIG1hbmFnZXJcbiAgICBjb25zdCBhZG1pbkZ1bmN0aW9uID0gbmV3IGxhbWJkYS5GdW5jdGlvbih0aGlzLCAnQWRtaW5GdW5jdGlvbicsIHtcbiAgICAgIHJ1bnRpbWU6IGxhbWJkYS5SdW50aW1lLk5PREVKU18xNF9YLFxuICAgICAgaGFuZGxlcjogJ2Vucm9sbC1hZG1pbi5oYW5kbGVyJyxcbiAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vbGFtYmRhcy9mYWJyaWMnKSksXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBBRE1JTl9QQVNTV09SRF9BUk46IGFkbWluUGFzc3dvcmRBcm4sXG4gICAgICAgIENBX0VORFBPSU5UOiBjYUVuZHBvaW50LFxuICAgICAgICBQUklWQVRFX0tFWV9BUk46IGFkbWluUHJpdmF0ZUtleUFybixcbiAgICAgICAgU0lHTkVEX0NFUlRfQVJOOiBhZG1pblNpZ25lZENlcnRBcm4sXG4gICAgICAgIFRMU19DRVJUX0JVQ0tFVDogdGxzQnVja2V0RGF0YS5idWNrZXROYW1lLFxuICAgICAgICBUTFNfQ0VSVF9LRVk6IHRsc0J1Y2tldERhdGEua2V5LFxuICAgICAgfSxcbiAgICAgIHJvbGU6IGN1c3RvbVJlc291cmNlUm9sZSxcbiAgICAgIHZwYzogY2xpZW50LnZwYyxcbiAgICAgIHZwY1N1Ym5ldHM6IGNsaWVudC52cGMuc2VsZWN0U3VibmV0cygpLFxuICAgICAgdGltZW91dDogY2RrLkR1cmF0aW9uLm1pbnV0ZXMoMSksXG4gICAgfSk7XG5cbiAgICAvLyBQb3J0IHJhbmdlIHRvIGFjY2VzcyB0aGUgTmV0d29ya1xuICAgIGNvbnN0IGxlZGdlclBvcnRSYW5nZSA9IGVjMi5Qb3J0LnRjcFJhbmdlKHV0aWxpdGllcy5TVEFSVElOR19QT1JULCB1dGlsaXRpZXMuRU5ESU5HX1BPUlQpO1xuXG4gICAgLy8gQWRkIGFjY2VzcyB0byB0aGUgbGFtYmRhIGZvciB0aGUgTmV0d29yayBwb3J0c1xuICAgIGNsaWVudC52cGNFbmRwb2ludC5jb25uZWN0aW9ucy5hbGxvd0Zyb20oYWRtaW5GdW5jdGlvbiwgbGVkZ2VyUG9ydFJhbmdlKTtcblxuICAgIC8vIEN1c3RvbSBSZXNvdXJjZSBwcm92aWRlclxuICAgIHRoaXMuYWRtaW5Qcm92aWRlciA9IG5ldyBjdXN0b21yZXNvdXJjZXMuUHJvdmlkZXIodGhpcywgJ0FkbWluUHJvdmlkZXInLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcjogYWRtaW5GdW5jdGlvbixcbiAgICAgIGxvZ1JldGVudGlvbjogbG9ncy5SZXRlbnRpb25EYXlzLk9ORV9EQVksXG4gICAgfSk7XG5cbiAgICAvLyBMYW1iZGEgZnVuY3Rpb24gdG8gcmVnaXN0ZXIgYW5kIGVucm9sbCB1c2VycyBhbmRcbiAgICAvLyBpbXBvcnQgY3JlZGVudGlhbHMgdG8gc2VjcmV0cyBtYW5hZ2VyXG4gICAgY29uc3QgdXNlckZ1bmN0aW9uID0gbmV3IGxhbWJkYS5GdW5jdGlvbihzY29wZSwgJ1VzZXJGdW5jdGlvbicsIHtcbiAgICAgIHJ1bnRpbWU6IGxhbWJkYS5SdW50aW1lLk5PREVKU18xNF9YLFxuICAgICAgaGFuZGxlcjogJ3JlZ2lzdGVyLXVzZXIuaGFuZGxlcicsXG4gICAgICBjb2RlOiBsYW1iZGEuQ29kZS5mcm9tQXNzZXQocGF0aC5qb2luKF9fZGlybmFtZSwgJy4uL2xhbWJkYXMvZmFicmljJykpLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgQ0FfRU5EUE9JTlQ6IGNhRW5kcG9pbnQsXG4gICAgICAgIE1FTUJFUl9OQU1FOiBtZW1iZXJOYW1lLFxuICAgICAgICBQUklWQVRFX0tFWV9BUk46IGFkbWluUHJpdmF0ZUtleUFybixcbiAgICAgICAgU0lHTkVEX0NFUlRfQVJOOiBhZG1pblNpZ25lZENlcnRBcm4sXG4gICAgICAgIFRMU19DRVJUX0JVQ0tFVDogdGxzQnVja2V0RGF0YS5idWNrZXROYW1lLFxuICAgICAgICBUTFNfQ0VSVF9LRVk6IHRsc0J1Y2tldERhdGEua2V5LFxuICAgICAgfSxcbiAgICAgIHJvbGU6IGN1c3RvbVJlc291cmNlUm9sZSxcbiAgICAgIHZwYzogY2xpZW50LnZwYyxcbiAgICAgIHZwY1N1Ym5ldHM6IGNsaWVudC52cGMuc2VsZWN0U3VibmV0cygpLFxuICAgICAgdGltZW91dDogY2RrLkR1cmF0aW9uLm1pbnV0ZXMoMSksXG4gICAgfSk7XG5cbiAgICAvLyBBZGQgYWNjZXNzIHRvIHRoZSBsYW1iZGEgZm9yIHRoZSBOZXR3b3JrIHBvcnRzXG4gICAgc2NvcGUuY2xpZW50LnZwY0VuZHBvaW50LmNvbm5lY3Rpb25zLmFsbG93RnJvbSh1c2VyRnVuY3Rpb24sIGxlZGdlclBvcnRSYW5nZSk7XG5cbiAgICAvLyBDdXN0b20gUmVzb3VyY2UgcHJvdmlkZXJcbiAgICBIeXBlcmxlZGdlckZhYnJpY0lkZW50aXR5LnVzZXJQcm92aWRlciA9IG5ldyBjdXN0b21yZXNvdXJjZXMuUHJvdmlkZXIoc2NvcGUsICdVc2VyUHJvdmlkZXInLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcjogdXNlckZ1bmN0aW9uLFxuICAgICAgbG9nUmV0ZW50aW9uOiBsb2dzLlJldGVudGlvbkRheXMuT05FX0RBWSxcbiAgICB9KTtcblxuICAgIC8vIFBvcHVsYXRlIHRoZSBjdXN0b20gcm9sZSBzdGF0aWMgdmFyaWFibGVcbiAgICBIeXBlcmxlZGdlckZhYnJpY0lkZW50aXR5LmN1c3RvbVJvbGUgPSBjdXN0b21SZXNvdXJjZVJvbGU7XG5cbiAgfVxuXG59Il19
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
// SPDX-License-Identifier: MIT-0
|
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
+
if (k2 === undefined) k2 = k;
|
|
6
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
7
|
+
}) : (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
o[k2] = m[k];
|
|
10
|
+
}));
|
|
11
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
12
|
+
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
__exportStar(require("./network"), exports);
|
|
16
|
+
__exportStar(require("./node"), exports);
|
|
17
|
+
__exportStar(require("./client"), exports);
|
|
18
|
+
__exportStar(require("./user"), exports);
|
|
19
|
+
var utilities_1 = require("./utilities");
|
|
20
|
+
Object.defineProperty(exports, "SUPPORTED_REGIONS", { enumerable: true, get: function () { return utilities_1.SUPPORTED_REGIONS; } });
|
|
21
|
+
Object.defineProperty(exports, "SUPPORTED_AVAILABILITY_ZONES", { enumerable: true, get: function () { return utilities_1.SUPPORTED_AVAILABILITY_ZONES; } });
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHFFQUFxRTtBQUNyRSxpQ0FBaUM7Ozs7Ozs7Ozs7OztBQUdqQyw0Q0FBMEI7QUFDMUIseUNBQXVCO0FBQ3ZCLDJDQUF5QjtBQUN6Qix5Q0FBdUI7QUFFdkIseUNBQThFO0FBQXJFLDhHQUFBLGlCQUFpQixPQUFBO0FBQUUseUhBQUEsNEJBQTRCLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVQtMFxuXG5cbmV4cG9ydCAqIGZyb20gJy4vbmV0d29yayc7XG5leHBvcnQgKiBmcm9tICcuL25vZGUnO1xuZXhwb3J0ICogZnJvbSAnLi9jbGllbnQnO1xuZXhwb3J0ICogZnJvbSAnLi91c2VyJztcblxuZXhwb3J0IHsgU1VQUE9SVEVEX1JFR0lPTlMsIFNVUFBPUlRFRF9BVkFJTEFCSUxJVFlfWk9ORVMgfSBmcm9tICcuL3V0aWxpdGllcyc7XG4iXX0=
|
package/lib/network.d.ts
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
|
|
2
|
+
import * as constructs from 'constructs';
|
|
3
|
+
import * as client from './client';
|
|
4
|
+
import * as node from './node';
|
|
5
|
+
import * as user from './user';
|
|
6
|
+
export declare enum FrameworkVersion {
|
|
7
|
+
VERSION_1_2 = "1.2",
|
|
8
|
+
VERSION_1_4 = "1.4",
|
|
9
|
+
VERSION_2_2 = "2.2"
|
|
10
|
+
}
|
|
11
|
+
export declare enum NetworkEdition {
|
|
12
|
+
STARTER = "STARTER",
|
|
13
|
+
STANDARD = "STANDARD"
|
|
14
|
+
}
|
|
15
|
+
export declare enum ThresholdComparator {
|
|
16
|
+
GREATER_THAN = "GREATER_THAN",
|
|
17
|
+
GREATER_THAN_OR_EQUAL_TO = "GREATER_THAN_OR_EQUAL_TO"
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Construct properties for `HyperledgerFabricNetwork`
|
|
21
|
+
*/
|
|
22
|
+
export interface HyperledgerFabricNetworkProps {
|
|
23
|
+
/**
|
|
24
|
+
* Managed Blockchain network name
|
|
25
|
+
*/
|
|
26
|
+
readonly networkName: string;
|
|
27
|
+
/**
|
|
28
|
+
* Managed Blockchain network description
|
|
29
|
+
*
|
|
30
|
+
* @default - Set to match network name
|
|
31
|
+
*/
|
|
32
|
+
readonly networkDescription?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Managed Blockchain member name
|
|
35
|
+
*/
|
|
36
|
+
readonly memberName: string;
|
|
37
|
+
/**
|
|
38
|
+
* Managed Blockchain member description
|
|
39
|
+
*
|
|
40
|
+
* @default - Set to match member name
|
|
41
|
+
*/
|
|
42
|
+
readonly memberDescription?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Hyperledger Fabric framework version
|
|
45
|
+
*
|
|
46
|
+
* @default - FrameworkVersion.VERSION_1_4
|
|
47
|
+
*/
|
|
48
|
+
readonly frameworkVersion?: FrameworkVersion;
|
|
49
|
+
/**
|
|
50
|
+
* Managed Blockchain network edition
|
|
51
|
+
*
|
|
52
|
+
* @default - NetworkEdition.STANDARD
|
|
53
|
+
*/
|
|
54
|
+
readonly networkEdition?: NetworkEdition;
|
|
55
|
+
/**
|
|
56
|
+
* The duration from the time that a proposal is created until it expires
|
|
57
|
+
* @default - 24 hours
|
|
58
|
+
*/
|
|
59
|
+
readonly proposalDurationInHours?: number;
|
|
60
|
+
/**
|
|
61
|
+
* The percentage of votes among all members that must be yes for a proposal to be approved
|
|
62
|
+
* @default - 50 percent
|
|
63
|
+
*/
|
|
64
|
+
readonly thresholdPercentage?: number;
|
|
65
|
+
/**
|
|
66
|
+
* Determines whether the yes votes must be greater than the threshold percentage
|
|
67
|
+
* or must be greater than or equal to the threhold percentage to be approved
|
|
68
|
+
* @default - GREATER_THAN
|
|
69
|
+
*/
|
|
70
|
+
readonly thresholdComparator?: ThresholdComparator;
|
|
71
|
+
/**
|
|
72
|
+
* The configuration to enable or disable certificate authority logging
|
|
73
|
+
* @default - true
|
|
74
|
+
*/
|
|
75
|
+
readonly enableCaLogging?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* List of nodes to create on the network
|
|
78
|
+
*
|
|
79
|
+
* @default - One node with default configuration
|
|
80
|
+
*/
|
|
81
|
+
readonly nodes?: Array<node.HyperledgerFabricNodeProps>;
|
|
82
|
+
/**
|
|
83
|
+
* The Client network to interact with the Hyperledger Fabric network
|
|
84
|
+
* @default - Client network with Default properties
|
|
85
|
+
* (CIDR-`10.0.0.0/16` and subnets of type `PRIVATE_ISOLATED`)
|
|
86
|
+
*/
|
|
87
|
+
readonly client?: client.HyperledgerFabricClientProps;
|
|
88
|
+
/**
|
|
89
|
+
* List of users to register with Fabric CA
|
|
90
|
+
*/
|
|
91
|
+
readonly users?: Array<user.HyperledgerFabricUserProps>;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Creates a Hyperledger Fabric network on Amazon Managed Blockchain
|
|
95
|
+
*/
|
|
96
|
+
export declare class HyperledgerFabricNetwork extends constructs.Construct {
|
|
97
|
+
/**
|
|
98
|
+
* Managed Blockchain network name
|
|
99
|
+
*/
|
|
100
|
+
readonly networkName: string;
|
|
101
|
+
/**
|
|
102
|
+
* Managed Blockchain network description
|
|
103
|
+
*/
|
|
104
|
+
readonly networkDescription: string;
|
|
105
|
+
/**
|
|
106
|
+
* Managed Blockchain network identifier generated on construction
|
|
107
|
+
*/
|
|
108
|
+
readonly networkId: string;
|
|
109
|
+
/**
|
|
110
|
+
* Managed Blockchain member name
|
|
111
|
+
*/
|
|
112
|
+
readonly memberName: string;
|
|
113
|
+
/**
|
|
114
|
+
* Managed Blockchain member description
|
|
115
|
+
*/
|
|
116
|
+
readonly memberDescription: string;
|
|
117
|
+
/**
|
|
118
|
+
* Managed Blockchain member identifier generated on construction
|
|
119
|
+
*/
|
|
120
|
+
readonly memberId: string;
|
|
121
|
+
/**
|
|
122
|
+
* Hyperledger Fabric framework version
|
|
123
|
+
*/
|
|
124
|
+
readonly frameworkVersion: FrameworkVersion;
|
|
125
|
+
/**
|
|
126
|
+
* Managed Blockchain network edition
|
|
127
|
+
*/
|
|
128
|
+
readonly networkEdition: NetworkEdition;
|
|
129
|
+
/**
|
|
130
|
+
* The duration from the time that a proposal is created until it expires
|
|
131
|
+
*/
|
|
132
|
+
readonly proposalDurationInHours: number;
|
|
133
|
+
/**
|
|
134
|
+
* The percentage of votes among all members that must be yes for a proposal to be approved
|
|
135
|
+
*/
|
|
136
|
+
readonly thresholdPercentage: number;
|
|
137
|
+
/**
|
|
138
|
+
* Determines whether the yes votes must be greater than the threshold percentage
|
|
139
|
+
* or must be greater than or equal to the threhold percentage to be approved
|
|
140
|
+
*/
|
|
141
|
+
readonly thresholdComparator: ThresholdComparator;
|
|
142
|
+
/**
|
|
143
|
+
* The configuration to enable or disable certificate authority logging
|
|
144
|
+
*/
|
|
145
|
+
readonly enableCaLogging: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Managed Blockchain network VPC endpoint service name
|
|
148
|
+
*/
|
|
149
|
+
readonly vpcEndpointServiceName: string;
|
|
150
|
+
/**
|
|
151
|
+
* Managed Blockchain network ordering service endpoint
|
|
152
|
+
*/
|
|
153
|
+
readonly ordererEndpoint: string;
|
|
154
|
+
/**
|
|
155
|
+
* Managed Blockchain member CA endpoint
|
|
156
|
+
*/
|
|
157
|
+
readonly caEndpoint: string;
|
|
158
|
+
/**
|
|
159
|
+
* Secret ARN for the Hyperledger Fabric admin password
|
|
160
|
+
*/
|
|
161
|
+
readonly adminPasswordSecret: secretsmanager.Secret;
|
|
162
|
+
/**
|
|
163
|
+
* Secret for Hyperledger Fabric admin private key
|
|
164
|
+
*/
|
|
165
|
+
readonly adminPrivateKeySecret: secretsmanager.Secret;
|
|
166
|
+
/**
|
|
167
|
+
* Secret for Hyperledger Fabric admin signed certificate
|
|
168
|
+
*/
|
|
169
|
+
readonly adminSignedCertSecret: secretsmanager.Secret;
|
|
170
|
+
/**
|
|
171
|
+
* List of nodes created in the network
|
|
172
|
+
*/
|
|
173
|
+
readonly nodes: Array<node.HyperledgerFabricNode>;
|
|
174
|
+
/**
|
|
175
|
+
* The client network to interact with the Hyperledger Fabric network
|
|
176
|
+
*/
|
|
177
|
+
readonly client: client.HyperledgerFabricClient;
|
|
178
|
+
/**
|
|
179
|
+
* List of users registered with CA
|
|
180
|
+
*/
|
|
181
|
+
readonly users: Array<user.HyperledgerFabricUser>;
|
|
182
|
+
constructor(scope: constructs.Construct, id: string, props: HyperledgerFabricNetworkProps);
|
|
183
|
+
}
|
package/lib/network.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.HyperledgerFabricNetwork = exports.ThresholdComparator = exports.NetworkEdition = exports.FrameworkVersion = void 0;
|
|
5
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
6
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
7
|
+
// SPDX-License-Identifier: MIT-0
|
|
8
|
+
const cdk = require("aws-cdk-lib");
|
|
9
|
+
const managedblockchain = require("aws-cdk-lib/aws-managedblockchain");
|
|
10
|
+
const secretsmanager = require("aws-cdk-lib/aws-secretsmanager");
|
|
11
|
+
const customresources = require("aws-cdk-lib/custom-resources");
|
|
12
|
+
const constructs = require("constructs");
|
|
13
|
+
const client = require("./client");
|
|
14
|
+
const identity = require("./identity");
|
|
15
|
+
const node = require("./node");
|
|
16
|
+
const user = require("./user");
|
|
17
|
+
const utilities = require("./utilities");
|
|
18
|
+
/*
|
|
19
|
+
* Define which Hyperledger Fabric framework to use
|
|
20
|
+
*/
|
|
21
|
+
var FrameworkVersion;
|
|
22
|
+
(function (FrameworkVersion) {
|
|
23
|
+
FrameworkVersion["VERSION_1_2"] = "1.2";
|
|
24
|
+
FrameworkVersion["VERSION_1_4"] = "1.4";
|
|
25
|
+
FrameworkVersion["VERSION_2_2"] = "2.2";
|
|
26
|
+
})(FrameworkVersion = exports.FrameworkVersion || (exports.FrameworkVersion = {}));
|
|
27
|
+
/*
|
|
28
|
+
* Starter networks are cheaper, but are limited to 2 nodes that
|
|
29
|
+
* can only be from a subset of types (see node.ts for the list)
|
|
30
|
+
*/
|
|
31
|
+
var NetworkEdition;
|
|
32
|
+
(function (NetworkEdition) {
|
|
33
|
+
NetworkEdition["STARTER"] = "STARTER";
|
|
34
|
+
NetworkEdition["STANDARD"] = "STANDARD";
|
|
35
|
+
})(NetworkEdition = exports.NetworkEdition || (exports.NetworkEdition = {}));
|
|
36
|
+
/*
|
|
37
|
+
* Constants to define ties in voting for new members
|
|
38
|
+
*/
|
|
39
|
+
var ThresholdComparator;
|
|
40
|
+
(function (ThresholdComparator) {
|
|
41
|
+
ThresholdComparator["GREATER_THAN"] = "GREATER_THAN";
|
|
42
|
+
ThresholdComparator["GREATER_THAN_OR_EQUAL_TO"] = "GREATER_THAN_OR_EQUAL_TO";
|
|
43
|
+
})(ThresholdComparator = exports.ThresholdComparator || (exports.ThresholdComparator = {}));
|
|
44
|
+
/**
|
|
45
|
+
* Creates a Hyperledger Fabric network on Amazon Managed Blockchain
|
|
46
|
+
*/
|
|
47
|
+
class HyperledgerFabricNetwork extends constructs.Construct {
|
|
48
|
+
constructor(scope, id, props) {
|
|
49
|
+
super(scope, id);
|
|
50
|
+
// Collect metadata on the stack
|
|
51
|
+
const partition = cdk.Stack.of(this).partition;
|
|
52
|
+
const region = cdk.Stack.of(this).region;
|
|
53
|
+
const account = cdk.Stack.of(this).account;
|
|
54
|
+
// Populate instance variables from input properties, using defaults if values not provided
|
|
55
|
+
this.networkName = props.networkName;
|
|
56
|
+
this.networkDescription = props.networkDescription ?? props.networkName;
|
|
57
|
+
this.memberName = props.memberName;
|
|
58
|
+
this.memberDescription = props.memberDescription ?? props.memberName;
|
|
59
|
+
this.frameworkVersion = props.frameworkVersion ?? FrameworkVersion.VERSION_1_4;
|
|
60
|
+
this.networkEdition = props.networkEdition ?? NetworkEdition.STANDARD;
|
|
61
|
+
this.proposalDurationInHours = props.proposalDurationInHours ?? 24;
|
|
62
|
+
this.thresholdPercentage = props.thresholdPercentage ?? 50;
|
|
63
|
+
this.thresholdComparator = props.thresholdComparator ?? ThresholdComparator.GREATER_THAN;
|
|
64
|
+
this.enableCaLogging = props.enableCaLogging ?? true;
|
|
65
|
+
this.users = [];
|
|
66
|
+
// Ensure the parameters captured above are valid, so we don't
|
|
67
|
+
// need to wait until deployment time to discover an error
|
|
68
|
+
utilities.validateRegion(region);
|
|
69
|
+
if (!utilities.validateString(this.networkName, 1, 64)) {
|
|
70
|
+
throw new Error('Network name is invalid or not provided. It can be up to 64 characters long.');
|
|
71
|
+
}
|
|
72
|
+
if (!utilities.validateString(this.networkDescription, 0, 128)) {
|
|
73
|
+
throw new Error('Network description is invalid. It can be up to 128 characters long.');
|
|
74
|
+
}
|
|
75
|
+
if (!utilities.validateString(this.memberName, 1, 64, /^(?!-|[0-9])(?!.*-$)(?!.*?--)[a-zA-Z0-9-]+$/)) {
|
|
76
|
+
throw new Error('Member name is invalid or not provided. It can be up to 64 characters long, and can have alphanumeric characters and hyphen(s). It cannot start with a number, or start and end with a hyphen (-), or have two consecutive hyphens. The member name must also be unique across the network.');
|
|
77
|
+
}
|
|
78
|
+
if (!utilities.validateString(this.memberDescription, 0, 128)) {
|
|
79
|
+
throw new Error('Member description is invalid. It can be up to 128 characters long.');
|
|
80
|
+
}
|
|
81
|
+
if (!utilities.validateInteger(this.proposalDurationInHours, 1, 168)) {
|
|
82
|
+
throw new Error('Voting policy proposal duration must be between 1 and 168 hours.');
|
|
83
|
+
}
|
|
84
|
+
if (!utilities.validateInteger(this.thresholdPercentage, 0, 100)) {
|
|
85
|
+
throw new Error('Voting policy threshold percentage must be between 0 and 100.');
|
|
86
|
+
}
|
|
87
|
+
// Ensure the user affiliation includes the member name,
|
|
88
|
+
// if the user list for registration is provided
|
|
89
|
+
if (props.users) {
|
|
90
|
+
props.users.forEach(e => {
|
|
91
|
+
if (!e.affilitation.startsWith(this.memberName))
|
|
92
|
+
throw new Error('User affiliation is invalid. Affiliation should start with Member name');
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
// Per the Managed Blockchain documentation, the admin password must be at least eight
|
|
96
|
+
// characters long and no more than 32 characters. It must contain at least one uppercase
|
|
97
|
+
// letter, one lowercase letter, and one digit. It cannot have a single quotation mark (‘),
|
|
98
|
+
// a double quotation marks (“), a forward slash(/), a backward slash(\), @, or a space;
|
|
99
|
+
// several other characters are exluded here to make the password easier to use in scripts
|
|
100
|
+
const passwordRequirements = {
|
|
101
|
+
passwordLength: 32,
|
|
102
|
+
requireEachIncludedType: true,
|
|
103
|
+
excludeCharacters: '\'"/\\@ &{}<>*|',
|
|
104
|
+
};
|
|
105
|
+
this.adminPasswordSecret = new secretsmanager.Secret(this, 'AdminPassword', { generateSecretString: passwordRequirements });
|
|
106
|
+
// The initially enrolled admin user credentials will be stored in these secrets
|
|
107
|
+
this.adminPrivateKeySecret = new secretsmanager.Secret(this, 'AdminPrivateKey');
|
|
108
|
+
this.adminSignedCertSecret = new secretsmanager.Secret(this, 'AdminSignedCert');
|
|
109
|
+
// Build out the Cloudformation construct for the network/member
|
|
110
|
+
const networkConfiguration = {
|
|
111
|
+
name: this.networkName,
|
|
112
|
+
description: this.networkDescription,
|
|
113
|
+
framework: 'HYPERLEDGER_FABRIC',
|
|
114
|
+
frameworkVersion: this.frameworkVersion,
|
|
115
|
+
networkFrameworkConfiguration: {
|
|
116
|
+
networkFabricConfiguration: {
|
|
117
|
+
edition: this.networkEdition,
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
votingPolicy: {
|
|
121
|
+
approvalThresholdPolicy: {
|
|
122
|
+
proposalDurationInHours: this.proposalDurationInHours,
|
|
123
|
+
thresholdPercentage: this.thresholdPercentage,
|
|
124
|
+
thresholdComparator: this.thresholdComparator,
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
// Note the use of the unwrap below is the only possible way to get
|
|
129
|
+
// the secret value into the CloudFormation; it will still not directly
|
|
130
|
+
// be included in the synthesized template so usage here is still safe
|
|
131
|
+
const memberConfiguration = {
|
|
132
|
+
name: this.memberName,
|
|
133
|
+
description: this.memberDescription,
|
|
134
|
+
memberFrameworkConfiguration: {
|
|
135
|
+
memberFabricConfiguration: {
|
|
136
|
+
adminUsername: 'admin',
|
|
137
|
+
adminPassword: this.adminPasswordSecret.secretValue.unsafeUnwrap(),
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
const network = new managedblockchain.CfnMember(this, 'Network', { networkConfiguration, memberConfiguration });
|
|
142
|
+
// Capture data included in the Cloudformation output in instance variables
|
|
143
|
+
this.networkId = network.getAtt('NetworkId').toString();
|
|
144
|
+
this.memberId = network.getAtt('MemberId').toString();
|
|
145
|
+
// Build out the associated node constructs
|
|
146
|
+
this.nodes = node.HyperledgerFabricNode.constructNodes(this, props.nodes);
|
|
147
|
+
// Due to a race condition in CDK custom resources (https://github.com/aws/aws-cdk/issues/18237),
|
|
148
|
+
// the necessary permissions for all SDK calls in the stack need to be added here, even though
|
|
149
|
+
// the calls in this construct don't need access to the nodes; this also means node constructs
|
|
150
|
+
// can't populate their outputs fully until later, which is annoying
|
|
151
|
+
const nodeIds = this.nodes.map(n => n.nodeId);
|
|
152
|
+
const nodeArns = nodeIds.map(i => `arn:${partition}:managedblockchain:${region}:${account}:nodes/${i}`);
|
|
153
|
+
const sdkCallPolicy = customresources.AwsCustomResourcePolicy.fromSdkCalls({
|
|
154
|
+
resources: [
|
|
155
|
+
`arn:${partition}:managedblockchain:${region}::networks/${this.networkId}`,
|
|
156
|
+
`arn:${partition}:managedblockchain:${region}:${account}:members/${this.memberId}`,
|
|
157
|
+
...nodeArns,
|
|
158
|
+
],
|
|
159
|
+
});
|
|
160
|
+
// Cloudformation doesn't include all the network and member attributes
|
|
161
|
+
// needed to use Hyperledger Fabric, so use SDK calls to fetch said data
|
|
162
|
+
const networkDataSdkCall = {
|
|
163
|
+
service: 'ManagedBlockchain',
|
|
164
|
+
action: 'getNetwork',
|
|
165
|
+
parameters: { NetworkId: this.networkId },
|
|
166
|
+
physicalResourceId: customresources.PhysicalResourceId.of('Id'),
|
|
167
|
+
};
|
|
168
|
+
const memberDataSdkCall = {
|
|
169
|
+
service: 'ManagedBlockchain',
|
|
170
|
+
action: 'getMember',
|
|
171
|
+
parameters: { NetworkId: this.networkId, MemberId: this.memberId },
|
|
172
|
+
physicalResourceId: customresources.PhysicalResourceId.of('Id'),
|
|
173
|
+
};
|
|
174
|
+
// Data items need fetching on creation and updating; nothing needs doing on deletion
|
|
175
|
+
const networkData = new customresources.AwsCustomResource(this, 'NetworkDataResource', {
|
|
176
|
+
policy: sdkCallPolicy,
|
|
177
|
+
onCreate: networkDataSdkCall,
|
|
178
|
+
onUpdate: networkDataSdkCall,
|
|
179
|
+
});
|
|
180
|
+
const memberData = new customresources.AwsCustomResource(this, 'MemberDataResource', {
|
|
181
|
+
policy: sdkCallPolicy,
|
|
182
|
+
onCreate: memberDataSdkCall,
|
|
183
|
+
onUpdate: memberDataSdkCall,
|
|
184
|
+
});
|
|
185
|
+
// Cloudformation doesn't include logging configuration so use SDK call to do so
|
|
186
|
+
const logConfiguration = {
|
|
187
|
+
Fabric: { CaLogs: { Cloudwatch: { Enabled: this.enableCaLogging } } },
|
|
188
|
+
};
|
|
189
|
+
const configureCaLogSdkCall = {
|
|
190
|
+
service: 'ManagedBlockchain',
|
|
191
|
+
action: 'updateMember',
|
|
192
|
+
parameters: { NetworkId: this.networkId, MemberId: this.memberId, LogPublishingConfiguration: logConfiguration },
|
|
193
|
+
physicalResourceId: customresources.PhysicalResourceId.of('Id'),
|
|
194
|
+
};
|
|
195
|
+
new customresources.AwsCustomResource(this, 'ConfigureCaLogResource', {
|
|
196
|
+
policy: sdkCallPolicy,
|
|
197
|
+
onCreate: configureCaLogSdkCall,
|
|
198
|
+
onUpdate: configureCaLogSdkCall,
|
|
199
|
+
});
|
|
200
|
+
// Grab items out of the above return values and stick them in output properties
|
|
201
|
+
this.vpcEndpointServiceName = networkData.getResponseField('Network.VpcEndpointServiceName');
|
|
202
|
+
this.ordererEndpoint = networkData.getResponseField('Network.FrameworkAttributes.Fabric.OrderingServiceEndpoint');
|
|
203
|
+
this.caEndpoint = memberData.getResponseField('Member.FrameworkAttributes.Fabric.CaEndpoint');
|
|
204
|
+
// As stated earlier, node constructs can't populate all their properties
|
|
205
|
+
// until after the above network and member SDK calls succeed; thus the
|
|
206
|
+
// function calls below where fetches are split out and logging is configured
|
|
207
|
+
for (const n of this.nodes) {
|
|
208
|
+
n.configureLogging(sdkCallPolicy);
|
|
209
|
+
n.fetchData(sdkCallPolicy);
|
|
210
|
+
}
|
|
211
|
+
// Build out the client VPC construct
|
|
212
|
+
this.client = new client.HyperledgerFabricClient(this, 'NetworkClient', props.client);
|
|
213
|
+
// Build out all the custom resources to register and enroll identities to CA
|
|
214
|
+
const identityResources = new identity.HyperledgerFabricIdentity(this, 'Identity');
|
|
215
|
+
// Enroll the administrator and store its credentials on Secrets Manager
|
|
216
|
+
new cdk.CustomResource(this, 'AdminCustomResource', { serviceToken: identityResources.adminProvider.serviceToken });
|
|
217
|
+
// Register and enroll users, if provided
|
|
218
|
+
if (props.users)
|
|
219
|
+
this.users = Array.from(props.users.entries()).map(e => new user.HyperledgerFabricUser(this, `User${e[0]}`, e[1]));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
exports.HyperledgerFabricNetwork = HyperledgerFabricNetwork;
|
|
223
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
224
|
+
HyperledgerFabricNetwork[_a] = { fqn: "@cdklabs/cdk-hyperledger-fabric-network.HyperledgerFabricNetwork", version: "0.0.20" };
|
|
225
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV0d29yay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9uZXR3b3JrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEscUVBQXFFO0FBQ3JFLGlDQUFpQztBQUdqQyxtQ0FBbUM7QUFDbkMsdUVBQXVFO0FBQ3ZFLGlFQUFpRTtBQUNqRSxnRUFBZ0U7QUFDaEUseUNBQXlDO0FBRXpDLG1DQUFtQztBQUNuQyx1Q0FBdUM7QUFDdkMsK0JBQStCO0FBQy9CLCtCQUErQjtBQUMvQix5Q0FBeUM7QUFHekM7O0dBRUc7QUFDSCxJQUFZLGdCQUlYO0FBSkQsV0FBWSxnQkFBZ0I7SUFDMUIsdUNBQW1CLENBQUE7SUFDbkIsdUNBQW1CLENBQUE7SUFDbkIsdUNBQW1CLENBQUE7QUFDckIsQ0FBQyxFQUpXLGdCQUFnQixHQUFoQix3QkFBZ0IsS0FBaEIsd0JBQWdCLFFBSTNCO0FBRUQ7OztHQUdHO0FBQ0gsSUFBWSxjQUdYO0FBSEQsV0FBWSxjQUFjO0lBQ3hCLHFDQUFtQixDQUFBO0lBQ25CLHVDQUFxQixDQUFBO0FBQ3ZCLENBQUMsRUFIVyxjQUFjLEdBQWQsc0JBQWMsS0FBZCxzQkFBYyxRQUd6QjtBQUVEOztHQUVHO0FBQ0gsSUFBWSxtQkFHWDtBQUhELFdBQVksbUJBQW1CO0lBQzdCLG9EQUE2QixDQUFBO0lBQzdCLDRFQUFxRCxDQUFBO0FBQ3ZELENBQUMsRUFIVyxtQkFBbUIsR0FBbkIsMkJBQW1CLEtBQW5CLDJCQUFtQixRQUc5QjtBQTZGRDs7R0FFRztBQUNILE1BQWEsd0JBQXlCLFNBQVEsVUFBVSxDQUFDLFNBQVM7SUE2R2hFLFlBQVksS0FBMkIsRUFBRSxFQUFVLEVBQUUsS0FBb0M7UUFFdkYsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixnQ0FBZ0M7UUFDaEMsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDO1FB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QUF1RTtRQUN2RSw2RUFBNkU7UUFDN0UsS0FBSyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQzFCLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNsQyxDQUFDLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1NBQzVCO1FBRUQscUNBQXFDO1FBQ3JDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsdUJBQXVCLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFdEYsNkVBQTZFO1FBQzdFLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxRQUFRLENBQUMseUJBQXlCLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBRW5GLHdFQUF3RTtRQUN4RSxJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLHFCQUFxQixFQUFFLEVBQUUsWUFBWSxFQUFFLGlCQUFpQixDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1FBRXBILHlDQUF5QztRQUN6QyxJQUFJLEtBQUssQ0FBQyxLQUFLO1lBQUUsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3RJLENBQUM7O0FBNVNILDREQThTQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCBBbWF6b24uY29tLCBJbmMuIG9yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVC0wXG5cblxuaW1wb3J0ICogYXMgY2RrIGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIG1hbmFnZWRibG9ja2NoYWluIGZyb20gJ2F3cy1jZGstbGliL2F3cy1tYW5hZ2VkYmxvY2tjaGFpbic7XG5pbXBvcnQgKiBhcyBzZWNyZXRzbWFuYWdlciBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtc2VjcmV0c21hbmFnZXInO1xuaW1wb3J0ICogYXMgY3VzdG9tcmVzb3VyY2VzIGZyb20gJ2F3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXMnO1xuaW1wb3J0ICogYXMgY29uc3RydWN0cyBmcm9tICdjb25zdHJ1Y3RzJztcblxuaW1wb3J0ICogYXMgY2xpZW50IGZyb20gJy4vY2xpZW50JztcbmltcG9ydCAqIGFzIGlkZW50aXR5IGZyb20gJy4vaWRlbnRpdHknO1xuaW1wb3J0ICogYXMgbm9kZSBmcm9tICcuL25vZGUnO1xuaW1wb3J0ICogYXMgdXNlciBmcm9tICcuL3VzZXInO1xuaW1wb3J0ICogYXMgdXRpbGl0aWVzIGZyb20gJy4vdXRpbGl0aWVzJztcblxuXG4vKlxuICogRGVmaW5lIHdoaWNoIEh5cGVybGVkZ2VyIEZhYnJpYyBmcmFtZXdvcmsgdG8gdXNlXG4gKi9cbmV4cG9ydCBlbnVtIEZyYW1ld29ya1ZlcnNpb24ge1xuICBWRVJTSU9OXzFfMiA9ICcxLjInLFxuICBWRVJTSU9OXzFfNCA9ICcxLjQnLFxuICBWRVJTSU9OXzJfMiA9ICcyLjInLFxufVxuXG4vKlxuICogU3RhcnRlciBuZXR3b3JrcyBhcmUgY2hlYXBlciwgYnV0IGFyZSBsaW1pdGVkIHRvIDIgbm9kZXMgdGhhdFxuICogY2FuIG9ubHkgYmUgZnJvbSBhIHN1YnNldCBvZiB0eXBlcyAoc2VlIG5vZGUudHMgZm9yIHRoZSBsaXN0KVxuICovXG5leHBvcnQgZW51bSBOZXR3b3JrRWRpdGlvbiB7XG4gIFNUQVJURVIgPSAnU1RBUlRFUicsXG4gIFNUQU5EQVJEID0gJ1NUQU5EQVJEJyxcbn1cblxuLypcbiAqIENvbnN0YW50cyB0byBkZWZpbmUgdGllcyBpbiB2b3RpbmcgZm9yIG5ldyBtZW1iZXJzXG4gKi9cbmV4cG9ydCBlbnVtIFRocmVzaG9sZENvbXBhcmF0b3Ige1xuICBHUkVBVEVSX1RIQU4gPSAnR1JFQVRFUl9USEFOJyxcbiAgR1JFQVRFUl9USEFOX09SX0VRVUFMX1RPID0gJ0dSRUFURVJfVEhBTl9PUl9FUVVBTF9UTycsXG59XG5cblxuLyoqXG4gKiBDb25zdHJ1Y3QgcHJvcGVydGllcyBmb3IgYEh5cGVybGVkZ2VyRmFicmljTmV0d29ya2BcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIeXBlcmxlZGdlckZhYnJpY05ldHdvcmtQcm9wcyB7XG5cbiAgLyoqXG4gICAqIE1hbmFnZWQgQmxvY2tjaGFpbiBuZXR3b3JrIG5hbWVcbiAgICovXG4gIHJlYWRvbmx5IG5ldHdvcmtOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE1hbmFnZWQgQmxvY2tjaGFpbiBuZXR3b3JrIGRlc2NyaXB0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gU2V0IHRvIG1hdGNoIG5ldHdvcmsgbmFtZVxuICAgKi9cbiAgcmVhZG9ubHkgbmV0d29ya0Rlc2NyaXB0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBNYW5hZ2VkIEJsb2NrY2hhaW4gbWVtYmVyIG5hbWVcbiAgICovXG4gIHJlYWRvbmx5IG1lbWJlck5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogTWFuYWdlZCBCbG9ja2NoYWluIG1lbWJlciBkZXNjcmlwdGlvblxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFNldCB0byBtYXRjaCBtZW1iZXIgbmFtZVxuICAgKi9cbiAgcmVhZG9ubHkgbWVtYmVyRGVzY3JpcHRpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEh5cGVybGVkZ2VyIEZhYnJpYyBmcmFtZXdvcmsgdmVyc2lvblxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEZyYW1ld29ya1ZlcnNpb24uVkVSU0lPTl8xXzRcbiAgICovXG4gIHJlYWRvbmx5IGZyYW1ld29ya1ZlcnNpb24/OiBGcmFtZXdvcmtWZXJzaW9uO1xuXG4gIC8qKlxuICAgKiBNYW5hZ2VkIEJsb2NrY2hhaW4gbmV0d29yayBlZGl0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTmV0d29ya0VkaXRpb24uU1RBTkRBUkRcbiAgICovXG4gIHJlYWRvbmx5IG5ldHdvcmtFZGl0aW9uPzogTmV0d29ya0VkaXRpb247XG5cbiAgLyoqXG4gICAqIFRoZSBkdXJhdGlvbiBmcm9tIHRoZSB0aW1lIHRoYXQgYSBwcm9wb3NhbCBpcyBjcmVhdGVkIHVudGlsIGl0IGV4cGlyZXNcbiAgICogQGRlZmF1bHQgLSAyNCBob3Vyc1xuICAgKi9cbiAgcmVhZG9ubHkgcHJvcG9zYWxEdXJhdGlvbkluSG91cnM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBwZXJjZW50YWdlIG9mIHZvdGVzIGFtb25nIGFsbCBtZW1iZXJzIHRoYXQgbXVzdCBiZSB5ZXMgZm9yIGEgcHJvcG9zYWwgdG8gYmUgYXBwcm92ZWRcbiAgICogQGRlZmF1bHQgLSA1MCBwZXJjZW50XG4gICAqL1xuICByZWFkb25seSB0aHJlc2hvbGRQZXJjZW50YWdlPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHllcyB2b3RlcyBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB0aGUgdGhyZXNob2xkIHBlcmNlbnRhZ2VcbiAgICogb3IgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHRocmVob2xkIHBlcmNlbnRhZ2UgdG8gYmUgYXBwcm92ZWRcbiAgICogQGRlZmF1bHQgLSBHUkVBVEVSX1RIQU5cbiAgICovXG4gIHJlYWRvbmx5IHRocmVzaG9sZENvbXBhcmF0b3I/OiBUaHJlc2hvbGRDb21wYXJhdG9yO1xuXG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJhdGlvbiB0byBlbmFibGUgb3IgZGlzYWJsZSBjZXJ0aWZpY2F0ZSBhdXRob3JpdHkgbG9nZ2luZ1xuICAgKiBAZGVmYXVsdCAtIHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGVuYWJsZUNhTG9nZ2luZz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIExpc3Qgb2Ygbm9kZXMgdG8gY3JlYXRlIG9uIHRoZSBuZXR3b3JrXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gT25lIG5vZGUgd2l0aCBkZWZhdWx0IGNvbmZpZ3VyYXRpb25cbiAgICovXG4gIHJlYWRvbmx5IG5vZGVzPzogQXJyYXk8bm9kZS5IeXBlcmxlZGdlckZhYnJpY05vZGVQcm9wcz47XG5cbiAgLyoqXG4gICAqIFRoZSBDbGllbnQgbmV0d29yayB0byBpbnRlcmFjdCB3aXRoIHRoZSBIeXBlcmxlZGdlciBGYWJyaWMgbmV0d29ya1xuICAgKiBAZGVmYXVsdCAtIENsaWVudCBuZXR3b3JrIHdpdGggRGVmYXVsdCBwcm9wZXJ0aWVzXG4gICAqIChDSURSLWAxMC4wLjAuMC8xNmAgYW5kIHN1Ym5ldHMgb2YgdHlwZSBgUFJJVkFURV9JU09MQVRFRGApXG4gICAqL1xuICByZWFkb25seSBjbGllbnQ/OiBjbGllbnQuSHlwZXJsZWRnZXJGYWJyaWNDbGllbnRQcm9wcztcblxuICAvKipcbiAgICogTGlzdCBvZiB1c2VycyB0byByZWdpc3RlciB3aXRoIEZhYnJpYyBDQVxuICAgKi9cbiAgcmVhZG9ubHkgdXNlcnM/OiBBcnJheTx1c2VyLkh5cGVybGVkZ2VyRmFicmljVXNlclByb3BzPjtcblxufVxuXG5cbi8qKlxuICogQ3JlYXRlcyBhIEh5cGVybGVkZ2VyIEZhYnJpYyBuZXR3b3JrIG9uIEFtYXpvbiBNYW5hZ2VkIEJsb2NrY2hhaW5cbiAqL1xuZXhwb3J0IGNsYXNzIEh5cGVybGVkZ2VyRmFicmljTmV0d29yayBleHRlbmRzIGNvbnN0cnVjdHMuQ29uc3RydWN0IHtcblxuICAvKipcbiAgICogTWFuYWdlZCBCbG9ja2NoYWluIG5ldHdvcmsgbmFtZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG5ldHdvcmtOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE1hbmFnZWQgQmxvY2tjaGFpbiBuZXR3b3JrIGRlc2NyaXB0aW9uXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbmV0d29ya0Rlc2NyaXB0aW9uOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE1hbmFnZWQgQmxvY2tjaGFpbiBuZXR3b3JrIGlkZW50aWZpZXIgZ2VuZXJhdGVkIG9uIGNvbnN0cnVjdGlvblxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG5ldHdvcmtJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBNYW5hZ2VkIEJsb2NrY2hhaW4gbWVtYmVyIG5hbWVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBtZW1iZXJOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE1hbmFnZWQgQmxvY2tjaGFpbiBtZW1iZXIgZGVzY3JpcHRpb25cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBtZW1iZXJEZXNjcmlwdGlvbjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBNYW5hZ2VkIEJsb2NrY2hhaW4gbWVtYmVyIGlkZW50aWZpZXIgZ2VuZXJhdGVkIG9uIGNvbnN0cnVjdGlvblxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG1lbWJlcklkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEh5cGVybGVkZ2VyIEZhYnJpYyBmcmFtZXdvcmsgdmVyc2lvblxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGZyYW1ld29ya1ZlcnNpb246IEZyYW1ld29ya1ZlcnNpb247XG5cbiAgLyoqXG4gICAqIE1hbmFnZWQgQmxvY2tjaGFpbiBuZXR3b3JrIGVkaXRpb25cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBuZXR3b3JrRWRpdGlvbjogTmV0d29ya0VkaXRpb247XG5cbiAgLyoqXG4gICAqIFRoZSBkdXJhdGlvbiBmcm9tIHRoZSB0aW1lIHRoYXQgYSBwcm9wb3NhbCBpcyBjcmVhdGVkIHVudGlsIGl0IGV4cGlyZXNcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBwcm9wb3NhbER1cmF0aW9uSW5Ib3VyczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgcGVyY2VudGFnZSBvZiB2b3RlcyBhbW9uZyBhbGwgbWVtYmVycyB0aGF0IG11c3QgYmUgeWVzIGZvciBhIHByb3Bvc2FsIHRvIGJlIGFwcHJvdmVkXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdGhyZXNob2xkUGVyY2VudGFnZTogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHllcyB2b3RlcyBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB0aGUgdGhyZXNob2xkIHBlcmNlbnRhZ2VcbiAgICogb3IgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHRocmVob2xkIHBlcmNlbnRhZ2UgdG8gYmUgYXBwcm92ZWRcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB0aHJlc2hvbGRDb21wYXJhdG9yOiBUaHJlc2hvbGRDb21wYXJhdG9yO1xuXG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJhdGlvbiB0byBlbmFibGUgb3IgZGlzYWJsZSBjZXJ0aWZpY2F0ZSBhdXRob3JpdHkgbG9nZ2luZ1xuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGVuYWJsZUNhTG9nZ2luZzogYm9vbGVhbjtcblxuICAvKipcbiAgICogTWFuYWdlZCBCbG9ja2NoYWluIG5ldHdvcmsgVlBDIGVuZHBvaW50IHNlcnZpY2UgbmFtZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHZwY0VuZHBvaW50U2VydmljZU5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogTWFuYWdlZCBCbG9ja2NoYWluIG5ldHdvcmsgb3JkZXJpbmcgc2VydmljZSBlbmRwb2ludFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG9yZGVyZXJFbmRwb2ludDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBNYW5hZ2VkIEJsb2NrY2hhaW4gbWVtYmVyIENBIGVuZHBvaW50XG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY2FFbmRwb2ludDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTZWNyZXQgQVJOIGZvciB0aGUgSHlwZXJsZWRnZXIgRmFicmljIGFkbWluIHBhc3N3b3JkXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYWRtaW5QYXNzd29yZFNlY3JldDogc2VjcmV0c21hbmFnZXIuU2VjcmV0O1xuXG4gIC8qKlxuICAgKiBTZWNyZXQgZm9yIEh5cGVybGVkZ2VyIEZhYnJpYyBhZG1pbiBwcml2YXRlIGtleVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFkbWluUHJpdmF0ZUtleVNlY3JldDogc2VjcmV0c21hbmFnZXIuU2VjcmV0O1xuXG4gIC8qKlxuICAgKiBTZWNyZXQgZm9yIEh5cGVybGVkZ2VyIEZhYnJpYyBhZG1pbiBzaWduZWQgY2VydGlmaWNhdGVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBhZG1pblNpZ25lZENlcnRTZWNyZXQ6IHNlY3JldHNtYW5hZ2VyLlNlY3JldDtcblxuICAvKipcbiAgICogTGlzdCBvZiBub2RlcyBjcmVhdGVkIGluIHRoZSBuZXR3b3JrXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbm9kZXM6IEFycmF5PG5vZGUuSHlwZXJsZWRnZXJGYWJyaWNOb2RlPjtcblxuICAvKipcbiAgICogVGhlIGNsaWVudCBuZXR3b3JrIHRvIGludGVyYWN0IHdpdGggdGhlIEh5cGVybGVkZ2VyIEZhYnJpYyBuZXR3b3JrXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY2xpZW50OiBjbGllbnQuSHlwZXJsZWRnZXJGYWJyaWNDbGllbnQ7XG5cbiAgLyoqXG4gICAqIExpc3Qgb2YgdXNlcnMgcmVnaXN0ZXJlZCB3aXRoIENBXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdXNlcnM6IEFycmF5PHVzZXIuSHlwZXJsZWRnZXJGYWJyaWNVc2VyPjtcblxuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBjb25zdHJ1Y3RzLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IEh5cGVybGVkZ2VyRmFicmljTmV0d29ya1Byb3BzKSB7XG5cbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgLy8gQ29sbGVjdCBtZXRhZGF0YSBvbiB0aGUgc3RhY2tcbiAgICBjb25zdCBwYXJ0aXRpb24gPSBjZGsuU3RhY2sub2YodGhpcykucGFydGl0aW9uO1xuICAgIGNvbnN0IHJlZ2lvbiA9IGNkay5TdGFjay5vZih0aGlzKS5yZWdpb247XG4gICAgY29uc3QgYWNjb3VudCA9IGNkay5TdGFjay5vZih0aGlzKS5hY2NvdW50O1xuXG4gICAgLy8gUG9wdWxhdGUgaW5zdGFuY2UgdmFyaWFibGVzIGZyb20gaW5wdXQgcHJvcGVydGllcywgdXNpbmcgZGVmYXVsdHMgaWYgdmFsdWVzIG5vdCBwcm92aWRlZFxuICAgIHRoaXMubmV0d29ya05hbWUgPSBwcm9wcy5uZXR3b3JrTmFtZTtcbiAgICB0aGlzLm5ldHdvcmtEZXNjcmlwdGlvbiA9IHByb3BzLm5ldHdvcmtEZXNjcmlwdGlvbiA/PyBwcm9wcy5uZXR3b3JrTmFtZTtcbiAgICB0aGlzLm1lbWJlck5hbWUgPSBwcm9wcy5tZW1iZXJOYW1lO1xuICAgIHRoaXMubWVtYmVyRGVzY3JpcHRpb24gPSBwcm9wcy5tZW1iZXJEZXNjcmlwdGlvbiA/PyBwcm9wcy5tZW1iZXJOYW1lO1xuICAgIHRoaXMuZnJhbWV3b3JrVmVyc2lvbiA9IHByb3BzLmZyYW1ld29ya1ZlcnNpb24gPz8gRnJhbWV3b3JrVmVyc2lvbi5WRVJTSU9OXzFfNDtcbiAgICB0aGlzLm5ldHdvcmtFZGl0aW9uID0gcHJvcHMubmV0d29ya0VkaXRpb24gPz8gTmV0d29ya0VkaXRpb24uU1RBTkRBUkQ7XG4gICAgdGhpcy5wcm9wb3NhbER1cmF0aW9uSW5Ib3VycyA9IHByb3BzLnByb3Bvc2FsRHVyYXRpb25JbkhvdXJzID8/IDI0O1xuICAgIHRoaXMudGhyZXNob2xkUGVyY2VudGFnZSA9IHByb3BzLnRocmVzaG9sZFBlcmNlbnRhZ2UgPz8gNTA7XG4gICAgdGhpcy50aHJlc2hvbGRDb21wYXJhdG9yID0gcHJvcHMudGhyZXNob2xkQ29tcGFyYXRvciA/PyBUaHJlc2hvbGRDb21wYXJhdG9yLkdSRUFURVJfVEhBTjtcbiAgICB0aGlzLmVuYWJsZUNhTG9nZ2luZyA9IHByb3BzLmVuYWJsZUNhTG9nZ2luZyA/PyB0cnVlO1xuICAgIHRoaXMudXNlcnMgPSBbXTtcblxuICAgIC8vIEVuc3VyZSB0aGUgcGFyYW1ldGVycyBjYXB0dXJlZCBhYm92ZSBhcmUgdmFsaWQsIHNvIHdlIGRvbid0XG4gICAgLy8gbmVlZCB0byB3YWl0IHVudGlsIGRlcGxveW1lbnQgdGltZSB0byBkaXNjb3ZlciBhbiBlcnJvclxuICAgIHV0aWxpdGllcy52YWxpZGF0ZVJlZ2lvbihyZWdpb24pO1xuICAgIGlmICghdXRpbGl0aWVzLnZhbGlkYXRlU3RyaW5nKHRoaXMubmV0d29ya05hbWUsIDEsIDY0KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOZXR3b3JrIG5hbWUgaXMgaW52YWxpZCBvciBub3QgcHJvdmlkZWQuIEl0IGNhbiBiZSB1cCB0byA2NCBjaGFyYWN0ZXJzIGxvbmcuJyk7XG4gICAgfVxuICAgIGlmICghdXRpbGl0aWVzLnZhbGlkYXRlU3RyaW5nKHRoaXMubmV0d29ya0Rlc2NyaXB0aW9uLCAwLCAxMjgpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05ldHdvcmsgZGVzY3JpcHRpb24gaXMgaW52YWxpZC4gSXQgY2FuIGJlIHVwIHRvIDEyOCBjaGFyYWN0ZXJzIGxvbmcuJyk7XG4gICAgfVxuICAgIGlmICghdXRpbGl0aWVzLnZhbGlkYXRlU3RyaW5nKHRoaXMubWVtYmVyTmFtZSwgMSwgNjQsIC9eKD8hLXxbMC05XSkoPyEuKi0kKSg/IS4qPy0tKVthLXpBLVowLTktXSskLykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWVtYmVyIG5hbWUgaXMgaW52YWxpZCBvciBub3QgcHJvdmlkZWQuIEl0IGNhbiBiZSB1cCB0byA2NCBjaGFyYWN0ZXJzIGxvbmcsIGFuZCBjYW4gaGF2ZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBhbmQgaHlwaGVuKHMpLiBJdCBjYW5ub3Qgc3RhcnQgd2l0aCBhIG51bWJlciwgb3Igc3RhcnQgYW5kIGVuZCB3aXRoIGEgaHlwaGVuICgtKSwgb3IgaGF2ZSB0d28gY29uc2VjdXRpdmUgaHlwaGVucy4gVGhlIG1lbWJlciBuYW1lIG11c3QgYWxzbyBiZSB1bmlxdWUgYWNyb3NzIHRoZSBuZXR3b3JrLicpO1xuICAgIH1cbiAgICBpZiAoIXV0aWxpdGllcy52YWxpZGF0ZVN0cmluZyh0aGlzLm1lbWJlckRlc2NyaXB0aW9uLCAwLCAxMjgpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01lbWJlciBkZXNjcmlwdGlvbiBpcyBpbnZhbGlkLiBJdCBjYW4gYmUgdXAgdG8gMTI4IGNoYXJhY3RlcnMgbG9uZy4nKTtcbiAgICB9XG4gICAgaWYgKCF1dGlsaXRpZXMudmFsaWRhdGVJbnRlZ2VyKHRoaXMucHJvcG9zYWxEdXJhdGlvbkluSG91cnMsIDEsIDE2OCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVm90aW5nIHBvbGljeSBwcm9wb3NhbCBkdXJhdGlvbiBtdXN0IGJlIGJldHdlZW4gMSBhbmQgMTY4IGhvdXJzLicpO1xuICAgIH1cbiAgICBpZiAoIXV0aWxpdGllcy52YWxpZGF0ZUludGVnZXIodGhpcy50aHJlc2hvbGRQZXJjZW50YWdlLCAwLCAxMDApKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ZvdGluZyBwb2xpY3kgdGhyZXNob2xkIHBlcmNlbnRhZ2UgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEwMC4nKTtcbiAgICB9XG5cbiAgICAvLyBFbnN1cmUgdGhlIHVzZXIgYWZmaWxpYXRpb24gaW5jbHVkZXMgdGhlIG1lbWJlciBuYW1lLFxuICAgIC8vIGlmIHRoZSB1c2VyIGxpc3QgZm9yIHJlZ2lzdHJhdGlvbiBpcyBwcm92aWRlZFxuICAgIGlmIChwcm9wcy51c2Vycykge1xuICAgICAgcHJvcHMudXNlcnMuZm9yRWFjaChlID0+IHtcbiAgICAgICAgaWYgKCFlLmFmZmlsaXRhdGlvbi5zdGFydHNXaXRoKHRoaXMubWVtYmVyTmFtZSkpIHRocm93IG5ldyBFcnJvcignVXNlciBhZmZpbGlhdGlvbiBpcyBpbnZhbGlkLiBBZmZpbGlhdGlvbiBzaG91bGQgc3RhcnQgd2l0aCBNZW1iZXIgbmFtZScpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gUGVyIHRoZSBNYW5hZ2VkIEJsb2NrY2hhaW4gZG9jdW1lbnRhdGlvbiwgdGhlIGFkbWluIHBhc3N3b3JkIG11c3QgYmUgYXQgbGVhc3QgZWlnaHRcbiAgICAvLyBjaGFyYWN0ZXJzIGxvbmcgYW5kIG5vIG1vcmUgdGhhbiAzMiBjaGFyYWN0ZXJzLiBJdCBtdXN0IGNvbnRhaW4gYXQgbGVhc3Qgb25lIHVwcGVyY2FzZVxuICAgIC8vIGxldHRlciwgb25lIGxvd2VyY2FzZSBsZXR0ZXIsIGFuZCBvbmUgZGlnaXQuIEl0IGNhbm5vdCBoYXZlIGEgc2luZ2xlIHF1b3RhdGlvbiBtYXJrICjigJgpLFxuICAgIC8vIGEgZG91YmxlIHF1b3RhdGlvbiBtYXJrcyAo4oCcKSwgYSBmb3J3YXJkIHNsYXNoKC8pLCBhIGJhY2t3YXJkIHNsYXNoKFxcKSwgQCwgb3IgYSBzcGFjZTtcbiAgICAvLyBzZXZlcmFsIG90aGVyIGNoYXJhY3RlcnMgYXJlIGV4bHVkZWQgaGVyZSB0byBtYWtlIHRoZSBwYXNzd29yZCBlYXNpZXIgdG8gdXNlIGluIHNjcmlwdHNcbiAgICBjb25zdCBwYXNzd29yZFJlcXVpcmVtZW50cyA9IHtcbiAgICAgIHBhc3N3b3JkTGVuZ3RoOiAzMixcbiAgICAgIHJlcXVpcmVFYWNoSW5jbHVkZWRUeXBlOiB0cnVlLFxuICAgICAgZXhjbHVkZUNoYXJhY3RlcnM6ICdcXCdcIi9cXFxcQCAme308Pip8JyxcbiAgICB9O1xuICAgIHRoaXMuYWRtaW5QYXNzd29yZFNlY3JldCA9IG5ldyBzZWNyZXRzbWFuYWdlci5TZWNyZXQodGhpcywgJ0FkbWluUGFzc3dvcmQnLCB7IGdlbmVyYXRlU2VjcmV0U3RyaW5nOiBwYXNzd29yZFJlcXVpcmVtZW50cyB9KTtcblxuICAgIC8vIFRoZSBpbml0aWFsbHkgZW5yb2xsZWQgYWRtaW4gdXNlciBjcmVkZW50aWFscyB3aWxsIGJlIHN0b3JlZCBpbiB0aGVzZSBzZWNyZXRzXG4gICAgdGhpcy5hZG1pblByaXZhdGVLZXlTZWNyZXQgPSBuZXcgc2VjcmV0c21hbmFnZXIuU2VjcmV0KHRoaXMsICdBZG1pblByaXZhdGVLZXknKTtcbiAgICB0aGlzLmFkbWluU2lnbmVkQ2VydFNlY3JldCA9IG5ldyBzZWNyZXRzbWFuYWdlci5TZWNyZXQodGhpcywgJ0FkbWluU2lnbmVkQ2VydCcpO1xuXG4gICAgLy8gQnVpbGQgb3V0IHRoZSBDbG91ZGZvcm1hdGlvbiBjb25zdHJ1Y3QgZm9yIHRoZSBuZXR3b3JrL21lbWJlclxuICAgIGNvbnN0IG5ldHdvcmtDb25maWd1cmF0aW9uID0ge1xuICAgICAgbmFtZTogdGhpcy5uZXR3b3JrTmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiB0aGlzLm5ldHdvcmtEZXNjcmlwdGlvbixcbiAgICAgIGZyYW1ld29yazogJ0hZUEVSTEVER0VSX0ZBQlJJQycsXG4gICAgICBmcmFtZXdvcmtWZXJzaW9uOiB0aGlzLmZyYW1ld29ya1ZlcnNpb24sXG4gICAgICBuZXR3b3JrRnJhbWV3b3JrQ29uZmlndXJhdGlvbjoge1xuICAgICAgICBuZXR3b3JrRmFicmljQ29uZmlndXJhdGlvbjoge1xuICAgICAgICAgIGVkaXRpb246IHRoaXMubmV0d29ya0VkaXRpb24sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgdm90aW5nUG9saWN5OiB7XG4gICAgICAgIGFwcHJvdmFsVGhyZXNob2xkUG9saWN5OiB7XG4gICAgICAgICAgcHJvcG9zYWxEdXJhdGlvbkluSG91cnM6IHRoaXMucHJvcG9zYWxEdXJhdGlvbkluSG91cnMsXG4gICAgICAgICAgdGhyZXNob2xkUGVyY2VudGFnZTogdGhpcy50aHJlc2hvbGRQZXJjZW50YWdlLFxuICAgICAgICAgIHRocmVzaG9sZENvbXBhcmF0b3I6IHRoaXMudGhyZXNob2xkQ29tcGFyYXRvcixcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIC8vIE5vdGUgdGhlIHVzZSBvZiB0aGUgdW53cmFwIGJlbG93IGlzIHRoZSBvbmx5IHBvc3NpYmxlIHdheSB0byBnZXRcbiAgICAvLyB0aGUgc2VjcmV0IHZhbHVlIGludG8gdGhlIENsb3VkRm9ybWF0aW9uOyBpdCB3aWxsIHN0aWxsIG5vdCBkaXJlY3RseVxuICAgIC8vIGJlIGluY2x1ZGVkIGluIHRoZSBzeW50aGVzaXplZCB0ZW1wbGF0ZSBzbyB1c2FnZSBoZXJlIGlzIHN0aWxsIHNhZmVcbiAgICBjb25zdCBtZW1iZXJDb25maWd1cmF0aW9uID0ge1xuICAgICAgbmFtZTogdGhpcy5tZW1iZXJOYW1lLFxuICAgICAgZGVzY3JpcHRpb246IHRoaXMubWVtYmVyRGVzY3JpcHRpb24sXG4gICAgICBtZW1iZXJGcmFtZXdvcmtDb25maWd1cmF0aW9uOiB7XG4gICAgICAgIG1lbWJlckZhYnJpY0NvbmZpZ3VyYXRpb246IHtcbiAgICAgICAgICBhZG1pblVzZXJuYW1lOiAnYWRtaW4nLFxuICAgICAgICAgIGFkbWluUGFzc3dvcmQ6IHRoaXMuYWRtaW5QYXNzd29yZFNlY3JldC5zZWNyZXRWYWx1ZS51bnNhZmVVbndyYXAoKSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBjb25zdCBuZXR3b3JrID0gbmV3IG1hbmFnZWRibG9ja2NoYWluLkNmbk1lbWJlcih0aGlzLCAnTmV0d29yaycsIHsgbmV0d29ya0NvbmZpZ3VyYXRpb24sIG1lbWJlckNvbmZpZ3VyYXRpb24gfSk7XG5cbiAgICAvLyBDYXB0dXJlIGRhdGEgaW5jbHVkZWQgaW4gdGhlIENsb3VkZm9ybWF0aW9uIG91dHB1dCBpbiBpbnN0YW5jZSB2YXJpYWJsZXNcbiAgICB0aGlzLm5ldHdvcmtJZCA9IG5ldHdvcmsuZ2V0QXR0KCdOZXR3b3JrSWQnKS50b1N0cmluZygpO1xuICAgIHRoaXMubWVtYmVySWQgPSBuZXR3b3JrLmdldEF0dCgnTWVtYmVySWQnKS50b1N0cmluZygpO1xuXG4gICAgLy8gQnVpbGQgb3V0IHRoZSBhc3NvY2lhdGVkIG5vZGUgY29uc3RydWN0c1xuICAgIHRoaXMubm9kZXMgPSBub2RlLkh5cGVybGVkZ2VyRmFicmljTm9kZS5jb25zdHJ1Y3ROb2Rlcyh0aGlzLCBwcm9wcy5ub2Rlcyk7XG5cbiAgICAvLyBEdWUgdG8gYSByYWNlIGNvbmRpdGlvbiBpbiBDREsgY3VzdG9tIHJlc291cmNlcyAoaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy8xODIzNyksXG4gICAgLy8gdGhlIG5lY2Vzc2FyeSBwZXJtaXNzaW9ucyBmb3IgYWxsIFNESyBjYWxscyBpbiB0aGUgc3RhY2sgbmVlZCB0byBiZSBhZGRlZCBoZXJlLCBldmVuIHRob3VnaFxuICAgIC8vIHRoZSBjYWxscyBpbiB0aGlzIGNvbnN0cnVjdCBkb24ndCBuZWVkIGFjY2VzcyB0byB0aGUgbm9kZXM7IHRoaXMgYWxzbyBtZWFucyBub2RlIGNvbnN0cnVjdHNcbiAgICAvLyBjYW4ndCBwb3B1bGF0ZSB0aGVpciBvdXRwdXRzIGZ1bGx5IHVudGlsIGxhdGVyLCB3aGljaCBpcyBhbm5veWluZ1xuICAgIGNvbnN0IG5vZGVJZHMgPSB0aGlzLm5vZGVzLm1hcChuID0+IG4ubm9kZUlkKTtcbiAgICBjb25zdCBub2RlQXJucyA9IG5vZGVJZHMubWFwKGkgPT4gYGFybjoke3BhcnRpdGlvbn06bWFuYWdlZGJsb2NrY2hhaW46JHtyZWdpb259OiR7YWNjb3VudH06bm9kZXMvJHtpfWApO1xuICAgIGNvbnN0IHNka0NhbGxQb2xpY3kgPSBjdXN0b21yZXNvdXJjZXMuQXdzQ3VzdG9tUmVzb3VyY2VQb2xpY3kuZnJvbVNka0NhbGxzKHtcbiAgICAgIHJlc291cmNlczogW1xuICAgICAgICBgYXJuOiR7cGFydGl0aW9ufTptYW5hZ2VkYmxvY2tjaGFpbjoke3JlZ2lvbn06Om5ldHdvcmtzLyR7dGhpcy5uZXR3b3JrSWR9YCxcbiAgICAgICAgYGFybjoke3BhcnRpdGlvbn06bWFuYWdlZGJsb2NrY2hhaW46JHtyZWdpb259OiR7YWNjb3VudH06bWVtYmVycy8ke3RoaXMubWVtYmVySWR9YCxcbiAgICAgICAgLi4ubm9kZUFybnMsXG4gICAgICBdLFxuICAgIH0pO1xuXG4gICAgLy8gQ2xvdWRmb3JtYXRpb24gZG9lc24ndCBpbmNsdWRlIGFsbCB0aGUgbmV0d29yayBhbmQgbWVtYmVyIGF0dHJpYnV0ZXNcbiAgICAvLyBuZWVkZWQgdG8gdXNlIEh5cGVybGVkZ2VyIEZhYnJpYywgc28gdXNlIFNESyBjYWxscyB0byBmZXRjaCBzYWlkIGRhdGFcbiAgICBjb25zdCBuZXR3b3JrRGF0YVNka0NhbGwgPSB7XG4gICAgICBzZXJ2aWNlOiAnTWFuYWdlZEJsb2NrY2hhaW4nLFxuICAgICAgYWN0aW9uOiAnZ2V0TmV0d29yaycsXG4gICAgICBwYXJhbWV0ZXJzOiB7IE5ldHdvcmtJZDogdGhpcy5uZXR3b3JrSWQgfSxcbiAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZDogY3VzdG9tcmVzb3VyY2VzLlBoeXNpY2FsUmVzb3VyY2VJZC5vZignSWQnKSxcbiAgICB9O1xuICAgIGNvbnN0IG1lbWJlckRhdGFTZGtDYWxsID0ge1xuICAgICAgc2VydmljZTogJ01hbmFnZWRCbG9ja2NoYWluJyxcbiAgICAgIGFjdGlvbjogJ2dldE1lbWJlcicsXG4gICAgICBwYXJhbWV0ZXJzOiB7IE5ldHdvcmtJZDogdGhpcy5uZXR3b3JrSWQsIE1lbWJlcklkOiB0aGlzLm1lbWJlcklkIH0sXG4gICAgICBwaHlzaWNhbFJlc291cmNlSWQ6IGN1c3RvbXJlc291cmNlcy5QaHlzaWNhbFJlc291cmNlSWQub2YoJ0lkJyksXG4gICAgfTtcblxuICAgIC8vIERhdGEgaXRlbXMgbmVlZCBmZXRjaGluZyBvbiBjcmVhdGlvbiBhbmQgdXBkYXRpbmc7IG5vdGhpbmcgbmVlZHMgZG9pbmcgb24gZGVsZXRpb25cbiAgICBjb25zdCBuZXR3b3JrRGF0YSA9IG5ldyBjdXN0b21yZXNvdXJjZXMuQXdzQ3VzdG9tUmVzb3VyY2UodGhpcywgJ05ldHdvcmtEYXRhUmVzb3VyY2UnLCB7XG4gICAgICBwb2xpY3k6IHNka0NhbGxQb2xpY3ksXG4gICAgICBvbkNyZWF0ZTogbmV0d29ya0RhdGFTZGtDYWxsLFxuICAgICAgb25VcGRhdGU6IG5ldHdvcmtEYXRhU2RrQ2FsbCxcbiAgICB9KTtcbiAgICBjb25zdCBtZW1iZXJEYXRhID0gbmV3IGN1c3RvbXJlc291cmNlcy5Bd3NDdXN0b21SZXNvdXJjZSh0aGlzLCAnTWVtYmVyRGF0YVJlc291cmNlJywge1xuICAgICAgcG9saWN5OiBzZGtDYWxsUG9saWN5LFxuICAgICAgb25DcmVhdGU6IG1lbWJlckRhdGFTZGtDYWxsLFxuICAgICAgb25VcGRhdGU6IG1lbWJlckRhdGFTZGtDYWxsLFxuICAgIH0pO1xuXG4gICAgLy8gQ2xvdWRmb3JtYXRpb24gZG9lc24ndCBpbmNsdWRlIGxvZ2dpbmcgY29uZmlndXJhdGlvbiBzbyB1c2UgU0RLIGNhbGwgdG8gZG8gc29cbiAgICBjb25zdCBsb2dDb25maWd1cmF0aW9uID0ge1xuICAgICAgRmFicmljOiB7IENhTG9nczogeyBDbG91ZHdhdGNoOiB7IEVuYWJsZWQ6IHRoaXMuZW5hYmxlQ2FMb2dnaW5nIH0gfSB9LFxuICAgIH07XG4gICAgY29uc3QgY29uZmlndXJlQ2FMb2dTZGtDYWxsID0ge1xuICAgICAgc2VydmljZTogJ01hbmFnZWRCbG9ja2NoYWluJyxcbiAgICAgIGFjdGlvbjogJ3VwZGF0ZU1lbWJlcicsXG4gICAgICBwYXJhbWV0ZXJzOiB7IE5ldHdvcmtJZDogdGhpcy5uZXR3b3JrSWQsIE1lbWJlcklkOiB0aGlzLm1lbWJlcklkLCBMb2dQdWJsaXNoaW5nQ29uZmlndXJhdGlvbjogbG9nQ29uZmlndXJhdGlvbiB9LFxuICAgICAgcGh5c2ljYWxSZXNvdXJjZUlkOiBjdXN0b21yZXNvdXJjZXMuUGh5c2ljYWxSZXNvdXJjZUlkLm9mKCdJZCcpLFxuICAgIH07XG4gICAgbmV3IGN1c3RvbXJlc291cmNlcy5Bd3NDdXN0b21SZXNvdXJjZSh0aGlzLCAnQ29uZmlndXJlQ2FMb2dSZXNvdXJjZScsIHtcbiAgICAgIHBvbGljeTogc2RrQ2FsbFBvbGljeSxcbiAgICAgIG9uQ3JlYXRlOiBjb25maWd1cmVDYUxvZ1Nka0NhbGwsXG4gICAgICBvblVwZGF0ZTogY29uZmlndXJlQ2FMb2dTZGtDYWxsLFxuICAgIH0pO1xuXG4gICAgLy8gR3JhYiBpdGVtcyBvdXQgb2YgdGhlIGFib3ZlIHJldHVybiB2YWx1ZXMgYW5kIHN0aWNrIHRoZW0gaW4gb3V0cHV0IHByb3BlcnRpZXNcbiAgICB0aGlzLnZwY0VuZHBvaW50U2VydmljZU5hbWUgPSBuZXR3b3JrRGF0YS5nZXRSZXNwb25zZUZpZWxkKCdOZXR3b3JrLlZwY0VuZHBvaW50U2VydmljZU5hbWUnKTtcbiAgICB0aGlzLm9yZGVyZXJFbmRwb2ludCA9IG5ldHdvcmtEYXRhLmdldFJlc3BvbnNlRmllbGQoJ05ldHdvcmsuRnJhbWV3b3JrQXR0cmlidXRlcy5GYWJyaWMuT3JkZXJpbmdTZXJ2aWNlRW5kcG9pbnQnKTtcbiAgICB0aGlzLmNhRW5kcG9pbnQgPSBtZW1iZXJEYXRhLmdldFJlc3BvbnNlRmllbGQoJ01lbWJlci5GcmFtZXdvcmtBdHRyaWJ1dGVzLkZhYnJpYy5DYUVuZHBvaW50Jyk7XG5cbiAgICAvLyBBcyBzdGF0ZWQgZWFybGllciwgbm9kZSBjb25zdHJ1Y3RzIGNhbid0IHBvcHVsYXRlIGFsbCB0aGVpciBwcm9wZXJ0aWVzXG4gICAgLy8gdW50aWwgYWZ0ZXIgdGhlIGFib3ZlIG5ldHdvcmsgYW5kIG1lbWJlciBTREsgY2FsbHMgc3VjY2VlZDsgdGh1cyB0aGVcbiAgICAvLyBmdW5jdGlvbiBjYWxscyBiZWxvdyB3aGVyZSBmZXRjaGVzIGFyZSBzcGxpdCBvdXQgYW5kIGxvZ2dpbmcgaXMgY29uZmlndXJlZFxuICAgIGZvciAoY29uc3QgbiBvZiB0aGlzLm5vZGVzKSB7XG4gICAgICBuLmNvbmZpZ3VyZUxvZ2dpbmcoc2RrQ2FsbFBvbGljeSk7XG4gICAgICBuLmZldGNoRGF0YShzZGtDYWxsUG9saWN5KTtcbiAgICB9XG5cbiAgICAvLyBCdWlsZCBvdXQgdGhlIGNsaWVudCBWUEMgY29uc3RydWN0XG4gICAgdGhpcy5jbGllbnQgPSBuZXcgY2xpZW50Lkh5cGVybGVkZ2VyRmFicmljQ2xpZW50KHRoaXMsICdOZXR3b3JrQ2xpZW50JywgcHJvcHMuY2xpZW50KTtcblxuICAgIC8vIEJ1aWxkIG91dCBhbGwgdGhlIGN1c3RvbSByZXNvdXJjZXMgdG8gcmVnaXN0ZXIgYW5kIGVucm9sbCBpZGVudGl0aWVzIHRvIENBXG4gICAgY29uc3QgaWRlbnRpdHlSZXNvdXJjZXMgPSBuZXcgaWRlbnRpdHkuSHlwZXJsZWRnZXJGYWJyaWNJZGVudGl0eSh0aGlzLCAnSWRlbnRpdHknKTtcblxuICAgIC8vIEVucm9sbCB0aGUgYWRtaW5pc3RyYXRvciBhbmQgc3RvcmUgaXRzIGNyZWRlbnRpYWxzIG9uIFNlY3JldHMgTWFuYWdlclxuICAgIG5ldyBjZGsuQ3VzdG9tUmVzb3VyY2UodGhpcywgJ0FkbWluQ3VzdG9tUmVzb3VyY2UnLCB7IHNlcnZpY2VUb2tlbjogaWRlbnRpdHlSZXNvdXJjZXMuYWRtaW5Qcm92aWRlci5zZXJ2aWNlVG9rZW4gfSk7XG5cbiAgICAvLyBSZWdpc3RlciBhbmQgZW5yb2xsIHVzZXJzLCBpZiBwcm92aWRlZFxuICAgIGlmIChwcm9wcy51c2VycykgdGhpcy51c2VycyA9IEFycmF5LmZyb20ocHJvcHMudXNlcnMuZW50cmllcygpKS5tYXAoZSA9PiBuZXcgdXNlci5IeXBlcmxlZGdlckZhYnJpY1VzZXIodGhpcywgYFVzZXIke2VbMF19YCwgZVsxXSkpO1xuICB9XG5cbn1cbiJdfQ==
|