@aws-solutions-constructs/core
Version:
Core CDK Construct for patterns library
384 lines • 39.5 kB
JavaScript
"use strict";
/**
* 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 });
const aws_cdk_lib_1 = require("aws-cdk-lib");
const s3 = require("aws-cdk-lib/aws-s3");
const kms = require("aws-cdk-lib/aws-kms");
const defaults = require("../index");
const utils_1 = require("../lib/utils");
const assertions_1 = require("aws-cdk-lib/assertions");
const test_helper_1 = require("./test-helper");
const test_helper_2 = require("./test-helper");
test('test s3Bucket override versioningConfiguration', () => {
const stack = new aws_cdk_lib_1.Stack();
const defaultProps = defaults.DefaultS3Props();
const inProps = {
versioned: false
};
const outProps = (0, utils_1.overrideProps)(defaultProps, inProps);
new s3.Bucket(stack, 'test-s3-verioning', outProps);
assertions_1.Template.fromStack(stack).hasResourceProperties("AWS::S3::Bucket", {
BucketEncryption: {
ServerSideEncryptionConfiguration: [
{
ServerSideEncryptionByDefault: {
SSEAlgorithm: "AES256"
}
}
]
},
PublicAccessBlockConfiguration: {
BlockPublicAcls: true,
BlockPublicPolicy: true,
IgnorePublicAcls: true,
RestrictPublicBuckets: true
}
});
});
test('test s3Bucket override bucketEncryption', () => {
const stack = new aws_cdk_lib_1.Stack();
const defaultProps = defaults.DefaultS3Props();
const inProps = {
encryption: s3.BucketEncryption.KMS,
encryptionKey: new kms.Key(stack, 'mykeyid')
};
const outProps = (0, utils_1.overrideProps)(defaultProps, inProps);
new s3.Bucket(stack, 'test-s3-encryption', outProps);
assertions_1.Template.fromStack(stack).hasResourceProperties("AWS::S3::Bucket", {
BucketEncryption: {
ServerSideEncryptionConfiguration: [
{
ServerSideEncryptionByDefault: {
KMSMasterKeyID: {
"Fn::GetAtt": [
"mykeyidFA4203B0",
"Arn"
]
},
SSEAlgorithm: "aws:kms"
}
}
]
},
});
});
test('test s3Bucket override publicAccessBlockConfiguration', () => {
const stack = new aws_cdk_lib_1.Stack();
const defaultProps = defaults.DefaultS3Props();
const inProps = {
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ACLS
};
const outProps = (0, utils_1.overrideProps)(defaultProps, inProps);
new s3.Bucket(stack, 'test-s3-publicAccessBlock', outProps);
assertions_1.Template.fromStack(stack).hasResourceProperties("AWS::S3::Bucket", {
PublicAccessBlockConfiguration: {
BlockPublicAcls: true,
IgnorePublicAcls: true
},
});
});
test('test s3Bucket add lifecycleConfiguration', () => {
const stack = new aws_cdk_lib_1.Stack();
const defaultProps = defaults.DefaultS3Props();
const inProps = {
lifecycleRules: [{
expiration: aws_cdk_lib_1.Duration.days(365)
}]
};
const outProps = (0, utils_1.overrideProps)(defaultProps, inProps);
new s3.Bucket(stack, 'test-s3-lifecycle', outProps);
assertions_1.Template.fromStack(stack).hasResourceProperties("AWS::S3::Bucket", {
LifecycleConfiguration: {
Rules: [
{
Status: 'Enabled',
ExpirationInDays: 365,
}
]
}
});
});
test('test s3Bucket override serverAccessLogsBucket', () => {
const stack = new aws_cdk_lib_1.Stack();
const myLoggingBucket = new s3.Bucket(stack, 'MyS3LoggingBucket', defaults.DefaultS3Props());
const myS3Props = defaults.DefaultS3Props(myLoggingBucket);
defaults.buildS3Bucket(stack, {
bucketProps: myS3Props
});
assertions_1.Template.fromStack(stack).hasResourceProperties("AWS::S3::Bucket", {
LoggingConfiguration: {
DestinationBucketName: {
Ref: "MyS3LoggingBucket119BE896"
}
}
});
});
test('test createAlbLoggingBucket()', () => {
const stack = new aws_cdk_lib_1.Stack();
defaults.createAlbLoggingBucket(stack, 'test-bucket', {
bucketName: 'test-name'
});
assertions_1.Template.fromStack(stack).hasResourceProperties("AWS::S3::Bucket", {
BucketName: 'test-name'
});
});
test('Test bucket policy that only accepts SSL requests only', () => {
const stack = new aws_cdk_lib_1.Stack();
defaults.buildS3Bucket(stack, {
bucketProps: {
enforceSSL: true
}
}, 'test-bucket');
assertions_1.Template.fromStack(stack).hasResourceProperties("AWS::S3::BucketPolicy", {
PolicyDocument: {
Statement: [
{
Action: "s3:*",
Condition: {
Bool: {
"aws:SecureTransport": "false"
}
},
Effect: "Deny",
Principal: {
AWS: "*"
},
Resource: [
{
"Fn::GetAtt": [
"testbucketS3Bucket87F6BFFC",
"Arn"
]
},
{
"Fn::Join": [
"",
[
{
"Fn::GetAtt": [
"testbucketS3Bucket87F6BFFC",
"Arn"
]
},
"/*"
]
]
}
]
}
],
Version: "2012-10-17"
}
});
});
test('Test bucket policy that accepts any requests', () => {
const stack = new aws_cdk_lib_1.Stack();
defaults.buildS3Bucket(stack, {
bucketProps: {
enforceSSL: false
}
}, 'test-bucket');
(0, test_helper_1.expectNonexistence)(stack, "AWS::S3::BucketPolicy", {
PolicyDocument: {
Statement: [
{
Action: "s3:*",
Condition: {
Bool: {
"aws:SecureTransport": "false"
}
},
Effect: "Deny",
Principal: {
AWS: "*"
},
Resource: [
{
"Fn::GetAtt": [
"testbucketS3Bucket87F6BFFC",
"Arn"
]
},
{
"Fn::Join": [
"",
[
{
"Fn::GetAtt": [
"testbucketS3Bucket87F6BFFC",
"Arn"
]
},
"/*"
]
]
}
]
}
],
Version: "2012-10-17"
}
});
});
test('Test enforcing SSL when bucketProps is not provided', () => {
const stack = new aws_cdk_lib_1.Stack();
defaults.buildS3Bucket(stack, {}, 'test-bucket');
assertions_1.Template.fromStack(stack).hasResourceProperties("AWS::S3::BucketPolicy", {
PolicyDocument: {
Statement: [
{
Action: "s3:*",
Condition: {
Bool: {
"aws:SecureTransport": "false"
}
},
Effect: "Deny",
Principal: {
AWS: "*"
},
Resource: [
{
"Fn::GetAtt": [
"testbucketS3Bucket87F6BFFC",
"Arn"
]
},
{
"Fn::Join": [
"",
[
{
"Fn::GetAtt": [
"testbucketS3Bucket87F6BFFC",
"Arn"
]
},
"/*"
]
]
}
]
}
],
Version: "2012-10-17"
}
});
});
test('Test enforcing SSL when bucketProps is provided and enforceSSL is not set', () => {
const stack = new aws_cdk_lib_1.Stack();
defaults.buildS3Bucket(stack, {
bucketProps: {
versioned: false,
publicReadAccess: false
}
}, 'test-bucket');
assertions_1.Template.fromStack(stack).hasResourceProperties("AWS::S3::BucketPolicy", {
PolicyDocument: {
Statement: [
{
Action: "s3:*",
Condition: {
Bool: {
"aws:SecureTransport": "false"
}
},
Effect: "Deny",
Principal: {
AWS: "*"
},
Resource: [
{
"Fn::GetAtt": [
"testbucketS3Bucket87F6BFFC",
"Arn"
]
},
{
"Fn::Join": [
"",
[
{
"Fn::GetAtt": [
"testbucketS3Bucket87F6BFFC",
"Arn"
]
},
"/*"
]
]
}
]
}
],
Version: "2012-10-17"
}
});
});
// ---------------------------
// Prop Tests
// ---------------------------
test('Test fail S3 check', () => {
const stack = new aws_cdk_lib_1.Stack();
const props = {
existingBucketObj: (0, test_helper_2.CreateScrapBucket)(stack, "scrapBucket"),
bucketProps: {},
};
const app = () => {
defaults.CheckS3Props(props);
};
// Assertion
expect(app).toThrowError('Error - Either provide bucketProps or existingBucketObj, but not both.\n');
});
test('Test fail existing log bucket and log bucket prop check', () => {
const stack = new aws_cdk_lib_1.Stack();
const props = {
existingLoggingBucketObj: new s3.Bucket(stack, 'logging-bucket'),
loggingBucketProps: {
autoDeleteObjects: true
}
};
const app = () => {
defaults.CheckS3Props(props);
};
// Assertion
expect(app).toThrowError('Error - Either provide existingLoggingBucketObj or loggingBucketProps, but not both.\n');
});
test('Test fail false logS3Accesslogs and loggingBucketProps check', () => {
const stack = new aws_cdk_lib_1.Stack();
const props = {
existingLoggingBucketObj: new s3.Bucket(stack, 'logging-bucket'),
logS3AccessLogs: false
};
const app = () => {
defaults.CheckS3Props(props);
};
// Assertion
expect(app).toThrowError('Error - If logS3AccessLogs is false, supplying loggingBucketProps or existingLoggingBucketObj is invalid.\n');
});
test('Test fail existingBucketObj and loggingBucketProps check', () => {
const stack = new aws_cdk_lib_1.Stack();
const props = {
existingBucketObj: new s3.Bucket(stack, 'temp-bucket'),
loggingBucketProps: {
autoDeleteObjects: true
}
};
const app = () => {
defaults.CheckS3Props(props);
};
// Assertion
expect(app).toThrowError('Error - If existingBucketObj is provided, supplying loggingBucketProps or logS3AccessLogs is an error.\n');
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiczMtYnVja2V0LnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzMy1idWNrZXQudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7O0dBV0c7O0FBRUgsNkNBQThDO0FBQzlDLHlDQUF5QztBQUN6QywyQ0FBMkM7QUFDM0MscUNBQXFDO0FBQ3JDLHdDQUE2QztBQUM3Qyx1REFBa0Q7QUFDbEQsK0NBQW1EO0FBQ25ELCtDQUFrRDtBQUVsRCxJQUFJLENBQUMsZ0RBQWdELEVBQUUsR0FBRyxFQUFFO0lBQzFELE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO0lBQzFCLE1BQU0sWUFBWSxHQUFtQixRQUFRLENBQUMsY0FBYyxFQUFFLENBQUM7SUFFL0QsTUFBTSxPQUFPLEdBQW1CO1FBQzlCLFNBQVMsRUFBRSxLQUFLO0tBQ2pCLENBQUM7SUFFRixNQUFNLFFBQVEsR0FBRyxJQUFBLHFCQUFhLEVBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3RELElBQUksRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFFcEQscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMscUJBQXFCLENBQUMsaUJBQWlCLEVBQUU7UUFDakUsZ0JBQWdCLEVBQUU7WUFDaEIsaUNBQWlDLEVBQUU7Z0JBQ2pDO29CQUNFLDZCQUE2QixFQUFFO3dCQUM3QixZQUFZLEVBQUUsUUFBUTtxQkFDdkI7aUJBQ0Y7YUFDRjtTQUNGO1FBQ0QsOEJBQThCLEVBQUU7WUFDOUIsZUFBZSxFQUFFLElBQUk7WUFDckIsaUJBQWlCLEVBQUUsSUFBSTtZQUN2QixnQkFBZ0IsRUFBRSxJQUFJO1lBQ3RCLHFCQUFxQixFQUFFLElBQUk7U0FDNUI7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQztBQUVILElBQUksQ0FBQyx5Q0FBeUMsRUFBRSxHQUFHLEVB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QUFNLEdBQUcsR0FBRyxHQUFHLEVBQUU7UUFDZixRQUFRLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQy9CLENBQUMsQ0FBQztJQUVGLFlBQVk7SUFDWixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsWUFBWSxDQUFDLDZHQUE2RyxDQUFDLENBQUM7QUFDMUksQ0FBQyxDQUFDLENBQUM7QUFFSCxJQUFJLENBQUMsMERBQTBELEVBQUUsR0FBRyxFQUFFO0lBQ3BFLE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO0lBRTFCLE1BQU0sS0FBSyxHQUFxQjtRQUM5QixpQkFBaUIsRUFBRSxJQUFJLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLGFBQWEsQ0FBQztRQUN0RCxrQkFBa0IsRUFBRTtZQUNsQixpQkFBaUIsRUFBRSxJQUFJO1NBQ3hCO0tBQ0YsQ0FBQztJQUVGLE1BQU0sR0FBRyxHQUFHLEdBQUcsRUFBRTtRQUNmLFFBQVEsQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQyxDQUFDO0lBRUYsWUFBWTtJQUNaLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxZQUFZLENBQUMsMEdBQTBHLENBQUMsQ0FBQztBQUN2SSxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogIENvcHlyaWdodCBBbWF6b24uY29tLCBJbmMuIG9yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpLiBZb3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXG4gKiAgd2l0aCB0aGUgTGljZW5zZS4gQSBjb3B5IG9mIHRoZSBMaWNlbnNlIGlzIGxvY2F0ZWQgYXRcbiAqXG4gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqICBvciBpbiB0aGUgJ2xpY2Vuc2UnIGZpbGUgYWNjb21wYW55aW5nIHRoaXMgZmlsZS4gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICdBUyBJUycgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFU1xuICogIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zXG4gKiAgYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IER1cmF0aW9uLCBTdGFjayB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIHMzIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMyc7XG5pbXBvcnQgKiBhcyBrbXMgZnJvbSAnYXdzLWNkay1saWIvYXdzLWttcyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0cyBmcm9tICcuLi9pbmRleCc7XG5pbXBvcnQgeyBvdmVycmlkZVByb3BzIH0gZnJvbSAnLi4vbGliL3V0aWxzJztcbmltcG9ydCB7IFRlbXBsYXRlIH0gZnJvbSAnYXdzLWNkay1saWIvYXNzZXJ0aW9ucyc7XG5pbXBvcnQgeyBleHBlY3ROb25leGlzdGVuY2UgfSBmcm9tIFwiLi90ZXN0LWhlbHBlclwiO1xuaW1wb3J0IHsgQ3JlYXRlU2NyYXBCdWNrZXQgfSBmcm9tICcuL3Rlc3QtaGVscGVyJztcblxudGVzdCgndGVzdCBzM0J1Y2tldCBvdmVycmlkZSB2ZXJzaW9uaW5nQ29uZmlndXJhdGlvbicsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgY29uc3QgZGVmYXVsdFByb3BzOiBzMy5CdWNrZXRQcm9wcyA9IGRlZmF1bHRzLkRlZmF1bHRTM1Byb3BzKCk7XG5cbiAgY29uc3QgaW5Qcm9wczogczMuQnVja2V0UHJvcHMgPSB7XG4gICAgdmVyc2lvbmVkOiBmYWxzZVxuICB9O1xuXG4gIGNvbnN0IG91dFByb3BzID0gb3ZlcnJpZGVQcm9wcyhkZWZhdWx0UHJvcHMsIGluUHJvcHMpO1xuICBuZXcgczMuQnVja2V0KHN0YWNrLCAndGVzdC1zMy12ZXJpb25pbmcnLCBvdXRQcm9wcyk7XG5cbiAgVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwge1xuICAgIEJ1Y2tldEVuY3J5cHRpb246IHtcbiAgICAgIFNlcnZlclNpZGVFbmNyeXB0aW9uQ29uZmlndXJhdGlvbjogW1xuICAgICAgICB7XG4gICAgICAgICAgU2VydmVyU2lkZUVuY3J5cHRpb25CeURlZmF1bHQ6IHtcbiAgICAgICAgICAgIFNTRUFsZ29yaXRobTogXCJBRVMyNTZcIlxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgXVxuICAgIH0sXG4gICAgUHVibGljQWNjZXNzQmxvY2tDb25maWd1cmF0aW9uOiB7XG4gICAgICBCbG9ja1B1YmxpY0FjbHM6IHRydWUsXG4gICAgICBCbG9ja1B1YmxpY1BvbGljeTogdHJ1ZSxcbiAgICAgIElnbm9yZVB1YmxpY0FjbHM6IHRydWUsXG4gICAgICBSZXN0cmljdFB1YmxpY0J1Y2tldHM6IHRydWVcbiAgICB9XG4gIH0pO1xufSk7XG5cbnRlc3QoJ3Rlc3QgczNCdWNrZXQgb3ZlcnJpZGUgYnVja2V0RW5jcnlwdGlvbicsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgY29uc3QgZGVmYXVsdFByb3BzOiBzMy5CdWNrZXRQcm9wcyA9IGRlZmF1bHRzLkRlZmF1bHRTM1Byb3BzKCk7XG5cbiAgY29uc3QgaW5Qcm9wczogczMuQnVja2V0UHJvcHMgPSB7XG4gICAgZW5jcnlwdGlvbjogczMuQnVja2V0RW5jcnlwdGlvbi5LTVMsXG4gICAgZW5jcnlwdGlvbktleTogbmV3IGttcy5LZXkoc3RhY2ssICdteWtleWlkJylcbiAgfTtcblxuICBjb25zdCBvdXRQcm9wcyA9IG92ZXJyaWRlUHJvcHMoZGVmYXVsdFByb3BzLCBpblByb3BzKTtcbiAgbmV3IHMzLkJ1Y2tldChzdGFjaywgJ3Rlc3QtczMtZW5jcnlwdGlvbicsIG91dFByb3BzKTtcblxuICBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6UzM6OkJ1Y2tldFwiLCB7XG4gICAgQnVja2V0RW5jcnlwdGlvbjoge1xuICAgICAgU2VydmVyU2lkZUVuY3J5cHRpb25Db25maWd1cmF0aW9uOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBTZXJ2ZXJTaWRlRW5jcnlwdGlvbkJ5RGVmYXVsdDoge1xuICAgICAgICAgICAgS01TTWFzdGVyS2V5SUQ6IHtcbiAgICAgICAgICAgICAgXCJGbjo6R2V0QXR0XCI6IFtcbiAgICAgICAgICAgICAgICBcIm15a2V5aWRGQTQyMDNCMFwiLFxuICAgICAgICAgICAgICAgIFwiQXJuXCJcbiAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFNTRUFsZ29yaXRobTogXCJhd3M6a21zXCJcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIF1cbiAgICB9LFxuICB9KTtcbn0pO1xuXG50ZXN0KCd0ZXN0IHMzQnVja2V0IG92ZXJyaWRlIHB1YmxpY0FjY2Vzc0Jsb2NrQ29uZmlndXJhdGlvbicsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgY29uc3QgZGVmYXVsdFByb3BzOiBzMy5CdWNrZXRQcm9wcyA9IGRlZmF1bHRzLkRlZmF1bHRTM1Byb3BzKCk7XG5cbiAgY29uc3QgaW5Qcm9wczogczMuQnVja2V0UHJvcHMgPSB7XG4gICAgYmxvY2tQdWJsaWNBY2Nlc3M6IHMzLkJsb2NrUHVibGljQWNjZXNzLkJMT0NLX0FDTFNcbiAgfTtcblxuICBjb25zdCBvdXRQcm9wcyA9IG92ZXJyaWRlUHJvcHMoZGVmYXVsdFByb3BzLCBpblByb3BzKTtcbiAgbmV3IHMzLkJ1Y2tldChzdGFjaywgJ3Rlc3QtczMtcHVibGljQWNjZXNzQmxvY2snLCBvdXRQcm9wcyk7XG5cbiAgVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwge1xuICAgIFB1YmxpY0FjY2Vzc0Jsb2NrQ29uZmlndXJhdGlvbjoge1xuICAgICAgQmxvY2tQdWJsaWNBY2xzOiB0cnVlLFxuICAgICAgSWdub3JlUHVibGljQWNsczogdHJ1ZVxuICAgIH0sXG4gIH0pO1xufSk7XG5cbnRlc3QoJ3Rlc3QgczNCdWNrZXQgYWRkIGxpZmVjeWNsZUNvbmZpZ3VyYXRpb24nLCAoKSA9PiB7XG4gIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG4gIGNvbnN0IGRlZmF1bHRQcm9wczogczMuQnVja2V0UHJvcHMgPSBkZWZhdWx0cy5EZWZhdWx0UzNQcm9wcygpO1xuXG4gIGNvbnN0IGluUHJvcHM6IHMzLkJ1Y2tldFByb3BzID0ge1xuICAgIGxpZmVjeWNsZVJ1bGVzOiBbe1xuICAgICAgZXhwaXJhdGlvbjogRHVyYXRpb24uZGF5cygzNjUpXG4gICAgfV1cbiAgfTtcblxuICBjb25zdCBvdXRQcm9wcyA9IG92ZXJyaWRlUHJvcHMoZGVmYXVsdFByb3BzLCBpblByb3BzKTtcbiAgbmV3IHMzLkJ1Y2tldChzdGFjaywgJ3Rlc3QtczMtbGlmZWN5Y2xlJywgb3V0UHJvcHMpO1xuXG4gIFRlbXBsYXRlLmZyb21TdGFjayhzdGFjaykuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpTMzo6QnVja2V0XCIsIHtcbiAgICBMaWZlY3ljbGVDb25maWd1cmF0aW9uOiB7XG4gICAgICBSdWxlczogW1xuICAgICAgICB7XG4gICAgICAgICAgU3RhdHVzOiAnRW5hYmxlZCcsXG4gICAgICAgICAgRXhwaXJhdGlvbkluRGF5czogMzY1LFxuICAgICAgICB9XG4gICAgICBdXG4gICAgfVxuICB9KTtcbn0pO1xuXG50ZXN0KCd0ZXN0IHMzQnVja2V0IG92ZXJyaWRlIHNlcnZlckFjY2Vzc0xvZ3NCdWNrZXQnLCAoKSA9PiB7XG4gIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG5cbiAgY29uc3QgbXlMb2dnaW5nQnVja2V0OiBzMy5CdWNrZXQgPSBuZXcgczMuQnVja2V0KHN0YWNrLCAnTXlTM0xvZ2dpbmdCdWNrZXQnLCBkZWZhdWx0cy5EZWZhdWx0UzNQcm9wcygpKTtcblxuICBjb25zdCBteVMzUHJvcHM6IHMzLkJ1Y2tldFByb3BzID0gZGVmYXVsdHMuRGVmYXVsdFMzUHJvcHMobXlMb2dnaW5nQnVja2V0KTtcblxuICBkZWZhdWx0cy5idWlsZFMzQnVja2V0KHN0YWNrLCB7XG4gICAgYnVja2V0UHJvcHM6IG15UzNQcm9wc1xuICB9KTtcblxuICBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6UzM6OkJ1Y2tldFwiLCB7XG4gICAgTG9nZ2luZ0NvbmZpZ3VyYXRpb246IHtcbiAgICAgIERlc3RpbmF0aW9uQnVja2V0TmFtZToge1xuICAgICAgICBSZWY6IFwiTXlTM0xvZ2dpbmdCdWNrZXQxMTlCRTg5NlwiXG4gICAgICB9XG4gICAgfVxuICB9KTtcbn0pO1xuXG50ZXN0KCd0ZXN0IGNyZWF0ZUFsYkxvZ2dpbmdCdWNrZXQoKScsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcblxuICBkZWZhdWx0cy5jcmVhdGVBbGJMb2dnaW5nQnVja2V0KHN0YWNrLCAndGVzdC1idWNrZXQnLCB7XG4gICAgYnVja2V0TmFtZTogJ3Rlc3QtbmFtZSdcbiAgfSk7XG5cbiAgVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwge1xuICAgIEJ1Y2tldE5hbWU6ICd0ZXN0LW5hbWUnXG4gIH0pO1xufSk7XG5cbnRlc3QoJ1Rlc3QgYnVja2V0IHBvbGljeSB0aGF0IG9ubHkgYWNjZXB0cyBTU0wgcmVxdWVzdHMgb25seScsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcblxuICBkZWZhdWx0cy5idWlsZFMzQnVja2V0KHN0YWNrLCB7XG4gICAgYnVja2V0UHJvcHM6IHtcbiAgICAgIGVuZm9yY2VTU0w6IHRydWVcbiAgICB9XG4gIH0sICd0ZXN0LWJ1Y2tldCcpO1xuXG4gIFRlbXBsYXRlLmZyb21TdGFjayhzdGFjaykuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpTMzo6QnVja2V0UG9saWN5XCIsIHtcbiAgICBQb2xpY3lEb2N1bWVudDoge1xuICAgICAgU3RhdGVtZW50OiBbXG4gICAgICAgIHtcbiAgICAgICAgICBBY3Rpb246IFwiczM6KlwiLFxuICAgICAgICAgIENvbmRpdGlvbjoge1xuICAgICAgICAgICAgQm9vbDoge1xuICAgICAgICAgICAgICBcImF3czpTZWN1cmVUcmFuc3BvcnRcIjogXCJmYWxzZVwiXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBFZmZlY3Q6IFwiRGVueVwiLFxuICAgICAgICAgIFByaW5jaXBhbDoge1xuICAgICAgICAgICAgQVdTOiBcIipcIlxuICAgICAgICAgIH0sXG4gICAgICAgICAgUmVzb3VyY2U6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgXCJGbjo6R2V0QXR0XCI6IFtcbiAgICAgICAgICAgICAgICBcInRlc3RidWNrZXRTM0J1Y2tldDg3RjZCRkZDXCIsXG4gICAgICAgICAgICAgICAgXCJBcm5cIlxuICAgICAgICAgICAgICBdXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBcIkZuOjpKb2luXCI6IFtcbiAgICAgICAgICAgICAgICBcIlwiLFxuICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgXCJGbjo6R2V0QXR0XCI6IFtcbiAgICAgICAgICAgICAgICAgICAgICBcInRlc3RidWNrZXRTM0J1Y2tldDg3RjZCRkZDXCIsXG4gICAgICAgICAgICAgICAgICAgICAgXCJBcm5cIlxuICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgXCIvKlwiXG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICBdXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXVxuICAgICAgICB9XG4gICAgICBdLFxuICAgICAgVmVyc2lvbjogXCIyMDEyLTEwLTE3XCJcbiAgICB9XG4gIH0pO1xufSk7XG5cbnRlc3QoJ1Rlc3QgYnVja2V0IHBvbGljeSB0aGF0IGFjY2VwdHMgYW55IHJlcXVlc3RzJywgKCkgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuXG4gIGRlZmF1bHRzLmJ1aWxkUzNCdWNrZXQoc3RhY2ssIHtcbiAgICBidWNrZXRQcm9wczoge1xuICAgICAgZW5mb3JjZVNTTDogZmFsc2VcbiAgICB9XG4gIH0sICd0ZXN0LWJ1Y2tldCcpO1xuXG4gIGV4cGVjdE5vbmV4aXN0ZW5jZShzdGFjaywgXCJBV1M6OlMzOjpCdWNrZXRQb2xpY3lcIiwge1xuICAgIFBvbGljeURvY3VtZW50OiB7XG4gICAgICBTdGF0ZW1lbnQ6IFtcbiAgICAgICAge1xuICAgICAgICAgIEFjdGlvbjogXCJzMzoqXCIsXG4gICAgICAgICAgQ29uZGl0aW9uOiB7XG4gICAgICAgICAgICBCb29sOiB7XG4gICAgICAgICAgICAgIFwiYXdzOlNlY3VyZVRyYW5zcG9ydFwiOiBcImZhbHNlXCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIEVmZmVjdDogXCJEZW55XCIsXG4gICAgICAgICAgUHJpbmNpcGFsOiB7XG4gICAgICAgICAgICBBV1M6IFwiKlwiXG4gICAgICAgICAgfSxcbiAgICAgICAgICBSZXNvdXJjZTogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBcIkZuOjpHZXRBdHRcIjogW1xuICAgICAgICAgICAgICAgIFwidGVzdGJ1Y2tldFMzQnVja2V0ODdGNkJGRkNcIixcbiAgICAgICAgICAgICAgICBcIkFyblwiXG4gICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwiRm46OkpvaW5cIjogW1xuICAgICAgICAgICAgICAgIFwiXCIsXG4gICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBcIkZuOjpHZXRBdHRcIjogW1xuICAgICAgICAgICAgICAgICAgICAgIFwidGVzdGJ1Y2tldFMzQnVja2V0ODdGNkJGRkNcIixcbiAgICAgICAgICAgICAgICAgICAgICBcIkFyblwiXG4gICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBcIi8qXCJcbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICAgIF0sXG4gICAgICBWZXJzaW9uOiBcIjIwMTItMTAtMTdcIlxuICAgIH1cbiAgfSk7XG59KTtcblxudGVzdCgnVGVzdCBlbmZvcmNpbmcgU1NMIHdoZW4gYnVja2V0UHJvcHMgaXMgbm90IHByb3ZpZGVkJywgKCkgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuXG4gIGRlZmF1bHRzLmJ1aWxkUzNCdWNrZXQoc3RhY2ssIHt9LCAndGVzdC1idWNrZXQnKTtcblxuICBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6UzM6OkJ1Y2tldFBvbGljeVwiLCB7XG4gICAgUG9saWN5RG9jdW1lbnQ6IHtcbiAgICAgIFN0YXRlbWVudDogW1xuICAgICAgICB7XG4gICAgICAgICAgQWN0aW9uOiBcInMzOipcIixcbiAgICAgICAgICBDb25kaXRpb246IHtcbiAgICAgICAgICAgIEJvb2w6IHtcbiAgICAgICAgICAgICAgXCJhd3M6U2VjdXJlVHJhbnNwb3J0XCI6IFwiZmFsc2VcIlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgRWZmZWN0OiBcIkRlbnlcIixcbiAgICAgICAgICBQcmluY2lwYWw6IHtcbiAgICAgICAgICAgIEFXUzogXCIqXCJcbiAgICAgICAgICB9LFxuICAgICAgICAgIFJlc291cmNlOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwiRm46OkdldEF0dFwiOiBbXG4gICAgICAgICAgICAgICAgXCJ0ZXN0YnVja2V0UzNCdWNrZXQ4N0Y2QkZGQ1wiLFxuICAgICAgICAgICAgICAgIFwiQXJuXCJcbiAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgXCJGbjo6Sm9pblwiOiBbXG4gICAgICAgICAgICAgICAgXCJcIixcbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFwiRm46OkdldEF0dFwiOiBbXG4gICAgICAgICAgICAgICAgICAgICAgXCJ0ZXN0YnVja2V0UzNCdWNrZXQ4N0Y2QkZGQ1wiLFxuICAgICAgICAgICAgICAgICAgICAgIFwiQXJuXCJcbiAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIFwiLypcIlxuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgfVxuICAgICAgICAgIF1cbiAgICAgICAgfVxuICAgICAgXSxcbiAgICAgIFZlcnNpb246IFwiMjAxMi0xMC0xN1wiXG4gICAgfVxuICB9KTtcbn0pO1xuXG50ZXN0KCdUZXN0IGVuZm9yY2luZyBTU0wgd2hlbiBidWNrZXRQcm9wcyBpcyBwcm92aWRlZCBhbmQgZW5mb3JjZVNTTCBpcyBub3Qgc2V0JywgKCkgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuXG4gIGRlZmF1bHRzLmJ1aWxkUzNCdWNrZXQoc3RhY2ssIHtcbiAgICBidWNrZXRQcm9wczoge1xuICAgICAgdmVyc2lvbmVkOiBmYWxzZSxcbiAgICAgIHB1YmxpY1JlYWRBY2Nlc3M6IGZhbHNlXG4gICAgfVxuICB9LCAndGVzdC1idWNrZXQnKTtcblxuICBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6UzM6OkJ1Y2tldFBvbGljeVwiLCB7XG4gICAgUG9saWN5RG9jdW1lbnQ6IHtcbiAgICAgIFN0YXRlbWVudDogW1xuICAgICAgICB7XG4gICAgICAgICAgQWN0aW9uOiBcInMzOipcIixcbiAgICAgICAgICBDb25kaXRpb246IHtcbiAgICAgICAgICAgIEJvb2w6IHtcbiAgICAgICAgICAgICAgXCJhd3M6U2VjdXJlVHJhbnNwb3J0XCI6IFwiZmFsc2VcIlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgRWZmZWN0OiBcIkRlbnlcIixcbiAgICAgICAgICBQcmluY2lwYWw6IHtcbiAgICAgICAgICAgIEFXUzogXCIqXCJcbiAgICAgICAgICB9LFxuICAgICAgICAgIFJlc291cmNlOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwiRm46OkdldEF0dFwiOiBbXG4gICAgICAgICAgICAgICAgXCJ0ZXN0YnVja2V0UzNCdWNrZXQ4N0Y2QkZGQ1wiLFxuICAgICAgICAgICAgICAgIFwiQXJuXCJcbiAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgXCJGbjo6Sm9pblwiOiBbXG4gICAgICAgICAgICAgICAgXCJcIixcbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIFwiRm46OkdldEF0dFwiOiBbXG4gICAgICAgICAgICAgICAgICAgICAgXCJ0ZXN0YnVja2V0UzNCdWNrZXQ4N0Y2QkZGQ1wiLFxuICAgICAgICAgICAgICAgICAgICAgIFwiQXJuXCJcbiAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIFwiLypcIlxuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgfVxuICAgICAgICAgIF1cbiAgICAgICAgfVxuICAgICAgXSxcbiAgICAgIFZlcnNpb246IFwiMjAxMi0xMC0xN1wiXG4gICAgfVxuICB9KTtcbn0pO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFByb3AgVGVzdHNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxudGVzdCgnVGVzdCBmYWlsIFMzIGNoZWNrJywgKCkgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuXG4gIGNvbnN0IHByb3BzOiBkZWZhdWx0cy5TM1Byb3BzID0ge1xuICAgIGV4aXN0aW5nQnVja2V0T2JqOiBDcmVhdGVTY3JhcEJ1Y2tldChzdGFjaywgXCJzY3JhcEJ1Y2tldFwiKSxcbiAgICBidWNrZXRQcm9wczoge30sXG4gIH07XG5cbiAgY29uc3QgYXBwID0gKCkgPT4ge1xuICAgIGRlZmF1bHRzLkNoZWNrUzNQcm9wcyhwcm9wcyk7XG4gIH07XG5cbiAgLy8gQXNzZXJ0aW9uXG4gIGV4cGVjdChhcHApLnRvVGhyb3dFcnJvcignRXJyb3IgLSBFaXRoZXIgcHJvdmlkZSBidWNrZXRQcm9wcyBvciBleGlzdGluZ0J1Y2tldE9iaiwgYnV0IG5vdCBib3RoLlxcbicpO1xufSk7XG5cbnRlc3QoJ1Rlc3QgZmFpbCBleGlzdGluZyBsb2cgYnVja2V0IGFuZCBsb2cgYnVja2V0IHByb3AgY2hlY2snLCAoKSA9PiB7XG4gIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG5cbiAgY29uc3QgcHJvcHM6IGRlZmF1bHRzLlMzUHJvcHMgPSB7XG4gICAgZXhpc3RpbmdMb2dnaW5nQnVja2V0T2JqOiBuZXcgczMuQnVja2V0KHN0YWNrLCAnbG9nZ2luZy1idWNrZXQnKSxcbiAgICBsb2dnaW5nQnVja2V0UHJvcHM6IHtcbiAgICAgIGF1dG9EZWxldGVPYmplY3RzOiB0cnVlXG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGFwcCA9ICgpID0+IHtcbiAgICBkZWZhdWx0cy5DaGVja1MzUHJvcHMocHJvcHMpO1xuICB9O1xuXG4gIC8vIEFzc2VydGlvblxuICBleHBlY3QoYXBwKS50b1Rocm93RXJyb3IoJ0Vycm9yIC0gRWl0aGVyIHByb3ZpZGUgZXhpc3RpbmdMb2dnaW5nQnVja2V0T2JqIG9yIGxvZ2dpbmdCdWNrZXRQcm9wcywgYnV0IG5vdCBib3RoLlxcbicpO1xufSk7XG5cbnRlc3QoJ1Rlc3QgZmFpbCBmYWxzZSBsb2dTM0FjY2Vzc2xvZ3MgYW5kIGxvZ2dpbmdCdWNrZXRQcm9wcyBjaGVjaycsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcblxuICBjb25zdCBwcm9wczogZGVmYXVsdHMuUzNQcm9wcyA9IHtcbiAgICBleGlzdGluZ0xvZ2dpbmdCdWNrZXRPYmo6IG5ldyBzMy5CdWNrZXQoc3RhY2ssICdsb2dnaW5nLWJ1Y2tldCcpLFxuICAgIGxvZ1MzQWNjZXNzTG9nczogZmFsc2VcbiAgfTtcblxuICBjb25zdCBhcHAgPSAoKSA9PiB7XG4gICAgZGVmYXVsdHMuQ2hlY2tTM1Byb3BzKHByb3BzKTtcbiAgfTtcblxuICAvLyBBc3NlcnRpb25cbiAgZXhwZWN0KGFwcCkudG9UaHJvd0Vycm9yKCdFcnJvciAtIElmIGxvZ1MzQWNjZXNzTG9ncyBpcyBmYWxzZSwgc3VwcGx5aW5nIGxvZ2dpbmdCdWNrZXRQcm9wcyBvciBleGlzdGluZ0xvZ2dpbmdCdWNrZXRPYmogaXMgaW52YWxpZC5cXG4nKTtcbn0pO1xuXG50ZXN0KCdUZXN0IGZhaWwgZXhpc3RpbmdCdWNrZXRPYmogYW5kIGxvZ2dpbmdCdWNrZXRQcm9wcyBjaGVjaycsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcblxuICBjb25zdCBwcm9wczogZGVmYXVsdHMuUzNQcm9wcyA9IHtcbiAgICBleGlzdGluZ0J1Y2tldE9iajogbmV3IHMzLkJ1Y2tldChzdGFjaywgJ3RlbXAtYnVja2V0JyksXG4gICAgbG9nZ2luZ0J1Y2tldFByb3BzOiB7XG4gICAgICBhdXRvRGVsZXRlT2JqZWN0czogdHJ1ZVxuICAgIH1cbiAgfTtcblxuICBjb25zdCBhcHAgPSAoKSA9PiB7XG4gICAgZGVmYXVsdHMuQ2hlY2tTM1Byb3BzKHByb3BzKTtcbiAgfTtcblxuICAvLyBBc3NlcnRpb25cbiAgZXhwZWN0KGFwcCkudG9UaHJvd0Vycm9yKCdFcnJvciAtIElmIGV4aXN0aW5nQnVja2V0T2JqIGlzIHByb3ZpZGVkLCBzdXBwbHlpbmcgbG9nZ2luZ0J1Y2tldFByb3BzIG9yIGxvZ1MzQWNjZXNzTG9ncyBpcyBhbiBlcnJvci5cXG4nKTtcbn0pO1xuIl19