diff --git a/builtin/providers/datadog/resource_datadog_timeboard.go b/builtin/providers/datadog/resource_datadog_timeboard.go index 8ba5c91bf..8097d067e 100644 --- a/builtin/providers/datadog/resource_datadog_timeboard.go +++ b/builtin/providers/datadog/resource_datadog_timeboard.go @@ -31,6 +31,11 @@ func resourceDatadogTimeboard() *schema.Resource { Optional: true, Default: "line", }, + "aggregator": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateAggregatorMethod, + }, "style": &schema.Schema{ Type: schema.TypeMap, Optional: true, @@ -307,8 +312,9 @@ func appendRequests(datadogGraph *datadog.Graph, terraformRequests *[]interface{ for _, t_ := range *terraformRequests { t := t_.(map[string]interface{}) d := datadog.GraphDefinitionRequest{ - Query: t["q"].(string), - Type: t["type"].(string), + Query: t["q"].(string), + Type: t["type"].(string), + Aggregator: t["aggregator"].(string), } if stacked, ok := t["stacked"]; ok { d.Stacked = stacked.(bool) @@ -703,3 +709,18 @@ func resourceDatadogTimeboardExists(d *schema.ResourceData, meta interface{}) (b } return true, nil } + +func validateAggregatorMethod(v interface{}, k string) (ws []string, errors []error) { + value := v.(string) + validMethods := map[string]struct{}{ + "average": {}, + "max": {}, + "min": {}, + "sum": {}, + } + if _, ok := validMethods[value]; !ok { + errors = append(errors, fmt.Errorf( + `%q contains an invalid method %q. Valid methods are either "average", "max", "min", or "sum"`, k, value)) + } + return +} diff --git a/builtin/providers/datadog/resource_datadog_timeboard_test.go b/builtin/providers/datadog/resource_datadog_timeboard_test.go index 385eabbc0..2d57fe36f 100644 --- a/builtin/providers/datadog/resource_datadog_timeboard_test.go +++ b/builtin/providers/datadog/resource_datadog_timeboard_test.go @@ -42,6 +42,7 @@ resource "datadog_timeboard" "acceptance_test" { viz = "timeseries" request { q = "avg:redis.mem.used{$host} - avg:redis.mem.lua{$host}, avg:redis.mem.lua{$host}" + aggregator = "sum" stacked = true } request { @@ -53,6 +54,7 @@ resource "datadog_timeboard" "acceptance_test" { style { palette = "warm" } + aggregator = "max" } } template_variable { @@ -90,6 +92,7 @@ resource "datadog_timeboard" "acceptance_test" { request { q = "sum:aws.elb.request_count{*}.as_count()" type = "line" + aggregator = "min" conditional_format { comparator = ">" value = "1000" @@ -139,11 +142,14 @@ func TestAccDatadogTimeboard_update(t *testing.T) { resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.title", "Redis memory usage"), resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.viz", "timeseries"), resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.request.0.q", "avg:redis.mem.used{$host} - avg:redis.mem.lua{$host}, avg:redis.mem.lua{$host}"), + resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.request.0.aggregator", "sum"), resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.request.0.stacked", "true"), resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.request.1.q", "avg:redis.mem.rss{$host}"), resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "template_variable.0.name", "host"), resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "template_variable.0.prefix", "host"), resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.request.2.type", "bars"), + resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.request.2.q", "avg:redis.mem.rss{$host}"), + resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.request.2.aggregator", "max"), resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.request.2.style.palette", "warm"), ), } @@ -166,6 +172,7 @@ func TestAccDatadogTimeboard_update(t *testing.T) { resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.title", "ELB Requests"), resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.viz", "query_value"), resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.request.0.q", "sum:aws.elb.request_count{*}.as_count()"), + resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.request.0.aggregator", "min"), resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.request.0.type", "line"), resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.request.0.conditional_format.0.comparator", ">"), resource.TestCheckResourceAttr("datadog_timeboard.acceptance_test", "graph.1.request.0.conditional_format.0.value", "1000"), @@ -214,3 +221,32 @@ func checkDestroy(s *terraform.State) error { } return nil } + +func TestValidateAggregatorMethod(t *testing.T) { + validMethods := []string{ + "average", + "max", + "min", + "sum", + } + for _, v := range validMethods { + _, errors := validateAggregatorMethod(v, "request") + if len(errors) != 0 { + t.Fatalf("%q should be a valid aggregator method: %q", v, errors) + } + } + + invalidMethods := []string{ + "avg", + "suM", + "m", + "foo", + } + for _, v := range invalidMethods { + _, errors := validateAggregatorMethod(v, "request") + if len(errors) == 0 { + t.Fatalf("%q should be an invalid aggregator method", v) + } + } + +} diff --git a/website/source/docs/providers/datadog/r/timeboard.html.markdown b/website/source/docs/providers/datadog/r/timeboard.html.markdown index de2c70930..9b29035f9 100644 --- a/website/source/docs/providers/datadog/r/timeboard.html.markdown +++ b/website/source/docs/providers/datadog/r/timeboard.html.markdown @@ -109,7 +109,8 @@ Nested `graph` `marker` blocks have the following structure: Nested `graph` `request` blocks have the following structure: * `q` - (Required) The query of the request. Pro tip: Use the JSON tab inside the Datadog UI to help build you query strings. -* `stacked` - (Optional) Boolean value to determin if this is this a stacked area graph. Default: false (line chart). +* `aggregator` - (Optional) The aggregation method used when the number of data points outnumbers the max that can be shown. +* `stacked` - (Optional) Boolean value to determine if this is this a stacked area graph. Default: false (line chart). * `type` - (Optional) Choose how to draw the graph. For example: "lines", "bars" or "areas". Default: "lines". * `style` - (Optional) Nested block to customize the graph style.