-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
provider/datadog: Add datadog_downtime resource (#10994)
* provider/datadog: Initial datadog_downtime resource * provider/datadog: Update datadog_downtime resource to v2 library, fix recurrence handling * provider/datadog: Fix datadog_downtime import test
- Loading branch information
Showing
6 changed files
with
963 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package datadog | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/resource" | ||
) | ||
|
||
func TestDatadogDowntime_import(t *testing.T) { | ||
resourceName := "datadog_downtime.foo" | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckDatadogDowntimeDestroy, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testAccCheckDatadogDowntimeConfigImported, | ||
}, | ||
resource.TestStep{ | ||
ResourceName: resourceName, | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
const testAccCheckDatadogDowntimeConfigImported = ` | ||
resource "datadog_downtime" "foo" { | ||
scope = ["host:X", "host:Y"] | ||
start = 1735707600 | ||
end = 1735765200 | ||
message = "Example Datadog downtime message." | ||
} | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,339 @@ | ||
package datadog | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/hashicorp/terraform/helper/schema" | ||
"gopkg.in/zorkian/go-datadog-api.v2" | ||
) | ||
|
||
func resourceDatadogDowntime() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceDatadogDowntimeCreate, | ||
Read: resourceDatadogDowntimeRead, | ||
Update: resourceDatadogDowntimeUpdate, | ||
Delete: resourceDatadogDowntimeDelete, | ||
Exists: resourceDatadogDowntimeExists, | ||
Importer: &schema.ResourceImporter{ | ||
State: resourceDatadogDowntimeImport, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"active": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
}, | ||
"disabled": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
}, | ||
"end": { | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
}, | ||
"message": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
StateFunc: func(val interface{}) string { | ||
return strings.TrimSpace(val.(string)) | ||
}, | ||
}, | ||
"recurrence": { | ||
Type: schema.TypeList, | ||
Optional: true, | ||
MaxItems: 1, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"period": { | ||
Type: schema.TypeInt, | ||
Required: true, | ||
}, | ||
"type": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ValidateFunc: validateDatadogDowntimeRecurrenceType, | ||
}, | ||
"until_date": { | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
ConflictsWith: []string{"recurrence.until_occurrences"}, | ||
}, | ||
"until_occurrences": { | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
ConflictsWith: []string{"recurrence.until_date"}, | ||
}, | ||
"week_days": { | ||
Type: schema.TypeList, | ||
Optional: true, | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
ValidateFunc: validateDatadogDowntimeRecurrenceWeekDays, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
"scope": { | ||
Type: schema.TypeList, | ||
Required: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
}, | ||
"start": { | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func buildDowntimeStruct(d *schema.ResourceData) *datadog.Downtime { | ||
var dt datadog.Downtime | ||
|
||
if attr, ok := d.GetOk("active"); ok { | ||
dt.SetActive(attr.(bool)) | ||
} | ||
if attr, ok := d.GetOk("disabled"); ok { | ||
dt.SetDisabled(attr.(bool)) | ||
} | ||
if attr, ok := d.GetOk("end"); ok { | ||
dt.SetEnd(attr.(int)) | ||
} | ||
if attr, ok := d.GetOk("message"); ok { | ||
dt.SetMessage(strings.TrimSpace(attr.(string))) | ||
} | ||
if _, ok := d.GetOk("recurrence"); ok { | ||
var recurrence datadog.Recurrence | ||
|
||
if attr, ok := d.GetOk("recurrence.0.period"); ok { | ||
recurrence.SetPeriod(attr.(int)) | ||
} | ||
if attr, ok := d.GetOk("recurrence.0.type"); ok { | ||
recurrence.SetType(attr.(string)) | ||
} | ||
if attr, ok := d.GetOk("recurrence.0.until_date"); ok { | ||
recurrence.SetUntilDate(attr.(int)) | ||
} | ||
if attr, ok := d.GetOk("recurrence.0.until_occurrences"); ok { | ||
recurrence.SetUntilOccurrences(attr.(int)) | ||
} | ||
if attr, ok := d.GetOk("recurrence.0.week_days"); ok { | ||
weekDays := make([]string, 0, len(attr.([]interface{}))) | ||
for _, weekDay := range attr.([]interface{}) { | ||
weekDays = append(weekDays, weekDay.(string)) | ||
} | ||
recurrence.WeekDays = weekDays | ||
} | ||
|
||
dt.SetRecurrence(recurrence) | ||
} | ||
scope := []string{} | ||
for _, s := range d.Get("scope").([]interface{}) { | ||
scope = append(scope, s.(string)) | ||
} | ||
dt.Scope = scope | ||
if attr, ok := d.GetOk("start"); ok { | ||
dt.SetStart(attr.(int)) | ||
} | ||
|
||
return &dt | ||
} | ||
|
||
func resourceDatadogDowntimeExists(d *schema.ResourceData, meta interface{}) (b bool, e error) { | ||
// Exists - This is called to verify a resource still exists. It is called prior to Read, | ||
// and lowers the burden of Read to be able to assume the resource exists. | ||
client := meta.(*datadog.Client) | ||
|
||
id, err := strconv.Atoi(d.Id()) | ||
if err != nil { | ||
return false, err | ||
} | ||
|
||
if _, err = client.GetDowntime(id); err != nil { | ||
if strings.Contains(err.Error(), "404 Not Found") { | ||
return false, nil | ||
} | ||
return false, err | ||
} | ||
|
||
return true, nil | ||
} | ||
|
||
func resourceDatadogDowntimeCreate(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*datadog.Client) | ||
|
||
dts := buildDowntimeStruct(d) | ||
dt, err := client.CreateDowntime(dts) | ||
if err != nil { | ||
return fmt.Errorf("error updating downtime: %s", err.Error()) | ||
} | ||
|
||
d.SetId(strconv.Itoa(dt.GetId())) | ||
|
||
return nil | ||
} | ||
|
||
func resourceDatadogDowntimeRead(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*datadog.Client) | ||
|
||
id, err := strconv.Atoi(d.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
dt, err := client.GetDowntime(id) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
log.Printf("[DEBUG] downtime: %v", dt) | ||
d.Set("active", dt.GetActive()) | ||
d.Set("disabled", dt.GetDisabled()) | ||
d.Set("end", dt.GetEnd()) | ||
d.Set("message", dt.GetMessage()) | ||
if r, ok := dt.GetRecurrenceOk(); ok { | ||
recurrence := make(map[string]interface{}) | ||
recurrenceList := make([]map[string]interface{}, 0, 1) | ||
|
||
if attr, ok := r.GetPeriodOk(); ok { | ||
recurrence["period"] = strconv.Itoa(attr) | ||
} | ||
if attr, ok := r.GetTypeOk(); ok { | ||
recurrence["type"] = attr | ||
} | ||
if attr, ok := r.GetUntilDateOk(); ok { | ||
recurrence["until_date"] = strconv.Itoa(attr) | ||
} | ||
if attr, ok := r.GetUntilOccurrencesOk(); ok { | ||
recurrence["until_occurrences"] = strconv.Itoa(attr) | ||
} | ||
if r.WeekDays != nil { | ||
weekDays := make([]string, 0, len(r.WeekDays)) | ||
for _, weekDay := range r.WeekDays { | ||
weekDays = append(weekDays, weekDay) | ||
} | ||
recurrence["week_days"] = weekDays | ||
} | ||
recurrenceList = append(recurrenceList, recurrence) | ||
d.Set("recurrence", recurrenceList) | ||
} | ||
d.Set("scope", dt.Scope) | ||
d.Set("start", dt.GetStart()) | ||
|
||
return nil | ||
} | ||
|
||
func resourceDatadogDowntimeUpdate(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*datadog.Client) | ||
|
||
var dt datadog.Downtime | ||
|
||
id, err := strconv.Atoi(d.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
dt.SetId(id) | ||
if attr, ok := d.GetOk("active"); ok { | ||
dt.SetActive(attr.(bool)) | ||
} | ||
if attr, ok := d.GetOk("disabled"); ok { | ||
dt.SetDisabled(attr.(bool)) | ||
} | ||
if attr, ok := d.GetOk("end"); ok { | ||
dt.SetEnd(attr.(int)) | ||
} | ||
if attr, ok := d.GetOk("message"); ok { | ||
dt.SetMessage(attr.(string)) | ||
} | ||
|
||
if _, ok := d.GetOk("recurrence"); ok { | ||
var recurrence datadog.Recurrence | ||
|
||
if attr, ok := d.GetOk("recurrence.0.period"); ok { | ||
recurrence.SetPeriod(attr.(int)) | ||
} | ||
if attr, ok := d.GetOk("recurrence.0.type"); ok { | ||
recurrence.SetType(attr.(string)) | ||
} | ||
if attr, ok := d.GetOk("recurrence.0.until_date"); ok { | ||
recurrence.SetUntilDate(attr.(int)) | ||
} | ||
if attr, ok := d.GetOk("recurrence.0.until_occurrences"); ok { | ||
recurrence.SetUntilOccurrences(attr.(int)) | ||
} | ||
if attr, ok := d.GetOk("recurrence.0.week_days"); ok { | ||
weekDays := make([]string, 0, len(attr.([]interface{}))) | ||
for _, weekDay := range attr.([]interface{}) { | ||
weekDays = append(weekDays, weekDay.(string)) | ||
} | ||
recurrence.WeekDays = weekDays | ||
} | ||
|
||
dt.SetRecurrence(recurrence) | ||
} | ||
|
||
scope := make([]string, 0) | ||
for _, v := range d.Get("scope").([]interface{}) { | ||
scope = append(scope, v.(string)) | ||
} | ||
dt.Scope = scope | ||
if attr, ok := d.GetOk("start"); ok { | ||
dt.SetStart(attr.(int)) | ||
} | ||
|
||
if err = client.UpdateDowntime(&dt); err != nil { | ||
return fmt.Errorf("error updating downtime: %s", err.Error()) | ||
} | ||
|
||
return resourceDatadogDowntimeRead(d, meta) | ||
} | ||
|
||
func resourceDatadogDowntimeDelete(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*datadog.Client) | ||
|
||
id, err := strconv.Atoi(d.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if err = client.DeleteDowntime(id); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceDatadogDowntimeImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { | ||
if err := resourceDatadogDowntimeRead(d, meta); err != nil { | ||
return nil, err | ||
} | ||
return []*schema.ResourceData{d}, nil | ||
} | ||
|
||
func validateDatadogDowntimeRecurrenceType(v interface{}, k string) (ws []string, errors []error) { | ||
value := v.(string) | ||
switch value { | ||
case "days", "months", "weeks", "years": | ||
break | ||
default: | ||
errors = append(errors, fmt.Errorf( | ||
"%q contains an invalid recurrence type parameter %q. Valid parameters are days, months, weeks, or years", k, value)) | ||
} | ||
return | ||
} | ||
|
||
func validateDatadogDowntimeRecurrenceWeekDays(v interface{}, k string) (ws []string, errors []error) { | ||
value := v.(string) | ||
switch value { | ||
case "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun": | ||
break | ||
default: | ||
errors = append(errors, fmt.Errorf( | ||
"%q contains an invalid recurrence week day parameter %q. Valid parameters are Mon, Tue, Wed, Thu, Fri, Sat, or Sun", k, value)) | ||
} | ||
return | ||
} |
Oops, something went wrong.