Skip to content

Commit bbbb157

Browse files
Report: Add last_day_of_month option (#686)
Closes #625 Also, I converted all values used in the report code to constants
1 parent 0f7613e commit bbbb157

File tree

7 files changed

+102
-18
lines changed

7 files changed

+102
-18
lines changed

docs/resources/report.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ resource "grafana_report" "test" {
5151

5252
- `include_dashboard_link` (Boolean) Whether to include a link to the dashboard in the report. Defaults to `true`.
5353
- `include_table_csv` (Boolean) Whether to include a CSV file of table panel data. Defaults to `false`.
54-
- `layout` (String) Layout of the report. `simple` or `grid` Defaults to `grid`.
54+
- `layout` (String) Layout of the report. Allowed values: `simple`, `grid`. Defaults to `grid`.
5555
- `message` (String) Message to be sent in the report.
56-
- `orientation` (String) Orientation of the report. `landscape` or `portrait` Defaults to `landscape`.
56+
- `orientation` (String) Orientation of the report. Allowed values: `landscape`, `portrait`. Defaults to `landscape`.
5757
- `reply_to` (String) Reply-to email address of the report.
5858
- `time_range` (Block List, Max: 1) Time range of the report. (see [below for nested schema](#nestedblock--time_range))
5959

@@ -66,13 +66,14 @@ resource "grafana_report" "test" {
6666

6767
Required:
6868

69-
- `frequency` (String) Frequency of the report. One of `never`, `once`, `hourly`, `daily`, `weekly`, `monthly` or `custom`.
69+
- `frequency` (String) Frequency of the report. Allowed values: `never`, `once`, `hourly`, `daily`, `weekly`, `monthly`, `custom`.
7070

7171
Optional:
7272

7373
- `custom_interval` (String) Custom interval of the report.
7474
**Note:** This field is only available when frequency is set to `custom`.
7575
- `end_time` (String) End time of the report. If empty, the report will be sent indefinitely (according to frequency). Note that times will be saved as UTC in Grafana.
76+
- `last_day_of_month` (Boolean) Send the report on the last day of the month Defaults to `false`.
7677
- `start_time` (String) Start time of the report. If empty, the start date will be set to the creation time. Note that times will be saved as UTC in Grafana.
7778
- `workdays_only` (Boolean) Whether to send the report only on work days. Defaults to `false`.
7879

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
resource "grafana_dashboard" "test" {
2+
config_json = <<EOD
3+
{
4+
"title": "Dashboard for report",
5+
"uid": "report"
6+
}
7+
EOD
8+
message = "inital commit."
9+
}
10+
11+
resource "grafana_report" "test" {
12+
name = "my report"
13+
dashboard_id = grafana_dashboard.test.dashboard_id
14+
recipients = ["[email protected]"]
15+
schedule {
16+
frequency = "monthly"
17+
last_day_of_month = true
18+
}
19+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.18
55
require (
66
github.com/Masterminds/semver/v3 v3.1.1
77
github.com/grafana/amixr-api-go-client v0.0.5
8-
github.com/grafana/grafana-api-golang-client v0.12.0
8+
github.com/grafana/grafana-api-golang-client v0.12.1
99
github.com/grafana/machine-learning-go-client v0.1.1
1010
github.com/grafana/synthetic-monitoring-agent v0.9.4
1111
github.com/grafana/synthetic-monitoring-api-go-client v0.6.3

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
115115
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
116116
github.com/grafana/amixr-api-go-client v0.0.5 h1:jqmljnd5FozuOsCNuyhZVpooxmj0BW9MmeLA7PaLK6U=
117117
github.com/grafana/amixr-api-go-client v0.0.5/go.mod h1:N6x26XUrM5zGtK5zL5vNJnAn2JFMxLFPPLTw/6pDkFE=
118-
github.com/grafana/grafana-api-golang-client v0.12.0 h1:EqoBKAeDeWQdb9PXrTc7vvVMzJTLTFYR+MbbEJhua+o=
119-
github.com/grafana/grafana-api-golang-client v0.12.0/go.mod h1:24W29gPe9yl0/3A9X624TPkAOR8DpHno490cPwnkv8E=
118+
github.com/grafana/grafana-api-golang-client v0.12.1 h1:GLkNXslTWf/ZBxjRHK6VYW6FSqFnhaiA47pTZe9GUBw=
119+
github.com/grafana/grafana-api-golang-client v0.12.1/go.mod h1:24W29gPe9yl0/3A9X624TPkAOR8DpHno490cPwnkv8E=
120120
github.com/grafana/machine-learning-go-client v0.1.1 h1:Gw6cX8xAd6IVF2LApkXOIdBK8Gzz07B3jQPukecw7fc=
121121
github.com/grafana/machine-learning-go-client v0.1.1/go.mod h1:QFfZz8NkqVF8++skjkKQXJEZfpCYd8S0yTWJUpsLLTA=
122122
github.com/grafana/synthetic-monitoring-agent v0.9.4 h1:Enx5s6gFbc/RAzL5KDX/00catAlbcY7/1IFPBe5lo/c=

grafana/resource_report.go

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,28 @@ import (
1818
gapi "github.com/grafana/grafana-api-golang-client"
1919
)
2020

21+
const (
22+
reportFrequencyHourly = "hourly"
23+
reportFrequencyDaily = "daily"
24+
reportFrequencyWeekly = "weekly"
25+
reportFrequencyMonthly = "monthly"
26+
reportFrequencyCustom = "custom"
27+
reportFrequencyOnce = "once"
28+
reportFrequencyNever = "never"
29+
30+
reportOrientationPortrait = "portrait"
31+
reportOrientationLandscape = "landscape"
32+
33+
reportLayoutGrid = "grid"
34+
reportLayoutSimple = "simple"
35+
)
36+
37+
var (
38+
reportLayouts = []string{reportLayoutSimple, reportLayoutGrid}
39+
reportOrientations = []string{reportOrientationLandscape, reportOrientationPortrait}
40+
reportFrequencies = []string{reportFrequencyNever, reportFrequencyOnce, reportFrequencyHourly, reportFrequencyDaily, reportFrequencyWeekly, reportFrequencyMonthly, reportFrequencyCustom}
41+
)
42+
2143
func ResourceReport() *schema.Resource {
2244
return &schema.Resource{
2345
Description: `
@@ -85,16 +107,16 @@ func ResourceReport() *schema.Resource {
85107
"layout": {
86108
Type: schema.TypeString,
87109
Optional: true,
88-
Description: "Layout of the report. `simple` or `grid`",
89-
Default: "grid",
90-
ValidateFunc: validation.StringInSlice([]string{"simple", "grid"}, false),
110+
Description: allowedValuesDescription("Layout of the report", reportLayouts),
111+
Default: reportLayoutGrid,
112+
ValidateFunc: validation.StringInSlice(reportLayouts, false),
91113
},
92114
"orientation": {
93115
Type: schema.TypeString,
94116
Optional: true,
95-
Description: "Orientation of the report. `landscape` or `portrait`",
96-
Default: "landscape",
97-
ValidateFunc: validation.StringInSlice([]string{"landscape", "portrait"}, false),
117+
Description: allowedValuesDescription("Orientation of the report", reportOrientations),
118+
Default: reportOrientationLandscape,
119+
ValidateFunc: validation.StringInSlice(reportOrientations, false),
98120
},
99121
"time_range": {
100122
Type: schema.TypeList,
@@ -129,8 +151,8 @@ func ResourceReport() *schema.Resource {
129151
"frequency": {
130152
Type: schema.TypeString,
131153
Required: true,
132-
Description: "Frequency of the report. One of `never`, `once`, `hourly`, `daily`, `weekly`, `monthly` or `custom`.",
133-
ValidateFunc: validation.StringInSlice([]string{"never", "once", "hourly", "daily", "weekly", "monthly", "custom"}, false),
154+
Description: allowedValuesDescription("Frequency of the report", reportFrequencies),
155+
ValidateFunc: validation.StringInSlice(reportFrequencies, false),
134156
},
135157
"start_time": {
136158
Type: schema.TypeString,
@@ -179,6 +201,12 @@ func ResourceReport() *schema.Resource {
179201
return diag.FromErr(err)
180202
},
181203
},
204+
"last_day_of_month": {
205+
Type: schema.TypeBool,
206+
Optional: true,
207+
Description: "Send the report on the last day of the month",
208+
Default: false,
209+
},
182210
},
183211
},
184212
},
@@ -253,6 +281,9 @@ func ReadReport(ctx context.Context, d *schema.ResourceData, meta interface{}) d
253281
if r.Schedule.EndDate != nil {
254282
schedule["end_time"] = r.Schedule.EndDate.Format(time.RFC3339)
255283
}
284+
if r.Schedule.DayOfMonth == "last" {
285+
schedule["last_day_of_month"] = true
286+
}
256287

257288
d.Set("schedule", []interface{}{schedule})
258289

@@ -320,7 +351,7 @@ func schemaToReport(d *schema.ResourceData) (gapi.Report, error) {
320351
}
321352

322353
// Set schedule start time
323-
if frequency != "never" {
354+
if frequency != reportFrequencyNever {
324355
if startTimeStr := d.Get("schedule.0.start_time").(string); startTimeStr != "" {
325356
startDate, err := time.Parse(time.RFC3339, startTimeStr)
326357
if err != nil {
@@ -332,7 +363,7 @@ func schemaToReport(d *schema.ResourceData) (gapi.Report, error) {
332363
}
333364

334365
// Set schedule end time
335-
if frequency != "once" && frequency != "never" {
366+
if frequency != reportFrequencyOnce && frequency != reportFrequencyNever {
336367
if endTimeStr := d.Get("schedule.0.end_time").(string); endTimeStr != "" {
337368
endDate, err := time.Parse(time.RFC3339, endTimeStr)
338369
if err != nil {
@@ -343,10 +374,16 @@ func schemaToReport(d *schema.ResourceData) (gapi.Report, error) {
343374
}
344375
}
345376

377+
if frequency == reportFrequencyMonthly {
378+
if lastDayOfMonth := d.Get("schedule.0.last_day_of_month").(bool); lastDayOfMonth {
379+
report.Schedule.DayOfMonth = "last"
380+
}
381+
}
382+
346383
if reportWorkdaysOnlyConfigAllowed(frequency) {
347384
report.Schedule.WorkdaysOnly = d.Get("schedule.0.workdays_only").(bool)
348385
}
349-
if frequency == "custom" {
386+
if frequency == reportFrequencyCustom {
350387
customInterval := d.Get("schedule.0.custom_interval").(string)
351388
amount, unit, err := parseCustomReportInterval(customInterval)
352389
if err != nil {
@@ -360,7 +397,7 @@ func schemaToReport(d *schema.ResourceData) (gapi.Report, error) {
360397
}
361398

362399
func reportWorkdaysOnlyConfigAllowed(frequency string) bool {
363-
return frequency == "hourly" || frequency == "daily" || frequency == "custom"
400+
return frequency == reportFrequencyHourly || frequency == reportFrequencyDaily || frequency == reportFrequencyCustom
364401
}
365402

366403
func parseCustomReportInterval(i interface{}) (int, string, error) {

grafana/resource_report_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,27 @@ func TestAccResourceReport(t *testing.T) {
6565
resource.TestCheckResourceAttr("grafana_report.test", "time_range.0.to", "now"),
6666
),
6767
},
68+
{
69+
Config: testAccExample(t, "resources/grafana_report/monthly.tf"),
70+
Check: resource.ComposeTestCheckFunc(
71+
testAccReportCheckExists("grafana_report.test", &report),
72+
resource.TestCheckResourceAttrSet("grafana_report.test", "id"),
73+
resource.TestCheckResourceAttrSet("grafana_report.test", "dashboard_id"),
74+
resource.TestCheckResourceAttr("grafana_report.test", "name", "my report"),
75+
resource.TestCheckResourceAttr("grafana_report.test", "recipients.0", "[email protected]"),
76+
resource.TestCheckNoResourceAttr("grafana_report.test", "recipients.1"),
77+
resource.TestCheckResourceAttr("grafana_report.test", "schedule.0.frequency", "monthly"),
78+
resource.TestCheckResourceAttrSet("grafana_report.test", "schedule.0.start_time"), // Date set to current time
79+
resource.TestCheckResourceAttr("grafana_report.test", "schedule.0.end_time", ""), // No end time
80+
resource.TestCheckResourceAttr("grafana_report.test", "schedule.0.last_day_of_month", "true"),
81+
resource.TestCheckResourceAttr("grafana_report.test", "orientation", "landscape"),
82+
resource.TestCheckResourceAttr("grafana_report.test", "layout", "grid"),
83+
resource.TestCheckResourceAttr("grafana_report.test", "include_dashboard_link", "true"),
84+
resource.TestCheckResourceAttr("grafana_report.test", "include_table_csv", "false"),
85+
resource.TestCheckNoResourceAttr("grafana_report.test", "time_range.0.from"),
86+
resource.TestCheckNoResourceAttr("grafana_report.test", "time_range.0.to"),
87+
),
88+
},
6889
},
6990
})
7091
}

grafana/schema.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package grafana
22

33
import (
4+
"fmt"
45
"strconv"
6+
"strings"
57

68
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
79
)
@@ -43,3 +45,7 @@ func cloneResourceSchemaForDatasource(r *schema.Resource, updates map[string]*sc
4345
}
4446
return clone
4547
}
48+
49+
func allowedValuesDescription(description string, allowedValues []string) string {
50+
return fmt.Sprintf("%s. Allowed values: `%s`.", description, strings.Join(allowedValues, "`, `"))
51+
}

0 commit comments

Comments
 (0)