Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate Silence attribute and Fix multiple terraform runs #221

Merged
merged 15 commits into from
Jun 11, 2019
63 changes: 56 additions & 7 deletions datadog/resource_datadog_monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"sort"
"strconv"
"strings"
"time"

"github.com/hashicorp/terraform/helper/schema"
"github.com/zorkian/go-datadog-api"
Expand Down Expand Up @@ -157,9 +158,10 @@ func resourceDatadogMonitor() *schema.Resource {
Optional: true,
},
"silenced": {
Type: schema.TypeMap,
Optional: true,
Elem: schema.TypeInt,
Type: schema.TypeMap,
Optional: true,
Elem: schema.TypeInt,
Deprecated: "use Downtime Resource instead",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

},
"include_tags": {
Type: schema.TypeBool,
Expand Down Expand Up @@ -323,6 +325,19 @@ func resourceDatadogMonitorExists(d *schema.ResourceData, meta interface{}) (b b
return true, nil
}

func getUnmutedScopes(d *schema.ResourceData) []string {
var unmuteScopes []string
if attr, ok := d.GetOk("silenced"); ok {
for k, v := range attr.(map[string]interface{}) {
if v.(int) == -1 {
unmuteScopes = append(unmuteScopes, k)
}
}
log.Printf("[DEBUG] Unmute Scopes are: %v", unmuteScopes)
}
return unmuteScopes
}

func resourceDatadogMonitorCreate(d *schema.ResourceData, meta interface{}) error {

client := meta.(*datadog.Client)
Expand Down Expand Up @@ -398,7 +413,6 @@ func resourceDatadogMonitorRead(d *schema.ResourceData, meta interface{}) error
d.Set("notify_audit", m.Options.GetNotifyAudit())
d.Set("timeout_h", m.Options.GetTimeoutH())
d.Set("escalation_message", m.Options.GetEscalationMessage())
d.Set("silenced", m.Options.Silenced)
d.Set("include_tags", m.Options.GetIncludeTags())
d.Set("tags", tags)
d.Set("require_full_window", m.Options.GetRequireFullWindow()) // TODO Is this one of those options that we neeed to check?
Expand All @@ -418,6 +432,32 @@ func resourceDatadogMonitorRead(d *schema.ResourceData, meta interface{}) error
d.Set("query_config", queryConfig)
}

// The Datadog API doesn't return old timestamps or support a special value for unmuting scopes
// So we provide this functionality by saving values to the state
apiSilenced := m.Options.Silenced
configSilenced := d.Get("silenced").(map[string]interface{})
unmutedScopes := getUnmutedScopes(d)

// If the scope is in the API response but not in the config
bkabrda marked this conversation as resolved.
Show resolved Hide resolved
// we need to unmute the scope since there was drift
for k := range apiSilenced {
if _, ok := configSilenced[k]; !ok {
unmutedScopes = append(unmutedScopes, k)
}
}
for _, scope := range unmutedScopes {
apiSilenced[scope] = -1
}

// Ignore any timestamps in the past that aren't -1 or 0
for k, v := range configSilenced {
if v.(int) < int(time.Now().Unix()) && v.(int) != 0 && v.(int) != -1 {
// sync the state with whats in the config so its ignored
apiSilenced[k] = v.(int)
}
}
d.Set("silenced", apiSilenced)

return nil
}

Expand Down Expand Up @@ -511,6 +551,7 @@ func resourceDatadogMonitorUpdate(d *schema.ResourceData, meta interface{}) erro
if attr, ok := d.GetOk("escalation_message"); ok {
o.SetEscalationMessage(attr.(string))
}

silenced := false
if attr, ok := d.GetOk("silenced"); ok {
// TODO: this is not very defensive, test if we can fail non int input
Expand Down Expand Up @@ -549,14 +590,22 @@ func resourceDatadogMonitorUpdate(d *schema.ResourceData, meta interface{}) erro
return retval
}

// if the silenced section was removed from the config, we unmute it via the API
// The API wouldn't automatically unmute the monitor if the config is just missing
if _, ok := d.GetOk("silenced"); ok && !silenced {
// This means the monitor must be manually unmuted since the API
// wouldn't do it automatically when `silenced` is just missing
retval = client.UnmuteMonitorScopes(*m.Id, &datadog.UnmuteMonitorScopes{AllScopes: datadog.Bool(true)})
d.Set("silenced", map[string]int{})
}

return retval
// Similarly, if the silenced attribute is -1, lets unmute those scopes
unmutedScopes := getUnmutedScopes(d)
if len(unmutedScopes) != 0 {
for _, scope := range unmutedScopes {
client.UnmuteMonitorScopes(*m.Id, &datadog.UnmuteMonitorScopes{Scope: &scope})
}
}

return resourceDatadogMonitorRead(d, meta)
}

func resourceDatadogMonitorDelete(d *schema.ResourceData, meta interface{}) error {
Expand Down
3 changes: 2 additions & 1 deletion website/docs/r/monitor.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ The following arguments are supported:
* `threshold_windows` (Optional) A mapping containing `recovery_window` and `trigger_window` values, e.g. `last_15m`. Can only be used for anomaly monitors.
* `recovery_window` describes how long an anomalous metric must be normal before the alert recovers.
* `trigger_window` describes how long a metric must be anomalous before an alert triggers.
* `silenced` (Optional) Each scope will be muted until the given POSIX timestamp or forever if the value is 0.
* `silenced` (Optional) Each scope will be muted until the given POSIX timestamp or forever if the value is 0. Use `-1` if you want to unmute the scope. **Deprecated** The `silenced` parameter is being deprecated in favor of the downtime resource. This will be removed in the next major version of the Terraform Provider.

To mute the alert completely:

silenced = {
Expand Down