@gammarers/aws-codepipeline-execution-state-change-notification-stack
Version:
This AWS CDK Construct Stack receives all state changes of CodePipeline and sends a message to the specified notification destination when the CodePipeline is tagged with a specified tag. Therefore, you can send messages simply by adding tags without need
117 lines • 24.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NotificationStateMachine = void 0;
const aws_cdk_lib_1 = require("aws-cdk-lib");
const sfn = require("aws-cdk-lib/aws-stepfunctions");
const tasks = require("aws-cdk-lib/aws-stepfunctions-tasks");
class NotificationStateMachine extends sfn.StateMachine {
constructor(scope, id, props) {
super(scope, id, {
...props,
definitionBody: (() => {
// 👇 Get Account
const account = aws_cdk_lib_1.Stack.of(scope).account;
const initPipelineStateEmojisDefinition = new sfn.Pass(scope, 'InitPipelineStateEmojiDefinition', {
result: sfn.Result.fromObject([
{ name: 'STARTED', emoji: '🥳' },
{ name: 'SUCCEEDED', emoji: '🤩' },
{ name: 'RESUMED', emoji: '🤔' },
{ name: 'FAILED', emoji: '😫' },
{ name: 'STOPPING', emoji: '😮' },
{ name: 'STOPPED', emoji: '😌' },
{ name: 'SUPERSEDED', emoji: '🧐' },
]),
resultPath: '$.Definition.StateEmojis',
});
const succeed = new sfn.Succeed(scope, 'Succeed');
// describe pipeline
const getPipeline = new tasks.CallAwsService(scope, 'GetPipeline', {
iamResources: [`arn:aws:codepipeline:*:${account}:*`],
service: 'codepipeline',
action: 'getPipeline',
parameters: {
Name: sfn.JsonPath.stringAt('$.event.detail.pipeline'),
},
resultPath: '$.Result.Pipeline',
resultSelector: {
Arn: sfn.JsonPath.stringAt('$.Metadata.PipelineArn'),
},
});
initPipelineStateEmojisDefinition.next(getPipeline);
// 👇 Get Resources from resource arn list
const getResourceTagMappingList = new tasks.CallAwsService(scope, 'GetResourceTagMappingList', {
service: 'resourcegroupstaggingapi',
action: 'getResources',
parameters: {
// ResourceARNList: sfn.JsonPath.listAt('$.resources'),
ResourceTypeFilters: ['codepipeline:pipeline'], // ResourceTypeFilters is not allowed when providing a ResourceARNList
TagFilters: [
{
Key: sfn.JsonPath.stringAt('$.params.tagKey'),
Values: sfn.JsonPath.stringAt('$.params.tagValues'),
},
], // TagFilters is not allowed when providing a ResourceARNList
},
iamAction: 'tag:GetResources',
iamResources: ['*'],
resultPath: '$.Result.GetMatchTagResource',
resultSelector: {
Arns: sfn.JsonPath.stringAt('$..ResourceTagMappingList[*].ResourceARN'),
},
});
// getTags.addCatch()
getPipeline.next(getResourceTagMappingList);
// 👇 Is in
const checkTagFilterArnsContain = new sfn.Pass(scope, 'CheckTagFilterArnsContain', {
parameters: {
Is: sfn.JsonPath.arrayContains(sfn.JsonPath.stringAt('$.Result.GetMatchTagResource.Arns'), sfn.JsonPath.stringAt('$.Result.Pipeline.Arn')),
},
resultPath: '$.Result.TagFilterArnsContain',
});
getResourceTagMappingList.next(checkTagFilterArnsContain);
// 👇 Create pipeline URL
const generatePipelineUrl = new sfn.Pass(scope, 'GeneratePipelineUrl', {
resultPath: '$.Generate.PipelineUrl',
parameters: {
Value: sfn.JsonPath.format('https://{}.console.aws.amazon.com/codesuite/codepipeline/pipelines/{}/view?region={}', sfn.JsonPath.stringAt('$.event.region'), sfn.JsonPath.stringAt('$.event.detail.pipeline'), sfn.JsonPath.stringAt('$.event.region')),
},
});
const generateTopicSubject = new sfn.Pass(scope, 'GenerateTopicSubject', {
resultPath: '$.Generate.Topic.Subject',
parameters: {
Value: sfn.JsonPath.format('{} [{}] AWS CodePipeline Pipeline Execution State Notification [{}][{}]', sfn.JsonPath.arrayGetItem(sfn.JsonPath.stringAt('$.Definition.StateEmojis[?(@.name == $.event.detail.state)].emoji'), 0), sfn.JsonPath.stringAt('$.event.detail.state'), sfn.JsonPath.stringAt('$.event.account'), sfn.JsonPath.stringAt('$.event.region')),
},
});
generatePipelineUrl.next(generateTopicSubject);
// 👇 Make send default & email message
const generateTopicTextMessage = new sfn.Pass(scope, 'GeneratedPipelineMessage', {
resultPath: '$.Generate.Topic.Message',
parameters: {
Value: sfn.JsonPath.format('Account : {}\nRegion : {}\nPipeline : {}\nState : {}\nTime : {}\nURL : {}\n', sfn.JsonPath.stringAt('$.event.account'), sfn.JsonPath.stringAt('$.event.region'), sfn.JsonPath.stringAt('$.event.detail.pipeline'), sfn.JsonPath.stringAt('$.event.detail.state'), sfn.JsonPath.stringAt('$.event.time'), sfn.JsonPath.stringAt('$.Generate.PipelineUrl.Value')),
},
});
generateTopicSubject.next(generateTopicTextMessage);
// 👇 Choice state for message
const checkPipelineStateMatch = new sfn.Choice(scope, 'CheckPipelineStateMatch')
.when(sfn.Condition.or(sfn.Condition.stringEquals('$.event.detail.state', 'STARTED'), sfn.Condition.stringEquals('$.event.detail.state', 'SUCCEEDED'), sfn.Condition.stringEquals('$.event.detail.state', 'RESUMED'), sfn.Condition.stringEquals('$.event.detail.state', 'FAILED'), sfn.Condition.stringEquals('$.event.detail.state', 'STOPPING'), sfn.Condition.stringEquals('$.event.detail.state', 'STOPPED'), sfn.Condition.stringEquals('$.event.detail.state', 'SUPERSEDED')), generatePipelineUrl)
.otherwise(new sfn.Pass(scope, 'UnMatchStatus'));
const checkFoundTagMatch = new sfn.Choice(scope, 'CheckFoundTagMatch')
.when(sfn.Condition.booleanEquals('$.Result.TagFilterArnsContain.Is', true), checkPipelineStateMatch)
.otherwise(new sfn.Pass(scope, 'UnMatchPipelineTagFilter'));
checkTagFilterArnsContain.next(checkFoundTagMatch);
// 👇 Send notification task
const sendNotification = new tasks.SnsPublish(scope, 'SendNotification', {
topic: props.notificationTopic,
subject: sfn.JsonPath.stringAt('$.Generate.Topic.Subject.Value'),
message: sfn.TaskInput.fromJsonPathAt('$.Generate.Topic.Message.Value'),
resultPath: '$.snsResult',
});
generateTopicTextMessage.next(sendNotification);
sendNotification.next(succeed);
return sfn.DefinitionBody.fromChainable(initPipelineStateEmojisDefinition);
})(),
});
}
}
exports.NotificationStateMachine = NotificationStateMachine;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90aWZpY2F0aW9uLXN0YXRlLW1hY2hpbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVzb3VyY2VzL25vdGlmaWNhdGlvbi1zdGF0ZS1tYWNoaW5lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUFvQztBQUVwQyxxREFBcUQ7QUFDckQsNkRBQTZEO0FBTzdELE1BQWEsd0JBQXlCLFNBQVEsR0FBRyxDQUFDLFlBQVk7SUFDNUQsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFvQztRQUM1RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtZQUNmLEdBQUcsS0FBSztZQUNSLGNBQWMsRUFBRSxDQUFDLEdBQUcsRUFBRTtnQkFFcEIsaUJBQWlCO2dCQUNqQixNQUFNLE9BQU8sR0FBRyxtQkFBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUM7Z0JBRXhDLE1BQU0saUNBQWlDLEdBQWEsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxrQ0FBa0MsRUFBRTtvQkFDMUcsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO3dCQUM1QixFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRTt3QkFDaEMsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUU7d0JBQ2xDLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFO3dCQUNoQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRTt3QkFDL0IsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUU7d0JBQ2pDLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFO3dCQUNoQyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsS0FB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LGFBQWEsQ0FBQyxrQ0FBa0MsRUFBRSxJQUFJLENBQUMsRUFBRSx1QkFBdUIsQ0FBQztxQkFDcEcsU0FBUyxDQUFDLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsMEJBQTBCLENBQUMsQ0FBQyxDQUFDO2dCQUU5RCx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztnQkFFbkQsNEJBQTRCO2dCQUM1QixNQUFNLGdCQUFnQixHQUFxQixJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLGtCQUFrQixFQUFFO29CQUN6RixLQUFLLEVBQUUsS0FBSyxDQUFDLGlCQUFpQjtvQkFDOUIsT0FBTyxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLGdDQUFnQyxDQUFDO29CQUNoRSxPQUFPLEVBQUUsR0FBRyxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsZ0NBQWdDLENBQUM7b0JBQ3ZFLFVBQVUsRUFBRSxhQUFhO2lCQUMxQixDQUFDLENBQUM7Z0JBRUgsd0JBQXdCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0JBRWhELGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDL0IsT0FBTyxHQUFHLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1lBRTdFLENBQUMsQ0FBQyxFQUFFO1NBQ0wsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBMUpELDREQTBKQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0ICogYXMgc25zIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zbnMnO1xuaW1wb3J0ICogYXMgc2ZuIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zdGVwZnVuY3Rpb25zJztcbmltcG9ydCAqIGFzIHRhc2tzIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zdGVwZnVuY3Rpb25zLXRhc2tzJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE5vdGlmaWNhdGlvblN0YXRlTWFjaGluZVByb3BzIGV4dGVuZHMgc2ZuLlN0YXRlTWFjaGluZVByb3BzIHtcbiAgbm90aWZpY2F0aW9uVG9waWM6IHNucy5JVG9waWM7XG59XG5cbmV4cG9ydCBjbGFzcyBOb3RpZmljYXRpb25TdGF0ZU1hY2hpbmUgZXh0ZW5kcyBzZm4uU3RhdGVNYWNoaW5lIHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE5vdGlmaWNhdGlvblN0YXRlTWFjaGluZVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIGRlZmluaXRpb25Cb2R5OiAoKCkgPT4ge1xuXG4gICAgICAgIC8vIPCfkYcgR2V0IEFjY291bnRcbiAgICAgICAgY29uc3QgYWNjb3VudCA9IFN0YWNrLm9mKHNjb3BlKS5hY2NvdW50O1xuXG4gICAgICAgIGNvbnN0IGluaXRQaXBlbGluZVN0YXRlRW1vamlzRGVmaW5pdGlvbjogc2ZuLlBhc3MgPSBuZXcgc2ZuLlBhc3Moc2NvcGUsICdJbml0UGlwZWxpbmVTdGF0ZUVtb2ppRGVmaW5pdGlvbicsIHtcbiAgICAgICAgICByZXN1bHQ6IHNmbi5SZXN1bHQuZnJvbU9iamVjdChbXG4gICAgICAgICAgICB7IG5hbWU6ICdTVEFSVEVEJywgZW1vamk6ICfwn6WzJyB9LFxuICAgICAgICAgICAgeyBuYW1lOiAnU1VDQ0VFREVEJywgZW1vamk6ICfwn6SpJyB9LFxuICAgICAgICAgICAgeyBuYW1lOiAnUkVTVU1FRCcsIGVtb2ppOiAn8J+klCcgfSxcbiAgICAgICAgICAgIHsgbmFtZTogJ0ZBSUxFRCcsIGVtb2ppOiAn8J+YqycgfSxcbiAgICAgICAgICAgIHsgbmFtZTogJ1NUT1BQSU5HJywgZW1vamk6ICfwn5iuJyB9LFxuICAgICAgICAgICAgeyBuYW1lOiAnU1RPUFBFRCcsIGVtb2ppOiAn8J+YjCcgfSxcbiAgICAgICAgICAgIHsgbmFtZTogJ1NVUEVSU0VERUQnLCBlbW9qaTogJ/Cfp5AnIH0sXG4gICAgICAgICAgXSksXG4gICAgICAgICAgcmVzdWx0UGF0aDogJyQuRGVmaW5pdGlvbi5TdGF0ZUVtb2ppcycsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHN1Y2NlZWQ6IHNmbi5TdWNjZWVkID0gbmV3IHNmbi5TdWNjZWVkKHNjb3BlLCAnU3VjY2VlZCcpO1xuXG4gICAgICAgIC8vIGRlc2NyaWJlIHBpcGVsaW5lXG4gICAgICAgIGNvbnN0IGdldFBpcGVsaW5lID0gbmV3IHRhc2tzLkNhbGxBd3NTZXJ2aWNlKHNjb3BlLCAnR2V0UGlwZWxpbmUnLCB7XG4gICAgICAgICAgaWFtUmVzb3VyY2VzOiBbYGFybjphd3M6Y29kZXBpcGVsaW5lOio6JHthY2NvdW50fToqYF0sXG4gICAgICAgICAgc2VydmljZTogJ2NvZGVwaXBlbGluZScsXG4gICAgICAgICAgYWN0aW9uOiAnZ2V0UGlwZWxpbmUnLFxuICAgICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgIE5hbWU6IHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5ldmVudC5kZXRhaWwucGlwZWxpbmUnKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlc3VsdFBhdGg6ICckLlJlc3VsdC5QaXBlbGluZScsXG4gICAgICAgICAgcmVzdWx0U2VsZWN0b3I6IHtcbiAgICAgICAgICAgIEFybjogc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLk1ldGFkYXRhLlBpcGVsaW5lQXJuJyksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGluaXRQaXBlbGluZVN0YXRlRW1vamlzRGVmaW5pdGlvbi5uZXh0KGdldFBpcGVsaW5lKTtcblxuICAgICAgICAvLyDwn5GHIEdldCBSZXNvdXJjZXMgZnJvbSByZXNvdXJjZSBhcm4gbGlzdFxuICAgICAgICBjb25zdCBnZXRSZXNvdXJjZVRhZ01hcHBpbmdMaXN0OiB0YXNrcy5DYWxsQXdzU2VydmljZSA9IG5ldyB0YXNrcy5DYWxsQXdzU2VydmljZShzY29wZSwgJ0dldFJlc291cmNlVGFnTWFwcGluZ0xpc3QnLCB7XG4gICAgICAgICAgc2VydmljZTogJ3Jlc291cmNlZ3JvdXBzdGFnZ2luZ2FwaScsXG4gICAgICAgICAgYWN0aW9uOiAnZ2V0UmVzb3VyY2VzJyxcbiAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAvLyBSZXNvdXJjZUFSTkxpc3Q6IHNmbi5Kc29uUGF0aC5saXN0QXQoJyQucmVzb3VyY2VzJyksXG4gICAgICAgICAgICBSZXNvdXJjZVR5cGVGaWx0ZXJzOiBbJ2NvZGVwaXBlbGluZTpwaXBlbGluZSddLCAvLyBSZXNvdXJjZVR5cGVGaWx0ZXJzIGlzIG5vdCBhbGxvd2VkIHdoZW4gcHJvdmlkaW5nIGEgUmVzb3VyY2VBUk5MaXN0XG4gICAgICAgICAgICBUYWdGaWx0ZXJzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBLZXk6IHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5wYXJhbXMudGFnS2V5JyksXG4gICAgICAgICAgICAgICAgVmFsdWVzOiBzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQucGFyYW1zLnRhZ1ZhbHVlcycpLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSwgLy8gVGFnRmlsdGVycyBpcyBub3QgYWxsb3dlZCB3aGVuIHByb3ZpZGluZyBhIFJlc291cmNlQVJOTGlzdFxuICAgICAgICAgIH0sXG4gICAgICAgICAgaWFtQWN0aW9uOiAndGFnOkdldFJlc291cmNlcycsXG4gICAgICAgICAgaWFtUmVzb3VyY2VzOiBbJyonXSxcbiAgICAgICAgICByZXN1bHRQYXRoOiAnJC5SZXN1bHQuR2V0TWF0Y2hUYWdSZXNvdXJjZScsXG4gICAgICAgICAgcmVzdWx0U2VsZWN0b3I6IHtcbiAgICAgICAgICAgIEFybnM6IHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC4uUmVzb3VyY2VUYWdNYXBwaW5nTGlzdFsqXS5SZXNvdXJjZUFSTicpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBnZXRUYWdzLmFkZENhdGNoKClcbiAgICAgICAgZ2V0UGlwZWxpbmUubmV4dChnZXRSZXNvdXJjZVRhZ01hcHBpbmdMaXN0KTtcblxuICAgICAgICAvLyDwn5GHIElzIGluXG4gICAgICAgIGNvbnN0IGNoZWNrVGFnRmlsdGVyQXJuc0NvbnRhaW46IHNmbi5QYXNzID0gbmV3IHNmbi5QYXNzKHNjb3BlLCAnQ2hlY2tUYWdGaWx0ZXJBcm5zQ29udGFpbicsIHtcbiAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICBJczogc2ZuLkpzb25QYXRoLmFycmF5Q29udGFpbnMoc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLlJlc3VsdC5HZXRNYXRjaFRhZ1Jlc291cmNlLkFybnMnKSwgc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLlJlc3VsdC5QaXBlbGluZS5Bcm4nKSksXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXN1bHRQYXRoOiAnJC5SZXN1bHQuVGFnRmlsdGVyQXJuc0NvbnRhaW4nLFxuICAgICAgICB9KTtcblxuICAgICAgICBnZXRSZXNvdXJjZVRhZ01hcHBpbmdMaXN0Lm5leHQoY2hlY2tUYWdGaWx0ZXJBcm5zQ29udGFpbik7XG5cbiAgICAgICAgLy8g8J+RhyBDcmVhdGUgcGlwZWxpbmUgVVJMXG4gICAgICAgIGNvbnN0IGdlbmVyYXRlUGlwZWxpbmVVcmwgPSBuZXcgc2ZuLlBhc3Moc2NvcGUsICdHZW5lcmF0ZVBpcGVsaW5lVXJsJywge1xuICAgICAgICAgIHJlc3VsdFBhdGg6ICckLkdlbmVyYXRlLlBpcGVsaW5lVXJsJyxcbiAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICBWYWx1ZTogc2ZuLkpzb25QYXRoLmZvcm1hdCgnaHR0cHM6Ly97fS5jb25zb2xlLmF3cy5hbWF6b24uY29tL2NvZGVzdWl0ZS9jb2RlcGlwZWxpbmUvcGlwZWxpbmVzL3t9L3ZpZXc/cmVnaW9uPXt9JyxcbiAgICAgICAgICAgICAgc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLmV2ZW50LnJlZ2lvbicpLFxuICAgICAgICAgICAgICBzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQuZXZlbnQuZGV0YWlsLnBpcGVsaW5lJyksXG4gICAgICAgICAgICAgIHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5ldmVudC5yZWdpb24nKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgZ2VuZXJhdGVUb3BpY1N1YmplY3QgPSBuZXcgc2ZuLlBhc3Moc2NvcGUsICdHZW5lcmF0ZVRvcGljU3ViamVjdCcsIHtcbiAgICAgICAgICByZXN1bHRQYXRoOiAnJC5HZW5lcmF0ZS5Ub3BpYy5TdWJqZWN0JyxcbiAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICBWYWx1ZTogc2ZuLkpzb25QYXRoLmZvcm1hdCgne30gW3t9XSBBV1MgQ29kZVBpcGVsaW5lIFBpcGVsaW5lIEV4ZWN1dGlvbiBTdGF0ZSBOb3RpZmljYXRpb24gW3t9XVt7fV0nLFxuICAgICAgICAgICAgICBzZm4uSnNvblBhdGguYXJyYXlHZXRJdGVtKHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5EZWZpbml0aW9uLlN0YXRlRW1vamlzWz8oQC5uYW1lID09ICQuZXZlbnQuZGV0YWlsLnN0YXRlKV0uZW1vamknKSwgMCksXG4gICAgICAgICAgICAgIHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5ldmVudC5kZXRhaWwuc3RhdGUnKSxcbiAgICAgICAgICAgICAgc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLmV2ZW50LmFjY291bnQnKSxcbiAgICAgICAgICAgICAgc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLmV2ZW50LnJlZ2lvbicpLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBnZW5lcmF0ZVBpcGVsaW5lVXJsLm5leHQoZ2VuZXJhdGVUb3BpY1N1YmplY3QpO1xuXG4gICAgICAgIC8vIPCfkYcgTWFrZSBzZW5kIGRlZmF1bHQgJiBlbWFpbCBtZXNzYWdlXG4gICAgICAgIGNvbnN0IGdlbmVyYXRlVG9waWNUZXh0TWVzc2FnZTogc2ZuLlBhc3MgPSBuZXcgc2ZuLlBhc3Moc2NvcGUsICdHZW5lcmF0ZWRQaXBlbGluZU1lc3NhZ2UnLCB7XG4gICAgICAgICAgcmVzdWx0UGF0aDogJyQuR2VuZXJhdGUuVG9waWMuTWVzc2FnZScsXG4gICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgVmFsdWU6IHNmbi5Kc29uUGF0aC5mb3JtYXQoJ0FjY291bnQgOiB7fVxcblJlZ2lvbiA6IHt9XFxuUGlwZWxpbmUgOiB7fVxcblN0YXRlIDoge31cXG5UaW1lIDoge31cXG5VUkwgOiB7fVxcbicsXG4gICAgICAgICAgICAgIHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5ldmVudC5hY2NvdW50JyksXG4gICAgICAgICAgICAgIHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5ldmVudC5yZWdpb24nKSxcbiAgICAgICAgICAgICAgc2ZuLkpzb25QYXRoLnN0cmluZ0F0KCckLmV2ZW50LmRldGFpbC5waXBlbGluZScpLFxuICAgICAgICAgICAgICBzZm4uSnNvblBhdGguc3RyaW5nQXQoJyQuZXZlbnQuZGV0YWlsLnN0YXRlJyksXG4gICAgICAgICAgICAgIHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5ldmVudC50aW1lJyksXG4gICAgICAgICAgICAgIHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5HZW5lcmF0ZS5QaXBlbGluZVVybC5WYWx1ZScpLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBnZW5lcmF0ZVRvcGljU3ViamVjdC5uZXh0KGdlbmVyYXRlVG9waWNUZXh0TWVzc2FnZSk7XG5cbiAgICAgICAgLy8g8J+RhyBDaG9pY2Ugc3RhdGUgZm9yIG1lc3NhZ2VcbiAgICAgICAgY29uc3QgY2hlY2tQaXBlbGluZVN0YXRlTWF0Y2g6IHNmbi5DaG9pY2UgPSBuZXcgc2ZuLkNob2ljZShzY29wZSwgJ0NoZWNrUGlwZWxpbmVTdGF0ZU1hdGNoJylcbiAgICAgICAgICAud2hlbihcbiAgICAgICAgICAgIHNmbi5Db25kaXRpb24ub3IoXG4gICAgICAgICAgICAgIHNmbi5Db25kaXRpb24uc3RyaW5nRXF1YWxzKCckLmV2ZW50LmRldGFpbC5zdGF0ZScsICdTVEFSVEVEJyksXG4gICAgICAgICAgICAgIHNmbi5Db25kaXRpb24uc3RyaW5nRXF1YWxzKCckLmV2ZW50LmRldGFpbC5zdGF0ZScsICdTVUNDRUVERUQnKSxcbiAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcXVhbHMoJyQuZXZlbnQuZGV0YWlsLnN0YXRlJywgJ1JFU1VNRUQnKSxcbiAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcXVhbHMoJyQuZXZlbnQuZGV0YWlsLnN0YXRlJywgJ0ZBSUxFRCcpLFxuICAgICAgICAgICAgICBzZm4uQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJC5ldmVudC5kZXRhaWwuc3RhdGUnLCAnU1RPUFBJTkcnKSxcbiAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcXVhbHMoJyQuZXZlbnQuZGV0YWlsLnN0YXRlJywgJ1NUT1BQRUQnKSxcbiAgICAgICAgICAgICAgc2ZuLkNvbmRpdGlvbi5zdHJpbmdFcXVhbHMoJyQuZXZlbnQuZGV0YWlsLnN0YXRlJywgJ1NVUEVSU0VERUQnKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBnZW5lcmF0ZVBpcGVsaW5lVXJsLFxuICAgICAgICAgIClcbiAgICAgICAgICAub3RoZXJ3aXNlKG5ldyBzZm4uUGFzcyhzY29wZSwgJ1VuTWF0Y2hTdGF0dXMnKSk7XG5cbiAgICAgICAgY29uc3QgY2hlY2tGb3VuZFRhZ01hdGNoID0gbmV3IHNmbi5DaG9pY2Uoc2NvcGUsICdDaGVja0ZvdW5kVGFnTWF0Y2gnKVxuICAgICAgICAgIC53aGVuKHNmbi5Db25kaXRpb24uYm9vbGVhbkVxdWFscygnJC5SZXN1bHQuVGFnRmlsdGVyQXJuc0NvbnRhaW4uSXMnLCB0cnVlKSwgY2hlY2tQaXBlbGluZVN0YXRlTWF0Y2gpXG4gICAgICAgICAgLm90aGVyd2lzZShuZXcgc2ZuLlBhc3Moc2NvcGUsICdVbk1hdGNoUGlwZWxpbmVUYWdGaWx0ZXInKSk7XG5cbiAgICAgICAgY2hlY2tUYWdGaWx0ZXJBcm5zQ29udGFpbi5uZXh0KGNoZWNrRm91bmRUYWdNYXRjaCk7XG5cbiAgICAgICAgLy8g8J+RhyBTZW5kIG5vdGlmaWNhdGlvbiB0YXNrXG4gICAgICAgIGNvbnN0IHNlbmROb3RpZmljYXRpb246IHRhc2tzLlNuc1B1Ymxpc2ggPSBuZXcgdGFza3MuU25zUHVibGlzaChzY29wZSwgJ1NlbmROb3RpZmljYXRpb24nLCB7XG4gICAgICAgICAgdG9waWM6IHByb3BzLm5vdGlmaWNhdGlvblRvcGljLFxuICAgICAgICAgIHN1YmplY3Q6IHNmbi5Kc29uUGF0aC5zdHJpbmdBdCgnJC5HZW5lcmF0ZS5Ub3BpYy5TdWJqZWN0LlZhbHVlJyksXG4gICAgICAgICAgbWVzc2FnZTogc2ZuLlRhc2tJbnB1dC5mcm9tSnNvblBhdGhBdCgnJC5HZW5lcmF0ZS5Ub3BpYy5NZXNzYWdlLlZhbHVlJyksXG4gICAgICAgICAgcmVzdWx0UGF0aDogJyQuc25zUmVzdWx0JyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZ2VuZXJhdGVUb3BpY1RleHRNZXNzYWdlLm5leHQoc2VuZE5vdGlmaWNhdGlvbik7XG5cbiAgICAgICAgc2VuZE5vdGlmaWNhdGlvbi5uZXh0KHN1Y2NlZWQpO1xuICAgICAgICByZXR1cm4gc2ZuLkRlZmluaXRpb25Cb2R5LmZyb21DaGFpbmFibGUoaW5pdFBpcGVsaW5lU3RhdGVFbW9qaXNEZWZpbml0aW9uKTtcblxuICAgICAgfSkoKSxcbiAgICB9KTtcbiAgfVxufSJdfQ==