@aws-solutions-constructs/core
Version:
Core CDK Construct for patterns library
217 lines • 29.8 kB
JavaScript
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildKendraIndex = buildKendraIndex;
exports.AddMultipleKendraDataSources = AddMultipleKendraDataSources;
exports.AddKendraDataSource = AddKendraDataSource;
exports.normalizeKendraPermissions = normalizeKendraPermissions;
/*
* The functions found here in the core library are for internal use and can be changed
* or removed outside of a major release. We recommend against calling them directly from client code.
*/
const kendra = require("aws-cdk-lib/aws-kendra");
const iam = require("aws-cdk-lib/aws-iam");
const utils_1 = require("./utils");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const kendra_defaults_1 = require("./kendra-defaults");
/**
* @internal This is an internal core function and should not be called directly by Solutions Constructs clients.
*/
function buildKendraIndex(scope, id, props) {
// Conditional lambda function creation
if (props.existingIndexObj) {
// The client provided an Index, so we'll do nothing and return it to them
return props.existingIndexObj;
}
else {
let indexRoleArn = "";
// If the client provided a role, then don't bother creating a new one that we don't need
if (!props.kendraIndexProps?.roleArn) {
indexRoleArn = CreateKendraIndexLoggingRole(scope, id);
}
const defaultIndexProperties = (0, kendra_defaults_1.DefaultKendraIndexProps)(id, indexRoleArn);
const consolidatedIndexProperties = (0, utils_1.consolidateProps)(defaultIndexProperties, props.kendraIndexProps);
const newIndex = new kendra.CfnIndex(scope, `kendra-index-${id}`, consolidatedIndexProperties);
(0, utils_1.addCfnSuppressRules)(newIndex, [{
id: "W80",
reason: "We consulted the Kendra TFC and they confirmed the default encryption is sufficient for general use cases"
}]);
return newIndex;
}
}
/**
* @internal This is an internal core function and should not be called directly by Solutions Constructs clients.
*/
function AddMultipleKendraDataSources(scope, id, kendraIndex, clientDataSourceProps) {
const returnDataSources = [];
clientDataSourceProps.forEach((props, index) => {
returnDataSources.push(AddKendraDataSource(scope, `${id}${index}`, kendraIndex, props));
});
return returnDataSources;
}
/**
* @internal This is an internal core function and should not be called directly by Solutions Constructs clients.
*/
function AddKendraDataSource(scope, id, index, clientDataSourceProps) {
if (clientDataSourceProps.type === 'S3') {
return CreateS3DataSource(scope, index, id, clientDataSourceProps);
}
else {
if (clientDataSourceProps.indexId) {
throw new Error('Invalid DataSource prop specified - Construct must set the indexId prop');
}
return new kendra.CfnDataSource(scope, `kendra-data-source-${id}`, {
...clientDataSourceProps,
indexId: index.attrId
});
}
}
function CreateS3DataSource(scope, targetIndex, id, clientProps) {
// We go through some hoops here to extract the various inputs, because we need to narrow
// the type to remove the union with IResolvable
const dataSourceConfig = clientProps.dataSourceConfiguration;
if (!dataSourceConfig) {
throw new Error('Error - an S3 Kendra DataSource requires an DataSourceConfiguration prop');
}
const s3DataSourceConfig = dataSourceConfig.s3Configuration;
if (!s3DataSourceConfig) {
throw new Error('Error - an S3 Kendra DataSource requires an DataSourceConfiguration.S3Configuration prop');
}
// No Bucket name is an error
if (!s3DataSourceConfig.bucketName) {
throw new Error('Error - an S3 Kendra DataSource requires the DataSourceConfiguration.S3Configuration.bucketName prop');
}
// If there's no role, make a role and put it into defaultProps
// Put bucket name in default props
let defaultProps = {
indexId: targetIndex.ref,
name: (0, utils_1.generatePhysicalKendraIndexName)('', ['s3-datasource', id]),
type: 'S3'
};
// Return consolidated default and user props
if (!clientProps.roleArn) {
const s3CrawlPolicy = new iam.PolicyDocument({
statements: [
new iam.PolicyStatement({
actions: [
"s3:GetObject"
],
resources: [
`arn:aws:s3:::${s3DataSourceConfig.bucketName}/*`
],
effect: iam.Effect.ALLOW
}),
new iam.PolicyStatement({
actions: [
"s3:ListBucket"
],
resources: [
`arn:aws:s3:::${s3DataSourceConfig.bucketName}`
],
effect: iam.Effect.ALLOW
}),
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: [
"kendra:BatchPutDocument",
"kendra:BatchDeleteDocument"
],
resources: [
targetIndex.attrArn
]
}),
]
});
const dataSourceRole = new iam.Role(scope, `data-source-role-${id}`, {
assumedBy: new iam.ServicePrincipal('kendra.amazonaws.com'),
description: 'Policy for Kendra S3 Data Source',
inlinePolicies: {
s3CrawlPolicy,
},
});
defaultProps = (0, utils_1.overrideProps)(defaultProps, { roleArn: dataSourceRole.roleArn });
(0, utils_1.addCfnGuardSuppressRules)(dataSourceRole, ["IAM_NO_INLINE_POLICY_CHECK"]);
}
const consolidatedProps = (0, utils_1.consolidateProps)(defaultProps, clientProps);
return new kendra.CfnDataSource(scope, `data-source-${id}`, consolidatedProps);
}
function CreateKendraIndexLoggingRole(scope, id) {
const allowKendraToLogPolicy = new iam.PolicyDocument({
statements: [
new iam.PolicyStatement({
resources: ['*'],
actions: [
"cloudwatch:PutMetricData"
],
effect: iam.Effect.ALLOW,
conditions: {
StringEquals: {
"cloudwatch:namespace": "AWS/Kendra"
}
}
}),
new iam.PolicyStatement({
resources: [`arn:aws:logs:${aws_cdk_lib_1.Aws.REGION}:${aws_cdk_lib_1.Aws.ACCOUNT_ID}:log-group:/aws/kendra/*`],
actions: [
"logs:CreateLogGroup"
],
effect: iam.Effect.ALLOW,
}),
new iam.PolicyStatement({
resources: [`arn:${aws_cdk_lib_1.Aws.PARTITION}:logs:${aws_cdk_lib_1.Aws.REGION}:${aws_cdk_lib_1.Aws.ACCOUNT_ID}:log-group:/aws/kendra/*`],
actions: [
"logs:DescribeLogGroups"
],
effect: iam.Effect.ALLOW,
}),
new iam.PolicyStatement({
resources: [`arn:${aws_cdk_lib_1.Aws.PARTITION}:logs:${aws_cdk_lib_1.Aws.REGION}:${aws_cdk_lib_1.Aws.ACCOUNT_ID}:log-group:/aws/kendra/*:log-stream:*`],
actions: [
'logs:CreateLogStream',
'logs:PutLogEvents',
'logs:DescribeLogStream',
],
effect: iam.Effect.ALLOW,
}),
],
});
const indexRole = new iam.Role(scope, `kendra-index-role-${id}`, {
assumedBy: new iam.ServicePrincipal('kendra.amazonaws.com'),
description: 'Allow Kendra index to write CloudWatch Logs',
inlinePolicies: {
AllowLogging: allowKendraToLogPolicy,
},
});
(0, utils_1.addCfnSuppressRules)(indexRole, [{
id: "W11",
reason: "PutMetricData does not allow resource specification, " +
"scope is narrowed by the namespace condition. " +
"https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazoncloudwatch.html"
}]);
(0, utils_1.addCfnGuardSuppressRules)(indexRole, ["IAM_NO_INLINE_POLICY_CHECK"]);
return indexRole.roleArn;
}
// @summary Confirm each entry is a correct value, uppercase each entry
function normalizeKendraPermissions(rawPermissions) {
const validPermissions = ["READ", "SUBMITFEEDBACK", "WRITE"];
const result = rawPermissions.map((s) => {
const upperCaseValue = s.toUpperCase();
if (!validPermissions.includes(upperCaseValue)) {
throw new Error(`Invalid indexPermission value - valid values are "READ", "SUBMITFEEDBACK" and "WRITE"`);
}
return upperCaseValue;
});
return result;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2VuZHJhLWhlbHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImtlbmRyYS1oZWxwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7OztHQVdHOztBQTZCSCw0Q0F3QkM7QUFLRCxvRUFVQztBQUtELGtEQWVDO0FBaUpELGdFQVdDO0FBbFBEOzs7R0FHRztBQUVILGlEQUFpRDtBQUNqRCwyQ0FBMkM7QUFDM0MsbUNBQTBJO0FBQzFJLDZDQUFrQztBQUlsQyx1REFBNEQ7QUFZNUQ7O0dBRUc7QUFDSCxTQUFnQixnQkFBZ0IsQ0FBQyxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUE0QjtJQUN6Rix1Q0FBdUM7SUFDdkMsSUFBSSxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUMzQiwwRUFBMEU7UUFDMUUsT0FBTyxLQUFLLENBQUMsZ0JBQWdCLENBQUM7SUFDaEMsQ0FBQztTQUFNLENBQUM7UUFFTixJQUFJLFlBQVksR0FBVyxFQUFFLENBQUM7UUFFOUIseUZBQXlGO1FBQ3pGLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDckMsWUFBWSxHQUFHLDRCQUE0QixDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN6RCxDQUFDO1FBQ0QsTUFBTSxzQkFBc0IsR0FBRyxJQUFBLHlDQUF1QixFQUFDLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUV6RSxNQUFNLDJCQUEyQixHQUFHLElBQUEsd0JBQWdCLEVBQUMsc0JBQXNCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDckcsTUFBTSxRQUFRLEdBQUcsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxFQUFFLEVBQUUsMkJBQTJCLENBQUMsQ0FBQztRQUMvRixJQUFBLDJCQUFtQixFQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUM3QixFQUFFLEVBQUUsS0FBSztnQkFDVCxN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QUM7SUFDSCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgQ29weXJpZ2h0IEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIikuIFlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcbiAqICB3aXRoIHRoZSBMaWNlbnNlLiBBIGNvcHkgb2YgdGhlIExpY2Vuc2UgaXMgbG9jYXRlZCBhdFxuICpcbiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogIG9yIGluIHRoZSAnbGljZW5zZScgZmlsZSBhY2NvbXBhbnlpbmcgdGhpcyBmaWxlLiBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgb24gYW4gJ0FTIElTJyBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTXG4gKiAgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnNcbiAqICBhbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuLypcbiAqICBUaGUgZnVuY3Rpb25zIGZvdW5kIGhlcmUgaW4gdGhlIGNvcmUgbGlicmFyeSBhcmUgZm9yIGludGVybmFsIHVzZSBhbmQgY2FuIGJlIGNoYW5nZWRcbiAqICBvciByZW1vdmVkIG91dHNpZGUgb2YgYSBtYWpvciByZWxlYXNlLiBXZSByZWNvbW1lbmQgYWdhaW5zdCBjYWxsaW5nIHRoZW0gZGlyZWN0bHkgZnJvbSBjbGllbnQgY29kZS5cbiAqL1xuXG5pbXBvcnQgKiBhcyBrZW5kcmEgZnJvbSAnYXdzLWNkay1saWIvYXdzLWtlbmRyYSc7XG5pbXBvcnQgKiBhcyBpYW0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQgeyBhZGRDZm5HdWFyZFN1cHByZXNzUnVsZXMsIGFkZENmblN1cHByZXNzUnVsZXMsIGNvbnNvbGlkYXRlUHJvcHMsIGdlbmVyYXRlUGh5c2ljYWxLZW5kcmFJbmRleE5hbWUsIG92ZXJyaWRlUHJvcHMgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgQXdzIH0gZnJvbSAnYXdzLWNkay1saWInO1xuXG4vLyBOb3RlOiBUbyBlbnN1cmUgQ0RLdjIgY29tcGF0aWJpbGl0eSwga2VlcCB0aGUgaW1wb3J0IHN0YXRlbWVudCBmb3IgQ29uc3RydWN0IHNlcGFyYXRlXG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IERlZmF1bHRLZW5kcmFJbmRleFByb3BzIH0gZnJvbSAnLi9rZW5kcmEtZGVmYXVsdHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkS2VuZHJhSW5kZXhQcm9wcyB7XG4gIHJlYWRvbmx5IGtlbmRyYUluZGV4UHJvcHM/OiBrZW5kcmEuQ2ZuSW5kZXhQcm9wcyB8IGFueTtcbiAgLyoqXG4gICAqIEV4aXN0aW5nIGluc3RhbmNlIG9mIEtlbmRyYSBJbmRleCBvYmplY3QsIFByb3ZpZGluZyBib3RoIHRoaXMgYW5kIGtlbmRyYUluZGV4UHJvcHMgd2lsbCBjYXVzZSBhbiBlcnJvci5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBOb25lXG4gICAqL1xuICByZWFkb25seSBleGlzdGluZ0luZGV4T2JqPzoga2VuZHJhLkNmbkluZGV4O1xufVxuXG4vKipcbiAqIEBpbnRlcm5hbCBUaGlzIGlzIGFuIGludGVybmFsIGNvcmUgZnVuY3Rpb24gYW5kIHNob3VsZCBub3QgYmUgY2FsbGVkIGRpcmVjdGx5IGJ5IFNvbHV0aW9ucyBDb25zdHJ1Y3RzIGNsaWVudHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEtlbmRyYUluZGV4KHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBCdWlsZEtlbmRyYUluZGV4UHJvcHMpOiBrZW5kcmEuQ2ZuSW5kZXgge1xuICAvLyBDb25kaXRpb25hbCBsYW1iZGEgZnVuY3Rpb24gY3JlYXRpb25cbiAgaWYgKHByb3BzLmV4aXN0aW5nSW5kZXhPYmopIHtcbiAgICAvLyBUaGUgY2xpZW50IHByb3ZpZGVkIGFuIEluZGV4LCBzbyB3ZSdsbCBkbyBub3RoaW5nIGFuZCByZXR1cm4gaXQgdG8gdGhlbVxuICAgIHJldHVybiBwcm9wcy5leGlzdGluZ0luZGV4T2JqO1xuICB9IGVsc2Uge1xuXG4gICAgbGV0IGluZGV4Um9sZUFybjogc3RyaW5nID0gXCJcIjtcblxuICAgIC8vIElmIHRoZSBjbGllbnQgcHJvdmlkZWQgYSByb2xlLCB0aGVuIGRvbid0IGJvdGhlciBjcmVhdGluZyBhIG5ldyBvbmUgdGhhdCB3ZSBkb24ndCBuZWVkXG4gICAgaWYgKCFwcm9wcy5rZW5kcmFJbmRleFByb3BzPy5yb2xlQXJuKSB7XG4gICAgICBpbmRleFJvbGVBcm4gPSBDcmVhdGVLZW5kcmFJbmRleExvZ2dpbmdSb2xlKHNjb3BlLCBpZCk7XG4gICAgfVxuICAgIGNvbnN0IGRlZmF1bHRJbmRleFByb3BlcnRpZXMgPSBEZWZhdWx0S2VuZHJhSW5kZXhQcm9wcyhpZCwgaW5kZXhSb2xlQXJuKTtcblxuICAgIGNvbnN0IGNvbnNvbGlkYXRlZEluZGV4UHJvcGVydGllcyA9IGNvbnNvbGlkYXRlUHJvcHMoZGVmYXVsdEluZGV4UHJvcGVydGllcywgcHJvcHMua2VuZHJhSW5kZXhQcm9wcyk7XG4gICAgY29uc3QgbmV3SW5kZXggPSBuZXcga2VuZHJhLkNmbkluZGV4KHNjb3BlLCBga2VuZHJhLWluZGV4LSR7aWR9YCwgY29uc29saWRhdGVkSW5kZXhQcm9wZXJ0aWVzKTtcbiAgICBhZGRDZm5TdXBwcmVzc1J1bGVzKG5ld0luZGV4LCBbe1xuICAgICAgaWQ6IFwiVzgwXCIsXG4gICAgICByZWFzb246IFwiV2UgY29uc3VsdGVkIHRoZSBLZW5kcmEgVEZDIGFuZCB0aGV5IGNvbmZpcm1lZCB0aGUgZGVmYXVsdCBlbmNyeXB0aW9uIGlzIHN1ZmZpY2llbnQgZm9yIGdlbmVyYWwgdXNlIGNhc2VzXCJcbiAgICB9XSk7XG5cbiAgICByZXR1cm4gbmV3SW5kZXg7XG4gIH1cbn1cblxuLyoqXG4gKiBAaW50ZXJuYWwgVGhpcyBpcyBhbiBpbnRlcm5hbCBjb3JlIGZ1bmN0aW9uIGFuZCBzaG91bGQgbm90IGJlIGNhbGxlZCBkaXJlY3RseSBieSBTb2x1dGlvbnMgQ29uc3RydWN0cyBjbGllbnRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gQWRkTXVsdGlwbGVLZW5kcmFEYXRhU291cmNlcyhzY29wZTogQ29uc3RydWN0LFxuICBpZDogc3RyaW5nLFxuICBrZW5kcmFJbmRleDoga2VuZHJhLkNmbkluZGV4LFxuICBjbGllbnREYXRhU291cmNlUHJvcHM6IFBhcnRpYWw8a2VuZHJhLkNmbkRhdGFTb3VyY2VQcm9wcz5bXSk6IGtlbmRyYS5DZm5EYXRhU291cmNlW10ge1xuXG4gIGNvbnN0IHJldHVybkRhdGFTb3VyY2VzOiBrZW5kcmEuQ2ZuRGF0YVNvdXJjZVtdID0gW107XG4gIGNsaWVudERhdGFTb3VyY2VQcm9wcy5mb3JFYWNoKChwcm9wcywgaW5kZXgpID0+IHtcbiAgICByZXR1cm5EYXRhU291cmNlcy5wdXNoKEFkZEtlbmRyYURhdGFTb3VyY2Uoc2NvcGUsIGAke2lkfSR7aW5kZXh9YCwga2VuZHJhSW5kZXgsIHByb3BzKSk7XG4gIH0pO1xuICByZXR1cm4gcmV0dXJuRGF0YVNvdXJjZXM7XG59XG5cbi8qKlxuICogQGludGVybmFsIFRoaXMgaXMgYW4gaW50ZXJuYWwgY29yZSBmdW5jdGlvbiBhbmQgc2hvdWxkIG5vdCBiZSBjYWxsZWQgZGlyZWN0bHkgYnkgU29sdXRpb25zIENvbnN0cnVjdHMgY2xpZW50cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEFkZEtlbmRyYURhdGFTb3VyY2Uoc2NvcGU6IENvbnN0cnVjdCxcbiAgaWQ6IHN0cmluZywgaW5kZXg6IGtlbmRyYS5DZm5JbmRleCxcbiAgY2xpZW50RGF0YVNvdXJjZVByb3BzOiBrZW5kcmEuQ2ZuRGF0YVNvdXJjZVByb3BzIHwgYW55KToga2VuZHJhLkNmbkRhdGFTb3VyY2Uge1xuXG4gIGlmICAoY2xpZW50RGF0YVNvdXJjZVByb3BzLnR5cGUgPT09ICdTMycpIHtcbiAgICByZXR1cm4gQ3JlYXRlUzNEYXRhU291cmNlKHNjb3BlLCBpbmRleCwgaWQsIGNsaWVudERhdGFTb3VyY2VQcm9wcyk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKGNsaWVudERhdGFTb3VyY2VQcm9wcy5pbmRleElkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgRGF0YVNvdXJjZSBwcm9wIHNwZWNpZmllZCAtIENvbnN0cnVjdCBtdXN0IHNldCB0aGUgaW5kZXhJZCBwcm9wJyk7XG4gICAgfVxuICAgIHJldHVybiBuZXcga2VuZHJhLkNmbkRhdGFTb3VyY2Uoc2NvcGUsIGBrZW5kcmEtZGF0YS1zb3VyY2UtJHtpZH1gLCB7XG4gICAgICAuLi5jbGllbnREYXRhU291cmNlUHJvcHMsXG4gICAgICBpbmRleElkOiBpbmRleC5hdHRySWRcbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBDcmVhdGVTM0RhdGFTb3VyY2Uoc2NvcGU6IENvbnN0cnVjdCxcbiAgdGFyZ2V0SW5kZXg6IGtlbmRyYS5DZm5JbmRleCxcbiAgaWQ6IHN0cmluZyxcbiAgY2xpZW50UHJvcHM6IFBhcnRpYWw8a2VuZHJhLkNmbkRhdGFTb3VyY2VQcm9wcz4pOiBrZW5kcmEuQ2ZuRGF0YVNvdXJjZSB7XG5cbiAgLy8gV2UgZ28gdGhyb3VnaCBzb21lIGhvb3BzIGhlcmUgdG8gZXh0cmFjdCB0aGUgdmFyaW91cyBpbnB1dHMsIGJlY2F1c2Ugd2UgbmVlZCB0byBuYXJyb3dcbiAgLy8gdGhlIHR5cGUgdG8gcmVtb3ZlIHRoZSB1bmlvbiB3aXRoIElSZXNvbHZhYmxlXG4gIGNvbnN0IGRhdGFTb3VyY2VDb25maWcgPSBjbGllbnRQcm9wcy5kYXRhU291cmNlQ29uZmlndXJhdGlvbiBhcyBrZW5kcmEuQ2ZuRGF0YVNvdXJjZS5EYXRhU291cmNlQ29uZmlndXJhdGlvblByb3BlcnR5O1xuICBpZiAoIWRhdGFTb3VyY2VDb25maWcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Vycm9yIC0gYW4gUzMgS2VuZHJhIERhdGFTb3VyY2UgcmVxdWlyZXMgYW4gRGF0YVNvdXJjZUNvbmZpZ3VyYXRpb24gcHJvcCcpO1xuICB9XG5cbiAgY29uc3QgczNEYXRhU291cmNlQ29uZmlnID0gZGF0YVNvdXJjZUNvbmZpZy5zM0NvbmZpZ3VyYXRpb24gYXMga2VuZHJhLkNmbkRhdGFTb3VyY2UuUzNEYXRhU291cmNlQ29uZmlndXJhdGlvblByb3BlcnR5O1xuXG4gIGlmICghczNEYXRhU291cmNlQ29uZmlnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdFcnJvciAtIGFuIFMzIEtlbmRyYSBEYXRhU291cmNlIHJlcXVpcmVzIGFuIERhdGFTb3VyY2VDb25maWd1cmF0aW9uLlMzQ29uZmlndXJhdGlvbiBwcm9wJyk7XG4gIH1cblxuICAvLyBObyBCdWNrZXQgbmFtZSBpcyBhbiBlcnJvclxuICBpZiAoIXMzRGF0YVNvdXJjZUNvbmZpZy5idWNrZXROYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdFcnJvciAtIGFuIFMzIEtlbmRyYSBEYXRhU291cmNlIHJlcXVpcmVzIHRoZSBEYXRhU291cmNlQ29uZmlndXJhdGlvbi5TM0NvbmZpZ3VyYXRpb24uYnVja2V0TmFtZSBwcm9wJyk7XG4gIH1cblxuICAvLyBJZiB0aGVyZSdzIG5vIHJvbGUsIG1ha2UgYSByb2xlIGFuZCBwdXQgaXQgaW50byBkZWZhdWx0UHJvcHNcbiAgLy8gUHV0IGJ1Y2tldCBuYW1lIGluIGRlZmF1bHQgcHJvcHNcbiAgbGV0IGRlZmF1bHRQcm9wczoga2VuZHJhLkNmbkRhdGFTb3VyY2VQcm9wcyA9IHtcbiAgICBpbmRleElkOiB0YXJnZXRJbmRleC5yZWYsXG4gICAgbmFtZTogZ2VuZXJhdGVQaHlzaWNhbEtlbmRyYUluZGV4TmFtZSgnJywgWydzMy1kYXRhc291cmNlJywgaWRdKSxcbiAgICB0eXBlOiAnUzMnXG4gIH07XG5cbiAgLy8gUmV0dXJuIGNvbnNvbGlkYXRlZCBkZWZhdWx0IGFuZCB1c2VyIHByb3BzXG4gIGlmICghY2xpZW50UHJvcHMucm9sZUFybikge1xuICAgIGNvbnN0IHMzQ3Jhd2xQb2xpY3kgPSBuZXcgaWFtLlBvbGljeURvY3VtZW50KHtcbiAgICAgIHN0YXRlbWVudHM6IFtcbiAgICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgIFwiczM6R2V0T2JqZWN0XCJcbiAgICAgICAgICBdLFxuICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgYGFybjphd3M6czM6Ojoke3MzRGF0YVNvdXJjZUNvbmZpZy5idWNrZXROYW1lfS8qYFxuICAgICAgICAgIF0sXG4gICAgICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XXG4gICAgICAgIH0pLFxuICAgICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgXCJzMzpMaXN0QnVja2V0XCJcbiAgICAgICAgICBdLFxuICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgYGFybjphd3M6czM6Ojoke3MzRGF0YVNvdXJjZUNvbmZpZy5idWNrZXROYW1lfWBcbiAgICAgICAgICBdLFxuICAgICAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPV1xuICAgICAgICB9KSxcbiAgICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVyxcbiAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICBcImtlbmRyYTpCYXRjaFB1dERvY3VtZW50XCIsXG4gICAgICAgICAgICBcImtlbmRyYTpCYXRjaERlbGV0ZURvY3VtZW50XCJcbiAgICAgICAgICBdLFxuICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgdGFyZ2V0SW5kZXguYXR0ckFyblxuICAgICAgICAgIF1cbiAgICAgICAgfSksXG4gICAgICBdXG4gICAgfSk7XG5cbiAgICBjb25zdCBkYXRhU291cmNlUm9sZTogaWFtLlJvbGUgPSBuZXcgaWFtLlJvbGUoc2NvcGUsIGBkYXRhLXNvdXJjZS1yb2xlLSR7aWR9YCwge1xuICAgICAgYXNzdW1lZEJ5OiBuZXcgaWFtLlNlcnZpY2VQcmluY2lwYWwoJ2tlbmRyYS5hbWF6b25hd3MuY29tJyksXG4gICAgICBkZXNjcmlwdGlvbjogJ1BvbGljeSBmb3IgS2VuZHJhIFMzIERhdGEgU291cmNlJyxcbiAgICAgIGlubGluZVBvbGljaWVzOiB7XG4gICAgICAgIHMzQ3Jhd2xQb2xpY3ksXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGRlZmF1bHRQcm9wcyA9IG92ZXJyaWRlUHJvcHMoZGVmYXVsdFByb3BzLCB7IHJvbGVBcm46IGRhdGFTb3VyY2VSb2xlLnJvbGVBcm4gfSk7XG4gICAgYWRkQ2ZuR3VhcmRTdXBwcmVzc1J1bGVzKGRhdGFTb3VyY2VSb2xlLCBbXCJJQU1fTk9fSU5MSU5FX1BPTElDWV9DSEVDS1wiXSk7XG4gIH1cblxuICBjb25zdCBjb25zb2xpZGF0ZWRQcm9wczoga2VuZHJhLkNmbkRhdGFTb3VyY2VQcm9wcyA9IGNvbnNvbGlkYXRlUHJvcHMoZGVmYXVsdFByb3BzLCBjbGllbnRQcm9wcyk7XG5cbiAgcmV0dXJuIG5ldyBrZW5kcmEuQ2ZuRGF0YVNvdXJjZShzY29wZSwgYGRhdGEtc291cmNlLSR7aWR9YCwgY29uc29saWRhdGVkUHJvcHMpO1xuXG59XG5cbmZ1bmN0aW9uIENyZWF0ZUtlbmRyYUluZGV4TG9nZ2luZ1JvbGUoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGFsbG93S2VuZHJhVG9Mb2dQb2xpY3kgPSBuZXcgaWFtLlBvbGljeURvY3VtZW50KHtcbiAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICBcImNsb3Vkd2F0Y2g6UHV0TWV0cmljRGF0YVwiXG4gICAgICAgIF0sXG4gICAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVyxcbiAgICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICAgIFN0cmluZ0VxdWFsczoge1xuICAgICAgICAgICAgXCJjbG91ZHdhdGNoOm5hbWVzcGFjZVwiOiBcIkFXUy9LZW5kcmFcIlxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIHJlc291cmNlczogW2Bhcm46YXdzOmxvZ3M6JHtBd3MuUkVHSU9OfToke0F3cy5BQ0NPVU5UX0lEfTpsb2ctZ3JvdXA6L2F3cy9rZW5kcmEvKmBdLFxuICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgXCJsb2dzOkNyZWF0ZUxvZ0dyb3VwXCJcbiAgICAgICAgXSxcbiAgICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgfSksXG4gICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIHJlc291cmNlczogW2Bhcm46JHtBd3MuUEFSVElUSU9OfTpsb2dzOiR7QXdzLlJFR0lPTn06JHtBd3MuQUNDT1VOVF9JRH06bG9nLWdyb3VwOi9hd3Mva2VuZHJhLypgXSxcbiAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgIFwibG9nczpEZXNjcmliZUxvZ0dyb3Vwc1wiXG4gICAgICAgIF0sXG4gICAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVyxcbiAgICAgIH0pLFxuICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICByZXNvdXJjZXM6IFtgYXJuOiR7QXdzLlBBUlRJVElPTn06bG9nczoke0F3cy5SRUdJT059OiR7QXdzLkFDQ09VTlRfSUR9OmxvZy1ncm91cDovYXdzL2tlbmRyYS8qOmxvZy1zdHJlYW06KmBdLFxuICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgJ2xvZ3M6Q3JlYXRlTG9nU3RyZWFtJyxcbiAgICAgICAgICAnbG9nczpQdXRMb2dFdmVudHMnLFxuICAgICAgICAgICdsb2dzOkRlc2NyaWJlTG9nU3RyZWFtJyxcbiAgICAgICAgXSxcbiAgICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgfSksXG4gICAgXSxcbiAgfSk7XG5cbiAgY29uc3QgaW5kZXhSb2xlOiBpYW0uUm9sZSA9IG5ldyBpYW0uUm9sZShzY29wZSwgYGtlbmRyYS1pbmRleC1yb2xlLSR7aWR9YCwge1xuICAgIGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdrZW5kcmEuYW1hem9uYXdzLmNvbScpLFxuICAgIGRlc2NyaXB0aW9uOiAnQWxsb3cgS2VuZHJhIGluZGV4IHRvIHdyaXRlIENsb3VkV2F0Y2ggTG9ncycsXG4gICAgaW5saW5lUG9saWNpZXM6IHtcbiAgICAgIEFsbG93TG9nZ2luZzogYWxsb3dLZW5kcmFUb0xvZ1BvbGljeSxcbiAgICB9LFxuICB9KTtcbiAgYWRkQ2ZuU3VwcHJlc3NSdWxlcyhpbmRleFJvbGUsIFt7XG4gICAgaWQ6IFwiVzExXCIsXG4gICAgcmVhc29uOiBcIlB1dE1ldHJpY0RhdGEgZG9lcyBub3QgYWxsb3cgcmVzb3VyY2Ugc3BlY2lmaWNhdGlvbiwgXCIgK1xuICAgICAgXCJzY29wZSBpcyBuYXJyb3dlZCBieSB0aGUgbmFtZXNwYWNlIGNvbmRpdGlvbi4gXCIgK1xuICAgICAgXCJodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hbWF6b25jbG91ZHdhdGNoLmh0bWxcIlxuICB9XSk7XG4gIGFkZENmbkd1YXJkU3VwcHJlc3NSdWxlcyhpbmRleFJvbGUsIFtcIklBTV9OT19JTkxJTkVfUE9MSUNZX0NIRUNLXCJdKTtcblxuICByZXR1cm4gaW5kZXhSb2xlLnJvbGVBcm47XG59XG5cbi8vIEBzdW1tYXJ5IENvbmZpcm0gZWFjaCBlbnRyeSBpcyBhIGNvcnJlY3QgdmFsdWUsIHVwcGVyY2FzZSBlYWNoIGVudHJ5XG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplS2VuZHJhUGVybWlzc2lvbnMocmF3UGVybWlzc2lvbnM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICBjb25zdCB2YWxpZFBlcm1pc3Npb25zID0gW1wiUkVBRFwiLCBcIlNVQk1JVEZFRURCQUNLXCIsIFwiV1JJVEVcIl07XG5cbiAgY29uc3QgcmVzdWx0ID0gcmF3UGVybWlzc2lvbnMubWFwPHN0cmluZz4oKHMpID0+IHtcbiAgICBjb25zdCB1cHBlckNhc2VWYWx1ZSA9IHMudG9VcHBlckNhc2UoKTtcbiAgICBpZiAoIXZhbGlkUGVybWlzc2lvbnMuaW5jbHVkZXModXBwZXJDYXNlVmFsdWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgaW5kZXhQZXJtaXNzaW9uIHZhbHVlIC0gdmFsaWQgdmFsdWVzIGFyZSBcIlJFQURcIiwgXCJTVUJNSVRGRUVEQkFDS1wiIGFuZCBcIldSSVRFXCJgKTtcbiAgICB9XG4gICAgcmV0dXJuIHVwcGVyQ2FzZVZhbHVlO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiJdfQ==
;