provider/datadog: Add `query` parameter to `metric_alert`
`query` is used when it is specified by the user, if not `metric`/`tags`/`keys`/`time_aggr`/`window` is used instead.
This commit is contained in:
parent
f407eea3f7
commit
775a3f8826
|
@ -24,8 +24,9 @@ func resourceDatadogMetricAlert() *schema.Resource {
|
||||||
Required: true,
|
Required: true,
|
||||||
},
|
},
|
||||||
"metric": &schema.Schema{
|
"metric": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Optional: true,
|
||||||
|
ConflictsWith: []string{"query"},
|
||||||
},
|
},
|
||||||
"tags": &schema.Schema{
|
"tags": &schema.Schema{
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
|
@ -33,21 +34,25 @@ func resourceDatadogMetricAlert() *schema.Resource {
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
},
|
},
|
||||||
"keys": &schema.Schema{
|
"keys": &schema.Schema{
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
ConflictsWith: []string{"query"},
|
||||||
},
|
},
|
||||||
"time_aggr": &schema.Schema{
|
"time_aggr": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Optional: true,
|
||||||
|
ConflictsWith: []string{"query"},
|
||||||
},
|
},
|
||||||
"time_window": &schema.Schema{
|
"time_window": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Optional: true,
|
||||||
|
ConflictsWith: []string{"query"},
|
||||||
},
|
},
|
||||||
"space_aggr": &schema.Schema{
|
"space_aggr": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Optional: true,
|
||||||
|
ConflictsWith: []string{"query"},
|
||||||
},
|
},
|
||||||
"operator": &schema.Schema{
|
"operator": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
|
@ -58,6 +63,14 @@ func resourceDatadogMetricAlert() *schema.Resource {
|
||||||
Required: true,
|
Required: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Optional Query for custom monitors
|
||||||
|
|
||||||
|
"query": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ConflictsWith: []string{"time_aggr", "time_window", "space_aggr", "metric", "keys"},
|
||||||
|
},
|
||||||
|
|
||||||
"thresholds": thresholdSchema(),
|
"thresholds": thresholdSchema(),
|
||||||
|
|
||||||
// Additional Settings
|
// Additional Settings
|
||||||
|
@ -89,6 +102,7 @@ func buildMetricAlertStruct(d *schema.ResourceData) *datadog.Monitor {
|
||||||
timeWindow := d.Get("time_window").(string)
|
timeWindow := d.Get("time_window").(string)
|
||||||
spaceAggr := d.Get("space_aggr").(string)
|
spaceAggr := d.Get("space_aggr").(string)
|
||||||
metric := d.Get("metric").(string)
|
metric := d.Get("metric").(string)
|
||||||
|
query := d.Get("query").(string)
|
||||||
|
|
||||||
// Tags are are no separate resource/gettable, so some trickery is needed
|
// Tags are are no separate resource/gettable, so some trickery is needed
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
|
@ -127,16 +141,23 @@ func buildMetricAlertStruct(d *schema.ResourceData) *datadog.Monitor {
|
||||||
threshold, thresholds := getThresholds(d)
|
threshold, thresholds := getThresholds(d)
|
||||||
|
|
||||||
operator := d.Get("operator").(string)
|
operator := d.Get("operator").(string)
|
||||||
query := fmt.Sprintf("%s(%s):%s:%s{%s} %s %s %s", timeAggr,
|
|
||||||
timeWindow,
|
|
||||||
spaceAggr,
|
|
||||||
metric,
|
|
||||||
tagsParsed,
|
|
||||||
keys,
|
|
||||||
operator,
|
|
||||||
threshold)
|
|
||||||
|
|
||||||
log.Print(fmt.Sprintf("[DEBUG] submitting query: %s", query))
|
var q string
|
||||||
|
|
||||||
|
if query == "" {
|
||||||
|
q = fmt.Sprintf("%s(%s):%s:%s{%s} %s %s %s", timeAggr,
|
||||||
|
timeWindow,
|
||||||
|
spaceAggr,
|
||||||
|
metric,
|
||||||
|
tagsParsed,
|
||||||
|
keys,
|
||||||
|
operator,
|
||||||
|
threshold)
|
||||||
|
} else {
|
||||||
|
q = fmt.Sprintf("%s %s %s", query, operator, threshold)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Print(fmt.Sprintf("[DEBUG] submitting query: %s", q))
|
||||||
|
|
||||||
o := datadog.Options{
|
o := datadog.Options{
|
||||||
NotifyNoData: d.Get("notify_no_data").(bool),
|
NotifyNoData: d.Get("notify_no_data").(bool),
|
||||||
|
@ -147,7 +168,7 @@ func buildMetricAlertStruct(d *schema.ResourceData) *datadog.Monitor {
|
||||||
|
|
||||||
m := datadog.Monitor{
|
m := datadog.Monitor{
|
||||||
Type: "metric alert",
|
Type: "metric alert",
|
||||||
Query: query,
|
Query: q,
|
||||||
Name: name,
|
Name: name,
|
||||||
Message: message,
|
Message: message,
|
||||||
Options: o,
|
Options: o,
|
||||||
|
|
|
@ -61,6 +61,43 @@ func TestAccDatadogMetricAlert_Basic(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccDatadogMetricAlert_Query(t *testing.T) {
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckDatadogMetricAlertDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccCheckDatadogMetricAlertConfigQuery,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckDatadogMetricAlertExists("datadog_metric_alert.foo"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"datadog_metric_alert.foo", "name", "name for metric_alert foo"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"datadog_metric_alert.foo", "message", "{{#is_alert}}Metric alert foo is critical"+
|
||||||
|
"{{/is_alert}}\n{{#is_warning}}Metric alert foo is at warning "+
|
||||||
|
"level{{/is_warning}}\n{{#is_recovery}}Metric alert foo has "+
|
||||||
|
"recovered{{/is_recovery}}\nNotify: @hipchat-channel\n"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"datadog_metric_alert.foo", "query", "avg(last_1h):avg:aws.ec2.cpu{environment:foo,host:foo} by {host}"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"datadog_metric_alert.foo", "operator", ">"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"datadog_metric_alert.foo", "notify_no_data", "false"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"datadog_metric_alert.foo", "renotify_interval", "60"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"datadog_metric_alert.foo", "thresholds.ok", "0"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"datadog_metric_alert.foo", "thresholds.warning", "1"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"datadog_metric_alert.foo", "thresholds.critical", "2"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func testAccCheckDatadogMetricAlertDestroy(s *terraform.State) error {
|
func testAccCheckDatadogMetricAlertDestroy(s *terraform.State) error {
|
||||||
client := testAccProvider.Meta().(*datadog.Client)
|
client := testAccProvider.Meta().(*datadog.Client)
|
||||||
|
|
||||||
|
@ -109,3 +146,25 @@ EOF
|
||||||
renotify_interval = 60
|
renotify_interval = 60
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
const testAccCheckDatadogMetricAlertConfigQuery = `
|
||||||
|
resource "datadog_metric_alert" "foo" {
|
||||||
|
name = "name for metric_alert foo"
|
||||||
|
message = <<EOF
|
||||||
|
{{#is_alert}}Metric alert foo is critical{{/is_alert}}
|
||||||
|
{{#is_warning}}Metric alert foo is at warning level{{/is_warning}}
|
||||||
|
{{#is_recovery}}Metric alert foo has recovered{{/is_recovery}}
|
||||||
|
Notify: @hipchat-channel
|
||||||
|
EOF
|
||||||
|
operator = ">" // <, <=, >, >=, ==, or !=
|
||||||
|
query = "avg(last_1h):avg:aws.ec2.cpu{environment:foo,host:foo} by {host}"
|
||||||
|
|
||||||
|
thresholds {
|
||||||
|
ok = 0
|
||||||
|
warning = 1
|
||||||
|
critical = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
notify_no_data = false
|
||||||
|
renotify_interval = 60
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
Loading…
Reference in New Issue