@project-lakechain/opensearch-index
Version:
Creates an OpenSearch index using AWS CDK.
179 lines • 20.4 kB
JavaScript
"use strict";
/*
* Copyright (C) 2023 Amazon.com, Inc. or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenSearchIndex = void 0;
const path_1 = __importDefault(require("path"));
const cdk = __importStar(require("aws-cdk-lib"));
const lambda = __importStar(require("aws-cdk-lib/aws-lambda"));
const node = __importStar(require("aws-cdk-lib/aws-lambda-nodejs"));
const custom = __importStar(require("aws-cdk-lib/custom-resources"));
const iam = __importStar(require("aws-cdk-lib/aws-iam"));
const constructs_1 = require("constructs");
/**
* A custom resource making it easy to create an index
* and manage its lifecycle as a CDK construct.
* This construct uses a lambda function to interact with
* the OpenSearch endpoint, and uses the OpenSearch SDK to
* create and delete the index.
* This construct is compatible with OpenSearch domains and serverless
* collections deployed in a VPC or not.
*/
class OpenSearchIndex extends constructs_1.Construct {
/**
* The name of the index managed by the construct.
*/
indexName;
/**
* OpenSearch Index constructor
* @param scope the scope of the construct
* @param id the id of the construct
*/
constructor(scope, id, props) {
super(scope, id);
// Set the index name.
this.indexName = props.indexName;
// The OpenSearch endpoint.
const endpoint = this.getEndpoint(props.endpoint);
// The identifier of the OpenSearch service.
const serviceIdentifier = this.getServiceIdentifier(props.endpoint);
// The path to the lambda function directory.
const processorPath = path_1.default.resolve(__dirname, 'lambdas', 'index-manager');
// Create the lambda function that will create the index.
const processor = new node.NodejsFunction(this, 'Compute', {
description: 'A custom resource managing the state of an OpenSearch index.',
entry: path_1.default.resolve(processorPath, 'index.js'),
vpc: props.vpc,
timeout: cdk.Duration.seconds(10),
runtime: lambda.Runtime.NODEJS_18_X,
architecture: lambda.Architecture.ARM_64,
logGroup: props.logGroup,
environment: {
OPENSEARCH_ENDPOINT: endpoint,
OPENSEARCH_INDEX_NAME: props.indexName,
BODY_PARAMETERS: JSON.stringify(props.body),
SERVICE_IDENTIFIER: serviceIdentifier
},
bundling: {
minify: true,
externalModules: [
'@aws-sdk/credential-provider-node'
]
}
});
if (serviceIdentifier === 'es') {
// Allow the lambda function to manage the index.
props.endpoint.grantWrite(processor);
}
else if (serviceIdentifier === 'aoss') {
const endpoint = props.endpoint;
// If the endpoint is a collection, we also need to create an
// access policy on the collection to allow the lambda function
// to manage the index.
// Add a new access policy.
endpoint.addAccessPolicy(this.indexName, [processor.role.roleArn], ['aoss:CreateIndex', 'aoss:DeleteIndex', 'aoss:UpdateIndex']);
// We also need to grant the lambda function permissions
// to write to the OpenSearch index.
processor.addToRolePolicy(new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['aoss:APIAccessAll'],
resources: [endpoint.collectionArn]
}));
}
// Create a custom resource that will manage the index.
const resource = new cdk.CustomResource(this, 'Resource', {
serviceToken: new custom.Provider(this, 'Provider', {
onEventHandler: processor,
logGroup: props.logGroup
}).serviceToken,
resourceType: 'Custom::OpenSearchIndex',
properties: {
IndexName: props.indexName,
Body: props.body,
Endpoint: endpoint
}
});
resource.node.addDependency(props.endpoint);
}
/**
* Get the URL of the OpenSearch endpoint.
* @param endpoint the OpenSearch endpoint.
* @returns the endpoint URL.
*/
getEndpoint(endpoint) {
const serviceIdentifier = this.getServiceIdentifier(endpoint);
if (serviceIdentifier === 'es') {
return (`https://${endpoint.domainEndpoint}`);
}
else if (serviceIdentifier === 'aoss') {
return (endpoint.collectionEndpoint);
}
else {
throw new Error('Invalid endpoint.');
}
}
/**
* Get the service identifier of the OpenSearch endpoint.
* @param endpoint the OpenSearch endpoint.
* @returns the service identifier.
*/
getServiceIdentifier(endpoint) {
const e = endpoint;
if (e.domainArn
&& e.domainName
&& e.domainId
&& e.domainEndpoint) {
return ('es');
}
else if (e.collectionName
&& e.collectionArn
&& e.collectionId
&& e.collectionEndpoint) {
return ('aoss');
}
else {
throw new Error('Invalid endpoint.');
}
}
}
exports.OpenSearchIndex = OpenSearchIndex;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7OztHQWNHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVILGdEQUF3QjtBQUV4QixpREFBbUM7QUFDbkMsK0RBQWlEO0FBQ2pELG9FQUFzRDtBQUV0RCxxRUFBdUQ7QUFFdkQseURBQTJDO0FBSTNDLDJDQUF1QztBQW9DdkM7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFhLGVBQWdCLFNBQVEsc0JBQVM7SUFFNUM7O09BRUc7SUFDYSxTQUFTLENBQVM7SUFFbEM7Ozs7T0FJRztJQUNILFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBMkI7UUFDbkUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixzQkFBc0I7UUFDdEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDO1FBRWpDLDJCQUEyQjtRQUMzQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUVsRCw0Q0FBNEM7UUFDNUMsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRXBFLDZDQUE2QztRQUM3QyxNQUFNLGFBQWEsR0FBRyxjQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFFMUUseURBQXlEO1FBQ3pELE1BQU0sU0FBUyxHQUFHLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFO1lBQ3pELFdBQVcsRUFBRSw4REFBOEQ7WUFDM0UsS0FBSyxFQUFFLGNBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQztZQUM5QyxHQUFHLEVBQUUsS0FBSyxDQUFD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Q0FBQztRQUN2QyxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxvQkFBb0IsQ0FBQyxRQUE4QztRQUN6RSxNQUFNLENBQUMsR0FBRyxRQUFlLENBQUM7UUFFMUIsSUFBSSxDQUFDLENBQUMsU0FBUztlQUNWLENBQUMsQ0FBQyxVQUFVO2VBQ1osQ0FBQyxDQUFDLFFBQVE7ZUFDVixDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDdEIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hCLENBQUM7YUFBTSxJQUFJLENBQUMsQ0FBQyxjQUFjO2VBQ3RCLENBQUMsQ0FBQyxhQUFhO2VBQ2YsQ0FBQyxDQUFDLFlBQVk7ZUFDZCxDQUFDLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUMxQixPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbEIsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDdkMsQ0FBQztJQUNILENBQUM7Q0FDRjtBQW5JRCwwQ0FtSUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChDKSAyMDIzIEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcblxuaW1wb3J0ICogYXMgY2RrIGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCAqIGFzIG5vZGUgZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYS1ub2RlanMnO1xuaW1wb3J0ICogYXMgZWMyIGZyb20gJ2F3cy1jZGstbGliL2F3cy1lYzInO1xuaW1wb3J0ICogYXMgY3VzdG9tIGZyb20gJ2F3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXMnO1xuaW1wb3J0ICogYXMgb3BlbnNlYXJjaCBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtb3BlbnNlYXJjaHNlcnZpY2UnO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0ICogYXMgb3NzIGZyb20gJ0Bwcm9qZWN0LWxha2VjaGFpbi9vcGVuc2VhcmNoLWNvbGxlY3Rpb24nO1xuaW1wb3J0ICogYXMgbG9ncyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbG9ncyc7XG5cbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgU2VydmljZUlkZW50aWZpZXIgfSBmcm9tICcuL2RlZmluaXRpb25zL3NlcnZpY2UtaWRlbnRpZmllcic7XG5cbi8qKlxuICogVGhlIHByb3BlcnRpZXMgZm9yIHRoZSBPcGVuU2VhcmNoSW5kZXggY29uc3RydWN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE9wZW5TZWFyY2hJbmRleFByb3BzIHtcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIGluZGV4LlxuICAgKi9cbiAgcmVhZG9ubHkgaW5kZXhOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBib2R5IG9mIHRoZSBpbmRleCBjcmVhdGlvbiByZXF1ZXN0LlxuICAgKi9cbiAgcmVhZG9ubHkgYm9keTogUmVjb3JkPHN0cmluZywgYW55PjtcblxuICAvKipcbiAgICogVGhlIE9wZW5TZWFyY2ggZW5kcG9pbnQgb24gd2hpY2ggdGhlIGluZGV4XG4gICAqIHNob3VsZCBiZSBjcmVhdGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZW5kcG9pbnQ6IG9wZW5zZWFyY2guSURvbWFpbiB8IG9zcy5JQ29sbGVjdGlvbjtcblxuICAvKipcbiAgICogVGhlIFZQQyBpbiB3aGljaCB0aGUgT3BlblNlYXJjaCBkb21haW4gaXMgZGVwbG95ZWQuXG4gICAqL1xuICByZWFkb25seSB2cGM/OiBlYzIuSVZwYztcblxuICAvKipcbiAgICogVGhlIGxvZyBncm91cCBpbiB3aGljaCB0aGUgbGFtYmRhIGZ1bmN0aW9uIHdpbGxcbiAgICogd3JpdGUgaXRzIGxvZ3MuXG4gICAqL1xuICByZWFkb25seSBsb2dHcm91cD86IGxvZ3MuSUxvZ0dyb3VwO1xufVxuXG4vKipcbiAqIEEgY3VzdG9tIHJlc291cmNlIG1ha2luZyBpdCBlYXN5IHRvIGNyZWF0ZSBhbiBpbmRleFxuICogYW5kIG1hbmFnZSBpdHMgbGlmZWN5Y2xlIGFzIGEgQ0RLIGNvbnN0cnVjdC5cbiAqIFRoaXMgY29uc3RydWN0IHVzZXMgYSBsYW1iZGEgZnVuY3Rpb24gdG8gaW50ZXJhY3Qgd2l0aFxuICogdGhlIE9wZW5TZWFyY2ggZW5kcG9pbnQsIGFuZCB1c2VzIHRoZSBPcGVuU2VhcmNoIFNESyB0b1xuICogY3JlYXRlIGFuZCBkZWxldGUgdGhlIGluZGV4LlxuICogVGhpcyBjb25zdHJ1Y3QgaXMgY29tcGF0aWJsZSB3aXRoIE9wZW5TZWFyY2ggZG9tYWlucyBhbmQgc2VydmVybGVzc1xuICogY29sbGVjdGlvbnMgZGVwbG95ZWQgaW4gYSBWUEMgb3Igbm90LlxuICovXG5leHBvcnQgY2xhc3MgT3BlblNlYXJjaEluZGV4IGV4dGVuZHMgQ29uc3RydWN0IHtcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIGluZGV4IG1hbmFnZWQgYnkgdGhlIGNvbnN0cnVjdC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpbmRleE5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogT3BlblNlYXJjaCBJbmRleCBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0gc2NvcGUgdGhlIHNjb3BlIG9mIHRoZSBjb25zdHJ1Y3RcbiAgICogQHBhcmFtIGlkIHRoZSBpZCBvZiB0aGUgY29uc3RydWN0XG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogT3BlblNlYXJjaEluZGV4UHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgLy8gU2V0IHRoZSBpbmRleCBuYW1lLlxuICAgIHRoaXMuaW5kZXhOYW1lID0gcHJvcHMuaW5kZXhOYW1lO1xuXG4gICAgLy8gVGhlIE9wZW5TZWFyY2ggZW5kcG9pbnQuXG4gICAgY29uc3QgZW5kcG9pbnQgPSB0aGlzLmdldEVuZHBvaW50KHByb3BzLmVuZHBvaW50KTtcblxuICAgIC8vIFRoZSBpZGVudGlmaWVyIG9mIHRoZSBPcGVuU2VhcmNoIHNlcnZpY2UuXG4gICAgY29uc3Qgc2VydmljZUlkZW50aWZpZXIgPSB0aGlzLmdldFNlcnZpY2VJZGVudGlmaWVyKHByb3BzLmVuZHBvaW50KTtcblxuICAgIC8vIFRoZSBwYXRoIHRvIHRoZSBsYW1iZGEgZnVuY3Rpb24gZGlyZWN0b3J5LlxuICAgIGNvbnN0IHByb2Nlc3NvclBhdGggPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnbGFtYmRhcycsICdpbmRleC1tYW5hZ2VyJyk7XG5cbiAgICAvLyBDcmVhdGUgdGhlIGxhbWJkYSBmdW5jdGlvbiB0aGF0IHdpbGwgY3JlYXRlIHRoZSBpbmRleC5cbiAgICBjb25zdCBwcm9jZXNzb3IgPSBuZXcgbm9kZS5Ob2RlanNGdW5jdGlvbih0aGlzLCAnQ29tcHV0ZScsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQSBjdXN0b20gcmVzb3VyY2UgbWFuYWdpbmcgdGhlIHN0YXRlIG9mIGFuIE9wZW5TZWFyY2ggaW5kZXguJyxcbiAgICAgIGVudHJ5OiBwYXRoLnJlc29sdmUocHJvY2Vzc29yUGF0aCwgJ2luZGV4LmpzJyksXG4gICAgICB2cGM6IHByb3BzLnZwYyxcbiAgICAgIHRpbWVvdXQ6IGNkay5EdXJhdGlvbi5zZWNvbmRzKDEwKSxcbiAgICAgIHJ1bnRpbWU6IGxhbWJkYS5SdW50aW1lLk5PREVKU18xOF9YLFxuICAgICAgYXJjaGl0ZWN0dXJlOiBsYW1iZGEuQXJjaGl0ZWN0dXJlLkFSTV82NCxcbiAgICAgIGxvZ0dyb3VwOiBwcm9wcy5sb2dHcm91cCxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIE9QRU5TRUFSQ0hfRU5EUE9JTlQ6IGVuZHBvaW50LFxuICAgICAgICBPUEVOU0VBUkNIX0lOREVYX05BTUU6IHByb3BzLmluZGV4TmFtZSxcbiAgICAgICAgQk9EWV9QQVJBTUVURVJTOiBKU09OLnN0cmluZ2lmeShwcm9wcy5ib2R5KSxcbiAgICAgICAgU0VSVklDRV9JREVOVElGSUVSOiBzZXJ2aWNlSWRlbnRpZmllclxuICAgICAgfSxcbiAgICAgIGJ1bmRsaW5nOiB7XG4gICAgICAgIG1pbmlmeTogdHJ1ZSxcbiAgICAgICAgZXh0ZXJuYWxNb2R1bGVzOiBbXG4gICAgICAgICAgJ0Bhd3Mtc2RrL2NyZWRlbnRpYWwtcHJvdmlkZXItbm9kZSdcbiAgICAgICAgXVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHNlcnZpY2VJZGVudGlmaWVyID09PSAnZXMnKSB7XG4gICAgICAvLyBBbGxvdyB0aGUgbGFtYmRhIGZ1bmN0aW9uIHRvIG1hbmFnZSB0aGUgaW5kZXguXG4gICAgICAocHJvcHMuZW5kcG9pbnQgYXMgb3BlbnNlYXJjaC5Eb21haW4pLmdyYW50V3JpdGUocHJvY2Vzc29yKTtcbiAgICB9IGVsc2UgaWYgKHNlcnZpY2VJZGVudGlmaWVyID09PSAnYW9zcycpIHtcbiAgICAgIGNvbnN0IGVuZHBvaW50ID0gcHJvcHMuZW5kcG9pbnQgYXMgb3NzLkNvbGxlY3Rpb247XG5cbiAgICAgIC8vIElmIHRoZSBlbmRwb2ludCBpcyBhIGNvbGxlY3Rpb24sIHdlIGFsc28gbmVlZCB0byBjcmVhdGUgYW5cbiAgICAgIC8vIGFjY2VzcyBwb2xpY3kgb24gdGhlIGNvbGxlY3Rpb24gdG8gYWxsb3cgdGhlIGxhbWJkYSBmdW5jdGlvblxuICAgICAgLy8gdG8gbWFuYWdlIHRoZSBpbmRleC5cbiAgICAgIC8vIEFkZCBhIG5ldyBhY2Nlc3MgcG9saWN5LlxuICAgICAgZW5kcG9pbnQuYWRkQWNjZXNzUG9saWN5KFxuICAgICAgICB0aGlzLmluZGV4TmFtZSxcbiAgICAgICAgW3Byb2Nlc3Nvci5yb2xlIS5yb2xlQXJuXSxcbiAgICAgICAgWydhb3NzOkNyZWF0ZUluZGV4JywgJ2Fvc3M6RGVsZXRlSW5kZXgnLCAnYW9zczpVcGRhdGVJbmRleCddXG4gICAgICApO1xuXG4gICAgICAvLyBXZSBhbHNvIG5lZWQgdG8gZ3JhbnQgdGhlIGxhbWJkYSBmdW5jdGlvbiBwZXJtaXNzaW9uc1xuICAgICAgLy8gdG8gd3JpdGUgdG8gdGhlIE9wZW5TZWFyY2ggaW5kZXguXG4gICAgICBwcm9jZXNzb3IuYWRkVG9Sb2xlUG9saWN5KG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgICBhY3Rpb25zOiBbJ2Fvc3M6QVBJQWNjZXNzQWxsJ10sXG4gICAgICAgIHJlc291cmNlczogW2VuZHBvaW50LmNvbGxlY3Rpb25Bcm5dXG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIGEgY3VzdG9tIHJlc291cmNlIHRoYXQgd2lsbCBtYW5hZ2UgdGhlIGluZGV4LlxuICAgIGNvbnN0IHJlc291cmNlID0gbmV3IGNkay5DdXN0b21SZXNvdXJjZSh0aGlzLCAnUmVzb3VyY2UnLCB7XG4gICAgICBzZXJ2aWNlVG9rZW46IG5ldyBjdXN0b20uUHJvdmlkZXIodGhpcywgJ1Byb3ZpZGVyJywge1xuICAgICAgICBvbkV2ZW50SGFuZGxlcjogcHJvY2Vzc29yLFxuICAgICAgICBsb2dHcm91cDogcHJvcHMubG9nR3JvdXBcbiAgICAgIH0pLnNlcnZpY2VUb2tlbixcbiAgICAgIHJlc291cmNlVHlwZTogJ0N1c3RvbTo6T3BlblNlYXJjaEluZGV4JyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgSW5kZXhOYW1lOiBwcm9wcy5pbmRleE5hbWUsXG4gICAgICAgIEJvZHk6IHByb3BzLmJvZHksXG4gICAgICAgIEVuZHBvaW50OiBlbmRwb2ludFxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmVzb3VyY2Uubm9kZS5hZGREZXBlbmRlbmN5KHByb3BzLmVuZHBvaW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIFVSTCBvZiB0aGUgT3BlblNlYXJjaCBlbmRwb2ludC5cbiAgICogQHBhcmFtIGVuZHBvaW50IHRoZSBPcGVuU2VhcmNoIGVuZHBvaW50LlxuICAgKiBAcmV0dXJucyB0aGUgZW5kcG9pbnQgVVJMLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRFbmRwb2ludChlbmRwb2ludDogb3BlbnNlYXJjaC5JRG9tYWluIHwgb3NzLklDb2xsZWN0aW9uKTogc3RyaW5nIHtcbiAgICBjb25zdCBzZXJ2aWNlSWRlbnRpZmllciA9IHRoaXMuZ2V0U2VydmljZUlkZW50aWZpZXIoZW5kcG9pbnQpO1xuXG4gICAgaWYgKHNlcnZpY2VJZGVudGlmaWVyID09PSAnZXMnKSB7XG4gICAgICByZXR1cm4gKGBodHRwczovLyR7KGVuZHBvaW50IGFzIG9wZW5zZWFyY2guRG9tYWluKS5kb21haW5FbmRwb2ludH1gKTtcbiAgICB9IGVsc2UgaWYgKHNlcnZpY2VJZGVudGlmaWVyID09PSAnYW9zcycpIHtcbiAgICAgIHJldHVybiAoKGVuZHBvaW50IGFzIG9zcy5Db2xsZWN0aW9uKS5jb2xsZWN0aW9uRW5kcG9pbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZW5kcG9pbnQuJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgc2VydmljZSBpZGVudGlmaWVyIG9mIHRoZSBPcGVuU2VhcmNoIGVuZHBvaW50LlxuICAgKiBAcGFyYW0gZW5kcG9pbnQgdGhlIE9wZW5TZWFyY2ggZW5kcG9pbnQuXG4gICAqIEByZXR1cm5zIHRoZSBzZXJ2aWNlIGlkZW50aWZpZXIuXG4gICAqL1xuICBwcml2YXRlIGdldFNlcnZpY2VJZGVudGlmaWVyKGVuZHBvaW50OiBvcGVuc2VhcmNoLklEb21haW4gfCBvc3MuSUNvbGxlY3Rpb24pOiBTZXJ2aWNlSWRlbnRpZmllciB7XG4gICAgY29uc3QgZSA9IGVuZHBvaW50IGFzIGFueTtcbiAgICBcbiAgICBpZiAoZS5kb21haW5Bcm5cbiAgICAgICYmIGUuZG9tYWluTmFtZVxuICAgICAgJiYgZS5kb21haW5JZFxuICAgICAgJiYgZS5kb21haW5FbmRwb2ludCkge1xuICAgICAgcmV0dXJuICgnZXMnKTtcbiAgICB9IGVsc2UgaWYgKGUuY29sbGVjdGlvbk5hbWVcbiAgICAgICYmIGUuY29sbGVjdGlvbkFyblxuICAgICAgJiYgZS5jb2xsZWN0aW9uSWRcbiAgICAgICYmIGUuY29sbGVjdGlvbkVuZHBvaW50KSB7XG4gICAgICByZXR1cm4gKCdhb3NzJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBlbmRwb2ludC4nKTtcbiAgICB9XG4gIH1cbn0iXX0=