From a44616ee887a6dc2c0977756dddef4f3cb9eda2c Mon Sep 17 00:00:00 2001 From: Julien Duchesne Date: Mon, 10 Jan 2022 14:07:37 -0500 Subject: [PATCH 1/2] Support reports --- report.go | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 report.go diff --git a/report.go b/report.go new file mode 100644 index 00000000..b4a403e6 --- /dev/null +++ b/report.go @@ -0,0 +1,101 @@ +package gapi + +import ( + "bytes" + "encoding/json" + "fmt" + "time" +) + +// ReportSchedule represents the schedule from a Grafana report. +type ReportSchedule struct { + StartDate *time.Time `json:"startDate,omitempty"` + EndDate *time.Time `json:"endDate,omitempty"` + Frequency string `json:"frequency"` + IntervalFrequency string `json:"intervalFrequency"` + IntervalAmount int64 `json:"intervalAmount"` + WorkdaysOnly bool `json:"workdaysOnly"` + TimeZone string `json:"timeZone"` +} + +// ReportTimeRange represents the time range from a Grafana report. +type ReportTimeRange struct { + From string `json:"from"` + To string `json:"to"` +} + +// ReportOptions represents the options for a Grafana report. +type ReportOptions struct { + Orientation string `json:"orientation"` + Layout string `json:"layout"` + TimeRange ReportTimeRange `json:"timeRange"` +} + +// Report represents a Grafana report. +type Report struct { + // ReadOnly + ID int64 `json:"id,omitempty"` + UserID int64 `json:"userId,omitempty"` + OrgID int64 `json:"orgId,omitempty"` + State string `json:"state,omitempty"` + + DashboardID int64 `json:"dashboardId"` + DashboardUID string `json:"dashboardUid"` + Name string `json:"name"` + Recipients string `json:"recipients"` + ReplyTo string `json:"replyTo"` + Message string `json:"message"` + Schedule ReportSchedule `json:"schedule"` + Options ReportOptions `json:"options"` + EnableDashboardURL bool `json:"enableDashboardUrl"` + EnableCSV bool `json:"enableCsv"` +} + +// Report fetches and returns a Grafana report. +func (c *Client) Report(id int64) (*Report, error) { + path := fmt.Sprintf("/api/reports/%d", id) + report := &Report{} + err := c.request("GET", path, nil, nil, report) + if err != nil { + return nil, err + } + + return report, nil +} + +// NewReport creates a new Grafana report. +func (c *Client) NewReport(report Report) (int64, error) { + data, err := json.Marshal(report) + if err != nil { + return 0, err + } + + result := struct { + ID int64 + }{} + + err = c.request("POST", "/api/reports", nil, bytes.NewBuffer(data), &result) + if err != nil { + return 0, err + } + + return result.ID, nil +} + +// UpdateReport updates a Grafana report. +func (c *Client) UpdateReport(report Report) error { + path := fmt.Sprintf("/api/reports/%d", report.ID) + data, err := json.Marshal(report) + if err != nil { + return err + } + + return c.request("PUT", path, nil, bytes.NewBuffer(data), nil) +} + +// DeleteReport deletes the Grafana report whose ID it's passed. +func (c *Client) DeleteReport(id int64) error { + path := fmt.Sprintf("/api/reports/%d", id) + + return c.request("DELETE", path, nil, nil, nil) +} From 23dda90f62761550a8a836f416a9f5eba1990f28 Mon Sep 17 00:00:00 2001 From: Julien Duchesne Date: Wed, 12 Jan 2022 13:01:37 -0500 Subject: [PATCH 2/2] Add test --- report_test.go | 135 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 report_test.go diff --git a/report_test.go b/report_test.go new file mode 100644 index 00000000..9d4333b0 --- /dev/null +++ b/report_test.go @@ -0,0 +1,135 @@ +package gapi + +import ( + "testing" + "time" + + "github.com/gobs/pretty" +) + +var ( + getReportJSON = ` + { + "id": 4, + "userId": 0, + "orgId": 1, + "dashboardId": 33, + "dashboardName": "Terraform Acceptance Test", + "dashboardUid": "", + "name": "My Report", + "recipients": "test@test.com", + "replyTo": "", + "message": "", + "schedule": { + "startDate": "2020-01-01T00:00:00Z", + "endDate": null, + "frequency": "custom", + "intervalFrequency": "weeks", + "intervalAmount": 2, + "workdaysOnly": true, + "dayOfMonth": "1", + "day": "wednesday", + "hour": 0, + "minute": 0, + "timeZone": "GMT" + }, + "options": { + "orientation": "landscape", + "layout": "grid", + "timeRange": { + "from": "now-1h", + "to": "now" + } + }, + "templateVars": {}, + "enableDashboardUrl": true, + "enableCsv": true, + "state": "", + "created": "2022-01-11T15:09:13Z", + "updated": "2022-01-11T16:18:34Z" + } +` + createReportJSON = ` + { + "id": 4 + } +` + now = time.Now() + testReport = Report{ + DashboardID: 33, + Name: "My Report", + Recipients: "test@test.com", + Schedule: ReportSchedule{ + StartDate: &now, + EndDate: nil, + Frequency: "custom", + IntervalFrequency: "weeks", + IntervalAmount: 2, + WorkdaysOnly: true, + TimeZone: "GMT", + }, + Options: ReportOptions{ + Orientation: "landscape", + Layout: "grid", + TimeRange: ReportTimeRange{ + From: "now-1h", + To: "now", + }, + }, + EnableDashboardURL: true, + EnableCSV: true, + } +) + +func TestReport(t *testing.T) { + server, client := gapiTestTools(t, 200, getReportJSON) + defer server.Close() + + report := int64(4) + resp, err := client.Report(report) + if err != nil { + t.Fatal(err) + } + + t.Log(pretty.PrettyFormat(resp)) + + if resp.ID != report || resp.Name != "My Report" { + t.Error("Not correctly parsing returned report.") + } +} + +func TestNewReport(t *testing.T) { + server, client := gapiTestTools(t, 200, createReportJSON) + defer server.Close() + + resp, err := client.NewReport(testReport) + if err != nil { + t.Fatal(err) + } + + t.Log(pretty.PrettyFormat(resp)) + + if resp != 4 { + t.Error("Not correctly parsing returned creation message.") + } +} + +func TestUpdateReport(t *testing.T) { + server, client := gapiTestTools(t, 200, "") + defer server.Close() + + err := client.UpdateReport(testReport) + if err != nil { + t.Fatal(err) + } +} + +func TestDeleteReport(t *testing.T) { + server, client := gapiTestTools(t, 200, "") + defer server.Close() + + err := client.DeleteReport(4) + if err != nil { + t.Fatal(err) + } +}