diff --git a/api/dashboards_test.go b/api/dashboards_test.go index 43bc9faa..f0f5080a 100644 --- a/api/dashboards_test.go +++ b/api/dashboards_test.go @@ -48,70 +48,123 @@ func TestGetDashboard(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write([]byte(` - { - "dashboard": { - "id": 1234, - "title": "Test", - "icon": "bar-chart", - "created_at": "2016-02-20T01:57:58Z", - "updated_at": "2016-09-27T22:59:21Z", - "visibility": "all", - "editable": "editable_by_all", - "ui_url": "https://insights.newrelic.com/accounts/1136088/dashboards/129507", - "api_url": "https://api.newrelic.com/v2/dashboards/129507", - "owner_email": "foo@bar.com", - "metadata": { - "version": 1 - }, - "filter": null, - "widgets": [ + { + "dashboard":{ + "id":1234, + "title":"Test", + "icon":"bar-chart", + "created_at":"2016-02-20T01:57:58Z", + "updated_at":"2016-09-27T22:59:21Z", + "visibility":"all", + "editable":"editable_by_all", + "ui_url":"https://insights.newrelic.com/accounts/1136088/dashboards/129507", + "api_url":"https://api.newrelic.com/v2/dashboards/129507", + "owner_email":"foo@bar.com", + "metadata":{ + "version":1 + }, + "filter":null, + "widgets":[ { - "visualization": "billboard", - "account_id": 1, - "data": [ - { - "nrql": "SELECT percentile(duration, 95) FROM SyntheticCheck FACET monitorName since 7 days ago" + "visualization":"billboard", + "account_id":1, + "data":[ + { + "nrql":"SELECT percentile(duration, 95) FROM SyntheticCheck FACET monitorName since 7 days ago" + } + ], + "presentation":{ + "title":"95th Percentile Load Time (ms)", + "notes":null, + "drilldown_dashboard_id":null + }, + "layout":{ + "width":1, + "height":1, + "row":1, + "column":1 + }, + "threshold":{ + "red":100, + "yellow":50 } - ], - "presentation": { - "title": "95th Percentile Load Time (ms)", - "notes": null, - "drilldown_dashboard_id": null - }, - "layout": { - "width": 2, - "height": 1, - "row": 1, - "column": 1 - }, - "threshold": { - "red": 100, - "yellow": 50 - } }, { - "visualization": "markdown", - "account_id": 1, - "data": [ - { - "source": "[test link](https://test.com)" + "visualization":"markdown", + "account_id":1, + "data":[ + { + "source":"[test link](https://test.com)" + } + ], + "presentation":{ + "title":"Links", + "notes":null, + "drilldown_dashboard_id":null + }, + "layout":{ + "width":1, + "height":1, + "row":1, + "column":2 + } + }, + { + "visualization":"metric_line_chart", + "account_id":1, + "data":[ + { + "duration":1800000, + "end_time":1800000000000, + "entity_ids":[ + 1234 + ], + "compare_with":[ + { + "offset_duration": "P7D", + "presentation": { + "name": "Last week", + "color": "#b1b6ba" + } + }, + { + "offset_duration": "P1D", + "presentation": { + "name": "Yesterday", + "color": "#77add4" + } + } + ], + "metrics":[ + { + "name":"CPU/System/Utilization", + "units":null, + "scope":"", + "values":[ + "percent" + ] + } + ], + "order_by":"score", + "limit":10, + "facet":"host", + "raw_metric_name":"CPU/System/Utilization" + } + ], + "presentation":{ + "title":"Links", + "notes":null + }, + "layout":{ + "width":1, + "height":1, + "row":1, + "column":3 } - ], - "presentation": { - "title": "Links", - "notes": null, - "drilldown_dashboard_id": null - }, - "layout": { - "width": 1, - "height": 1, - "row": 1, - "column": 2 - } } - ] - } + ] } + } `)) })) @@ -131,81 +184,134 @@ func TestCreateDashboardCondition(t *testing.T) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write([]byte(` - { - "dashboard": { - "id": 1234, - "title": "Test", - "icon": "bar-chart", - "created_at": "2016-02-20T01:57:58Z", - "updated_at": "2016-09-27T22:59:21Z", - "visibility": "all", - "editable": "editable_by_all", - "ui_url": "https://insights.newrelic.com/accounts/1136088/dashboards/129507", - "api_url": "https://api.newrelic.com/v2/dashboards/129507", - "owner_email": "foo@bar.com", - "metadata": { - "version": 1 - }, - "filter": null, - "widgets": [ + { + "dashboard":{ + "id":1234, + "title":"Test", + "icon":"bar-chart", + "created_at":"2016-02-20T01:57:58Z", + "updated_at":"2016-09-27T22:59:21Z", + "visibility":"all", + "editable":"editable_by_all", + "ui_url":"https://insights.newrelic.com/accounts/1136088/dashboards/129507", + "api_url":"https://api.newrelic.com/v2/dashboards/129507", + "owner_email":"foo@bar.com", + "metadata":{ + "version":1 + }, + "filter":null, + "widgets":[ { - "visualization": "billboard", - "account_id": 1, - "data": [ - { - "nrql": "SELECT percentile(duration, 95) FROM SyntheticCheck FACET monitorName since 7 days ago" + "visualization":"billboard", + "account_id":1, + "data":[ + { + "nrql":"SELECT percentile(duration, 95) FROM SyntheticCheck FACET monitorName since 7 days ago" + } + ], + "presentation":{ + "title":"95th Percentile Load Time (ms)", + "notes":null, + "drilldown_dashboard_id":null, + "threshold":{ + "red":100, + "yellow":50 + } + }, + "layout":{ + "width":1, + "height":1, + "row":1, + "column":1 } - ], - "presentation": { - "title": "95th Percentile Load Time (ms)", - "notes": null, - "drilldown_dashboard_id": null, - "threshold": { - "red": 100, - "yellow": 50 + }, + { + "visualization":"markdown", + "account_id":1, + "data":[ + { + "source":"[test link](https://test.com)" + } + ], + "presentation":{ + "title":"Links", + "notes":null, + "drilldown_dashboard_id":null + }, + "layout":{ + "width":1, + "height":1, + "row":1, + "column":2 } - }, - "layout": { - "width": 2, - "height": 1, - "row": 1, - "column": 1 - } }, { - "visualization": "markdown", - "account_id": 1, - "data": [ - { - "source": "[test link](https://test.com)" + "visualization":"metric_line_chart", + "account_id":1, + "data":[ + { + "duration":1800000, + "end_time":1800000000000, + "entity_ids":[ + 1234 + ], + "compare_with":[ + { + "offset_duration": "P7D", + "presentation": { + "name": "Last week", + "color": "#b1b6ba" + } + }, + { + "offset_duration": "P1D", + "presentation": { + "name": "Yesterday", + "color": "#77add4" + } + } + ], + "metrics":[ + { + "name":"CPU/System/Utilization", + "units":null, + "scope":"", + "values":[ + "percent" + ] + } + ], + "order_by":"score", + "limit":10, + "facet":"host", + "raw_metric_name":"CPU/System/Utilization" + } + ], + "presentation":{ + "title":"Links", + "notes":null + }, + "layout":{ + "width":1, + "height":1, + "row":1, + "column":3 } - ], - "presentation": { - "title": "Links", - "notes": null, - "drilldown_dashboard_id": null - }, - "layout": { - "width": 1, - "height": 1, - "row": 1, - "column": 2 - } } - ] - } + ] } + } `)) })) - dashboardWidget1Layout := DashboardWidgetLayout{ - Width: 2, + billboardWidgetLayout := DashboardWidgetLayout{ + Width: 1, Height: 1, Row: 1, Column: 1, } - dashboardWidget1Presentation := DashboardWidgetPresentation{ + billboardWidgetPresentation := DashboardWidgetPresentation{ Title: "95th Percentile Load Time (ms)", Notes: "", Threshold: &DashboardWidgetThreshold{ @@ -214,44 +320,103 @@ func TestCreateDashboardCondition(t *testing.T) { }, } - dashboardWidget1Data := []DashboardWidgetData{ + billboardWidgetData := []DashboardWidgetData{ { NRQL: "SELECT percentile(duration, 95) FROM SyntheticCheck FACET monitorName since 7 days ago", }, } - dashboardWidget2Layout := DashboardWidgetLayout{ + markdownWidgetLayout := DashboardWidgetLayout{ Width: 1, Height: 1, Row: 1, Column: 2, } - dashboardWidget2Presentation := DashboardWidgetPresentation{ + markdownWidgetPresentation := DashboardWidgetPresentation{ Title: "Links", Notes: "", } - dashboardWidget2Data := []DashboardWidgetData{ + markdownWidgetData := []DashboardWidgetData{ { Source: "[test link](https://test.com)", }, } + metricsWidgetLayout := DashboardWidgetLayout{ + Width: 1, + Height: 1, + Row: 1, + Column: 3, + } + + metricsWidgetPresentation := DashboardWidgetPresentation{ + Title: "Links", + Notes: "", + } + + metricsWidgetData := []DashboardWidgetData{ + { + Duration: 1800000, + EndTime: 1800000000000, + EntityIds: []int{ + 1234, + }, + CompareWith: []DashboardWidgetDataCompareWith{ + DashboardWidgetDataCompareWith{ + OffsetDuration: "P7D", + Presentation: DashboardWidgetDataCompareWithPresentation{ + Name: "Last week", + Color: "#b1b6ba", + }, + }, + DashboardWidgetDataCompareWith{ + OffsetDuration: "P1D", + Presentation: DashboardWidgetDataCompareWithPresentation{ + Name: "Yesterday", + Color: "#77add4", + }, + }, + }, + Metrics: []DashboardWidgetDataMetric{ + DashboardWidgetDataMetric{ + Name: "CPU/System/Utilization", + Units: "", + Scope: "", + Values: []string{ + "percent", + }, + }, + }, + RawMetricName: "CPU/System/Utilization", + Facet: "host", + OrderBy: "score", + Limit: 10, + }, + } + dashboardWidgets := []DashboardWidget{ { Visualization: "billboard", AccountID: 1, - Data: dashboardWidget1Data, - Presentation: dashboardWidget1Presentation, - Layout: dashboardWidget1Layout, + Data: billboardWidgetData, + Presentation: billboardWidgetPresentation, + Layout: billboardWidgetLayout, }, { Visualization: "markdown", AccountID: 1, - Data: dashboardWidget2Data, - Presentation: dashboardWidget2Presentation, - Layout: dashboardWidget2Layout, + Data: markdownWidgetData, + Presentation: markdownWidgetPresentation, + Layout: markdownWidgetLayout, + }, + { + Visualization: "metric_line_chart", + AccountID: 1, + Data: metricsWidgetData, + Presentation: metricsWidgetPresentation, + Layout: metricsWidgetLayout, }, } diff --git a/api/types.go b/api/types.go index 46c230cb..12c1e8d5 100644 --- a/api/types.go +++ b/api/types.go @@ -299,6 +299,7 @@ type DashboardMetadata struct { // DashboardWidget represents a widget in a dashboard. type DashboardWidget struct { Visualization string `json:"visualization,omitempty"` + ID int `json:"widget_id,omitempty"` AccountID int `json:"account_id,omitempty"` Data []DashboardWidgetData `json:"data,omitempty"` Presentation DashboardWidgetPresentation `json:"presentation,omitempty"` @@ -307,15 +308,45 @@ type DashboardWidget struct { // DashboardWidgetData represents the data backing a dashboard widget. type DashboardWidgetData struct { - NRQL string `json:"nrql,omitempty"` - Source string `json:"source,omitempty"` + NRQL string `json:"nrql,omitempty"` + Source string `json:"source,omitempty"` + Duration int `json:"duration,omitempty"` + EndTime int `json:"end_time,omitempty"` + EntityIds []int `json:"entity_ids,omitempty"` + CompareWith []DashboardWidgetDataCompareWith `json:"compare_with,omitempty"` + Metrics []DashboardWidgetDataMetric `json:"metrics,omitempty"` + RawMetricName string `json:"raw_metric_name,omitempty"` + Facet string `json:"facet,omitempty"` + OrderBy string `json:"order_by,omitempty"` + Limit int `json:"limit,omitempty"` +} + +// DashboardWidgetDataCompareWith represents the compare with configuration of the widget. +type DashboardWidgetDataCompareWith struct { + OffsetDuration string `json:"offset_duration,omitempty"` + Presentation DashboardWidgetDataCompareWithPresentation `json:"presentation,omitempty"` +} + +// DashboardWidgetDataCompareWithPresentation represents the compare with presentation configuration of the widget. +type DashboardWidgetDataCompareWithPresentation struct { + Name string `json:"name,omitempty"` + Color string `json:"color,omitempty"` +} + +// DashboardWidgetDataMetric represents the metrics data of the widget. +type DashboardWidgetDataMetric struct { + Name string `json:"name,omitempty"` + Units string `json:"units,omitempty"` + Scope string `json:"scope,omitempty"` + Values []string `json:"values,omitempty"` } // DashboardWidgetPresentation represents the visual presentation of a dashboard widget. type DashboardWidgetPresentation struct { - Title string `json:"title,omitempty"` - Notes string `json:"notes,omitempty"` - Threshold *DashboardWidgetThreshold `json:"threshold,omitempty"` + Title string `json:"title,omitempty"` + Notes string `json:"notes,omitempty"` + DrilldownDashboardID int `json:"drilldown_dashboard_id,omitempty"` + Threshold *DashboardWidgetThreshold `json:"threshold,omitempty"` } // DashboardWidgetThreshold represents the threshold configuration of a dashboard widget. diff --git a/go.mod b/go.mod index 4391a7de..94ca203a 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module github.com/paultyng/go-newrelic/v4 +go 1.13 + require ( github.com/go-resty/resty/v2 v2.1.0 + github.com/google/go-cmp v0.3.1 github.com/imdario/mergo v0.3.8 github.com/olekukonko/tablewriter v0.0.2 github.com/spf13/cobra v0.0.5 github.com/spf13/viper v1.5.0 - github.com/stretchr/testify v1.4.0 // indirect github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 ) - -go 1.13 diff --git a/go.sum b/go.sum index a524541a..00d46dac 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,7 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-resty/resty v1.12.0 h1:L1P5qymrXL5H/doXe2pKUr1wxovAI5ilm2LdVLbwThc= github.com/go-resty/resty/v2 v2.1.0 h1:Z6IefCpUMfnvItVJaJXWv/pMiiD11So35QgwEELsldE= github.com/go-resty/resty/v2 v2.1.0/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -38,7 +39,10 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=