From 8034a9e097ae87ea7fa6b16fa519f6aef2966576 Mon Sep 17 00:00:00 2001 From: Chad Bean Date: Thu, 12 Sep 2019 17:23:55 -0400 Subject: [PATCH 01/13] Make alert resource compatible with new appoptics SDK --- appoptics/resource_librato_alert.go | 331 ++++++++++++++++------------ 1 file changed, 188 insertions(+), 143 deletions(-) diff --git a/appoptics/resource_librato_alert.go b/appoptics/resource_librato_alert.go index a4fad62..3caeba7 100644 --- a/appoptics/resource_librato_alert.go +++ b/appoptics/resource_librato_alert.go @@ -8,7 +8,7 @@ import ( "strconv" "time" - "github.com/akahn/go-librato/librato" + "github.com/appoptics/appoptics-api-go" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" @@ -54,15 +54,32 @@ func resourceAppOpticsAlert() *schema.Resource { Schema: map[string]*schema.Schema{ "type": { Type: schema.TypeString, - Required: true, + Optional: true, }, "metric_name": { Type: schema.TypeString, - Required: true, + Optional: true, }, - "source": { - Type: schema.TypeString, + "tag": { + Type: schema.TypeList, Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + }, + "grouped": { + Type: schema.TypeBool, + Optional: true, + }, + "values": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, }, "detect_reset": { Type: schema.TypeBool, @@ -85,17 +102,8 @@ func resourceAppOpticsAlert() *schema.Resource { Set: resourceAppOpticsAlertConditionsHash, }, "attributes": { - Type: schema.TypeList, + Type: schema.TypeMap, Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "runbook_url": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, }, }, } @@ -107,9 +115,9 @@ func resourceAppOpticsAlertConditionsHash(v interface{}) int { buf.WriteString(fmt.Sprintf("%s-", m["type"].(string))) buf.WriteString(fmt.Sprintf("%s-", m["metric_name"].(string))) - source, present := m["source"] - if present { - buf.WriteString(fmt.Sprintf("%s-", source.(string))) + tags, present := m["tag"].([]interface{}) + if present && len(tags) > 0 { + buf.WriteString(fmt.Sprintf("%d-", tagsHash(tags))) } detectReset, present := m["detect_reset"] @@ -135,57 +143,92 @@ func resourceAppOpticsAlertConditionsHash(v interface{}) int { return hashcode.String(buf.String()) } +func tagsHash(tags []interface{}) int { + var buf bytes.Buffer + for _, v := range tags { + m := v.(map[string]interface{}) + buf.WriteString(fmt.Sprintf("%s-", m["name"])) + buf.WriteString(fmt.Sprintf("%s-", m["grouped"])) + buf.WriteString(fmt.Sprintf("%d-", tagsValuesHash(m["values"].([]interface{})))) + } + + return hashcode.String(buf.String()) +} + +func tagsValuesHash(s []interface{}) int { + var buf bytes.Buffer + for _, v := range s { + buf.WriteString(fmt.Sprintf("%s-", v)) + } + + return hashcode.String(buf.String()) +} + func resourceAppOpticsAlertCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*librato.Client) + client := meta.(*appoptics.Client) - alert := librato.Alert{ - Name: librato.String(d.Get("name").(string)), + alert := appoptics.Alert{ + Name: d.Get("name").(string), } if v, ok := d.GetOk("description"); ok { - alert.Description = librato.String(v.(string)) + alert.Description = v.(string) } // GetOK returns not OK for false boolean values, use Get - alert.Active = librato.Bool(d.Get("active").(bool)) + alert.Active = d.Get("active").(bool) if v, ok := d.GetOk("rearm_seconds"); ok { - alert.RearmSeconds = librato.Uint(uint(v.(int))) + alert.RearmSeconds = v.(int) } if v, ok := d.GetOk("services"); ok { vs := v.(*schema.Set) - services := make([]*string, vs.Len()) + services := make([]*appoptics.Service, vs.Len()) for i, serviceData := range vs.List() { - services[i] = librato.String(serviceData.(string)) + services[i] = serviceData.(*appoptics.Service) } alert.Services = services } if v, ok := d.GetOk("condition"); ok { vs := v.(*schema.Set) - conditions := make([]librato.AlertCondition, vs.Len()) + conditions := make([]*appoptics.AlertCondition, vs.Len()) + for i, conditionDataM := range vs.List() { conditionData := conditionDataM.(map[string]interface{}) - var condition librato.AlertCondition + condition := appoptics.AlertCondition{} + if v, ok := conditionData["type"].(string); ok && v != "" { - condition.Type = librato.String(v) + condition.Type = v } if v, ok := conditionData["threshold"].(float64); ok && !math.IsNaN(v) { - condition.Threshold = librato.Float(v) + condition.Threshold = v } if v, ok := conditionData["metric_name"].(string); ok && v != "" { - condition.MetricName = librato.String(v) - } - if v, ok := conditionData["source"].(string); ok && v != "" { - condition.Source = librato.String(v) + condition.MetricName = v } - if v, ok := conditionData["detect_reset"].(bool); ok { - condition.DetectReset = librato.Bool(v) + if v, ok := conditionData["tag"].([]interface{}); ok { + tags := make([]*appoptics.Tag, len(v)) + for i, tagData := range v { + tag := appoptics.Tag{} + tag.Grouped = tagData.(map[string]interface{})["grouped"].(bool) + tag.Name = tagData.(map[string]interface{})["name"].(string) + values := tagData.(map[string]interface{})["values"].([]interface{}) + valuesInStrings := make([]string, len(values)) + for i, v := range values { + valuesInStrings[i] = v.(string) + } + tag.Values = valuesInStrings + tags[i] = &tag + } + + condition.Tags = tags } if v, ok := conditionData["duration"].(int); ok { - condition.Duration = librato.Uint(uint(v)) + condition.Duration = v } if v, ok := conditionData["summary_function"].(string); ok && v != "" { - condition.SummaryFunction = librato.String(v) + condition.SummaryFunction = v } - conditions[i] = condition + conditions[i] = &condition } + alert.Conditions = conditions } if v, ok := d.GetOk("attributes"); ok { @@ -196,26 +239,22 @@ func resourceAppOpticsAlertCreate(d *schema.ResourceData, meta interface{}) erro if attributeData[0] == nil { return fmt.Errorf("No attributes found in attributes block") } - attributeDataMap := attributeData[0].(map[string]interface{}) - attributes := new(librato.AlertAttributes) - if v, ok := attributeDataMap["runbook_url"].(string); ok && v != "" { - attributes.RunbookURL = librato.String(v) - } - alert.Attributes = attributes + // The only attribute here should be the runbook_url + alert.Attributes = attributeData[0].(map[string]interface{}) } } - alertResult, _, err := client.Alerts.Create(&alert) + alertResult, err := client.AlertsService().Create(&alert) if err != nil { - return fmt.Errorf("Error creating AppOptics alert %s: %s", *alert.Name, err) + return fmt.Errorf("Error creating AppOptics alert %s: %s", alert.Name, err) } log.Printf("[INFO] Created AppOptics alert: %s", *alertResult) retryErr := resource.Retry(1*time.Minute, func() *resource.RetryError { - _, _, err := client.Alerts.Get(*alertResult.ID) + _, err := client.AlertsService().Retrieve(alertResult.ID) if err != nil { - if errResp, ok := err.(*librato.ErrorResponse); ok && errResp.Response.StatusCode == 404 { + if errResp, ok := err.(*appoptics.ErrorResponse); ok && errResp.Response.StatusCode == 404 { return resource.RetryableError(err) } return resource.NonRetryableError(err) @@ -223,25 +262,25 @@ func resourceAppOpticsAlertCreate(d *schema.ResourceData, meta interface{}) erro return nil }) if retryErr != nil { - return fmt.Errorf("Error creating librato alert: %s", err) + return fmt.Errorf("Error creating AppOptics alert: %s", err) } - d.SetId(strconv.FormatUint(uint64(*alertResult.ID), 10)) + d.SetId(strconv.FormatUint(uint64(alertResult.ID), 10)) return resourceAppOpticsAlertRead(d, meta) } func resourceAppOpticsAlertRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*librato.Client) + client := meta.(*appoptics.Client) id, err := strconv.ParseUint(d.Id(), 10, 0) if err != nil { return err } log.Printf("[INFO] Reading AppOptics Alert: %d", id) - alert, _, err := client.Alerts.Get(uint(id)) + alert, err := client.AlertsService().Retrieve(int(id)) if err != nil { - if errResp, ok := err.(*librato.ErrorResponse); ok && errResp.Response.StatusCode == 404 { + if errResp, ok := err.(*appoptics.ErrorResponse); ok && errResp.Response.StatusCode == 404 { d.SetId("") return nil } @@ -251,173 +290,179 @@ func resourceAppOpticsAlertRead(d *schema.ResourceData, meta interface{}) error d.Set("name", alert.Name) - if alert.Description != nil { - if err := d.Set("description", alert.Description); err != nil { - return err - } + if err := d.Set("description", alert.Description); err != nil { + return err } - if alert.Active != nil { - if err := d.Set("active", alert.Active); err != nil { - return err - } + + if err := d.Set("active", alert.Active); err != nil { + return err } - if alert.RearmSeconds != nil { - if err := d.Set("rearm_seconds", alert.RearmSeconds); err != nil { - return err - } + + if err := d.Set("rearm_seconds", alert.RearmSeconds); err != nil { + return err } // Since the following aren't simple terraform types (TypeList), it's best to // catch the error returned from the d.Set() function, and handle accordingly. - services := resourceAppOpticsAlertServicesGather(d, alert.Services.([]interface{})) + services := flattenServices(d, alert.Services) + // TODO: does this need `schema.NewSet(...)`? if err := d.Set("services", schema.NewSet(schema.HashString, services)); err != nil { return err } - conditions := resourceAppOpticsAlertConditionsGather(d, alert.Conditions) - if err := d.Set("condition", schema.NewSet(resourceAppOpticsAlertConditionsHash, conditions)); err != nil { + conditions := flattenCondition(d, alert.Conditions) + if err := d.Set("condition", conditions); err != nil { return err } - attributes := resourceAppOpticsAlertAttributesGather(d, alert.Attributes) - if err := d.Set("attributes", attributes); err != nil { + if err := d.Set("attributes", alert.Attributes); err != nil { return err } return nil } -func resourceAppOpticsAlertServicesGather(d *schema.ResourceData, services []interface{}) []interface{} { +func flattenServices(d *schema.ResourceData, services []*appoptics.Service) []interface{} { retServices := make([]interface{}, 0, len(services)) - for _, s := range services { - serviceData := s.(map[string]interface{}) - // ID field is returned as float64, for whatever reason - retServices = append(retServices, fmt.Sprintf("%.f", serviceData["id"])) + for _, serviceData := range services { + retServices = append(retServices, fmt.Sprintf("%.f", serviceData.ID)) } return retServices } -func resourceAppOpticsAlertConditionsGather(d *schema.ResourceData, conditions []librato.AlertCondition) []interface{} { +func flattenCondition(d *schema.ResourceData, conditions []*appoptics.AlertCondition) []interface{} { retConditions := make([]interface{}, 0, len(conditions)) for _, c := range conditions { condition := make(map[string]interface{}) - if c.Type != nil { - condition["type"] = *c.Type - } - if c.Threshold != nil { - condition["threshold"] = *c.Threshold - } - if c.MetricName != nil { - condition["metric_name"] = *c.MetricName - } - if c.Source != nil { - condition["source"] = *c.Source - } - if c.DetectReset != nil { - condition["detect_reset"] = *c.MetricName - } - if c.Duration != nil { - condition["duration"] = int(*c.Duration) - } - if c.SummaryFunction != nil { - condition["summary_function"] = *c.SummaryFunction - } + condition["type"] = c.Type + condition["threshold"] = c.Threshold + condition["metric_name"] = c.MetricName + condition["tag"] = flattenConditionTags(c.Tags) + // TODO: once we upgrade the appoptics-api-go dependency, + // we need to add a `condition["detect_reset"] = c.DetectReset` below + // SEE: https://github.com/appoptics/terraform-provider-appoptics/issues/12 + // condition["detect_reset"] = c.DetectReset + condition["duration"] = int(c.Duration) + condition["summary_function"] = c.SummaryFunction retConditions = append(retConditions, condition) } return retConditions } -// Flattens an attributes hash into something that flatmap.Flatten() can handle -func resourceAppOpticsAlertAttributesGather(d *schema.ResourceData, attributes *librato.AlertAttributes) []map[string]interface{} { - result := make([]map[string]interface{}, 0, 1) - - if attributes != nil { - retAttributes := make(map[string]interface{}) - if attributes.RunbookURL != nil { - retAttributes["runbook_url"] = *attributes.RunbookURL +func flattenConditionTags(in []*appoptics.Tag) []interface{} { + var out = make([]interface{}, 0, len(in)) + for _, v := range in { + m := make(map[string]interface{}) + m["name"] = v.Name + m["grouped"] = v.Grouped + if len(v.Values) > 0 { + m["values"] = flattenConditionTagsValues(v.Values) } - result = append(result, retAttributes) + out = append(out, m) } - return result + return out +} + +func flattenConditionTagsValues(in []string) []interface{} { + vs := make([]interface{}, 0, len(in)) + for _, v := range in { + vs = append(vs, v) + } + return vs } func resourceAppOpticsAlertUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*librato.Client) + client := meta.(*appoptics.Client) - id, err := strconv.ParseUint(d.Id(), 10, 0) + id, err := strconv.ParseInt(d.Id(), 10, 0) if err != nil { return err } - alert := new(librato.Alert) - alert.Name = librato.String(d.Get("name").(string)) + alert := new(appoptics.Alert) + alert.ID = int(id) + alert.Name = d.Get("name").(string) if d.HasChange("description") { - alert.Description = librato.String(d.Get("description").(string)) + alert.Description = d.Get("description").(string) } if d.HasChange("active") { - alert.Active = librato.Bool(d.Get("active").(bool)) + alert.Active = d.Get("active").(bool) } if d.HasChange("rearm_seconds") { - alert.RearmSeconds = librato.Uint(uint(d.Get("rearm_seconds").(int))) + alert.RearmSeconds = d.Get("rearm_seconds").(int) } if d.HasChange("services") { vs := d.Get("services").(*schema.Set) - services := make([]*string, vs.Len()) + services := make([]*appoptics.Service, vs.Len()) for i, serviceData := range vs.List() { - services[i] = librato.String(serviceData.(string)) + services[i] = serviceData.(*appoptics.Service) } alert.Services = services } + // We always have to send the conditions hash, from the API docs: + // + // NOTE: This method requires the conditions hash. + // If conditions is not included in the payload, the alert conditions will be removed. vs := d.Get("condition").(*schema.Set) - conditions := make([]librato.AlertCondition, vs.Len()) + conditions := make([]*appoptics.AlertCondition, vs.Len()) + for i, conditionDataM := range vs.List() { conditionData := conditionDataM.(map[string]interface{}) - var condition librato.AlertCondition + condition := appoptics.AlertCondition{} + if v, ok := conditionData["type"].(string); ok && v != "" { - condition.Type = librato.String(v) + condition.Type = v } if v, ok := conditionData["threshold"].(float64); ok && !math.IsNaN(v) { - condition.Threshold = librato.Float(v) + condition.Threshold = v } if v, ok := conditionData["metric_name"].(string); ok && v != "" { - condition.MetricName = librato.String(v) + condition.MetricName = v } - if v, ok := conditionData["source"].(string); ok && v != "" { - condition.Source = librato.String(v) - } - if v, ok := conditionData["detect_reset"].(bool); ok { - condition.DetectReset = librato.Bool(v) + if v, ok := conditionData["tag"].([]interface{}); ok { + tags := make([]*appoptics.Tag, len(v)) + for i, tagData := range v { + tag := appoptics.Tag{} + tag.Grouped = tagData.(map[string]interface{})["grouped"].(bool) + tag.Name = tagData.(map[string]interface{})["name"].(string) + values := tagData.(map[string]interface{})["values"].([]interface{}) + valuesInStrings := make([]string, len(values)) + for i, v := range values { + valuesInStrings[i] = v.(string) + } + tag.Values = valuesInStrings + tags[i] = &tag + } + + condition.Tags = tags } if v, ok := conditionData["duration"].(int); ok { - condition.Duration = librato.Uint(uint(v)) + condition.Duration = v } if v, ok := conditionData["summary_function"].(string); ok && v != "" { - condition.SummaryFunction = librato.String(v) + condition.SummaryFunction = v } - conditions[i] = condition - alert.Conditions = conditions + conditions[i] = &condition } + alert.Conditions = conditions + if d.HasChange("attributes") { attributeData := d.Get("attributes").([]interface{}) if attributeData[0] == nil { return fmt.Errorf("No attributes found in attributes block") } - attributeDataMap := attributeData[0].(map[string]interface{}) - attributes := new(librato.AlertAttributes) - if v, ok := attributeDataMap["runbook_url"].(string); ok && v != "" { - attributes.RunbookURL = librato.String(v) - } - alert.Attributes = attributes + + alert.Attributes = attributeData[0].(map[string]interface{}) } log.Printf("[INFO] Updating AppOptics alert: %s", alert) - _, updErr := client.Alerts.Update(uint(id), alert) + updErr := client.AlertsService().Update(alert) if updErr != nil { return fmt.Errorf("Error updating AppOptics alert: %s", updErr) } @@ -433,7 +478,7 @@ func resourceAppOpticsAlertUpdate(d *schema.ResourceData, meta interface{}) erro ContinuousTargetOccurence: 5, Refresh: func() (interface{}, string, error) { log.Printf("[DEBUG] Checking if AppOptics Alert %d was updated yet", id) - changedAlert, _, getErr := client.Alerts.Get(uint(id)) + changedAlert, getErr := client.AlertsService().Retrieve(int(id)) if getErr != nil { return changedAlert, "", getErr } @@ -450,22 +495,22 @@ func resourceAppOpticsAlertUpdate(d *schema.ResourceData, meta interface{}) erro } func resourceAppOpticsAlertDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*librato.Client) + client := meta.(*appoptics.Client) id, err := strconv.ParseUint(d.Id(), 10, 0) if err != nil { return err } log.Printf("[INFO] Deleting Alert: %d", id) - _, err = client.Alerts.Delete(uint(id)) + err = client.AlertsService().Delete(int(id)) if err != nil { return fmt.Errorf("Error deleting Alert: %s", err) } retryErr := resource.Retry(1*time.Minute, func() *resource.RetryError { - _, _, err := client.Alerts.Get(uint(id)) + _, err := client.AlertsService().Retrieve(int(id)) if err != nil { - if errResp, ok := err.(*librato.ErrorResponse); ok && errResp.Response.StatusCode == 404 { + if errResp, ok := err.(*appoptics.ErrorResponse); ok && errResp.Response.StatusCode == 404 { return nil } return resource.NonRetryableError(err) From fbfaba9b783bbcf4bb8938cd808bb8119a25601d Mon Sep 17 00:00:00 2001 From: Chad Bean Date: Sat, 14 Sep 2019 15:20:30 -0400 Subject: [PATCH 02/13] Rename alert resource file from librato --- .../{resource_librato_alert.go => resource_appoptics_alert.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename appoptics/{resource_librato_alert.go => resource_appoptics_alert.go} (100%) diff --git a/appoptics/resource_librato_alert.go b/appoptics/resource_appoptics_alert.go similarity index 100% rename from appoptics/resource_librato_alert.go rename to appoptics/resource_appoptics_alert.go From ab5759220631c810037a583543aa90b3c49c33d2 Mon Sep 17 00:00:00 2001 From: Chad Bean Date: Mon, 16 Sep 2019 08:55:35 -0400 Subject: [PATCH 03/13] Fix tests --- appoptics/resource_librato_space_chart_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appoptics/resource_librato_space_chart_test.go b/appoptics/resource_librato_space_chart_test.go index 7e95632..25451ab 100644 --- a/appoptics/resource_librato_space_chart_test.go +++ b/appoptics/resource_librato_space_chart_test.go @@ -40,7 +40,7 @@ func TestAccAppOpticsSpaceChart_Full(t *testing.T) { CheckDestroy: testAccCheckAppOpticsSpaceChartDestroy, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccCheckAppOpticsSpaceChartConfig_full, + Config: testAccCheckAppOpticsSpaceChartConfigFull, Check: resource.ComposeTestCheckFunc( testAccCheckAppOpticsSpaceChartExists("appoptics_space_chart.foobar", &spaceChart), testAccCheckAppOpticsSpaceChartName(&spaceChart, "Foo Bar"), From 1d98b8a6cd51efce6cfcbae3aa00ed957f47eeaa Mon Sep 17 00:00:00 2001 From: Chad Bean Date: Mon, 16 Sep 2019 09:29:52 -0400 Subject: [PATCH 04/13] Fix type references --- appoptics/resource_appoptics_alert.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/appoptics/resource_appoptics_alert.go b/appoptics/resource_appoptics_alert.go index 3caeba7..a826869 100644 --- a/appoptics/resource_appoptics_alert.go +++ b/appoptics/resource_appoptics_alert.go @@ -249,7 +249,7 @@ func resourceAppOpticsAlertCreate(d *schema.ResourceData, meta interface{}) erro if err != nil { return fmt.Errorf("Error creating AppOptics alert %s: %s", alert.Name, err) } - log.Printf("[INFO] Created AppOptics alert: %s", *alertResult) + log.Printf("[INFO] Created AppOptics alert: %s", alertResult.Name) retryErr := resource.Retry(1*time.Minute, func() *resource.RetryError { _, err := client.AlertsService().Retrieve(alertResult.ID) @@ -286,7 +286,7 @@ func resourceAppOpticsAlertRead(d *schema.ResourceData, meta interface{}) error } return fmt.Errorf("Error reading AppOptics Alert %s: %s", d.Id(), err) } - log.Printf("[INFO] Received AppOptics Alert: %s", *alert) + log.Printf("[INFO] Received AppOptics Alert: %s", alert.Name) d.Set("name", alert.Name) @@ -326,7 +326,7 @@ func flattenServices(d *schema.ResourceData, services []*appoptics.Service) []in retServices := make([]interface{}, 0, len(services)) for _, serviceData := range services { - retServices = append(retServices, fmt.Sprintf("%.f", serviceData.ID)) + retServices = append(retServices, fmt.Sprintf("%.d", serviceData.ID)) } return retServices @@ -461,7 +461,7 @@ func resourceAppOpticsAlertUpdate(d *schema.ResourceData, meta interface{}) erro alert.Attributes = attributeData[0].(map[string]interface{}) } - log.Printf("[INFO] Updating AppOptics alert: %s", alert) + log.Printf("[INFO] Updating AppOptics alert: %s", alert.Name) updErr := client.AlertsService().Update(alert) if updErr != nil { return fmt.Errorf("Error updating AppOptics alert: %s", updErr) From 80c9e25c098c2ebd7a85aa77f13f7dd64f72fd53 Mon Sep 17 00:00:00 2001 From: Chad Bean Date: Mon, 16 Sep 2019 09:30:24 -0400 Subject: [PATCH 05/13] Update alert resource tests for new SDK --- appoptics/resource_librato_alert_test.go | 84 ++++++++++++------------ 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/appoptics/resource_librato_alert_test.go b/appoptics/resource_librato_alert_test.go index bfbf498..c2878c3 100644 --- a/appoptics/resource_librato_alert_test.go +++ b/appoptics/resource_librato_alert_test.go @@ -5,14 +5,14 @@ import ( "strconv" "testing" - "github.com/akahn/go-librato/librato" + "github.com/appoptics/appoptics-api-go" "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" ) -func TestAccAppOpticsAlert_Minimal(t *testing.T) { - var alert librato.Alert +func TestAccAppOpticsAlertMinimal(t *testing.T) { + var alert appoptics.Alert name := acctest.RandString(10) resource.Test(t, resource.TestCase{ @@ -21,7 +21,7 @@ func TestAccAppOpticsAlert_Minimal(t *testing.T) { CheckDestroy: testAccCheckAppOpticsAlertDestroy, Steps: []resource.TestStep{ { - Config: testAccCheckAppOpticsAlertConfig_minimal(name), + Config: testAccCheckAppOpticsAlertConfigMinimal(name), Check: resource.ComposeTestCheckFunc( testAccCheckAppOpticsAlertExists("appoptics_alert.foobar", &alert), testAccCheckAppOpticsAlertName(&alert, name), @@ -33,8 +33,8 @@ func TestAccAppOpticsAlert_Minimal(t *testing.T) { }) } -func TestAccAppOpticsAlert_Basic(t *testing.T) { - var alert librato.Alert +func TestAccAppOpticsAlertBasic(t *testing.T) { + var alert appoptics.Alert name := acctest.RandString(10) resource.Test(t, resource.TestCase{ @@ -43,7 +43,7 @@ func TestAccAppOpticsAlert_Basic(t *testing.T) { CheckDestroy: testAccCheckAppOpticsAlertDestroy, Steps: []resource.TestStep{ { - Config: testAccCheckAppOpticsAlertConfig_basic(name), + Config: testAccCheckAppOpticsAlertConfigBasic(name), Check: resource.ComposeTestCheckFunc( testAccCheckAppOpticsAlertExists("appoptics_alert.foobar", &alert), testAccCheckAppOpticsAlertName(&alert, name), @@ -56,8 +56,8 @@ func TestAccAppOpticsAlert_Basic(t *testing.T) { }) } -func TestAccAppOpticsAlert_Full(t *testing.T) { - var alert librato.Alert +func TestAccAppOpticsAlertFull(t *testing.T) { + var alert appoptics.Alert name := acctest.RandString(10) resource.Test(t, resource.TestCase{ @@ -66,7 +66,7 @@ func TestAccAppOpticsAlert_Full(t *testing.T) { CheckDestroy: testAccCheckAppOpticsAlertDestroy, Steps: []resource.TestStep{ { - Config: testAccCheckAppOpticsAlertConfig_full(name), + Config: testAccCheckAppOpticsAlertConfigFull(name), Check: resource.ComposeTestCheckFunc( testAccCheckAppOpticsAlertExists("appoptics_alert.foobar", &alert), testAccCheckAppOpticsAlertName(&alert, name), @@ -74,7 +74,7 @@ func TestAccAppOpticsAlert_Full(t *testing.T) { resource.TestCheckResourceAttr( "appoptics_alert.foobar", "name", name), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.836525194.metric_name", "librato.cpu.percent.idle"), + "appoptics_alert.foobar", "condition.836525194.metric_name", "appoptics.cpu.percent.idle"), resource.TestCheckResourceAttr( "appoptics_alert.foobar", "condition.836525194.type", "above"), resource.TestCheckResourceAttr( @@ -87,8 +87,8 @@ func TestAccAppOpticsAlert_Full(t *testing.T) { }) } -func TestAccAppOpticsAlert_Updated(t *testing.T) { - var alert librato.Alert +func TestAccAppOpticsAlertUpdated(t *testing.T) { + var alert appoptics.Alert name := acctest.RandString(10) resource.Test(t, resource.TestCase{ @@ -97,7 +97,7 @@ func TestAccAppOpticsAlert_Updated(t *testing.T) { CheckDestroy: testAccCheckAppOpticsAlertDestroy, Steps: []resource.TestStep{ { - Config: testAccCheckAppOpticsAlertConfig_basic(name), + Config: testAccCheckAppOpticsAlertConfigBasic(name), Check: resource.ComposeTestCheckFunc( testAccCheckAppOpticsAlertExists("appoptics_alert.foobar", &alert), testAccCheckAppOpticsAlertDescription(&alert, "A Test Alert"), @@ -106,7 +106,7 @@ func TestAccAppOpticsAlert_Updated(t *testing.T) { ), }, { - Config: testAccCheckAppOpticsAlertConfig_new_value(name), + Config: testAccCheckAppOpticsAlertConfigNewValue(name), Check: resource.ComposeTestCheckFunc( testAccCheckAppOpticsAlertExists("appoptics_alert.foobar", &alert), testAccCheckAppOpticsAlertDescription(&alert, "A modified Test Alert"), @@ -118,8 +118,8 @@ func TestAccAppOpticsAlert_Updated(t *testing.T) { }) } -func TestAccAppOpticsAlert_Rename(t *testing.T) { - var alert librato.Alert +func TestAccAppOpticsAlertRename(t *testing.T) { + var alert appoptics.Alert name := acctest.RandString(10) newName := acctest.RandString(10) @@ -129,7 +129,7 @@ func TestAccAppOpticsAlert_Rename(t *testing.T) { CheckDestroy: testAccCheckAppOpticsAlertDestroy, Steps: []resource.TestStep{ { - Config: testAccCheckAppOpticsAlertConfig_basic(name), + Config: testAccCheckAppOpticsAlertConfigBasic(name), Check: resource.ComposeTestCheckFunc( testAccCheckAppOpticsAlertExists("appoptics_alert.foobar", &alert), resource.TestCheckResourceAttr( @@ -137,7 +137,7 @@ func TestAccAppOpticsAlert_Rename(t *testing.T) { ), }, { - Config: testAccCheckAppOpticsAlertConfig_basic(newName), + Config: testAccCheckAppOpticsAlertConfigBasic(newName), Check: resource.ComposeTestCheckFunc( testAccCheckAppOpticsAlertExists("appoptics_alert.foobar", &alert), resource.TestCheckResourceAttr( @@ -148,8 +148,8 @@ func TestAccAppOpticsAlert_Rename(t *testing.T) { }) } -func TestAccAppOpticsAlert_FullUpdate(t *testing.T) { - var alert librato.Alert +func TestAccAppOpticsAlertFullUpdate(t *testing.T) { + var alert appoptics.Alert name := acctest.RandString(10) resource.Test(t, resource.TestCase{ @@ -158,7 +158,7 @@ func TestAccAppOpticsAlert_FullUpdate(t *testing.T) { CheckDestroy: testAccCheckAppOpticsAlertDestroy, Steps: []resource.TestStep{ { - Config: testAccCheckAppOpticsAlertConfig_full_update(name), + Config: testAccCheckAppOpticsAlertConfigFullUpdate(name), Check: resource.ComposeTestCheckFunc( testAccCheckAppOpticsAlertExists("appoptics_alert.foobar", &alert), testAccCheckAppOpticsAlertName(&alert, name), @@ -168,7 +168,7 @@ func TestAccAppOpticsAlert_FullUpdate(t *testing.T) { resource.TestCheckResourceAttr( "appoptics_alert.foobar", "rearm_seconds", "1200"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.2524844643.metric_name", "librato.cpu.percent.idle"), + "appoptics_alert.foobar", "condition.2524844643.metric_name", "appoptics.cpu.percent.idle"), resource.TestCheckResourceAttr( "appoptics_alert.foobar", "condition.2524844643.type", "above"), resource.TestCheckResourceAttr( @@ -182,7 +182,7 @@ func TestAccAppOpticsAlert_FullUpdate(t *testing.T) { } func testAccCheckAppOpticsAlertDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*librato.Client) + client := testAccProvider.Meta().(*appoptics.Client) for _, rs := range s.RootModule().Resources { if rs.Type != "appoptics_alert" { @@ -194,7 +194,7 @@ func testAccCheckAppOpticsAlertDestroy(s *terraform.State) error { return fmt.Errorf("ID not a number") } - _, _, err = client.Alerts.Get(uint(id)) + _, err = client.AlertsService().Retrieve(int(id)) if err == nil { return fmt.Errorf("Alert still exists") @@ -204,29 +204,29 @@ func testAccCheckAppOpticsAlertDestroy(s *terraform.State) error { return nil } -func testAccCheckAppOpticsAlertName(alert *librato.Alert, name string) resource.TestCheckFunc { +func testAccCheckAppOpticsAlertName(alert *appoptics.Alert, name string) resource.TestCheckFunc { return func(s *terraform.State) error { - if alert.Name == nil || *alert.Name != name { - return fmt.Errorf("Bad name: %s", *alert.Name) + if alert.Name != name { + return fmt.Errorf("Bad name: %s", alert.Name) } return nil } } -func testAccCheckAppOpticsAlertDescription(alert *librato.Alert, description string) resource.TestCheckFunc { +func testAccCheckAppOpticsAlertDescription(alert *appoptics.Alert, description string) resource.TestCheckFunc { return func(s *terraform.State) error { - if alert.Description == nil || *alert.Description != description { - return fmt.Errorf("Bad description: %s", *alert.Description) + if alert.Description != description { + return fmt.Errorf("Bad description: %s", alert.Description) } return nil } } -func testAccCheckAppOpticsAlertExists(n string, alert *librato.Alert) resource.TestCheckFunc { +func testAccCheckAppOpticsAlertExists(n string, alert *appoptics.Alert) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -238,20 +238,20 @@ func testAccCheckAppOpticsAlertExists(n string, alert *librato.Alert) resource.T return fmt.Errorf("No Alert ID is set") } - client := testAccProvider.Meta().(*librato.Client) + client := testAccProvider.Meta().(*appoptics.Client) id, err := strconv.ParseUint(rs.Primary.ID, 10, 0) if err != nil { return fmt.Errorf("ID not a number") } - foundAlert, _, err := client.Alerts.Get(uint(id)) + foundAlert, err := client.AlertsService().Retrieve(int(id)) if err != nil { return err } - if foundAlert.ID == nil || *foundAlert.ID != uint(id) { + if foundAlert.ID == 0 { return fmt.Errorf("Alert not found") } @@ -261,14 +261,14 @@ func testAccCheckAppOpticsAlertExists(n string, alert *librato.Alert) resource.T } } -func testAccCheckAppOpticsAlertConfig_minimal(name string) string { +func testAccCheckAppOpticsAlertConfigMinimal(name string) string { return fmt.Sprintf(` resource "appoptics_alert" "foobar" { name = "%s" }`, name) } -func testAccCheckAppOpticsAlertConfig_basic(name string) string { +func testAccCheckAppOpticsAlertConfigBasic(name string) string { return fmt.Sprintf(` resource "appoptics_alert" "foobar" { name = "%s" @@ -276,7 +276,7 @@ resource "appoptics_alert" "foobar" { }`, name) } -func testAccCheckAppOpticsAlertConfig_new_value(name string) string { +func testAccCheckAppOpticsAlertConfigNewValue(name string) string { return fmt.Sprintf(` resource "appoptics_alert" "foobar" { name = "%s" @@ -284,7 +284,7 @@ resource "appoptics_alert" "foobar" { }`, name) } -func testAccCheckAppOpticsAlertConfig_full(name string) string { +func testAccCheckAppOpticsAlertConfigFull(name string) string { return fmt.Sprintf(` resource "appoptics_service" "foobar" { title = "Foo Bar" @@ -304,7 +304,7 @@ resource "appoptics_alert" "foobar" { type = "above" threshold = 10 duration = 600 - metric_name = "librato.cpu.percent.idle" + metric_name = "appoptics.cpu.percent.idle" } attributes { runbook_url = "https://www.youtube.com/watch?v=oHg5SJYRHA0" @@ -314,7 +314,7 @@ resource "appoptics_alert" "foobar" { }`, name) } -func testAccCheckAppOpticsAlertConfig_full_update(name string) string { +func testAccCheckAppOpticsAlertConfigFullUpdate(name string) string { return fmt.Sprintf(` resource "appoptics_service" "foobar" { title = "Foo Bar" @@ -334,7 +334,7 @@ resource "appoptics_alert" "foobar" { type = "above" threshold = 10 duration = 60 - metric_name = "librato.cpu.percent.idle" + metric_name = "appoptics.cpu.percent.idle" } attributes { runbook_url = "https://www.youtube.com/watch?v=oHg5SJYRHA0" From 5bef42870fd73036426977286bf925ce83a33e88 Mon Sep 17 00:00:00 2001 From: Chad Bean Date: Mon, 16 Sep 2019 09:30:59 -0400 Subject: [PATCH 06/13] Move alert test to use appoptics naming --- ...rce_librato_alert_test.go => resource_appoptics_alert_test.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename appoptics/{resource_librato_alert_test.go => resource_appoptics_alert_test.go} (100%) diff --git a/appoptics/resource_librato_alert_test.go b/appoptics/resource_appoptics_alert_test.go similarity index 100% rename from appoptics/resource_librato_alert_test.go rename to appoptics/resource_appoptics_alert_test.go From 18708ee97147d46e3b6590572e158c92602299b2 Mon Sep 17 00:00:00 2001 From: Chad Bean Date: Mon, 16 Sep 2019 11:06:57 -0400 Subject: [PATCH 07/13] Change variable names --- appoptics/resource_appoptics_alert.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/appoptics/resource_appoptics_alert.go b/appoptics/resource_appoptics_alert.go index a826869..0098804 100644 --- a/appoptics/resource_appoptics_alert.go +++ b/appoptics/resource_appoptics_alert.go @@ -333,7 +333,7 @@ func flattenServices(d *schema.ResourceData, services []*appoptics.Service) []in } func flattenCondition(d *schema.ResourceData, conditions []*appoptics.AlertCondition) []interface{} { - retConditions := make([]interface{}, 0, len(conditions)) + out := make([]interface{}, 0, len(conditions)) for _, c := range conditions { condition := make(map[string]interface{}) condition["type"] = c.Type @@ -346,10 +346,10 @@ func flattenCondition(d *schema.ResourceData, conditions []*appoptics.AlertCondi // condition["detect_reset"] = c.DetectReset condition["duration"] = int(c.Duration) condition["summary_function"] = c.SummaryFunction - retConditions = append(retConditions, condition) + out = append(out, condition) } - return retConditions + return out } func flattenConditionTags(in []*appoptics.Tag) []interface{} { @@ -368,11 +368,11 @@ func flattenConditionTags(in []*appoptics.Tag) []interface{} { } func flattenConditionTagsValues(in []string) []interface{} { - vs := make([]interface{}, 0, len(in)) + out := make([]interface{}, 0, len(in)) for _, v := range in { - vs = append(vs, v) + out = append(out, v) } - return vs + return out } func resourceAppOpticsAlertUpdate(d *schema.ResourceData, meta interface{}) error { From 034c24b7927c47149a23b7ca35b7152a67810b30 Mon Sep 17 00:00:00 2001 From: Chad Bean Date: Wed, 18 Sep 2019 08:42:10 -0400 Subject: [PATCH 08/13] Add condition block when creating any test alerts (it's required) --- appoptics/resource_appoptics_alert_test.go | 74 +++++++++++++--------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/appoptics/resource_appoptics_alert_test.go b/appoptics/resource_appoptics_alert_test.go index c2878c3..ac2b206 100644 --- a/appoptics/resource_appoptics_alert_test.go +++ b/appoptics/resource_appoptics_alert_test.go @@ -25,8 +25,7 @@ func TestAccAppOpticsAlertMinimal(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAppOpticsAlertExists("appoptics_alert.foobar", &alert), testAccCheckAppOpticsAlertName(&alert, name), - resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "name", name), + resource.TestCheckResourceAttr("appoptics_alert.foobar", "name", name), ), }, }, @@ -264,7 +263,12 @@ func testAccCheckAppOpticsAlertExists(n string, alert *appoptics.Alert) resource func testAccCheckAppOpticsAlertConfigMinimal(name string) string { return fmt.Sprintf(` resource "appoptics_alert" "foobar" { - name = "%s" + name = "%s" + condition { + type = "above" + threshold = 10 + metric_name = "system.cpu.utilization" + } }`, name) } @@ -272,15 +276,25 @@ func testAccCheckAppOpticsAlertConfigBasic(name string) string { return fmt.Sprintf(` resource "appoptics_alert" "foobar" { name = "%s" - description = "A Test Alert" + description = "A Test Alert" + condition { + type = "above" + threshold = 10 + metric_name = "system.cpu.utilization" + } }`, name) } func testAccCheckAppOpticsAlertConfigNewValue(name string) string { return fmt.Sprintf(` resource "appoptics_alert" "foobar" { - name = "%s" - description = "A modified Test Alert" + name = "%s" + description = "A modified Test Alert" + condition { + type = "above" + threshold = 10 + metric_name = "system.cpu.utilization" + } }`, name) } @@ -297,20 +311,19 @@ EOF } resource "appoptics_alert" "foobar" { - name = "%s" - description = "A Test Alert" - services = [ "${appoptics_service.foobar.id}" ] - condition { - type = "above" - threshold = 10 - duration = 600 - metric_name = "appoptics.cpu.percent.idle" - } - attributes { - runbook_url = "https://www.youtube.com/watch?v=oHg5SJYRHA0" - } - active = false - rearm_seconds = 300 + name = "%s" + description = "A Test Alert" + services = [ "${appoptics_service.foobar.id}" ] + condition { + type = "above" + threshold = 10 + metric_name = "system.cpu.utilization" + } + attributes { + runbook_url = "https://www.youtube.com/watch?v=oHg5SJYRHA0" + } + active = false + rearm_seconds = 300 }`, name) } @@ -330,16 +343,15 @@ resource "appoptics_alert" "foobar" { name = "%s" description = "A Test Alert" services = [ "${appoptics_service.foobar.id}" ] - condition { - type = "above" - threshold = 10 - duration = 60 - metric_name = "appoptics.cpu.percent.idle" - } - attributes { - runbook_url = "https://www.youtube.com/watch?v=oHg5SJYRHA0" - } - active = false - rearm_seconds = 1200 + condition { + type = "above" + threshold = 10 + metric_name = "system.cpu.utilization" + } + attributes { + runbook_url = "https://www.youtube.com/watch?v=oHg5SJYRHA0" + } + active = false + rearm_seconds = 1200 }`, name) } From 8b5dab3d225a2425b71e6e0d420b4cbe6ff4c93e Mon Sep 17 00:00:00 2001 From: Chad Bean Date: Fri, 20 Sep 2019 07:55:14 -0400 Subject: [PATCH 09/13] Fix services data structure to be valid --- appoptics/resource_appoptics_alert.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/appoptics/resource_appoptics_alert.go b/appoptics/resource_appoptics_alert.go index 0098804..b0b06a8 100644 --- a/appoptics/resource_appoptics_alert.go +++ b/appoptics/resource_appoptics_alert.go @@ -181,8 +181,10 @@ func resourceAppOpticsAlertCreate(d *schema.ResourceData, meta interface{}) erro if v, ok := d.GetOk("services"); ok { vs := v.(*schema.Set) services := make([]*appoptics.Service, vs.Len()) - for i, serviceData := range vs.List() { - services[i] = serviceData.(*appoptics.Service) + for i, serviceID := range vs.List() { + service := new(appoptics.Service) + service.ID = serviceID.(int) + services[i] = service } alert.Services = services } @@ -399,8 +401,10 @@ func resourceAppOpticsAlertUpdate(d *schema.ResourceData, meta interface{}) erro if d.HasChange("services") { vs := d.Get("services").(*schema.Set) services := make([]*appoptics.Service, vs.Len()) - for i, serviceData := range vs.List() { - services[i] = serviceData.(*appoptics.Service) + for i, serviceID := range vs.List() { + service := new(appoptics.Service) + service.ID = serviceID.(int) + services[i] = service } alert.Services = services } From e943f61d594a7105e0eae0bee49e2ef096fdef46 Mon Sep 17 00:00:00 2001 From: Chad Bean Date: Fri, 20 Sep 2019 08:01:01 -0400 Subject: [PATCH 10/13] Use proper type for returned ID --- appoptics/resource_appoptics_alert.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/appoptics/resource_appoptics_alert.go b/appoptics/resource_appoptics_alert.go index b0b06a8..1ab274e 100644 --- a/appoptics/resource_appoptics_alert.go +++ b/appoptics/resource_appoptics_alert.go @@ -403,7 +403,10 @@ func resourceAppOpticsAlertUpdate(d *schema.ResourceData, meta interface{}) erro services := make([]*appoptics.Service, vs.Len()) for i, serviceID := range vs.List() { service := new(appoptics.Service) - service.ID = serviceID.(int) + service.ID, err = strconv.Atoi(serviceID.(string)) + if err != nil { + return err + } services[i] = service } alert.Services = services From a8dd137664ef84a77e08a837e185e754f82112f6 Mon Sep 17 00:00:00 2001 From: Chad Bean Date: Fri, 20 Sep 2019 08:02:23 -0400 Subject: [PATCH 11/13] Apply previous fix in other function --- appoptics/resource_appoptics_alert.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/appoptics/resource_appoptics_alert.go b/appoptics/resource_appoptics_alert.go index 1ab274e..036767a 100644 --- a/appoptics/resource_appoptics_alert.go +++ b/appoptics/resource_appoptics_alert.go @@ -183,7 +183,10 @@ func resourceAppOpticsAlertCreate(d *schema.ResourceData, meta interface{}) erro services := make([]*appoptics.Service, vs.Len()) for i, serviceID := range vs.List() { service := new(appoptics.Service) - service.ID = serviceID.(int) + service.ID, err = strconv.Atoi(serviceID.(string)) + if err != nil { + return err + } services[i] = service } alert.Services = services From 1b6fb2de27082db1a60d291af92127cde93dbdb6 Mon Sep 17 00:00:00 2001 From: Chad Bean Date: Fri, 20 Sep 2019 09:19:45 -0400 Subject: [PATCH 12/13] Fix types and flesh out tests --- appoptics/resource_appoptics_alert.go | 11 ++++---- appoptics/resource_appoptics_alert_test.go | 32 ++++++++++++++++++---- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/appoptics/resource_appoptics_alert.go b/appoptics/resource_appoptics_alert.go index 036767a..b3aa3ad 100644 --- a/appoptics/resource_appoptics_alert.go +++ b/appoptics/resource_appoptics_alert.go @@ -183,6 +183,7 @@ func resourceAppOpticsAlertCreate(d *schema.ResourceData, meta interface{}) erro services := make([]*appoptics.Service, vs.Len()) for i, serviceID := range vs.List() { service := new(appoptics.Service) + var err error service.ID, err = strconv.Atoi(serviceID.(string)) if err != nil { return err @@ -237,15 +238,12 @@ func resourceAppOpticsAlertCreate(d *schema.ResourceData, meta interface{}) erro alert.Conditions = conditions } if v, ok := d.GetOk("attributes"); ok { - attributeData := v.([]interface{}) + attributeData := v.(map[string]interface{}) if len(attributeData) > 1 { return fmt.Errorf("Only one set of attributes per alert is supported") } else if len(attributeData) == 1 { - if attributeData[0] == nil { - return fmt.Errorf("No attributes found in attributes block") - } // The only attribute here should be the runbook_url - alert.Attributes = attributeData[0].(map[string]interface{}) + alert.Attributes = attributeData } } @@ -267,7 +265,7 @@ func resourceAppOpticsAlertCreate(d *schema.ResourceData, meta interface{}) erro return nil }) if retryErr != nil { - return fmt.Errorf("Error creating AppOptics alert: %s", err) + return fmt.Errorf("Error creating AppOptics alert %s: %s", alert.Name, err) } d.SetId(strconv.FormatUint(uint64(alertResult.ID), 10)) @@ -406,6 +404,7 @@ func resourceAppOpticsAlertUpdate(d *schema.ResourceData, meta interface{}) erro services := make([]*appoptics.Service, vs.Len()) for i, serviceID := range vs.List() { service := new(appoptics.Service) + var err error service.ID, err = strconv.Atoi(serviceID.(string)) if err != nil { return err diff --git a/appoptics/resource_appoptics_alert_test.go b/appoptics/resource_appoptics_alert_test.go index ac2b206..03acd50 100644 --- a/appoptics/resource_appoptics_alert_test.go +++ b/appoptics/resource_appoptics_alert_test.go @@ -73,13 +73,35 @@ func TestAccAppOpticsAlertFull(t *testing.T) { resource.TestCheckResourceAttr( "appoptics_alert.foobar", "name", name), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.836525194.metric_name", "appoptics.cpu.percent.idle"), + "appoptics_alert.foobar", "active", "true"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.836525194.type", "above"), + "appoptics_alert.foobar", "condition.#", "1"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.836525194.threshold", "10"), + "appoptics_alert.foobar", "condition.3796868183.detect_reset", ""), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.836525194.duration", "600"), + "appoptics_alert.foobar", "condition.3796868183.duration", "600"), + resource.TestCheckResourceAttr( + "appoptics_alert.foobar", "condition.3796868183.metric_name", "system.cpu.utilization"), + resource.TestCheckResourceAttr( + "appoptics_alert.foobar", "condition.3796868183.summary_function", ""), + resource.TestCheckResourceAttr( + "appoptics_alert.foobar", "condition.3796868183.tag.#", "1"), + resource.TestCheckResourceAttr( + "appoptics_alert.foobar", "condition.3796868183.tag.0.grouped", "true"), + resource.TestCheckResourceAttr( + "appoptics_alert.foobar", "condition.3796868183.tag.0.name", "hostname"), + resource.TestCheckResourceAttr( + "appoptics_alert.foobar", "condition.3796868183.tag.0.values.#", "2"), + resource.TestCheckResourceAttr( + "appoptics_alert.foobar", "condition.3796868183.tag.0.values.0", "host1"), + resource.TestCheckResourceAttr( + "appoptics_alert.foobar", "condition.3796868183.tag.0.values.1", "host2"), + resource.TestCheckResourceAttr( + "appoptics_alert.foobar", "condition.3796868183.threshold", "10"), + resource.TestCheckResourceAttr( + "appoptics_alert.foobar", "condition.3796868183.type", "above"), + resource.TestCheckResourceAttr( + "appoptics_alert.foobar", "rearm_seconds", "600"), ), }, }, @@ -167,7 +189,7 @@ func TestAccAppOpticsAlertFullUpdate(t *testing.T) { resource.TestCheckResourceAttr( "appoptics_alert.foobar", "rearm_seconds", "1200"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.2524844643.metric_name", "appoptics.cpu.percent.idle"), + "appoptics_alert.foobar", "condition.2524844643.metric_name", "system.cpu.utilization"), resource.TestCheckResourceAttr( "appoptics_alert.foobar", "condition.2524844643.type", "above"), resource.TestCheckResourceAttr( From 56500648d98096226cec66ed0f65d760096bfa28 Mon Sep 17 00:00:00 2001 From: Chad Bean Date: Tue, 24 Sep 2019 08:26:47 -0400 Subject: [PATCH 13/13] Update tests to include tag block on alert resource creaetion --- appoptics/resource_appoptics_alert_test.go | 50 ++++++++++------------ 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/appoptics/resource_appoptics_alert_test.go b/appoptics/resource_appoptics_alert_test.go index 03acd50..07e29bd 100644 --- a/appoptics/resource_appoptics_alert_test.go +++ b/appoptics/resource_appoptics_alert_test.go @@ -73,35 +73,27 @@ func TestAccAppOpticsAlertFull(t *testing.T) { resource.TestCheckResourceAttr( "appoptics_alert.foobar", "name", name), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "active", "true"), + "appoptics_alert.foobar", "attributes.runbook_url", "https://www.youtube.com/watch?v=oHg5SJYRHA0"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.#", "1"), + "appoptics_alert.foobar", "condition.411654007.metric_name", "system.cpu.utilization"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.3796868183.detect_reset", ""), + "appoptics_alert.foobar", "condition.411654007.summary_function", ""), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.3796868183.duration", "600"), + "appoptics_alert.foobar", "condition.411654007.threshold", "10"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.3796868183.metric_name", "system.cpu.utilization"), + "appoptics_alert.foobar", "condition.411654007.type", "above"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.3796868183.summary_function", ""), + "appoptics_alert.foobar", "condition.411654007.tag.0.grouped", "true"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.3796868183.tag.#", "1"), + "appoptics_alert.foobar", "condition.411654007.tag.0.name", "hostname"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.3796868183.tag.0.grouped", "true"), + "appoptics_alert.foobar", "condition.411654007.tag.0.values.#", "2"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.3796868183.tag.0.name", "hostname"), + "appoptics_alert.foobar", "condition.411654007.tag.0.values.0", "host1"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.3796868183.tag.0.values.#", "2"), + "appoptics_alert.foobar", "condition.411654007.tag.0.values.1", "host2"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.3796868183.tag.0.values.0", "host1"), - resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.3796868183.tag.0.values.1", "host2"), - resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.3796868183.threshold", "10"), - resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.3796868183.type", "above"), - resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "rearm_seconds", "600"), + "appoptics_alert.foobar", "rearm_seconds", "300"), ), }, }, @@ -189,13 +181,11 @@ func TestAccAppOpticsAlertFullUpdate(t *testing.T) { resource.TestCheckResourceAttr( "appoptics_alert.foobar", "rearm_seconds", "1200"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.2524844643.metric_name", "system.cpu.utilization"), - resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.2524844643.type", "above"), + "appoptics_alert.foobar", "condition.498665064.metric_name", "system.cpu.utilization"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.2524844643.threshold", "10"), + "appoptics_alert.foobar", "condition.498665064.type", "above"), resource.TestCheckResourceAttr( - "appoptics_alert.foobar", "condition.2524844643.duration", "60"), + "appoptics_alert.foobar", "condition.498665064.threshold", "10"), ), }, }, @@ -340,11 +330,16 @@ resource "appoptics_alert" "foobar" { type = "above" threshold = 10 metric_name = "system.cpu.utilization" + + tag { + name = "hostname" + grouped = true + values = ["host1", "host2"] + } } attributes { runbook_url = "https://www.youtube.com/watch?v=oHg5SJYRHA0" } - active = false rearm_seconds = 300 }`, name) } @@ -363,8 +358,8 @@ EOF resource "appoptics_alert" "foobar" { name = "%s" - description = "A Test Alert" - services = [ "${appoptics_service.foobar.id}" ] + description = "A Test Alert" + services = [ "${appoptics_service.foobar.id}" ] condition { type = "above" threshold = 10 @@ -373,7 +368,6 @@ resource "appoptics_alert" "foobar" { attributes { runbook_url = "https://www.youtube.com/watch?v=oHg5SJYRHA0" } - active = false rearm_seconds = 1200 }`, name) }