UNPKG

cdk-emrserverless-with-delta-lake

Version:
193 lines 27.2 kB
"use strict"; var _a, _b; Object.defineProperty(exports, "__esModule", { value: true }); exports.EmrClusterTemplateStack = exports.EmrStudioDeveloperStack = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const cdk = require("aws-cdk-lib"); const emr = require("aws-cdk-lib/aws-emr"); const iam = require("aws-cdk-lib/aws-iam"); const servicecatalog = require("aws-cdk-lib/aws-servicecatalog"); const constructs_1 = require("constructs"); /** * Creates a Service Catalog for EMR cluster templates. * * For detail, please refer to [Create AWS CloudFormation templates for Amazon EMR Studio](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-studio-cluster-templates.html). * * ```ts * const emrClusterTemplatePortfolio = new EmrStudioDeveloperStack(this, 'ClusterTempalte'); * ``` */ class EmrStudioDeveloperStack extends constructs_1.Construct { constructor(scope, name, props) { super(scope, name); if (props?.providerName === undefined) { console.log('`providerName` for the `EmrStudioDeveloperStack` construct is not defined, therefore, the default value \'scott.hsieh\' will be set.'); } if (props?.user === undefined) { console.log('`user` for the `EmrStudioDeveloperStack` construct is not defined, therefore, the default value, an IAM user named \'Administrator\' with the `AdministratorAccess` power, will be set.'); } if (props?.role === undefined) { console.log('`role` for the `EmrStudioDeveloperStack` construct is not defined, therefore, the default value, an IAM user named \'Administrator\' with the `AdministratorAccess` power, will be set.'); } if (props?.group === undefined) { console.log('`group` for the `EmrStudioDeveloperStack` construct is not defined, therefore, the default value, an IAM user named \'Administrator\' with the `AdministratorAccess` power, will be set.'); } const providerName = (props?.providerName !== undefined) ? props.providerName : 'scott.hsieh'; this.portfolio = new servicecatalog.Portfolio(this, 'Portfolio', { displayName: 'EMR Studio Developers Stack', providerName: providerName, description: 'A stack with a variety of pre-defined EMR clusters for developers.', messageLanguage: servicecatalog.MessageLanguage.EN, }); this.product = new servicecatalog.CloudFormationProduct(this, 'MyFirstProduct', { productName: 'EMR_6.6.0', owner: 'scott.hsieh', description: 'EMR cluster with 6.6.0 version', productVersions: [ { productVersionName: 'v1', validateTemplate: true, cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(new EmrClusterTemplateStack(this, 'EmrStudio')), }, ], }); this.portfolio.addProduct(this.product); if (props !== undefined) { if (props.group !== undefined) { this.portfolio.giveAccessToGroup(props.group); } if (props.role !== undefined) { this.portfolio.giveAccessToRole(props.role); } if (props.user !== undefined) { this.portfolio.giveAccessToUser(props.user); } } else { this.portfolio.giveAccessToUser(iam.User.fromUserName(this, 'AdminUser', 'Administrator')); } new cdk.CfnOutput(this, 'OEmrStudioPortfolioArn', { value: this.portfolio.portfolioArn, description: 'The ARN of the portfolio.' }); new cdk.CfnOutput(this, 'OEmrStudioPortfolioProductArn', { value: this.product.productArn, description: 'The ARN of the product.' }); } } exports.EmrStudioDeveloperStack = EmrStudioDeveloperStack; _a = JSII_RTTI_SYMBOL_1; EmrStudioDeveloperStack[_a] = { fqn: "cdk-emrserverless-with-delta-lake.EmrStudioDeveloperStack", version: "2.0.823" }; /** * Creates a CloudFormation template which will be a Product under a Portfolio of AWS Service Catalog. This is for creating an EMR cluster via cluster template in the EMR Studio, created by the `EmrServerless` construct, on the AWS Console. * * And you don't have control via the `EmrServerless` construct by now. The documentation is for you to grasp the architecture of the `EmrServerless` more easily. * * For detail, please refer to [Create AWS CloudFormation templates for Amazon EMR Studio](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-studio-cluster-templates.html). * * ```ts * const product = new servicecatalog.CloudFormationProduct(this, 'MyFirstProduct', { * productName: 'EMR_6.6.0', * owner: 'scott.hsieh', * description: 'EMR cluster with 6.6.0 version', * productVersions: [ * { * productVersionName: 'v1', * validateTemplate: true, * cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(new EmrClusterTemplateStack(this, 'EmrStudio')), * }, * ], * }); * ``` */ class EmrClusterTemplateStack extends servicecatalog.ProductStack { constructor(scope, id) { super(scope, id); const bidPrice = new cdk.CfnParameter(this, 'BidPrice', { type: 'String', default: '0.186', }); const clusterName = new cdk.CfnParameter(this, 'ClusterName', { type: 'String', default: 'Example_Two_Node_Cluster', }); const ec2SubnetId = new cdk.CfnParameter(this, 'Ec2SubnetId', { type: 'String', default: 'subnet-3571a36c', description: 'Buddy, the default value is one of the subnets in scott.hsieh\'s account, you gotta type your own.', }); const emrRelease = new cdk.CfnParameter(this, 'EmrRelease', { type: 'String', default: 'emr-7.1.0', allowedValues: [ 'emr-7.1.0', 'emr-7.0.0', ], }); const masterInstanceType = new cdk.CfnParameter(this, 'MasterInstanceType', { type: 'String', default: 'c7g.xlarge', allowedValues: [ 'm7g.xlarge', 'm7g.2xlarge', 'c7g.xlarge', 'c7g.2xlarge', ], }); const coreInstanceType = new cdk.CfnParameter(this, 'CoreInstanceType', { type: 'String', default: 'c7g.xlarge', allowedValues: [ 'm7g.xlarge', 'm7g.2xlarge', 'c7g.xlarge', 'c7g.2xlarge', ], }); const clusterTemplate = new emr.CfnCluster(this, 'TemplateCluster', { name: clusterName.valueAsString, applications: [ { name: 'Hadoop' }, { name: 'Spark' }, { name: 'Livy' }, { name: 'JupyterHub' }, { name: 'JupyterEnterpriseGateway' }, { name: 'Hive' }, ], ebsRootVolumeSize: 10, jobFlowRole: 'EMR_EC2_DefaultRole', serviceRole: 'EMR_DefaultRole', releaseLabel: emrRelease.valueAsString, visibleToAllUsers: true, configurations: [{ classification: 'hive-site', configurationProperties: { 'hive.metastore.client.factory.class': 'com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory', }, }, { classification: 'spark-hive-site', configurationProperties: { 'hive.metastore.client.factory.class': 'com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory', }, }], logUri: `s3n://aws-logs-${cdk.Aws.ACCOUNT_ID}-${cdk.Aws.REGION}/elasticmapreduce/`, instances: { terminationProtected: false, ec2SubnetId: ec2SubnetId.valueAsString, masterInstanceGroup: { market: 'ON_DEMAND', instanceCount: 1, instanceType: masterInstanceType.valueAsString, }, coreInstanceGroup: { instanceCount: 1, instanceType: coreInstanceType.valueAsString, bidPrice: bidPrice.valueAsString, market: 'SPOT', name: 'Core', }, }, }); new cdk.CfnOutput(this, 'ClusterId', { value: clusterTemplate.ref, description: 'The ID of the EMR Cluster' }); } } exports.EmrClusterTemplateStack = EmrClusterTemplateStack; _b = JSII_RTTI_SYMBOL_1; EmrClusterTemplateStack[_b] = { fqn: "cdk-emrserverless-with-delta-lake.EmrClusterTemplateStack", version: "2.0.823" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW1yLXN0dWRpby1jbHVzdGVyLXRlbXBsYXRlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9lbXItc3R1ZGlvLWNsdXN0ZXItdGVtcGxhdGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQywyQ0FBMkM7QUFDM0MsaUVBQWlFO0FBQ2pFLDJDQUF1QztBQXlCdkM7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFhLHVCQUF3QixTQUFRLHNCQUFTO0lBU3BELFlBQVksS0FBZ0IsRUFBRSxJQUFZLEVBQUUsS0FBb0M7UUFDOUUsS0FBSyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNuQixJQUFJLEtBQUssRUFBRSxZQUFZLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDdEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzSUFBc0ksQ0FBQyxDQUFDO1FBQ3RKLENBQUM7UUFDRCxJQUFJLEtBQUssRUFBRSxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDOUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5TEFBeUwsQ0FBQyxDQUFDO1FBQ3pNLENBQUM7UUFDRCxJQUFJLEtBQUssRUFBRSxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDOUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5TEFBeUwsQ0FBQyxDQUFDO1FBQ3pNLENBQUM7UUFDRCxJQUFJLEtBQUssRUFBRSxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDL0IsT0FBTyxDQUFDLEdBQUcsQ0FBQywwTEFBMEwsQ0FBQyxDQUFDO1FBQzFNLENBQUM7UUFDRCxNQUFNLFlBQVksR0FBVyxDQUFDLEtBQUssRUFBRSxZQUFZLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQztRQUV0RyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksY0FBYyxDQUFDLFNBQVMsQ0FBQyxJ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LENBQUM7SUFDakgsQ0FBQzs7QUExRkgsMERBMkZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY2RrIGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGVtciBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZW1yJztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCAqIGFzIHNlcnZpY2VjYXRhbG9nIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zZXJ2aWNlY2F0YWxvZyc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbi8qKlxuICogSW50ZXJmYWNlIGZvciBTZXJ2aWNlIENhdGFsb2cgb2YgRU1SIGNsdXN0ZXIgdGVtcGxhdGVzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVtclN0dWRpb0RldmVsb3BlclN0YWNrUHJvcHMge1xuICAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogVGhlIHByb3ZpZGVyIG5hbWUgaW4gYSBTZXJ2aWNlIENhdGFsb2cgZm9yIEVNUiBjbHVzdGVyIHRlbXBsYXRlcy5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogQGRlZmF1bHQgLSAnc2NvdHQuaHNpZWgnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuICByZWFkb25seSBwcm92aWRlck5hbWU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBhbiBJQU0gZ3JvdXAgeW91IHdpc2ggdG8gYXNzb2NpYXRlIHdpdGggdGhlIFBvcnRmb2xpbyBmb3IgRU1SIGNsdXN0ZXIgdGVtcGxhdGUuXG4gICAqL1xuICByZWFkb25seSBncm91cD86IGlhbS5JR3JvdXA7XG4gIC8qKlxuICAgKiBhbiBJQU0gcm9sZSB5b3Ugd2lzaCB0byBhc3NvY2lhdGUgd2l0aCB0aGUgUG9ydGZvbGlvIGZvciBFTVIgY2x1c3RlciB0ZW1wbGF0ZS5cbiAgICovXG4gIHJlYWRvbmx5IHJvbGU/OiBpYW0uSVJvbGU7XG4gIC8qKlxuICAgKiBhbiBJQU0gdXNlciB5b3Ugd2lzaCB0byBhc3NvY2lhdGUgd2l0aCB0aGUgUG9ydGZvbGlvIGZvciBFTVIgY2x1c3RlciB0ZW1wbGF0ZS5cbiAgICovXG4gIHJlYWRvbmx5IHVzZXI/OiBpYW0uSVVzZXI7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIFNlcnZpY2UgQ2F0YWxvZyBmb3IgRU1SIGNsdXN0ZXIgdGVtcGxhdGVzLlxuICpcbiAqIEZvciBkZXRhaWwsIHBsZWFzZSByZWZlciB0byBbQ3JlYXRlIEFXUyBDbG91ZEZvcm1hdGlvbiB0ZW1wbGF0ZXMgZm9yIEFtYXpvbiBFTVIgU3R1ZGlvXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZW1yL2xhdGVzdC9NYW5hZ2VtZW50R3VpZGUvZW1yLXN0dWRpby1jbHVzdGVyLXRlbXBsYXRlcy5odG1sKS5cbiAqXG4gKiBgYGB0c1xuICogY29uc3QgZW1yQ2x1c3RlclRlbXBsYXRlUG9ydGZvbGlvID0gbmV3IEVtclN0dWRpb0RldmVsb3BlclN0YWNrKHRoaXMsICdDbHVzdGVyVGVtcGFsdGUnKTtcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgRW1yU3R1ZGlvRGV2ZWxvcGVyU3RhY2sgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogVGhlIHJlcHJlc2VudGF0aXZlIG9mIHRoZSBzZXJ2aWNlIGNhdGFsb2cgZm9yIEVNUiBjbHVzdGVyIHRlbXBhbHRlcy5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4gIHB1YmxpYyByZWFkb25seSBwb3J0Zm9saW86IHNlcnZpY2VjYXRhbG9nLlBvcnRmb2xpbztcbiAgLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFRoZSByZXByZXNlbnRhdGl2ZSBvZiB0aGUgcHJvZHVjdCBmb3IgZGVtbyBwdXJwb3NlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHByb2R1Y3Q6IHNlcnZpY2VjYXRhbG9nLlByb2R1Y3Q7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIG5hbWU6IHN0cmluZywgcHJvcHM/OiBFbXJTdHVkaW9EZXZlbG9wZXJTdGFja1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIG5hbWUpO1xuICAgIGlmIChwcm9wcz8ucHJvdmlkZXJOYW1lID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdgcHJvdmlkZXJOYW1lYCBmb3IgdGhlIGBFbXJTdHVkaW9EZXZlbG9wZXJTdGFja2AgY29uc3RydWN0IGlzIG5vdCBkZWZpbmVkLCB0aGVyZWZvcmUsIHRoZSBkZWZhdWx0IHZhbHVlIFxcJ3Njb3R0LmhzaWVoXFwnIHdpbGwgYmUgc2V0LicpO1xuICAgIH1cbiAgICBpZiAocHJvcHM/LnVzZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc29sZS5sb2coJ2B1c2VyYCBmb3IgdGhlIGBFbXJTdHVkaW9EZXZlbG9wZXJTdGFja2AgY29uc3RydWN0IGlzIG5vdCBkZWZpbmVkLCB0aGVyZWZvcmUsIHRoZSBkZWZhdWx0IHZhbHVlLCBhbiBJQU0gdXNlciBuYW1lZCBcXCdBZG1pbmlzdHJhdG9yXFwnIHdpdGggdGhlIGBBZG1pbmlzdHJhdG9yQWNjZXNzYCBwb3dlciwgd2lsbCBiZSBzZXQuJyk7XG4gICAgfVxuICAgIGlmIChwcm9wcz8ucm9sZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zb2xlLmxvZygnYHJvbGVgIGZvciB0aGUgYEVtclN0dWRpb0RldmVsb3BlclN0YWNrYCBjb25zdHJ1Y3QgaXMgbm90IGRlZmluZWQsIHRoZXJlZm9yZSwgdGhlIGRlZmF1bHQgdmFsdWUsIGFuIElBTSB1c2VyIG5hbWVkIFxcJ0FkbWluaXN0cmF0b3JcXCcgd2l0aCB0aGUgYEFkbWluaXN0cmF0b3JBY2Nlc3NgIHBvd2VyLCB3aWxsIGJlIHNldC4nKTtcbiAgICB9XG4gICAgaWYgKHByb3BzPy5ncm91cCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zb2xlLmxvZygnYGdyb3VwYCBmb3IgdGhlIGBFbXJTdHVkaW9EZXZlbG9wZXJTdGFja2AgY29uc3RydWN0IGlzIG5vdCBkZWZpbmVkLCB0aGVyZWZvcmUsIHRoZSBkZWZhdWx0IHZhbHVlLCBhbiBJQU0gdXNlciBuYW1lZCBcXCdBZG1pbmlzdHJhdG9yXFwnIHdpdGggdGhlIGBBZG1pbmlzdHJhdG9yQWNjZXNzYCBwb3dlciwgd2lsbCBiZSBzZXQuJyk7XG4gICAgfVxuICAgIGNvbnN0IHByb3ZpZGVyTmFtZTogc3RyaW5nID0gKHByb3BzPy5wcm92aWRlck5hbWUgIT09IHVuZGVmaW5lZCkgPyBwcm9wcy5wcm92aWRlck5hbWUgOiAnc2NvdHQuaHNpZWgnO1xuXG4gICAgdGhpcy5wb3J0Zm9saW8gPSBuZXcgc2VydmljZWNhdGFsb2cuUG9ydGZvbGlvKHRoaXMsICdQb3J0Zm9saW8nLCB7XG4gICAgICBkaXNwbGF5TmFtZTogJ0VNUiBTdHVkaW8gRGV2ZWxvcGVycyBTdGFjaycsXG4gICAgICBwcm92aWRlck5hbWU6IHByb3ZpZGVyTmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiAnQSBzdGFjayB3aXRoIGEgdmFyaWV0eSBvZiBwcmUtZGVmaW5lZCBFTVIgY2x1c3RlcnMgZm9yIGRldmVsb3BlcnMuJyxcbiAgICAgIG1lc3NhZ2VMYW5ndWFnZTogc2VydmljZWNhdGFsb2cuTWVzc2FnZUxhbmd1YWdlLkVOLFxuICAgIH0pO1xuICAgIHRoaXMucHJvZHVjdCA9IG5ldyBzZXJ2aWNlY2F0YWxvZy5DbG91ZEZvcm1hdGlvblByb2R1Y3QodGhpcywgJ015Rmlyc3RQcm9kdWN0Jywge1xuICAgICAgcHJvZHVjdE5hbWU6ICdFTVJfNi42LjAnLFxuICAgICAgb3duZXI6ICdzY290dC5oc2llaCcsXG4gICAgICBkZXNjcmlwdGlvbjogJ0VNUiBjbHVzdGVyIHdpdGggNi42LjAgdmVyc2lvbicsXG4gICAgICBwcm9kdWN0VmVyc2lvbnM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHByb2R1Y3RWZXJzaW9uTmFtZTogJ3YxJyxcbiAgICAgICAgICB2YWxpZGF0ZVRlbXBsYXRlOiB0cnVlLFxuICAgICAgICAgIGNsb3VkRm9ybWF0aW9uVGVtcGxhdGU6IHNlcnZpY2VjYXRhbG9nLkNsb3VkRm9ybWF0aW9uVGVtcGxhdGUuZnJvbVByb2R1Y3RTdGFjayhuZXcgRW1yQ2x1c3RlclRlbXBsYXRlU3RhY2sodGhpcywgJ0VtclN0dWRpbycpKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gICAgdGhpcy5wb3J0Zm9saW8uYWRkUHJvZHVjdCh0aGlzLnByb2R1Y3QpO1xuICAgIGlmIChwcm9wcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAocHJvcHMhLmdyb3VwICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5wb3J0Zm9saW8uZ2l2ZUFjY2Vzc1RvR3JvdXAocHJvcHMhLmdyb3VwKTtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9wcyEucm9sZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMucG9ydGZvbGlvLmdpdmVBY2Nlc3NUb1JvbGUocHJvcHMhLnJvbGUpO1xuICAgICAgfVxuICAgICAgaWYgKHByb3BzIS51c2VyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5wb3J0Zm9saW8uZ2l2ZUFjY2Vzc1RvVXNlcihwcm9wcyEudXNlcik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucG9ydGZvbGlvLmdpdmVBY2Nlc3NUb1VzZXIoaWFtLlVzZXIuZnJvbVVzZXJOYW1lKHRoaXMsICdBZG1pblVzZXInLCAnQWRtaW5pc3RyYXRvcicpKTtcbiAgICB9XG4gICAgbmV3IGNkay5DZm5PdXRwdXQodGhpcywgJ09FbXJTdHVkaW9Qb3J0Zm9saW9Bcm4nLCB7IHZhbHVlOiB0aGlzLnBvcnRmb2xpby5wb3J0Zm9saW9Bcm4sIGRlc2NyaXB0aW9uOiAnVGhlIEFSTiBvZiB0aGUgcG9ydGZvbGlvLicgfSk7XG4gICAgbmV3IGNkay5DZm5PdXRwdXQodGhpcywgJ09FbXJTdHVkaW9Qb3J0Zm9saW9Qcm9kdWN0QXJuJywgeyB2YWx1ZTogdGhpcy5wcm9kdWN0LnByb2R1Y3RBcm4sIGRlc2NyaXB0aW9uOiAnVGhlIEFSTiBvZiB0aGUgcHJvZHVjdC4nIH0pO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIENsb3VkRm9ybWF0aW9uIHRlbXBsYXRlIHdoaWNoIHdpbGwgYmUgYSBQcm9kdWN0IHVuZGVyIGEgUG9ydGZvbGlvIG9mIEFXUyBTZXJ2aWNlIENhdGFsb2cuIFRoaXMgaXMgZm9yIGNyZWF0aW5nIGFuIEVNUiBjbHVzdGVyIHZpYSBjbHVzdGVyIHRlbXBsYXRlIGluIHRoZSBFTVIgU3R1ZGlvLCBjcmVhdGVkIGJ5IHRoZSBgRW1yU2VydmVybGVzc2AgY29uc3RydWN0LCBvbiB0aGUgQVdTIENvbnNvbGUuXG4gKlxuICogQW5kIHlvdSBkb24ndCBoYXZlIGNvbnRyb2wgdmlhIHRoZSBgRW1yU2VydmVybGVzc2AgY29uc3RydWN0IGJ5IG5vdy4gVGhlIGRvY3VtZW50YXRpb24gaXMgZm9yIHlvdSB0byBncmFzcCB0aGUgYXJjaGl0ZWN0dXJlIG9mIHRoZSBgRW1yU2VydmVybGVzc2AgbW9yZSBlYXNpbHkuXG4gKlxuICogRm9yIGRldGFpbCwgcGxlYXNlIHJlZmVyIHRvIFtDcmVhdGUgQVdTIENsb3VkRm9ybWF0aW9uIHRlbXBsYXRlcyBmb3IgQW1hem9uIEVNUiBTdHVkaW9dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbXIvbGF0ZXN0L01hbmFnZW1lbnRHdWlkZS9lbXItc3R1ZGlvLWNsdXN0ZXItdGVtcGxhdGVzLmh0bWwpLlxuICpcbiAqIGBgYHRzXG4gKiBjb25zdCBwcm9kdWN0ID0gbmV3IHNlcnZpY2VjYXRhbG9nLkNsb3VkRm9ybWF0aW9uUHJvZHVjdCh0aGlzLCAnTXlGaXJzdFByb2R1Y3QnLCB7XG4gKiAgICBwcm9kdWN0TmFtZTogJ0VNUl82LjYuMCcsXG4gKiAgICBvd25lcjogJ3Njb3R0LmhzaWVoJyxcbiAqICAgIGRlc2NyaXB0aW9uOiAnRU1SIGNsdXN0ZXIgd2l0aCA2LjYuMCB2ZXJzaW9uJyxcbiAqICAgIHByb2R1Y3RWZXJzaW9uczogW1xuICogICAgICB7XG4gKiAgICAgICAgcHJvZHVjdFZlcnNpb25OYW1lOiAndjEnLFxuICogICAgICAgIHZhbGlkYXRlVGVtcGxhdGU6IHRydWUsXG4gKiAgICAgICAgY2xvdWRGb3JtYXRpb25UZW1wbGF0ZTogc2VydmljZWNhdGFsb2cuQ2xvdWRGb3JtYXRpb25UZW1wbGF0ZS5mcm9tUHJvZHVjdFN0YWNrKG5ldyBFbXJDbHVzdGVyVGVtcGxhdGVTdGFjayh0aGlzLCAnRW1yU3R1ZGlvJykpLFxuICogICAgICB9LFxuICogXSxcbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBFbXJDbHVzdGVyVGVtcGxhdGVTdGFjayBleHRlbmRzIHNlcnZpY2VjYXRhbG9nLlByb2R1Y3RTdGFjayB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIGNvbnN0IGJpZFByaWNlID0gbmV3IGNkay5DZm5QYXJhbWV0ZXIodGhpcywgJ0JpZFByaWNlJywge1xuICAgICAgdHlwZTogJ1N0cmluZycsXG4gICAgICBkZWZhdWx0OiAnMC4xODYnLFxuICAgIH0pO1xuICAgIGNvbnN0IGNsdXN0ZXJOYW1lID0gbmV3IGNkay5DZm5QYXJhbWV0ZXIodGhpcywgJ0NsdXN0ZXJOYW1lJywge1xuICAgICAgdHlwZTogJ1N0cmluZycsXG4gICAgICBkZWZhdWx0OiAnRXhhbXBsZV9Ud29fTm9kZV9DbHVzdGVyJyxcbiAgICB9KTtcbiAgICBjb25zdCBlYzJTdWJuZXRJZCA9IG5ldyBjZGsuQ2ZuUGFyYW1ldGVyKHRoaXMsICdFYzJTdWJuZXRJZCcsIHtcbiAgICAgIHR5cGU6ICdTdHJpbmcnLFxuICAgICAgZGVmYXVsdDogJ3N1Ym5ldC0zNTcxYTM2YycsXG4gICAgICBkZXNjcmlwdGlvbjogJ0J1ZGR5LCB0aGUgZGVmYXVsdCB2YWx1ZSBpcyBvbmUgb2YgdGhlIHN1Ym5ldHMgaW4gc2NvdHQuaHNpZWhcXCdzIGFjY291bnQsIHlvdSBnb3R0YSB0eXBlIHlvdXIgb3duLicsXG4gICAgfSk7XG4gICAgY29uc3QgZW1yUmVsZWFzZSA9IG5ldyBjZGsuQ2ZuUGFyYW1ldGVyKHRoaXMsICdFbXJSZWxlYXNlJywge1xuICAgICAgdHlwZTogJ1N0cmluZycsXG4gICAgICBkZWZhdWx0OiAnZW1yLTcuMS4wJyxcbiAgICAgIGFsbG93ZWRWYWx1ZXM6IFtcbiAgICAgICAgJ2Vtci03LjEuMCcsXG4gICAgICAgICdlbXItNy4wLjAnLFxuICAgICAgXSxcbiAgICB9KTtcbiAgICBjb25zdCBtYXN0ZXJJbnN0YW5jZVR5cGUgPSBuZXcgY2RrLkNmblBhcmFtZXRlcih0aGlzLCAnTWFzdGVySW5zdGFuY2VUeXBlJywge1xuICAgICAgdHlwZTogJ1N0cmluZycsXG4gICAgICBkZWZhdWx0OiAnYzdnLnhsYXJnZScsXG4gICAgICBhbGxvd2VkVmFsdWVzOiBbXG4gICAgICAgICdtN2cueGxhcmdlJyxcbiAgICAgICAgJ203Zy4yeGxhcmdlJyxcbiAgICAgICAgJ2M3Zy54bGFyZ2UnLFxuICAgICAgICAnYzdnLjJ4bGFyZ2UnLFxuICAgICAgXSxcbiAgICB9KTtcbiAgICBjb25zdCBjb3JlSW5zdGFuY2VUeXBlID0gbmV3IGNkay5DZm5QYXJhbWV0ZXIodGhpcywgJ0NvcmVJbnN0YW5jZVR5cGUnLCB7XG4gICAgICB0eXBlOiAnU3RyaW5nJyxcbiAgICAgIGRlZmF1bHQ6ICdjN2cueGxhcmdlJyxcbiAgICAgIGFsbG93ZWRWYWx1ZXM6IFtcbiAgICAgICAgJ203Zy54bGFyZ2UnLFxuICAgICAgICAnbTdnLjJ4bGFyZ2UnLFxuICAgICAgICAnYzdnLnhsYXJnZScsXG4gICAgICAgICdjN2cuMnhsYXJnZScsXG4gICAgICBdLFxuICAgIH0pO1xuICAgIGNvbnN0IGNsdXN0ZXJUZW1wbGF0ZSA9IG5ldyBlbXIuQ2ZuQ2x1c3Rlcih0aGlzLCAnVGVtcGxhdGVDbHVzdGVyJywge1xuICAgICAgbmFtZTogY2x1c3Rlck5hbWUudmFsdWVBc1N0cmluZyxcbiAgICAgIGFwcGxpY2F0aW9uczogW1xuICAgICAgICB7IG5hbWU6ICdIYWRvb3AnIH0sXG4gICAgICAgIHsgbmFtZTogJ1NwYXJrJyB9LFxuICAgICAgICB7IG5hbWU6ICdMaXZ5JyB9LFxuICAgICAgICB7IG5hbWU6ICdKdXB5dGVySHViJyB9LFxuICAgICAgICB7IG5hbWU6ICdKdXB5dGVyRW50ZXJwcmlzZUdhdGV3YXknIH0sXG4gICAgICAgIHsgbmFtZTogJ0hpdmUnIH0sXG4gICAgICBdLFxuICAgICAgZWJzUm9vdFZvbHVtZVNpemU6IDEwLFxuICAgICAgam9iRmxvd1JvbGU6ICdFTVJfRUMyX0RlZmF1bHRSb2xlJyxcbiAgICAgIHNlcnZpY2VSb2xlOiAnRU1SX0RlZmF1bHRSb2xlJyxcbiAgICAgIHJlbGVhc2VMYWJlbDogZW1yUmVsZWFzZS52YWx1ZUFzU3RyaW5nLFxuICAgICAgdmlzaWJsZVRvQWxsVXNlcnM6IHRydWUsXG4gICAgICBjb25maWd1cmF0aW9uczogW3tcbiAgICAgICAgY2xhc3NpZmljYXRpb246ICdoaXZlLXNpdGUnLFxuICAgICAgICBjb25maWd1cmF0aW9uUHJvcGVydGllczoge1xuICAgICAgICAgICdoaXZlLm1ldGFzdG9yZS5jbGllbnQuZmFjdG9yeS5jbGFzcyc6ICdjb20uYW1hem9uYXdzLmdsdWUuY2F0YWxvZy5tZXRhc3RvcmUuQVdTR2x1ZURhdGFDYXRhbG9nSGl2ZUNsaWVudEZhY3RvcnknLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgY2xhc3NpZmljYXRpb246ICdzcGFyay1oaXZlLXNpdGUnLFxuICAgICAgICBjb25maWd1cmF0aW9uUHJvcGVydGllczoge1xuICAgICAgICAgICdoaXZlLm1ldGFzdG9yZS5jbGllbnQuZmFjdG9yeS5jbGFzcyc6ICdjb20uYW1hem9uYXdzLmdsdWUuY2F0YWxvZy5tZXRhc3RvcmUuQVdTR2x1ZURhdGFDYXRhbG9nSGl2ZUNsaWVudEZhY3RvcnknLFxuICAgICAgICB9LFxuICAgICAgfV0sXG4gICAgICBsb2dVcmk6IGBzM246Ly9hd3MtbG9ncy0ke2Nkay5Bd3MuQUNDT1VOVF9JRH0tJHtjZGsuQXdzLlJFR0lPTn0vZWxhc3RpY21hcHJlZHVjZS9gLFxuICAgICAgaW5zdGFuY2VzOiB7XG4gICAgICAgIHRlcm1pbmF0aW9uUHJvdGVjdGVkOiBmYWxzZSxcbiAgICAgICAgZWMyU3VibmV0SWQ6IGVjMlN1Ym5ldElkLnZhbHVlQXNTdHJpbmcsXG4gICAgICAgIG1hc3Rlckluc3RhbmNlR3JvdXA6IHtcbiAgICAgICAgICBtYXJrZXQ6ICdPTl9ERU1BTkQnLFxuICAgICAgICAgIGluc3RhbmNlQ291bnQ6IDEsXG4gICAgICAgICAgaW5zdGFuY2VUeXBlOiBtYXN0ZXJJbnN0YW5jZVR5cGUudmFsdWVBc1N0cmluZyxcbiAgICAgICAgfSxcbiAgICAgICAgY29yZUluc3RhbmNlR3JvdXA6IHtcbiAgICAgICAgICBpbnN0YW5jZUNvdW50OiAxLFxuICAgICAgICAgIGluc3RhbmNlVHlwZTogY29yZUluc3RhbmNlVHlwZS52YWx1ZUFzU3RyaW5nLFxuICAgICAgICAgIGJpZFByaWNlOiBiaWRQcmljZS52YWx1ZUFzU3RyaW5nLFxuICAgICAgICAgIG1hcmtldDogJ1NQT1QnLFxuICAgICAgICAgIG5hbWU6ICdDb3JlJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgbmV3IGNkay5DZm5PdXRwdXQodGhpcywgJ0NsdXN0ZXJJZCcsIHsgdmFsdWU6IGNsdXN0ZXJUZW1wbGF0ZS5yZWYsIGRlc2NyaXB0aW9uOiAnVGhlIElEIG9mIHRoZSBFTVIgQ2x1c3RlcicgfSk7XG4gIH1cbn0iXX0=