From 030251ce1eb519855acab623e0a02ebd1680931e Mon Sep 17 00:00:00 2001 From: Clare Liguori Date: Wed, 10 Apr 2019 14:11:01 -0700 Subject: [PATCH 1/2] feat(aws-cloudwatch): add support for non-widget fields in dashboard body --- .../@aws-cdk/aws-cloudwatch/lib/dashboard.ts | 42 ++++++++++++++++++- .../integ.alarm-and-dashboard.expected.json | 2 +- .../test/integ.alarm-and-dashboard.ts | 7 +++- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-cloudwatch/lib/dashboard.ts b/packages/@aws-cdk/aws-cloudwatch/lib/dashboard.ts index cb35768f65c78..a487ceef5648e 100644 --- a/packages/@aws-cdk/aws-cloudwatch/lib/dashboard.ts +++ b/packages/@aws-cdk/aws-cloudwatch/lib/dashboard.ts @@ -3,6 +3,11 @@ import { CfnDashboard } from './cloudwatch.generated'; import { Column, Row } from "./layout"; import { IWidget } from "./widget"; +export enum PeriodOverride { + Auto = 'auto', + Inherit = 'inherit', +} + export interface DashboardProps { /** * Name of the dashboard @@ -10,6 +15,36 @@ export interface DashboardProps { * @default Automatically generated name */ readonly dashboardName?: string; + + /** + * The start of the time range to use for each widget on the dashboard. + * You can specify start without specifying end to specify a relative time range that ends with the current time. + * In this case, the value of start must begin with -P, and you can use M, H, D, W and M as abbreviations for + * minutes, hours, days, weeks and months. For example, -PT8H shows the last 8 hours and -P3M shows the last three months. + * You can also use start along with an end field, to specify an absolute time range. + * When specifying an absolute time range, use the ISO 8601 format. For example, 2018-12-17T06:00:00.000Z. + * + * @default When the dashboard loads, the start time will be the default time range. + */ + readonly start?: string; + + /** + * The end of the time range to use for each widget on the dashboard when the dashboard loads. + * If you specify a value for end, you must also specify a value for start. + * Specify an absolute time in the ISO 8601 format. For example, 2018-12-17T06:00:00.000Z. + * + * @default When the dashboard loads, the end date will be the current time. + */ + readonly end?: string; + + /** + * Use this field to specify the period for the graphs when the dashboard loads. + * Specifying `Auto` causes the period of all graphs on the dashboard to automatically adapt to the time range of the dashboard. + * Specifying `Inherit` ensures that the period set for each graph is always obeyed. + * + * @default Auto + */ + readonly periodOverride?: PeriodOverride; } /** @@ -33,7 +68,12 @@ export class Dashboard extends Construct { dashboardBody: new Token(() => { const column = new Column(...this.rows); column.position(0, 0); - return this.node.stringifyJson({ widgets: column.toJson() }); + return this.node.stringifyJson({ + start: props ? props.start : undefined, + end: props ? props.end : undefined, + periodOverride: props ? props.periodOverride : undefined, + widgets: column.toJson(), + }); }).toString() }); } diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.expected.json b/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.expected.json index 2a0b5888788c6..71b83bbda96f7 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.expected.json +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.expected.json @@ -34,7 +34,7 @@ "Fn::Join": [ "", [ - "{\"widgets\":[{\"type\":\"text\",\"width\":6,\"height\":2,\"x\":0,\"y\":0,\"properties\":{\"markdown\":\"# This is my dashboard\"}},{\"type\":\"text\",\"width\":6,\"height\":2,\"x\":6,\"y\":0,\"properties\":{\"markdown\":\"you like?\"}},{\"type\":\"metric\",\"width\":6,\"height\":6,\"x\":0,\"y\":2,\"properties\":{\"view\":\"timeSeries\",\"title\":\"Messages in queue\",\"region\":\"", + "{\"start\":\"-9H\",\"end\":\"2018-12-17T06:00:00.000Z\",\"periodOverride\":\"inherit\",\"widgets\":[{\"type\":\"text\",\"width\":6,\"height\":2,\"x\":0,\"y\":0,\"properties\":{\"markdown\":\"# This is my dashboard\"}},{\"type\":\"text\",\"width\":6,\"height\":2,\"x\":6,\"y\":0,\"properties\":{\"markdown\":\"you like?\"}},{\"type\":\"metric\",\"width\":6,\"height\":6,\"x\":0,\"y\":2,\"properties\":{\"view\":\"timeSeries\",\"title\":\"Messages in queue\",\"region\":\"", { "Ref": "AWS::Region" }, diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.ts b/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.ts index ae5a2f6bf3a27..6e70689d86c38 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.ts @@ -6,6 +6,7 @@ import cdk = require('@aws-cdk/cdk'); import cloudwatch = require('../lib'); +import { PeriodOverride } from '../lib'; const app = new cdk.App(); @@ -25,7 +26,11 @@ const alarm = metric.newAlarm(stack, 'Alarm', { datapointsToAlarm: 2, }); -const dashboard = new cloudwatch.Dashboard(stack, 'Dash'); +const dashboard = new cloudwatch.Dashboard(stack, 'Dash', { + start: '-9H', + end: '2018-12-17T06:00:00.000Z', + periodOverride: PeriodOverride.Inherit +}); dashboard.add( new cloudwatch.TextWidget({ markdown: '# This is my dashboard' }), new cloudwatch.TextWidget({ markdown: 'you like?' }), From 212643e516c2efc375aa0592cd5d1096caf59be4 Mon Sep 17 00:00:00 2001 From: Clare Liguori Date: Thu, 11 Apr 2019 11:03:08 -0700 Subject: [PATCH 2/2] Add unit test --- .../aws-cloudwatch/test/test.dashboard.ts | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-cloudwatch/test/test.dashboard.ts b/packages/@aws-cdk/aws-cloudwatch/test/test.dashboard.ts index 61d3c42324f5a..95ee4d33b1055 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/test.dashboard.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/test.dashboard.ts @@ -1,7 +1,7 @@ import { expect, haveResource, isSuperObject } from '@aws-cdk/assert'; import { App, Stack } from '@aws-cdk/cdk'; import { Test } from 'nodeunit'; -import { Dashboard, GraphWidget, TextWidget } from '../lib'; +import { Dashboard, GraphWidget, PeriodOverride, TextWidget } from '../lib'; export = { 'widgets in different adds are laid out underneath each other'(test: Test) { @@ -92,6 +92,34 @@ export = { test.done(); }, + 'dashboard body includes non-widget fields'(test: Test) { + // GIVEN + const stack = new Stack(); + const dashboard = new Dashboard(stack, 'Dash', + { + start: '-9H', + end: '2018-12-17T06:00:00.000Z', + periodOverride: PeriodOverride.Inherit + }); + + // WHEN + dashboard.add( + new GraphWidget({ width: 1, height: 1 }) // GraphWidget has internal reference to current region + ); + + // THEN + expect(stack).to(haveResource('AWS::CloudWatch::Dashboard', { + DashboardBody: { "Fn::Join": [ "", [ + "{\"start\":\"-9H\",\"end\":\"2018-12-17T06:00:00.000Z\",\"periodOverride\":\"inherit\",\ +\"widgets\":[{\"type\":\"metric\",\"width\":1,\"height\":1,\"x\":0,\"y\":0,\"properties\":{\"view\":\"timeSeries\",\"region\":\"", + { Ref: "AWS::Region" }, + "\",\"metrics\":[],\"annotations\":{\"horizontal\":[]},\"yAxis\":{\"left\":{\"min\":0},\"right\":{\"min\":0}}}}]}" + ]]} + })); + + test.done(); + }, + 'work around CloudFormation bug'(test: Test) { // See: https://github.com/awslabs/aws-cdk/issues/213