From 8fdc6518c8736c498a56da0eb065fa8c58617bb1 Mon Sep 17 00:00:00 2001 From: Jake Champlin Date: Fri, 13 Jan 2017 18:08:41 -0500 Subject: [PATCH] provider/datadog: Add aggregator method to timeboard graph resource Adds aggregator argument to the timeboard graph resource. Ex: ``` request { q = "top(avg:docker.cpu.system{*} by {container_name}, 10, 'mean', 'desc')" aggregator = "sum" } ``` ``` $ make testacc TEST=./builtin/providers/datadog TESTARGS='-run=TestAccDatadogTimeboard_update' ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/01/13 17:52:50 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/datadog -v -run=TestAccDatadogTimeboard_update -timeout 120m === RUN TestAccDatadogTimeboard_update --- PASS: TestAccDatadogTimeboard_update (82.60s) PASS ok github.com/hashicorp/terraform/builtin/providers/datadog 82.619s ``` Fixes: #11168 --- .../datadog/resource_datadog_timeboard.go | 25 +++++++++++-- .../resource_datadog_timeboard_test.go | 36 +++++++++++++++++++ .../datadog/r/timeboard.html.markdown | 3 +- 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/builtin/providers/datadog/resource_datadog_timeboard.go b/builtin/providers/datadog/resource_datadog_timeboard.go index 8ba5c91bf..26942f637 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"`)) + } + 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.