@gammarers/aws-budgets-notification
Version:
AWS Budgets Notification
186 lines • 20 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BudgetsNotification = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const crypto = require("crypto");
const cdk = require("aws-cdk-lib");
const budgets = require("aws-cdk-lib/aws-budgets");
const bot = require("aws-cdk-lib/aws-chatbot");
const iam = require("aws-cdk-lib/aws-iam");
//import * as logs from 'aws-cdk-lib/aws-logs';
const sns = require("aws-cdk-lib/aws-sns");
const constructs_1 = require("constructs");
class BudgetsNotification extends constructs_1.Construct {
constructor(scope, id, props) {
super(scope, id);
// 👇Get current account & region
const account = cdk.Stack.of(this).account;
// const region = cdk.Stack.of(this).region;
// 👇Create random key
const randomNameKey = crypto.createHash('shake256', { outputLength: 4 })
.update(`${cdk.Names.uniqueId(scope)}-${cdk.Names.uniqueId(this)}`)
.digest('hex');
// 👇Create SNS Topic
const topic = new sns.Topic(this, 'NotificationTopic', {
topicName: `budget-notification-${randomNameKey}-topic`,
displayName: `budget-notification-${randomNameKey}-topic`,
});
topic.addToResourcePolicy(new iam.PolicyStatement({
sid: 'AWSBudgetsSNSPublishingPermissions',
effect: iam.Effect.ALLOW,
principals: [
new iam.ServicePrincipal('budgets.amazonaws.com'),
],
actions: [
'sns:Publish',
],
resources: [
topic.topicArn,
],
}));
topic.addToResourcePolicy(new iam.PolicyStatement({
sid: 'OwnerSNSActionPermissions',
effect: iam.Effect.ALLOW,
principals: [
new iam.AnyPrincipal(),
],
actions: [
'sns:GetTopicAttributes',
'sns:SetTopicAttributes',
'sns:AddPermission',
'sns:RemovePermission',
'sns:DeleteTopic',
'sns:Subscribe',
'sns:ListSubscriptionsByTopic',
'sns:Publish',
'sns:Receive',
],
resources: [
topic.topicArn,
],
conditions: {
StringEquals: {
'AWS:SourceOwner': account,
},
},
}));
// 👇Create ChatBot
new bot.SlackChannelConfiguration(this, 'SlackChannelConfig', {
slackChannelConfigurationName: `slack-channel-budget-notification-${randomNameKey}-config`,
slackWorkspaceId: props.slackWorkspaceId,
slackChannelId: props.slackChannelId,
//logRetention: logs.RetentionDays.TWO_MONTHS,
//logRetentionRetryOptions: undefined,
//logRetentionRole: undefined,
loggingLevel: bot.LoggingLevel.ERROR,
notificationTopics: [
topic,
],
role: new iam.Role(this, 'SlackChannelConfigRole', {
roleName: `slack-channel-budget-notification-${randomNameKey}-config-role`,
description: 'slack channel budget notification config role.',
assumedBy: new iam.ServicePrincipal('chatbot.amazonaws.com'),
inlinePolicies: {
'chatbot-policy': new iam.PolicyDocument({
statements: [
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: [
'cloudwatch:Describe*',
'cloudwatch:Get*',
'cloudwatch:List*',
],
resources: ['*'],
}),
],
}),
},
}),
});
// 👇Common notification with subscribers.
const notificationsWithSubscribers = [
{
notification: {
notificationType: 'ACTUAL',
comparisonOperator: 'GREATER_THAN',
threshold: 60,
thresholdType: 'PERCENTAGE',
},
subscribers: [
{
subscriptionType: 'SNS',
address: topic.topicArn,
},
],
},
{
notification: {
notificationType: 'ACTUAL',
comparisonOperator: 'GREATER_THAN',
threshold: 80,
thresholdType: 'PERCENTAGE',
},
subscribers: [
{
subscriptionType: 'SNS',
address: topic.topicArn,
},
],
},
{
notification: {
notificationType: 'ACTUAL',
comparisonOperator: 'GREATER_THAN',
threshold: 100,
thresholdType: 'PERCENTAGE',
},
subscribers: [
{
subscriptionType: 'SNS',
address: topic.topicArn,
},
],
},
];
if (props.linkedAccounts && props.linkedAccounts.length >= 1) {
for (const linkedAccount of props.linkedAccounts) {
new budgets.CfnBudget(this, `Budget${linkedAccount}`, {
budget: {
budgetType: 'COST',
budgetName: `Monthly usage for ${linkedAccount}.`,
timeUnit: 'MONTHLY',
costFilters: {
LinkedAccount: [
linkedAccount,
],
},
budgetLimit: {
amount: props.budgetLimitAmount,
unit: 'USD',
},
},
notificationsWithSubscribers,
});
}
}
else {
new budgets.CfnBudget(this, 'Budget', {
budget: {
budgetType: 'COST',
budgetName: 'Monthly usage',
timeUnit: 'MONTHLY',
budgetLimit: {
amount: props.budgetLimitAmount,
unit: 'USD',
},
},
notificationsWithSubscribers,
});
}
}
}
exports.BudgetsNotification = BudgetsNotification;
_a = JSII_RTTI_SYMBOL_1;
BudgetsNotification[_a] = { fqn: "@gammarers/aws-budgets-notification.BudgetsNotification", version: "1.2.77" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxpQ0FBaUM7QUFDakMsbUNBQW1DO0FBQ25DLG1EQUFtRDtBQUNuRCwrQ0FBK0M7QUFDL0MsMkNBQTJDO0FBQzNDLCtDQUErQztBQUMvQywyQ0FBMkM7QUFDM0MsMkNBQXVDO0FBVXZDLE1BQWEsbUJBQW9CLFNBQVEsc0JBQVM7SUFFaEQsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUErQjtRQUN2RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLGlDQUFpQztRQUNqQyxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDM0MsNENBQTRDO1FBRTVDLHNCQUFzQjtRQUN0QixNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxFQUFFLFlBQVksRUFBRSxDQUFDLEVBQUUsQ0FBQzthQUNyRSxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2FBQ2xFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUVqQixxQkFBcUI7UUFDckIsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxtQkFBbUIsRUFBRTtZQUNyRCxTQUFTLEVBQUUsdUJBQXVCLGFBQWEsUUFBUTtZQUN2RCxXQUFXLEVBQUUsdUJBQXVCLGFBQWEsUUFBUTtTQUMxRCxDQUFDLENBQUM7UUFDSCxLQUFLLENBQUMsbUJBQW1CLENBQUMsSUFBSSxHQUFHLENBQUMsZUFBZSxDQUFDO1lBQ2hELEdBQUcsRUFBRSxvQ0FBb0M7WUFD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LFdBQVcsRUFBRTt3QkFDWCxNQUFNLEVBQUUsS0FBSyxDQUFDLGlCQUFpQjt3QkFDL0IsSUFBSSxFQUFFLEtBQUs7cUJBQ1o7aUJBQ0Y7Z0JBQ0QsNEJBQTRCO2FBQzdCLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDOztBQTdLSCxrREE4S0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjcnlwdG8gZnJvbSAnY3J5cHRvJztcbmltcG9ydCAqIGFzIGNkayBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBidWRnZXRzIGZyb20gJ2F3cy1jZGstbGliL2F3cy1idWRnZXRzJztcbmltcG9ydCAqIGFzIGJvdCBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY2hhdGJvdCc7XG5pbXBvcnQgKiBhcyBpYW0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG4vL2ltcG9ydCAqIGFzIGxvZ3MgZnJvbSAnYXdzLWNkay1saWIvYXdzLWxvZ3MnO1xuaW1wb3J0ICogYXMgc25zIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zbnMnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5cblxuZXhwb3J0IGludGVyZmFjZSBCdWRnZXRzTm90aWZpY2F0aW9uUHJvcHMge1xuICByZWFkb25seSBzbGFja1dvcmtzcGFjZUlkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHNsYWNrQ2hhbm5lbElkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGJ1ZGdldExpbWl0QW1vdW50OiBudW1iZXI7XG4gIHJlYWRvbmx5IGxpbmtlZEFjY291bnRzPzogc3RyaW5nW107XG59XG5cbmV4cG9ydCBjbGFzcyBCdWRnZXRzTm90aWZpY2F0aW9uIGV4dGVuZHMgQ29uc3RydWN0IHtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQnVkZ2V0c05vdGlmaWNhdGlvblByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIC8vIPCfkYdHZXQgY3VycmVudCBhY2NvdW50ICYgcmVnaW9uXG4gICAgY29uc3QgYWNjb3VudCA9IGNkay5TdGFjay5vZih0aGlzKS5hY2NvdW50O1xuICAgIC8vIGNvbnN0IHJlZ2lvbiA9IGNkay5TdGFjay5vZih0aGlzKS5yZWdpb247XG5cbiAgICAvLyDwn5GHQ3JlYXRlIHJhbmRvbSBrZXlcbiAgICBjb25zdCByYW5kb21OYW1lS2V5ID0gY3J5cHRvLmNyZWF0ZUhhc2goJ3NoYWtlMjU2JywgeyBvdXRwdXRMZW5ndGg6IDQgfSlcbiAgICAgIC51cGRhdGUoYCR7Y2RrLk5hbWVzLnVuaXF1ZUlkKHNjb3BlKX0tJHtjZGsuTmFtZXMudW5pcXVlSWQodGhpcyl9YClcbiAgICAgIC5kaWdlc3QoJ2hleCcpO1xuXG4gICAgLy8g8J+Rh0NyZWF0ZSBTTlMgVG9waWNcbiAgICBjb25zdCB0b3BpYyA9IG5ldyBzbnMuVG9waWModGhpcywgJ05vdGlmaWNhdGlvblRvcGljJywge1xuICAgICAgdG9waWNOYW1lOiBgYnVkZ2V0LW5vdGlmaWNhdGlvbi0ke3JhbmRvbU5hbWVLZXl9LXRvcGljYCxcbiAgICAgIGRpc3BsYXlOYW1lOiBgYnVkZ2V0LW5vdGlmaWNhdGlvbi0ke3JhbmRvbU5hbWVLZXl9LXRvcGljYCxcbiAgICB9KTtcbiAgICB0b3BpYy5hZGRUb1Jlc291cmNlUG9saWN5KG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgIHNpZDogJ0FXU0J1ZGdldHNTTlNQdWJsaXNoaW5nUGVybWlzc2lvbnMnLFxuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgcHJpbmNpcGFsczogW1xuICAgICAgICBuZXcgaWFtLlNlcnZpY2VQcmluY2lwYWwoJ2J1ZGdldHMuYW1hem9uYXdzLmNvbScpLFxuICAgICAgXSxcbiAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgJ3NuczpQdWJsaXNoJyxcbiAgICAgIF0sXG4gICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgdG9waWMudG9waWNBcm4sXG4gICAgICBdLFxuICAgIH0pKTtcbiAgICB0b3BpYy5hZGRUb1Jlc291cmNlUG9saWN5KG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgIHNpZDogJ093bmVyU05TQWN0aW9uUGVybWlzc2lvbnMnLFxuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgcHJpbmNpcGFsczogW1xuICAgICAgICBuZXcgaWFtLkFueVByaW5jaXBhbCgpLFxuICAgICAgXSxcbiAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgJ3NuczpHZXRUb3BpY0F0dHJpYnV0ZXMnLFxuICAgICAgICAnc25zOlNldFRvcGljQXR0cmlidXRlcycsXG4gICAgICAgICdzbnM6QWRkUGVybWlzc2lvbicsXG4gICAgICAgICdzbnM6UmVtb3ZlUGVybWlzc2lvbicsXG4gICAgICAgICdzbnM6RGVsZXRlVG9waWMnLFxuICAgICAgICAnc25zOlN1YnNjcmliZScsXG4gICAgICAgICdzbnM6TGlzdFN1YnNjcmlwdGlvbnNCeVRvcGljJyxcbiAgICAgICAgJ3NuczpQdWJsaXNoJyxcbiAgICAgICAgJ3NuczpSZWNlaXZlJyxcbiAgICAgIF0sXG4gICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgdG9waWMudG9waWNBcm4sXG4gICAgICBdLFxuICAgICAgY29uZGl0aW9uczoge1xuICAgICAgICBTdHJpbmdFcXVhbHM6IHtcbiAgICAgICAgICAnQVdTOlNvdXJjZU93bmVyJzogYWNjb3VudCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSkpO1xuXG4gICAgLy8g8J+Rh0NyZWF0ZSBDaGF0Qm90XG4gICAgbmV3IGJvdC5TbGFja0NoYW5uZWxDb25maWd1cmF0aW9uKHRoaXMsICdTbGFja0NoYW5uZWxDb25maWcnLCB7XG4gICAgICBzbGFja0NoYW5uZWxDb25maWd1cmF0aW9uTmFtZTogYHNsYWNrLWNoYW5uZWwtYnVkZ2V0LW5vdGlmaWNhdGlvbi0ke3JhbmRvbU5hbWVLZXl9LWNvbmZpZ2AsXG4gICAgICBzbGFja1dvcmtzcGFjZUlkOiBwcm9wcy5zbGFja1dvcmtzcGFjZUlkLFxuICAgICAgc2xhY2tDaGFubmVsSWQ6IHByb3BzLnNsYWNrQ2hhbm5lbElkLFxuICAgICAgLy9sb2dSZXRlbnRpb246IGxvZ3MuUmV0ZW50aW9uRGF5cy5UV09fTU9OVEhTLFxuICAgICAgLy9sb2dSZXRlbnRpb25SZXRyeU9wdGlvbnM6IHVuZGVmaW5lZCxcbiAgICAgIC8vbG9nUmV0ZW50aW9uUm9sZTogdW5kZWZpbmVkLFxuICAgICAgbG9nZ2luZ0xldmVsOiBib3QuTG9nZ2luZ0xldmVsLkVSUk9SLFxuICAgICAgbm90aWZpY2F0aW9uVG9waWNzOiBbXG4gICAgICAgIHRvcGljLFxuICAgICAgXSxcbiAgICAgIHJvbGU6IG5ldyBpYW0uUm9sZSh0aGlzLCAnU2xhY2tDaGFubmVsQ29uZmlnUm9sZScsIHtcbiAgICAgICAgcm9sZU5hbWU6IGBzbGFjay1jaGFubmVsLWJ1ZGdldC1ub3RpZmljYXRpb24tJHtyYW5kb21OYW1lS2V5fS1jb25maWctcm9sZWAsXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnc2xhY2sgY2hhbm5lbCBidWRnZXQgbm90aWZpY2F0aW9uIGNvbmZpZyByb2xlLicsXG4gICAgICAgIGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdjaGF0Ym90LmFtYXpvbmF3cy5jb20nKSxcbiAgICAgICAgaW5saW5lUG9saWNpZXM6IHtcbiAgICAgICAgICAnY2hhdGJvdC1wb2xpY3knOiBuZXcgaWFtLlBvbGljeURvY3VtZW50KHtcbiAgICAgICAgICAgIHN0YXRlbWVudHM6IFtcbiAgICAgICAgICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVyxcbiAgICAgICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICAgICAnY2xvdWR3YXRjaDpEZXNjcmliZSonLFxuICAgICAgICAgICAgICAgICAgJ2Nsb3Vkd2F0Y2g6R2V0KicsXG4gICAgICAgICAgICAgICAgICAnY2xvdWR3YXRjaDpMaXN0KicsXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSksXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIC8vIPCfkYdDb21tb24gbm90aWZpY2F0aW9uIHdpdGggc3Vic2NyaWJlcnMuXG4gICAgY29uc3Qgbm90aWZpY2F0aW9uc1dpdGhTdWJzY3JpYmVyczogQXJyYXk8YnVkZ2V0cy5DZm5CdWRnZXQuTm90aWZpY2F0aW9uV2l0aFN1YnNjcmliZXJzUHJvcGVydHk+ID0gW1xuICAgICAge1xuICAgICAgICBub3RpZmljYXRpb246IHtcbiAgICAgICAgICBub3RpZmljYXRpb25UeXBlOiAnQUNUVUFMJyxcbiAgICAgICAgICBjb21wYXJpc29uT3BlcmF0b3I6ICdHUkVBVEVSX1RIQU4nLFxuICAgICAgICAgIHRocmVzaG9sZDogNjAsXG4gICAgICAgICAgdGhyZXNob2xkVHlwZTogJ1BFUkNFTlRBR0UnLFxuICAgICAgICB9LFxuICAgICAgICBzdWJzY3JpYmVyczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHN1YnNjcmlwdGlvblR5cGU6ICdTTlMnLFxuICAgICAgICAgICAgYWRkcmVzczogdG9waWMudG9waWNBcm4sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5vdGlmaWNhdGlvbjoge1xuICAgICAgICAgIG5vdGlmaWNhdGlvblR5cGU6ICdBQ1RVQUwnLFxuICAgICAgICAgIGNvbXBhcmlzb25PcGVyYXRvcjogJ0dSRUFURVJfVEhBTicsXG4gICAgICAgICAgdGhyZXNob2xkOiA4MCxcbiAgICAgICAgICB0aHJlc2hvbGRUeXBlOiAnUEVSQ0VOVEFHRScsXG4gICAgICAgIH0sXG4gICAgICAgIHN1YnNjcmliZXJzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgc3Vic2NyaXB0aW9uVHlwZTogJ1NOUycsXG4gICAgICAgICAgICBhZGRyZXNzOiB0b3BpYy50b3BpY0FybixcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbm90aWZpY2F0aW9uOiB7XG4gICAgICAgICAgbm90aWZpY2F0aW9uVHlwZTogJ0FDVFVBTCcsXG4gICAgICAgICAgY29tcGFyaXNvbk9wZXJhdG9yOiAnR1JFQVRFUl9USEFOJyxcbiAgICAgICAgICB0aHJlc2hvbGQ6IDEwMCxcbiAgICAgICAgICB0aHJlc2hvbGRUeXBlOiAnUEVSQ0VOVEFHRScsXG4gICAgICAgIH0sXG4gICAgICAgIHN1YnNjcmliZXJzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgc3Vic2NyaXB0aW9uVHlwZTogJ1NOUycsXG4gICAgICAgICAgICBhZGRyZXNzOiB0b3BpYy50b3BpY0FybixcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSxcbiAgICBdO1xuXG4gICAgaWYgKHByb3BzLmxpbmtlZEFjY291bnRzICYmIHByb3BzLmxpbmtlZEFjY291bnRzLmxlbmd0aCA+PSAxKSB7XG4gICAgICBmb3IgKGNvbnN0IGxpbmtlZEFjY291bnQgb2YgcHJvcHMubGlua2VkQWNjb3VudHMpIHtcbiAgICAgICAgbmV3IGJ1ZGdldHMuQ2ZuQnVkZ2V0KHRoaXMsIGBCdWRnZXQke2xpbmtlZEFjY291bnR9YCwge1xuICAgICAgICAgIGJ1ZGdldDoge1xuICAgICAgICAgICAgYnVkZ2V0VHlwZTogJ0NPU1QnLFxuICAgICAgICAgICAgYnVkZ2V0TmFtZTogYE1vbnRobHkgdXNhZ2UgZm9yICR7bGlua2VkQWNjb3VudH0uYCxcbiAgICAgICAgICAgIHRpbWVVbml0OiAnTU9OVEhMWScsXG4gICAgICAgICAgICBjb3N0RmlsdGVyczoge1xuICAgICAgICAgICAgICBMaW5rZWRBY2NvdW50OiBbXG4gICAgICAgICAgICAgICAgbGlua2VkQWNjb3VudCxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBidWRnZXRMaW1pdDoge1xuICAgICAgICAgICAgICBhbW91bnQ6IHByb3BzLmJ1ZGdldExpbWl0QW1vdW50LFxuICAgICAgICAgICAgICB1bml0OiAnVVNEJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBub3RpZmljYXRpb25zV2l0aFN1YnNjcmliZXJzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbmV3IGJ1ZGdldHMuQ2ZuQnVkZ2V0KHRoaXMsICdCdWRnZXQnLCB7XG4gICAgICAgIGJ1ZGdldDoge1xuICAgICAgICAgIGJ1ZGdldFR5cGU6ICdDT1NUJyxcbiAgICAgICAgICBidWRnZXROYW1lOiAnTW9udGhseSB1c2FnZScsXG4gICAgICAgICAgdGltZVVuaXQ6ICdNT05USExZJyxcbiAgICAgICAgICBidWRnZXRMaW1pdDoge1xuICAgICAgICAgICAgYW1vdW50OiBwcm9wcy5idWRnZXRMaW1pdEFtb3VudCxcbiAgICAgICAgICAgIHVuaXQ6ICdVU0QnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIG5vdGlmaWNhdGlvbnNXaXRoU3Vic2NyaWJlcnMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn0iXX0=