aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
264 lines • 30.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const find_cloudwatch_logs_1 = require("../../../lib/api/logs/find-cloudwatch-logs");
const util_1 = require("../../util");
const mock_sdk_1 = require("../../util/mock-sdk");
let logsMockSdkProvider;
let mockGetEndpointSuffix;
beforeEach(() => {
logsMockSdkProvider = new LogsMockSdkProvider();
mockGetEndpointSuffix = jest.fn(() => 'amazonaws.com');
logsMockSdkProvider.stubGetEndpointSuffix(mockGetEndpointSuffix);
// clear the array
currentCfnStackResources.splice(0);
});
test('add log groups from lambda function', async () => {
// GIVEN
const cdkStackArtifact = cdkStackArtifactOf({
template: {
Resources: {
Func: {
Type: 'AWS::Lambda::Function',
Properties: {
FunctionName: 'my-function',
},
},
},
},
});
pushStackResourceSummaries(stackSummaryOf('Func', 'AWS::Lambda::Function', 'my-function'));
// WHEN
const result = await (0, find_cloudwatch_logs_1.findCloudWatchLogGroups)(logsMockSdkProvider.mockSdkProvider, cdkStackArtifact);
// THEN
expect(result.logGroupNames).toEqual(['/aws/lambda/my-function']);
});
test('add log groups from lambda function without physical name', async () => {
// GIVEN
const cdkStackArtifact = cdkStackArtifactOf({
template: {
Resources: {
Func: {
Type: 'AWS::Lambda::Function',
},
},
},
});
pushStackResourceSummaries(stackSummaryOf('Func', 'AWS::Lambda::Function', 'my-function'));
// WHEN
const result = await (0, find_cloudwatch_logs_1.findCloudWatchLogGroups)(logsMockSdkProvider.mockSdkProvider, cdkStackArtifact);
// THEN
expect(result.logGroupNames).toEqual(['/aws/lambda/my-function']);
});
test('empty template', async () => {
// GIVEN
const cdkStackArtifact = cdkStackArtifactOf({
template: {},
});
// WHEN
const result = await (0, find_cloudwatch_logs_1.findCloudWatchLogGroups)(logsMockSdkProvider.mockSdkProvider, cdkStackArtifact);
// THEN
expect(result.logGroupNames).toEqual([]);
});
test('add log groups from ECS Task Definitions', async () => {
// GIVEN
const cdkStackArtifact = cdkStackArtifactOf({
template: {
Resources: {
LogGroup: {
Type: 'AWS::Logs::LogGroup',
Properties: {
LogGroupName: 'log_group',
},
},
Def: {
Type: 'AWS::ECS::TaskDefinition',
Properties: {
Family: 'app',
ContainerDefinitions: [
{
LogConfiguration: {
LogDriver: 'awslogs',
Options: {
'awslogs-group': { Ref: 'LogGroup' },
},
},
},
],
},
},
},
},
});
pushStackResourceSummaries(stackSummaryOf('LogGroup', 'AWS::Logs::LogGroup', 'log_group'));
// WHEN
const result = await (0, find_cloudwatch_logs_1.findCloudWatchLogGroups)(logsMockSdkProvider.mockSdkProvider, cdkStackArtifact);
// THEN
expect(result.logGroupNames).toEqual(['log_group']);
});
test('add log groups from State Machines', async () => {
// GIVEN
const cdkStackArtifact = cdkStackArtifactOf({
template: {
Resources: {
LogGroup: {
Type: 'AWS::Logs::LogGroup',
Properties: {
LogGroupName: 'log_group',
},
},
Def: {
Type: 'AWS::StepFunctions::StateMachine',
Properties: {
LoggingConfiguration: {
Destinations: [
{
CloudWatchLogsLogGroup: {
LogGroupArn: {
'Fn::GetAtt': ['LogGroup', 'Arn'],
},
},
},
],
},
},
},
},
},
});
pushStackResourceSummaries(stackSummaryOf('LogGroup', 'AWS::Logs::LogGroup', 'log_group'));
// WHEN
const result = await (0, find_cloudwatch_logs_1.findCloudWatchLogGroups)(logsMockSdkProvider.mockSdkProvider, cdkStackArtifact);
// THEN
expect(result.logGroupNames).toEqual(['log_group']);
});
test('excluded log groups are not added', async () => {
// GIVEN
const cdkStackArtifact = cdkStackArtifactOf({
template: {
Resources: {
LogGroup: {
Type: 'AWS::Logs::LogGroup',
Properties: {
LogGroupName: 'log_group',
},
},
LogGroup2: {
Type: 'AWS::Logs::LogGroup',
Properties: {
LogGroupName: 'log_group2',
},
},
Def: {
Type: 'AWS::CodeBuild::Project',
Properties: {
PojectName: 'project',
LogsConfig: {
CloudWatchLogs: {
GroupName: { Ref: 'LogGroup' },
},
},
},
},
FlowLog: {
Type: 'AWS::EC2::FlowLog',
Properties: {
LogDestination: { Ref: 'LogGroup' },
},
},
FlowLog2: {
Type: 'AWS::EC2::FlowLog',
Properties: {
LogDestination: {
'Fn::GetAtt': ['LogGroup2', 'Arn'],
},
},
},
},
},
});
pushStackResourceSummaries(stackSummaryOf('LogGroup', 'AWS::Logs::LogGroup', 'log_group'));
pushStackResourceSummaries(stackSummaryOf('LogGroup2', 'AWS::Logs::LogGroup', 'log_group2'));
pushStackResourceSummaries(stackSummaryOf('FlowLog', 'AWS::EC2::FlowLog', 'flow_log'));
pushStackResourceSummaries(stackSummaryOf('FlowLog2', 'AWS::EC2::FlowLog', 'flow_log2'));
pushStackResourceSummaries(stackSummaryOf('Def', 'AWS::CodeBuild:Project', 'project'));
// WHEN
const result = await (0, find_cloudwatch_logs_1.findCloudWatchLogGroups)(logsMockSdkProvider.mockSdkProvider, cdkStackArtifact);
// THEN
expect(result.logGroupNames).toEqual([]);
});
test('unassociated log groups are added', async () => {
// GIVEN
const cdkStackArtifact = cdkStackArtifactOf({
template: {
Resources: {
LogGroup: {
Type: 'AWS::Logs::LogGroup',
Properties: {
LogGroupName: 'log_group',
},
},
},
},
});
pushStackResourceSummaries(stackSummaryOf('LogGroup', 'AWS::Logs::LogGroup', 'log_group'));
// WHEN
const result = await (0, find_cloudwatch_logs_1.findCloudWatchLogGroups)(logsMockSdkProvider.mockSdkProvider, cdkStackArtifact);
// THEN
expect(result.logGroupNames).toEqual(['log_group']);
});
test('log groups without physical names are added', async () => {
// GIVEN
const cdkStackArtifact = cdkStackArtifactOf({
template: {
Resources: {
LogGroup: {
Type: 'AWS::Logs::LogGroup',
},
},
},
});
pushStackResourceSummaries(stackSummaryOf('LogGroup', 'AWS::Logs::LogGroup', 'log_group'));
// WHEN
const result = await (0, find_cloudwatch_logs_1.findCloudWatchLogGroups)(logsMockSdkProvider.mockSdkProvider, cdkStackArtifact);
// THEN
expect(result.logGroupNames).toEqual(['log_group']);
});
const STACK_NAME = 'withouterrors';
const currentCfnStackResources = [];
function pushStackResourceSummaries(...items) {
currentCfnStackResources.push(...items);
}
function stackSummaryOf(logicalId, resourceType, physicalResourceId) {
return {
LogicalResourceId: logicalId,
PhysicalResourceId: physicalResourceId,
ResourceType: resourceType,
ResourceStatus: 'CREATE_COMPLETE',
LastUpdatedTimestamp: new Date(),
};
}
function cdkStackArtifactOf(testStackArtifact = {}) {
return (0, util_1.testStack)({
stackName: STACK_NAME,
...testStackArtifact,
});
}
class LogsMockSdkProvider {
constructor() {
this.mockSdkProvider = new mock_sdk_1.MockSdkProvider({ realSdk: false });
this.mockSdkProvider.stubCloudFormation({
listStackResources: ({ StackName: stackName }) => {
if (stackName !== STACK_NAME) {
throw new Error(`Expected Stack name in listStackResources() call to be: '${STACK_NAME}', but received: ${stackName}'`);
}
return {
StackResourceSummaries: currentCfnStackResources,
};
},
});
}
stubGetEndpointSuffix(stub) {
this.mockSdkProvider.stubGetEndpointSuffix(stub);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmluZC1jbG91ZHdhdGNoLWxvZ3MudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImZpbmQtY2xvdWR3YXRjaC1sb2dzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFHQSxxRkFBcUY7QUFDckYscUNBQTBEO0FBQzFELGtEQUFzRDtBQUV0RCxJQUFJLG1CQUF3QyxDQUFDO0FBQzdDLElBQUkscUJBQW1DLENBQUM7QUFFeEMsVUFBVSxDQUFDLEdBQUcsRUFBRTtJQUNkLG1CQUFtQixHQUFHLElBQUksbUJBQW1CLEVBQUUsQ0FBQztJQUNoRCxxQkFBcUIsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3ZELG1CQUFtQixDQUFDLHFCQUFxQixDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDakUsa0JBQWtCO0lBQ2xCLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNyQyxDQUFDLENBQUMsQ0FBQztBQUVILElBQUksQ0FBQyxxQ0FBcUMsRUFBRSxLQUFLLElBQUksRUFBRTtJQUNyRCxRQUFRO0lBQ1IsTUFBTSxnQkFBZ0IsR0FBRyxrQkFBa0IsQ0FBQztRQUMxQyxRQUFRLEVBQUU7WUFDUixTQUFTLEVBQUU7Z0JBQ1QsSUFBSSxFQUFFO29CQUNKLElBQUksRUFBRSx1QkFBdUI7b0JBQzdCLFVBQVUsRUFBRTt3QkFDVixZQUFZLEVBQUUsYUFBYTtxQkFDNUI7aUJBQ0Y7YUFDRjtTQUNGO0tBQ0YsQ0FBQyxDQUFDO0lBQ0gsMEJBQTBCLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSx1QkFBdUIsRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDO0lBRTNGLE9BQU87SUFDUCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEsOENBQXVCLEVBQUMsbUJBQW1CLENBQUMsZUFBZSxFQUFFLGdCQUFnQixDQUFDLENBQUM7SUFFcEcsT0FBTztJQUNQLE1BQU0sQ0FBQyxNQUFN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O0lBQ0wsQ0FBQztJQUVNLHFCQUFxQixDQUFDLElBQWtCO1FBQzdDLElBQUksQ0FBQyxlQUFlLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkQsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L29yZGVyICovXG5pbXBvcnQgKiBhcyBjeGFwaSBmcm9tICdAYXdzLWNkay9jeC1hcGknO1xuaW1wb3J0IHsgQ2xvdWRGb3JtYXRpb24gfSBmcm9tICdhd3Mtc2RrJztcbmltcG9ydCB7IGZpbmRDbG91ZFdhdGNoTG9nR3JvdXBzIH0gZnJvbSAnLi4vLi4vLi4vbGliL2FwaS9sb2dzL2ZpbmQtY2xvdWR3YXRjaC1sb2dzJztcbmltcG9ydCB7IHRlc3RTdGFjaywgVGVzdFN0YWNrQXJ0aWZhY3QgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IE1vY2tTZGtQcm92aWRlciB9IGZyb20gJy4uLy4uL3V0aWwvbW9jay1zZGsnO1xuXG5sZXQgbG9nc01vY2tTZGtQcm92aWRlcjogTG9nc01vY2tTZGtQcm92aWRlcjtcbmxldCBtb2NrR2V0RW5kcG9pbnRTdWZmaXg6ICgpID0+IHN0cmluZztcblxuYmVmb3JlRWFjaCgoKSA9PiB7XG4gIGxvZ3NNb2NrU2RrUHJvdmlkZXIgPSBuZXcgTG9nc01vY2tTZGtQcm92aWRlcigpO1xuICBtb2NrR2V0RW5kcG9pbnRTdWZmaXggPSBqZXN0LmZuKCgpID0+ICdhbWF6b25hd3MuY29tJyk7XG4gIGxvZ3NNb2NrU2RrUHJvdmlkZXIuc3R1YkdldEVuZHBvaW50U3VmZml4KG1vY2tHZXRFbmRwb2ludFN1ZmZpeCk7XG4gIC8vIGNsZWFyIHRoZSBhcnJheVxuICBjdXJyZW50Q2ZuU3RhY2tSZXNvdXJjZXMuc3BsaWNlKDApO1xufSk7XG5cbnRlc3QoJ2FkZCBsb2cgZ3JvdXBzIGZyb20gbGFtYmRhIGZ1bmN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAvLyBHSVZFTlxuICBjb25zdCBjZGtTdGFja0FydGlmYWN0ID0gY2RrU3RhY2tBcnRpZmFjdE9mKHtcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgIEZ1bmM6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJyxcbiAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBGdW5jdGlvbk5hbWU6ICdteS1mdW5jdGlvbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG4gIHB1c2hTdGFja1Jlc291cmNlU3VtbWFyaWVzKHN0YWNrU3VtbWFyeU9mKCdGdW5jJywgJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsICdteS1mdW5jdGlvbicpKTtcblxuICAvLyBXSEVOXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZpbmRDbG91ZFdhdGNoTG9nR3JvdXBzKGxvZ3NNb2NrU2RrUHJvdmlkZXIubW9ja1Nka1Byb3ZpZGVyLCBjZGtTdGFja0FydGlmYWN0KTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdChyZXN1bHQubG9nR3JvdXBOYW1lcykudG9FcXVhbChbJy9hd3MvbGFtYmRhL215LWZ1bmN0aW9uJ10pO1xufSk7XG5cbnRlc3QoJ2FkZCBsb2cgZ3JvdXBzIGZyb20gbGFtYmRhIGZ1bmN0aW9uIHdpdGhvdXQgcGh5c2ljYWwgbmFtZScsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgY29uc3QgY2RrU3RhY2tBcnRpZmFjdCA9IGNka1N0YWNrQXJ0aWZhY3RPZih7XG4gICAgdGVtcGxhdGU6IHtcbiAgICAgIFJlc291cmNlczoge1xuICAgICAgICBGdW5jOiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xuICBwdXNoU3RhY2tSZXNvdXJjZVN1bW1hcmllcyhzdGFja1N1bW1hcnlPZignRnVuYycsICdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCAnbXktZnVuY3Rpb24nKSk7XG5cbiAgLy8gV0hFTlxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBmaW5kQ2xvdWRXYXRjaExvZ0dyb3Vwcyhsb2dzTW9ja1Nka1Byb3ZpZGVyLm1vY2tTZGtQcm92aWRlciwgY2RrU3RhY2tBcnRpZmFjdCk7XG5cbiAgLy8gVEhFTlxuICBleHBlY3QocmVzdWx0LmxvZ0dyb3VwTmFtZXMpLnRvRXF1YWwoWycvYXdzL2xhbWJkYS9teS1mdW5jdGlvbiddKTtcbn0pO1xuXG50ZXN0KCdlbXB0eSB0ZW1wbGF0ZScsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgY29uc3QgY2RrU3RhY2tBcnRpZmFjdCA9IGNka1N0YWNrQXJ0aWZhY3RPZih7XG4gICAgdGVtcGxhdGU6IHt9LFxuICB9KTtcblxuICAvLyBXSEVOXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZpbmRDbG91ZFdhdGNoTG9nR3JvdXBzKGxvZ3NNb2NrU2RrUHJvdmlkZXIubW9ja1Nka1Byb3ZpZGVyLCBjZGtTdGFja0FydGlmYWN0KTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdChyZXN1bHQubG9nR3JvdXBOYW1lcykudG9FcXVhbChbXSk7XG59KTtcblxudGVzdCgnYWRkIGxvZyBncm91cHMgZnJvbSBFQ1MgVGFzayBEZWZpbml0aW9ucycsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgY29uc3QgY2RrU3RhY2tBcnRpZmFjdCA9IGNka1N0YWNrQXJ0aWZhY3RPZih7XG4gICAgdGVtcGxhdGU6IHtcbiAgICAgIFJlc291cmNlczoge1xuICAgICAgICBMb2dHcm91cDoge1xuICAgICAgICAgIFR5cGU6ICdBV1M6OkxvZ3M6OkxvZ0dyb3VwJyxcbiAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBMb2dHcm91cE5hbWU6ICdsb2dfZ3JvdXAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIERlZjoge1xuICAgICAgICAgIFR5cGU6ICdBV1M6OkVDUzo6VGFza0RlZmluaXRpb24nLFxuICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIEZhbWlseTogJ2FwcCcsXG4gICAgICAgICAgICBDb250YWluZXJEZWZpbml0aW9uczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgTG9nQ29uZmlndXJhdGlvbjoge1xuICAgICAgICAgICAgICAgICAgTG9nRHJpdmVyOiAnYXdzbG9ncycsXG4gICAgICAgICAgICAgICAgICBPcHRpb25zOiB7XG4gICAgICAgICAgICAgICAgICAgICdhd3Nsb2dzLWdyb3VwJzogeyBSZWY6ICdMb2dHcm91cCcgfSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG4gIHB1c2hTdGFja1Jlc291cmNlU3VtbWFyaWVzKHN0YWNrU3VtbWFyeU9mKCdMb2dHcm91cCcsICdBV1M6OkxvZ3M6OkxvZ0dyb3VwJywgJ2xvZ19ncm91cCcpKTtcblxuICAvLyBXSEVOXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZpbmRDbG91ZFdhdGNoTG9nR3JvdXBzKGxvZ3NNb2NrU2RrUHJvdmlkZXIubW9ja1Nka1Byb3ZpZGVyLCBjZGtTdGFja0FydGlmYWN0KTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdChyZXN1bHQubG9nR3JvdXBOYW1lcykudG9FcXVhbChbJ2xvZ19ncm91cCddKTtcbn0pO1xuXG50ZXN0KCdhZGQgbG9nIGdyb3VwcyBmcm9tIFN0YXRlIE1hY2hpbmVzJywgYXN5bmMgKCkgPT4ge1xuICAvLyBHSVZFTlxuICBjb25zdCBjZGtTdGFja0FydGlmYWN0ID0gY2RrU3RhY2tBcnRpZmFjdE9mKHtcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgUmVzb3VyY2VzOiB7XG4gICAgICAgIExvZ0dyb3VwOiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6TG9nczo6TG9nR3JvdXAnLFxuICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIExvZ0dyb3VwTmFtZTogJ2xvZ19ncm91cCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgRGVmOiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJyxcbiAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBMb2dnaW5nQ29uZmlndXJhdGlvbjoge1xuICAgICAgICAgICAgICBEZXN0aW5hdGlvbnM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBDbG91ZFdhdGNoTG9nc0xvZ0dyb3VwOiB7XG4gICAgICAgICAgICAgICAgICAgIExvZ0dyb3VwQXJuOiB7XG4gICAgICAgICAgICAgICAgICAgICAgJ0ZuOjpHZXRBdHQnOiBbJ0xvZ0dyb3VwJywgJ0FybiddLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbiAgcHVzaFN0YWNrUmVzb3VyY2VTdW1tYXJpZXMoc3RhY2tTdW1tYXJ5T2YoJ0xvZ0dyb3VwJywgJ0FXUzo6TG9nczo6TG9nR3JvdXAnLCAnbG9nX2dyb3VwJykpO1xuXG4gIC8vIFdIRU5cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZmluZENsb3VkV2F0Y2hMb2dHcm91cHMobG9nc01vY2tTZGtQcm92aWRlci5tb2NrU2RrUHJvdmlkZXIsIGNka1N0YWNrQXJ0aWZhY3QpO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KHJlc3VsdC5sb2dHcm91cE5hbWVzKS50b0VxdWFsKFsnbG9nX2dyb3VwJ10pO1xufSk7XG5cbnRlc3QoJ2V4Y2x1ZGVkIGxvZyBncm91cHMgYXJlIG5vdCBhZGRlZCcsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgY29uc3QgY2RrU3RhY2tBcnRpZmFjdCA9IGNka1N0YWNrQXJ0aWZhY3RPZih7XG4gICAgdGVtcGxhdGU6IHtcbiAgICAgIFJlc291cmNlczoge1xuICAgICAgICBMb2dHcm91cDoge1xuICAgICAgICAgIFR5cGU6ICdBV1M6OkxvZ3M6OkxvZ0dyb3VwJyxcbiAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBMb2dHcm91cE5hbWU6ICdsb2dfZ3JvdXAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIExvZ0dyb3VwMjoge1xuICAgICAgICAgIFR5cGU6ICdBV1M6OkxvZ3M6OkxvZ0dyb3VwJyxcbiAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBMb2dHcm91cE5hbWU6ICdsb2dfZ3JvdXAyJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBEZWY6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpDb2RlQnVpbGQ6OlByb2plY3QnLFxuICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIFBvamVjdE5hbWU6ICdwcm9qZWN0JyxcbiAgICAgICAgICAgIExvZ3NDb25maWc6IHtcbiAgICAgICAgICAgICAgQ2xvdWRXYXRjaExvZ3M6IHtcbiAgICAgICAgICAgICAgICBHcm91cE5hbWU6IHsgUmVmOiAnTG9nR3JvdXAnIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIEZsb3dMb2c6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpFQzI6OkZsb3dMb2cnLFxuICAgICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIExvZ0Rlc3RpbmF0aW9uOiB7IFJlZjogJ0xvZ0dyb3VwJyB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIEZsb3dMb2cyOiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6RUMyOjpGbG93TG9nJyxcbiAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICBMb2dEZXN0aW5hdGlvbjoge1xuICAgICAgICAgICAgICAnRm46OkdldEF0dCc6IFsnTG9nR3JvdXAyJywgJ0FybiddLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbiAgcHVzaFN0YWNrUmVzb3VyY2VTdW1tYXJpZXMoc3RhY2tTdW1tYXJ5T2YoJ0xvZ0dyb3VwJywgJ0FXUzo6TG9nczo6TG9nR3JvdXAnLCAnbG9nX2dyb3VwJykpO1xuICBwdXNoU3RhY2tSZXNvdXJjZVN1bW1hcmllcyhzdGFja1N1bW1hcnlPZignTG9nR3JvdXAyJywgJ0FXUzo6TG9nczo6TG9nR3JvdXAnLCAnbG9nX2dyb3VwMicpKTtcbiAgcHVzaFN0YWNrUmVzb3VyY2VTdW1tYXJpZXMoc3RhY2tTdW1tYXJ5T2YoJ0Zsb3dMb2cnLCAnQVdTOjpFQzI6OkZsb3dMb2cnLCAnZmxvd19sb2cnKSk7XG4gIHB1c2hTdGFja1Jlc291cmNlU3VtbWFyaWVzKHN0YWNrU3VtbWFyeU9mKCdGbG93TG9nMicsICdBV1M6OkVDMjo6Rmxvd0xvZycsICdmbG93X2xvZzInKSk7XG4gIHB1c2hTdGFja1Jlc291cmNlU3VtbWFyaWVzKHN0YWNrU3VtbWFyeU9mKCdEZWYnLCAnQVdTOjpDb2RlQnVpbGQ6UHJvamVjdCcsICdwcm9qZWN0JykpO1xuXG4gIC8vIFdIRU5cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZmluZENsb3VkV2F0Y2hMb2dHcm91cHMobG9nc01vY2tTZGtQcm92aWRlci5tb2NrU2RrUHJvdmlkZXIsIGNka1N0YWNrQXJ0aWZhY3QpO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KHJlc3VsdC5sb2dHcm91cE5hbWVzKS50b0VxdWFsKFtdKTtcbn0pO1xuXG50ZXN0KCd1bmFzc29jaWF0ZWQgbG9nIGdyb3VwcyBhcmUgYWRkZWQnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGNvbnN0IGNka1N0YWNrQXJ0aWZhY3QgPSBjZGtTdGFja0FydGlmYWN0T2Yoe1xuICAgIHRlbXBsYXRlOiB7XG4gICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgTG9nR3JvdXA6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpMb2dzOjpMb2dHcm91cCcsXG4gICAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgICAgTG9nR3JvdXBOYW1lOiAnbG9nX2dyb3VwJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbiAgcHVzaFN0YWNrUmVzb3VyY2VTdW1tYXJpZXMoc3RhY2tTdW1tYXJ5T2YoJ0xvZ0dyb3VwJywgJ0FXUzo6TG9nczo6TG9nR3JvdXAnLCAnbG9nX2dyb3VwJykpO1xuXG4gIC8vIFdIRU5cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZmluZENsb3VkV2F0Y2hMb2dHcm91cHMobG9nc01vY2tTZGtQcm92aWRlci5tb2NrU2RrUHJvdmlkZXIsIGNka1N0YWNrQXJ0aWZhY3QpO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KHJlc3VsdC5sb2dHcm91cE5hbWVzKS50b0VxdWFsKFsnbG9nX2dyb3VwJ10pO1xufSk7XG5cbnRlc3QoJ2xvZyBncm91cHMgd2l0aG91dCBwaHlzaWNhbCBuYW1lcyBhcmUgYWRkZWQnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGNvbnN0IGNka1N0YWNrQXJ0aWZhY3QgPSBjZGtTdGFja0FydGlmYWN0T2Yoe1xuICAgIHRlbXBsYXRlOiB7XG4gICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgTG9nR3JvdXA6IHtcbiAgICAgICAgICBUeXBlOiAnQVdTOjpMb2dzOjpMb2dHcm91cCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xuICBwdXNoU3RhY2tSZXNvdXJjZVN1bW1hcmllcyhzdGFja1N1bW1hcnlPZignTG9nR3JvdXAnLCAnQVdTOjpMb2dzOjpMb2dHcm91cCcsICdsb2dfZ3JvdXAnKSk7XG5cbiAgLy8gV0hFTlxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBmaW5kQ2xvdWRXYXRjaExvZ0dyb3Vwcyhsb2dzTW9ja1Nka1Byb3ZpZGVyLm1vY2tTZGtQcm92aWRlciwgY2RrU3RhY2tBcnRpZmFjdCk7XG5cbiAgLy8gVEhFTlxuICBleHBlY3QocmVzdWx0LmxvZ0dyb3VwTmFtZXMpLnRvRXF1YWwoWydsb2dfZ3JvdXAnXSk7XG59KTtcblxuY29uc3QgU1RBQ0tfTkFNRSA9ICd3aXRob3V0ZXJyb3JzJztcbmNvbnN0IGN1cnJlbnRDZm5TdGFja1Jlc291cmNlczogQ2xvdWRGb3JtYXRpb24uU3RhY2tSZXNvdXJjZVN1bW1hcnlbXSA9IFtdO1xuXG5mdW5jdGlvbiBwdXNoU3RhY2tSZXNvdXJjZVN1bW1hcmllcyguLi5pdGVtczogQ2xvdWRGb3JtYXRpb24uU3RhY2tSZXNvdXJjZVN1bW1hcnlbXSkge1xuICBjdXJyZW50Q2ZuU3RhY2tSZXNvdXJjZXMucHVzaCguLi5pdGVtcyk7XG59XG5cbmZ1bmN0aW9uIHN0YWNrU3VtbWFyeU9mKGxvZ2ljYWxJZDogc3RyaW5nLCByZXNvdXJjZVR5cGU6IHN0cmluZywgcGh5c2ljYWxSZXNvdXJjZUlkOiBzdHJpbmcpOiBDbG91ZEZvcm1hdGlvbi5TdGFja1Jlc291cmNlU3VtbWFyeSB7XG4gIHJldHVybiB7XG4gICAgTG9naWNhbFJlc291cmNlSWQ6IGxvZ2ljYWxJZCxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IHBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgICBSZXNvdXJjZVR5cGU6IHJlc291cmNlVHlwZSxcbiAgICBSZXNvdXJjZVN0YXR1czogJ0NSRUFURV9DT01QTEVURScsXG4gICAgTGFzdFVwZGF0ZWRUaW1lc3RhbXA6IG5ldyBEYXRlKCksXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNka1N0YWNrQXJ0aWZhY3RPZih0ZXN0U3RhY2tBcnRpZmFjdDogUGFydGlhbDxUZXN0U3RhY2tBcnRpZmFjdD4gPSB7fSk6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdCB7XG4gIHJldHVybiB0ZXN0U3RhY2soe1xuICAgIHN0YWNrTmFtZTogU1RBQ0tfTkFNRSxcbiAgICAuLi50ZXN0U3RhY2tBcnRpZmFjdCxcbiAgfSk7XG59XG5cbmNsYXNzIExvZ3NNb2NrU2RrUHJvdmlkZXIge1xuICBwdWJsaWMgcmVhZG9ubHkgbW9ja1Nka1Byb3ZpZGVyOiBNb2NrU2RrUHJvdmlkZXI7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5tb2NrU2RrUHJvdmlkZXIgPSBuZXcgTW9ja1Nka1Byb3ZpZGVyKHsgcmVhbFNkazogZmFsc2UgfSk7XG5cbiAgICB0aGlzLm1vY2tTZGtQcm92aWRlci5zdHViQ2xvdWRGb3JtYXRpb24oe1xuICAgICAgbGlzdFN0YWNrUmVzb3VyY2VzOiAoeyBTdGFja05hbWU6IHN0YWNrTmFtZSB9KSA9PiB7XG4gICAgICAgIGlmIChzdGFja05hbWUgIT09IFNUQUNLX05BTUUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIFN0YWNrIG5hbWUgaW4gbGlzdFN0YWNrUmVzb3VyY2VzKCkgY2FsbCB0byBiZTogJyR7U1RBQ0tfTkFNRX0nLCBidXQgcmVjZWl2ZWQ6ICR7c3RhY2tOYW1lfSdgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIFN0YWNrUmVzb3VyY2VTdW1tYXJpZXM6IGN1cnJlbnRDZm5TdGFja1Jlc291cmNlcyxcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc3R1YkdldEVuZHBvaW50U3VmZml4KHN0dWI6ICgpID0+IHN0cmluZykge1xuICAgIHRoaXMubW9ja1Nka1Byb3ZpZGVyLnN0dWJHZXRFbmRwb2ludFN1ZmZpeChzdHViKTtcbiAgfVxufVxuIl19