From 1de7e78baeb1b979d412c18b5657a8f8a16d9e51 Mon Sep 17 00:00:00 2001 From: Eric Choi Date: Thu, 1 Aug 2024 17:14:00 -0700 Subject: [PATCH 01/10] FFM-274: Add support for Archived metrics --- go.mod | 2 + go.sum | 6 - signalfx/resource_signalfx_metric_ruleset.go | 125 +++++++++++++++++- .../resource_signalfx_metric_ruleset_test.go | 124 +++++++++++++++-- 4 files changed, 236 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index e1d88247..a6dc140a 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/splunk-terraform/terraform-provider-signalfx go 1.20 +replace github.com/signalfx/signalfx-go v1.39.0 => /Users/echoi/go/src/github.com/signalfx/signalfx-go + require ( github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d github.com/davecgh/go-spew v1.1.1 diff --git a/go.sum b/go.sum index 644fab86..010a91bb 100644 --- a/go.sum +++ b/go.sum @@ -125,12 +125,6 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0= github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/signalfx/signalfx-go v1.37.0 h1:AtCvcW9VGoVUnCVcoHLbRD5QUsMpy1SnViJN+jKGBU8= -github.com/signalfx/signalfx-go v1.37.0/go.mod h1:aVrA69k02raBhDtIL1l+KBu+H5eEmS5b0IFbqgKh7eg= -github.com/signalfx/signalfx-go v1.38.0 h1:uWnQHjYdDWK6CtnnQaYgDo9KuHhqVzj2y/NEASBbuQ8= -github.com/signalfx/signalfx-go v1.38.0/go.mod h1:aVrA69k02raBhDtIL1l+KBu+H5eEmS5b0IFbqgKh7eg= -github.com/signalfx/signalfx-go v1.39.0 h1:kjE3F3SOn928FKzu6z6HQlLL1p4yx2m2Rmm8MgDLLqk= -github.com/signalfx/signalfx-go v1.39.0/go.mod h1:aVrA69k02raBhDtIL1l+KBu+H5eEmS5b0IFbqgKh7eg= github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= diff --git a/signalfx/resource_signalfx_metric_ruleset.go b/signalfx/resource_signalfx_metric_ruleset.go index a3ebf0cd..6ef48c30 100644 --- a/signalfx/resource_signalfx_metric_ruleset.go +++ b/signalfx/resource_signalfx_metric_ruleset.go @@ -4,12 +4,13 @@ import ( "context" "encoding/json" "fmt" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - "github.com/signalfx/signalfx-go/metric_ruleset" "log" "strconv" "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/signalfx/signalfx-go/metric_ruleset" ) func metricRulesetResource() *schema.Resource { @@ -115,6 +116,65 @@ func metricRulesetResource() *schema.Resource { }, }, }, + "exception_rules": { + Type: schema.TypeList, + Optional: true, + Description: "Exception rules in the ruleset", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Name of this exception rule", + }, + "enabled": { + Type: schema.TypeBool, + Required: true, + Description: "Status of this exception rule", + }, + "matcher": { + Type: schema.TypeSet, + Required: true, + Description: "The matcher for this rule", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + Description: "The type of the matcher", + ValidateFunc: validation.StringInSlice([]string{"dimension"}, false), + }, + "filters": { + Type: schema.TypeList, + Optional: true, + Description: "List of filters to match on", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "not": { + Type: schema.TypeBool, + Required: true, + Description: "Flag specifying equals or not equals", + }, + "property": { + Type: schema.TypeString, + Required: true, + Description: "Name of dimension to match", + }, + "property_value": { + Type: schema.TypeSet, + Required: true, + Description: "List of dimension values to match", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, "routing_rule": { Type: schema.TypeSet, Required: true, @@ -125,7 +185,7 @@ func metricRulesetResource() *schema.Resource { Type: schema.TypeString, Required: true, Description: "Destination to send the input metric", - ValidateFunc: validation.StringInSlice([]string{"RealTime", "Drop"}, false), + ValidateFunc: validation.StringInSlice([]string{"RealTime", "Archived", "Drop"}, false), }, }, }, @@ -176,6 +236,7 @@ func metricRulesetCreate(d *schema.ResourceData, meta interface{}) error { } payload := metric_ruleset.CreateMetricRulesetRequest{ AggregationRules: payloadReq.AggregationRules, + ExceptionRules: payloadReq.ExceptionRules, MetricName: *payloadReq.MetricName, RoutingRule: *payloadReq.RoutingRule, } @@ -193,6 +254,7 @@ func metricRulesetCreate(d *schema.ResourceData, meta interface{}) error { Version: metricRulesetResp.Version, MetricName: metricRulesetResp.MetricName, AggregationRules: metricRulesetResp.AggregationRules, + ExceptionRules: metricRulesetResp.ExceptionRules, RoutingRule: metricRulesetResp.RoutingRule, Creator: metricRulesetResp.Creator, Created: metricRulesetResp.Created, @@ -215,6 +277,7 @@ func metricRulesetRead(d *schema.ResourceData, meta interface{}) error { Version: metricRulesetResp.Version, MetricName: metricRulesetResp.MetricName, AggregationRules: metricRulesetResp.AggregationRules, + ExceptionRules: metricRulesetResp.ExceptionRules, RoutingRule: metricRulesetResp.RoutingRule, Creator: metricRulesetResp.Creator, Created: metricRulesetResp.Created, @@ -237,6 +300,7 @@ func metricRulesetUpdate(d *schema.ResourceData, meta interface{}) error { payloadReq, err := getPayloadMetricRuleset(d) payload := metric_ruleset.UpdateMetricRulesetRequest{ AggregationRules: payloadReq.AggregationRules, + ExceptionRules: payloadReq.ExceptionRules, MetricName: payloadReq.MetricName, RoutingRule: payloadReq.RoutingRule, Version: currentMetricRuleset.Version, @@ -255,6 +319,7 @@ func metricRulesetUpdate(d *schema.ResourceData, meta interface{}) error { metricRuleset := metric_ruleset.MetricRuleset{ AggregationRules: metricRulesetResp.AggregationRules, + ExceptionRules: metricRulesetResp.ExceptionRules, Creator: metricRulesetResp.Creator, CreatorName: metricRulesetResp.CreatorName, Created: metricRulesetResp.Created, @@ -360,6 +425,37 @@ func metricRulesetAPIToTF(d *schema.ResourceData, metricRuleset *metric_ruleset. } } + if metricRuleset.ExceptionRules != nil { + rules := make([]map[string]interface{}, len(metricRuleset.ExceptionRules)) + for i, rule := range metricRuleset.ExceptionRules { + excRule := map[string]interface{}{ + "name": rule.Name, + "enabled": rule.Enabled, + } + + filters := make([]map[string]interface{}, len(rule.Matcher.DimensionMatcher.Filters)) + for j, filter := range rule.Matcher.DimensionMatcher.Filters { + entry := map[string]interface{}{ + "property": filter.Property, + "property_value": filter.PropertyValue, + "not": *filter.NOT, + } + filters[j] = entry + } + + matcher := map[string]interface{}{ + "type": rule.Matcher.DimensionMatcher.Type, + "filters": filters, + } + excRule["matcher"] = []map[string]interface{}{matcher} + + rules[i] = excRule + } + if err := d.Set("exception_rules", rules); err != nil { + return err + } + } + dest := map[string]interface{}{"destination": metricRuleset.RoutingRule.Destination} routingRule := []interface{}{dest} if err := d.Set("routing_rule", routingRule); err != nil { @@ -374,6 +470,7 @@ func getPayloadMetricRuleset(d *schema.ResourceData) (*metric_ruleset.MetricRule cudr := &metric_ruleset.MetricRuleset{ MetricName: &metricName, AggregationRules: []metric_ruleset.AggregationRule{}, + ExceptionRules: []metric_ruleset.ExceptionRule{}, RoutingRule: &metric_ruleset.RoutingRule{}, } @@ -381,6 +478,10 @@ func getPayloadMetricRuleset(d *schema.ResourceData) (*metric_ruleset.MetricRule cudr.AggregationRules = getAggregationRules(val) } + if val, ok := d.Get("exception_rules").([]interface{}); ok { + cudr.ExceptionRules = getExceptionRules(val) + } + if val, ok := d.GetOk("routing_rule"); ok && len(val.(*schema.Set).List()) > 0 { routingRule := val.(*schema.Set).List()[0].(map[string]interface{}) rr := getRoutingRule(routingRule) @@ -407,6 +508,22 @@ func getAggregationRules(tfRules []interface{}) []metric_ruleset.AggregationRule return aggregationRulesList } +func getExceptionRules(tfRules []interface{}) []metric_ruleset.ExceptionRule { + var exceptionRulesList []metric_ruleset.ExceptionRule + for _, tfRule := range tfRules { + newTfRule := tfRule.(map[string]interface{}) + ruleName := newTfRule["name"].(string) + rule := metric_ruleset.ExceptionRule{ + Name: &ruleName, + Enabled: newTfRule["enabled"].(bool), + Matcher: getMatcher(newTfRule), + } + exceptionRulesList = append(exceptionRulesList, rule) + } + + return exceptionRulesList +} + func getMatcher(tfRule map[string]interface{}) metric_ruleset.MetricMatcher { matcher := tfRule["matcher"].(*schema.Set).List()[0].(map[string]interface{}) filters := make([]interface{}, 0) diff --git a/signalfx/resource_signalfx_metric_ruleset_test.go b/signalfx/resource_signalfx_metric_ruleset_test.go index ec1a68b8..4bbebb47 100644 --- a/signalfx/resource_signalfx_metric_ruleset_test.go +++ b/signalfx/resource_signalfx_metric_ruleset_test.go @@ -83,6 +83,69 @@ resource "signalfx_metric_ruleset" "demo_trans_latency_metric_ruleset" { ` ) +const ( + demoTransCountRuleset = ` +resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { + metric_name = "demo.trans.count" + + exception_rules { + name = "rule1" + enabled = true + matcher { + type = "dimension" + filters { + property = "demo_datacenter" + property_value = [ "Paris", "Tokyo" ] + not = false + } + } + } + + routing_rule { + destination = "Archived" + } +} +` +) + +const ( + demoTransCountRulesetUpdated = ` +resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { + metric_name = "demo.trans.count" + + exception_rules { + name = "rule1" + enabled = true + matcher { + type = "dimension" + filters { + property = "demo_datacenter" + property_value = [ "Tokyo" ] + not = false + } + } + } + + exception_rules { + name = "rule2" + enabled = true + matcher { + type = "dimension" + filters { + property = "demo_host" + property_value = [ "server1", "server2" ] + not = false + } + } + } + + routing_rule { + destination = "Drop" + } +} +` +) + func TestAccCreateUpdateMetricRuleset(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -160,6 +223,44 @@ func TestAccCreateUpdateMetricRuleset(t *testing.T) { }) } +func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccMetricRulesetDestroy, + Steps: []resource.TestStep{ + // Validate plan + { + Config: demoTransCountRuleset, + PlanOnly: true, + ExpectNonEmptyPlan: true, + }, + // Create it + { + Config: demoTransCountRuleset, + Check: resource.ComposeTestCheckFunc( + testAccMetricRulesetExists, + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "metric_name", "demo.trans.count"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "version", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.name", "rule1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.enabled", "true"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.type", "dimension"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property", "demo_datacenter"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.#", "2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.0", "Paris"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.1", "Tokyo"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.not", "false"), + + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "routing_rule.0.destination", "Archived"), + ), + }, + }, + }) +} + func testAccMetricRulesetExists(s *terraform.State) error { client := newTestClient() for _, rs := range s.RootModule().Resources { @@ -177,17 +278,18 @@ func testAccMetricRulesetExists(s *terraform.State) error { } func testAccMetricRulesetDestroy(s *terraform.State) error { - client := newTestClient() - for _, rs := range s.RootModule().Resources { - switch rs.Type { - case "signalfx_metric_ruleset": - metricRuleset, _ := client.GetMetricRuleset(context.TODO(), rs.Primary.ID) - if metricRuleset != nil { - return fmt.Errorf("Found deleted metric ruleset %s", rs.Primary.ID) + /* + client := newTestClient() + for _, rs := range s.RootModule().Resources { + switch rs.Type { + case "signalfx_metric_ruleset": + metricRuleset, _ := client.GetMetricRuleset(context.TODO(), rs.Primary.ID) + if metricRuleset != nil { + return fmt.Errorf("Found deleted metric ruleset %s", rs.Primary.ID) + } + default: + return fmt.Errorf("Unexpected resource of type: %s", rs.Type) } - default: - return fmt.Errorf("Unexpected resource of type: %s", rs.Type) - } - } + }*/ return nil } From b0492157ca9e6bdaa10f76a85e731c4690619aaf Mon Sep 17 00:00:00 2001 From: Eric Choi Date: Thu, 1 Aug 2024 19:54:05 -0700 Subject: [PATCH 02/10] refactoring --- signalfx/resource_signalfx_metric_ruleset.go | 26 ++++++-- .../resource_signalfx_metric_ruleset_test.go | 59 +++++++++++++++---- 2 files changed, 66 insertions(+), 19 deletions(-) diff --git a/signalfx/resource_signalfx_metric_ruleset.go b/signalfx/resource_signalfx_metric_ruleset.go index 6ef48c30..abe35fe1 100644 --- a/signalfx/resource_signalfx_metric_ruleset.go +++ b/signalfx/resource_signalfx_metric_ruleset.go @@ -433,8 +433,8 @@ func metricRulesetAPIToTF(d *schema.ResourceData, metricRuleset *metric_ruleset. "enabled": rule.Enabled, } - filters := make([]map[string]interface{}, len(rule.Matcher.DimensionMatcher.Filters)) - for j, filter := range rule.Matcher.DimensionMatcher.Filters { + filters := make([]map[string]interface{}, len(rule.Matcher.Filters)) + for j, filter := range rule.Matcher.Filters { entry := map[string]interface{}{ "property": filter.Property, "property_value": filter.PropertyValue, @@ -444,7 +444,7 @@ func metricRulesetAPIToTF(d *schema.ResourceData, metricRuleset *metric_ruleset. } matcher := map[string]interface{}{ - "type": rule.Matcher.DimensionMatcher.Type, + "type": rule.Matcher.Type, "filters": filters, } excRule["matcher"] = []map[string]interface{}{matcher} @@ -512,11 +512,10 @@ func getExceptionRules(tfRules []interface{}) []metric_ruleset.ExceptionRule { var exceptionRulesList []metric_ruleset.ExceptionRule for _, tfRule := range tfRules { newTfRule := tfRule.(map[string]interface{}) - ruleName := newTfRule["name"].(string) rule := metric_ruleset.ExceptionRule{ - Name: &ruleName, + Name: newTfRule["name"].(string), Enabled: newTfRule["enabled"].(bool), - Matcher: getMatcher(newTfRule), + Matcher: getDimensionMatcher(newTfRule), } exceptionRulesList = append(exceptionRulesList, rule) } @@ -541,6 +540,21 @@ func getMatcher(tfRule map[string]interface{}) metric_ruleset.MetricMatcher { return metricMatcher } +func getDimensionMatcher(tfRule map[string]interface{}) metric_ruleset.DimensionMatcher { + matcher := tfRule["matcher"].(*schema.Set).List()[0].(map[string]interface{}) + filters := make([]interface{}, 0) + if matcher["filters"] != nil { + filters = matcher["filters"].([]interface{}) + } + + dimensionMatcher := metric_ruleset.DimensionMatcher{ + Type: matcher["type"].(string), + Filters: getFilters(filters), + } + + return dimensionMatcher +} + func getFilters(filters []interface{}) []metric_ruleset.PropertyFilter { var filterList []metric_ruleset.PropertyFilter for _, filter := range filters { diff --git a/signalfx/resource_signalfx_metric_ruleset_test.go b/signalfx/resource_signalfx_metric_ruleset_test.go index 4bbebb47..52bf0210 100644 --- a/signalfx/resource_signalfx_metric_ruleset_test.go +++ b/signalfx/resource_signalfx_metric_ruleset_test.go @@ -3,9 +3,10 @@ package signalfx import ( "context" "fmt" + "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - "testing" ) const ( @@ -254,6 +255,39 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.1", "Tokyo"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.not", "false"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "routing_rule.0.destination", "Archived"), + ), + }, + // Update it + { + Config: demoTransLatencyRulesetUpdated, + Check: resource.ComposeTestCheckFunc( + testAccMetricRulesetExists, + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "metric_name", "demo.trans.count"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "version", "2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.#", "2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.name", "rule1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.enabled", "true"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.type", "dimension"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property", "demo_datacenter"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.#", "2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.0", "Paris"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.1", "Tokyo"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.not", "false"), + + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.name", "rule2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.enabled", "true"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.type", "dimension"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property", "demo_host"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.#", "2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.0", "server1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.1", "server3"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.not", "false"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "routing_rule.0.destination", "Archived"), ), }, @@ -278,18 +312,17 @@ func testAccMetricRulesetExists(s *terraform.State) error { } func testAccMetricRulesetDestroy(s *terraform.State) error { - /* - client := newTestClient() - for _, rs := range s.RootModule().Resources { - switch rs.Type { - case "signalfx_metric_ruleset": - metricRuleset, _ := client.GetMetricRuleset(context.TODO(), rs.Primary.ID) - if metricRuleset != nil { - return fmt.Errorf("Found deleted metric ruleset %s", rs.Primary.ID) - } - default: - return fmt.Errorf("Unexpected resource of type: %s", rs.Type) + client := newTestClient() + for _, rs := range s.RootModule().Resources { + switch rs.Type { + case "signalfx_metric_ruleset": + metricRuleset, _ := client.GetMetricRuleset(context.TODO(), rs.Primary.ID) + if metricRuleset != nil { + return fmt.Errorf("Found deleted metric ruleset %s", rs.Primary.ID) } - }*/ + default: + return fmt.Errorf("Unexpected resource of type: %s", rs.Type) + } + } return nil } From 709cd389d44341f47cd7623bb8bf6ed975368264 Mon Sep 17 00:00:00 2001 From: Eric Choi Date: Fri, 2 Aug 2024 09:12:32 -0700 Subject: [PATCH 03/10] update web page docs --- .../resource_signalfx_metric_ruleset_test.go | 21 ++++++++++------ website/docs/r/metric_ruleset.html.markdown | 25 +++++++++++++++++-- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/signalfx/resource_signalfx_metric_ruleset_test.go b/signalfx/resource_signalfx_metric_ruleset_test.go index 52bf0210..1b99fb97 100644 --- a/signalfx/resource_signalfx_metric_ruleset_test.go +++ b/signalfx/resource_signalfx_metric_ruleset_test.go @@ -134,14 +134,14 @@ resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { type = "dimension" filters { property = "demo_host" - property_value = [ "server1", "server2" ] + property_value = [ "server1", "server3" ] not = false } } } routing_rule { - destination = "Drop" + destination = "Archived" } } ` @@ -217,7 +217,7 @@ func TestAccCreateUpdateMetricRuleset(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.1.aggregator.0.drop_dimensions", "false"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.1.aggregator.0.dimensions.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.1.aggregator.0.dimensions.0", "demo_host"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "routing_rule.0.destination", "Drop"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "routing_rule.0.destination", "Archived"), ), }, }, @@ -258,9 +258,15 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "routing_rule.0.destination", "Archived"), ), }, + // Validate plan + { + Config: demoTransCountRulesetUpdated, + PlanOnly: true, + ExpectNonEmptyPlan: true, + }, // Update it { - Config: demoTransLatencyRulesetUpdated, + Config: demoTransCountRulesetUpdated, Check: resource.ComposeTestCheckFunc( testAccMetricRulesetExists, resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "metric_name", "demo.trans.count"), @@ -272,9 +278,8 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.type", "dimension"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property", "demo_datacenter"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.#", "2"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.0", "Paris"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.1", "Tokyo"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.0", "Tokyo"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.not", "false"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.name", "rule2"), @@ -288,7 +293,7 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.1", "server3"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.not", "false"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "routing_rule.0.destination", "Archived"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "routing_rule.0.destination", "Drop"), ), }, }, diff --git a/website/docs/r/metric_ruleset.html.markdown b/website/docs/r/metric_ruleset.html.markdown index 6485b314..9bc371ee 100644 --- a/website/docs/r/metric_ruleset.html.markdown +++ b/website/docs/r/metric_ruleset.html.markdown @@ -37,8 +37,20 @@ resource "signalfx_metric_ruleset" "cpu_utilization_metric_ruleset" { } } + exception_rules { + name = "Route us-east-2 to real-time" + enabled = true + matcher { + type = "dimension" + filters { + property = "realm" + property_value = [ "us-east-2" ] + not = false + } + } + } routing_rule { - destination = "RealTime" + destination = "Archived" } } ``` @@ -62,5 +74,14 @@ The following arguments are supported in the resource block: * `dimensions` - (Required) List of dimensions to either be kept or dropped in the new aggregated MTSs * `drop_dimensions` - (Required) when true, the specified dimensions will be dropped from the aggregated MTSs * `output_name` - (Required) name of the new aggregated metric +* `exception_rules` - (Optional) List of exception rules for the metric + * `enabled` - (Required) When false, this rule will not route matched data to real-time + * `name` - (Required) name of the exception rule + * `matcher` - (Required) Matcher object + * `type` - (Required) Type of matcher. Must always be "dimension" + * `filters` - (Required) List of filters to filter the set of input MTSs + * `property` - (Required) - Name of the dimension + * `property_value` - (Required) - Value of the dimension + * `not` - When true, this filter will match all values not matching the property_values * `routing_rule` - (Required) Routing Rule object - * `destination` - (Required) - end destination of the input metric. Must be `RealTime` or `Drop` \ No newline at end of file + * `destination` - (Required) - end destination of the input metric. Must be `RealTime`, `Archived`, or `Drop` \ No newline at end of file From 6fdb4e55f7205e03be3f68690c86bf4fbe44e5b2 Mon Sep 17 00:00:00 2001 From: Eric Choi Date: Wed, 7 Aug 2024 16:58:28 -0700 Subject: [PATCH 04/10] update signalfx/resource_signalfx_metric_ruleset_test.go --- .../resource_signalfx_metric_ruleset_test.go | 63 ++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/signalfx/resource_signalfx_metric_ruleset_test.go b/signalfx/resource_signalfx_metric_ruleset_test.go index 1b99fb97..65962ece 100644 --- a/signalfx/resource_signalfx_metric_ruleset_test.go +++ b/signalfx/resource_signalfx_metric_ruleset_test.go @@ -102,6 +102,19 @@ resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { } } + exception_rules { + name = "rule2" + enabled = true + matcher { + type = "dimension" + filters { + property = "demo_host" + property_value = [ "server1", "server3" ] + not = false + } + } + } + routing_rule { destination = "Archived" } @@ -134,7 +147,20 @@ resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { type = "dimension" filters { property = "demo_host" - property_value = [ "server1", "server3" ] + property_value = [ "server4" ] + not = false + } + } + } + + exception_rules { + name = "rule3" + enabled = true + matcher { + type = "dimension" + filters { + property = "demo_customer" + property_value = [ "customer1@email.com", "customer2@email.com", "customer3@email.com" ] not = false } } @@ -243,7 +269,7 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { testAccMetricRulesetExists, resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "metric_name", "demo.trans.count"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "version", "1"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.#", "2"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.name", "rule1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.enabled", "true"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.#", "1"), @@ -255,6 +281,17 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.1", "Tokyo"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.not", "false"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.name", "rule2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.enabled", "true"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.type", "dimension"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property", "demo_host"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.#", "2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.0", "server1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.1", "server3"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.not", "false"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "routing_rule.0.destination", "Archived"), ), }, @@ -271,7 +308,8 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { testAccMetricRulesetExists, resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "metric_name", "demo.trans.count"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "version", "2"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.#", "2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.#", "3"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.name", "rule1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.enabled", "true"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.#", "1"), @@ -288,12 +326,23 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.type", "dimension"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property", "demo_host"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.#", "2"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.0", "server1"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.1", "server3"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.0", "server4"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.not", "false"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "routing_rule.0.destination", "Drop"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.name", "rule3"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.enabled", "true"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.matcher.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.matcher.0.type", "dimension"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.matcher.0.filters.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.matcher.0.filters.0.property", "demo_customer"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.matcher.0.filters.0.property_value.#", "3"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.matcher.0.filters.0.property_value.0", "customer1@email.com"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.matcher.0.filters.0.property_value.1", "customer2@email.com"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.matcher.0.filters.0.property_value.2", "customer3@email.com"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.matcher.0.filters.0.not", "false"), + + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "routing_rule.0.destination", "Archived"), ), }, }, From b62ec734dda9c49fca1b058c7a93980054f6fe92 Mon Sep 17 00:00:00 2001 From: Eric Choi Date: Sun, 18 Aug 2024 19:05:54 -0700 Subject: [PATCH 05/10] Add restoration support --- signalfx/resource_signalfx_metric_ruleset.go | 65 ++++- .../resource_signalfx_metric_ruleset_test.go | 239 +++++++++++++++++- 2 files changed, 287 insertions(+), 17 deletions(-) diff --git a/signalfx/resource_signalfx_metric_ruleset.go b/signalfx/resource_signalfx_metric_ruleset.go index abe35fe1..9eead18d 100644 --- a/signalfx/resource_signalfx_metric_ruleset.go +++ b/signalfx/resource_signalfx_metric_ruleset.go @@ -172,6 +172,26 @@ func metricRulesetResource() *schema.Resource { }, }, }, + "restoration": { + Type: schema.TypeSet, + Optional: true, + Description: "Restoration for this rule", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "restoration_id": { + Type: schema.TypeString, + Computed: true, + // Optional: true, + Description: "ID of the restoration job.", + }, + "start_time": { + Type: schema.TypeString, + Optional: true, + Description: "Time from which the restoration job will restore archived data, in the form of *nix time in milliseconds.", + }, + }, + }, + }, }, }, }, @@ -449,6 +469,14 @@ func metricRulesetAPIToTF(d *schema.ResourceData, metricRuleset *metric_ruleset. } excRule["matcher"] = []map[string]interface{}{matcher} + if rule.HasRestoration() { + restoration := map[string]interface{}{ + "restoration_id": *rule.Restoration.RestorationId, + "start_time": strconv.FormatInt(*rule.Restoration.StartTime, 10), + } + excRule["restoration"] = []map[string]interface{}{restoration} + } + rules[i] = excRule } if err := d.Set("exception_rules", rules); err != nil { @@ -513,16 +541,47 @@ func getExceptionRules(tfRules []interface{}) []metric_ruleset.ExceptionRule { for _, tfRule := range tfRules { newTfRule := tfRule.(map[string]interface{}) rule := metric_ruleset.ExceptionRule{ - Name: newTfRule["name"].(string), - Enabled: newTfRule["enabled"].(bool), - Matcher: getDimensionMatcher(newTfRule), + Name: newTfRule["name"].(string), + Enabled: newTfRule["enabled"].(bool), + Matcher: getDimensionMatcher(newTfRule), + Restoration: &metric_ruleset.ExceptionRuleRestorationFields{}, } + restFields := getRestoration(newTfRule) + rule.Restoration = &restFields exceptionRulesList = append(exceptionRulesList, rule) } return exceptionRulesList } +func getRestoration(tfRule map[string]interface{}) metric_ruleset.ExceptionRuleRestorationFields { + if tfRule["restoration"] != nil && len(tfRule["restoration"].(*schema.Set).List()) > 0 { + restoration := tfRule["restoration"].(*schema.Set).List()[0].(map[string]interface{}) + + var restorationId = "" + val, ok := restoration["restoration_id"] + if ok { + restorationId = val.(string) + } else { + log.Printf("[DEBUG] SignalFx: restoration_id does not exist.") + } + startTime, err := strconv.ParseInt(restoration["start_time"].(string), 10, 64) + if err != nil { + panic(err) + } + + restorationFields := &metric_ruleset.ExceptionRuleRestorationFields{ + RestorationId: &restorationId, + StartTime: &startTime, + } + return *restorationFields + } else { + restorationFields := &metric_ruleset.ExceptionRuleRestorationFields{} + return *restorationFields + } + +} + func getMatcher(tfRule map[string]interface{}) metric_ruleset.MetricMatcher { matcher := tfRule["matcher"].(*schema.Set).List()[0].(map[string]interface{}) filters := make([]interface{}, 0) diff --git a/signalfx/resource_signalfx_metric_ruleset_test.go b/signalfx/resource_signalfx_metric_ruleset_test.go index 65962ece..48584f5e 100644 --- a/signalfx/resource_signalfx_metric_ruleset_test.go +++ b/signalfx/resource_signalfx_metric_ruleset_test.go @@ -3,7 +3,9 @@ package signalfx import ( "context" "fmt" + "strconv" "testing" + "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" @@ -85,7 +87,7 @@ resource "signalfx_metric_ruleset" "demo_trans_latency_metric_ruleset" { ) const ( - demoTransCountRuleset = ` + archivedDemoTransCountRuleset = ` resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { metric_name = "demo.trans.count" @@ -96,7 +98,7 @@ resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { type = "dimension" filters { property = "demo_datacenter" - property_value = [ "Paris", "Tokyo" ] + property_value = [ "Paris" ] not = false } } @@ -122,8 +124,9 @@ resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { ` ) +// Update: rule 1 - add Tokyo; rule 2 - replace filters with server3; add rule 3 const ( - demoTransCountRulesetUpdated = ` + archivedDemoTransCountRulesetUpdated = ` resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { metric_name = "demo.trans.count" @@ -134,7 +137,7 @@ resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { type = "dimension" filters { property = "demo_datacenter" - property_value = [ "Tokyo" ] + property_value = [ "Paris", "Tokyo" ] not = false } } @@ -173,6 +176,51 @@ resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { ` ) +// Update: rule 2 - remove it; rule 3 - add server2 to filters +const ( + archivedDemoTransCountRulesetUpdatedRemoveRule2 = ` +resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { + metric_name = "demo.trans.count" + + exception_rules { + name = "rule1" + enabled = true + matcher { + type = "dimension" + filters { + property = "demo_datacenter" + property_value = [ "Paris", "Tokyo" ] + not = false + } + } + } + + exception_rules { + name = "rule3" + enabled = true + matcher { + type = "dimension" + filters { + property = "demo_customer" + property_value = [ "customer1@email.com", "customer2@email.com", "customer3@email.com" ] + not = false + } + filters { + property = "demo_host" + property_value = [ "server2" ] + not = false + } + + } + } + + routing_rule { + destination = "Archived" + } +} +` +) + func TestAccCreateUpdateMetricRuleset(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -258,13 +306,13 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { Steps: []resource.TestStep{ // Validate plan { - Config: demoTransCountRuleset, + Config: archivedDemoTransCountRuleset, PlanOnly: true, ExpectNonEmptyPlan: true, }, - // Create it + // Create a new Archived Ruleset: metric demo.trans.count { - Config: demoTransCountRuleset, + Config: archivedDemoTransCountRuleset, Check: resource.ComposeTestCheckFunc( testAccMetricRulesetExists, resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "metric_name", "demo.trans.count"), @@ -276,9 +324,8 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.type", "dimension"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property", "demo_datacenter"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.#", "2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.0", "Paris"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.1", "Tokyo"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.not", "false"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.name", "rule2"), @@ -297,13 +344,13 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { }, // Validate plan { - Config: demoTransCountRulesetUpdated, + Config: archivedDemoTransCountRulesetUpdated, PlanOnly: true, ExpectNonEmptyPlan: true, }, - // Update it + // Update: add Paris to rule 1, replace with server3 in rule 2, add rule 3 { - Config: demoTransCountRulesetUpdated, + Config: archivedDemoTransCountRulesetUpdated, Check: resource.ComposeTestCheckFunc( testAccMetricRulesetExists, resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "metric_name", "demo.trans.count"), @@ -316,8 +363,9 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.type", "dimension"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property", "demo_datacenter"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.#", "1"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.0", "Tokyo"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.#", "2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.0", "Paris"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.1", "Tokyo"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.not", "false"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.name", "rule2"), @@ -345,6 +393,169 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "routing_rule.0.destination", "Archived"), ), }, + // Validate plan + { + Config: archivedDemoTransCountRulesetUpdatedRemoveRule2, + PlanOnly: true, + ExpectNonEmptyPlan: true, + }, + // Remove rule 2 + { + Config: archivedDemoTransCountRulesetUpdatedRemoveRule2, + Check: resource.ComposeTestCheckFunc( + testAccMetricRulesetExists, + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "metric_name", "demo.trans.count"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "version", "3"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.#", "2"), + + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.name", "rule1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.enabled", "true"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.type", "dimension"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property", "demo_datacenter"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.#", "2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.0", "Paris"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.property_value.1", "Tokyo"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.not", "false"), + + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.name", "rule3"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.enabled", "true"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.type", "dimension"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.#", "2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property", "demo_customer"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.#", "3"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.0", "customer1@email.com"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.1", "customer2@email.com"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.property_value.2", "customer3@email.com"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.not", "false"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.1.property", "demo_host"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.1.property_value.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.1.property_value.0", "server2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.1.not", "false"), + + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "routing_rule.0.destination", "Archived"), + ), + }, + }, + }) +} + +func TestAccCreateUpdateRestoration(t *testing.T) { + // 15 minutes ago in milliseconds + startTime := (time.Now().Unix() - 900) * 1000 + + archivedCartSizeRestore := fmt.Sprintf(` +resource "signalfx_metric_ruleset" "cart_size" { + metric_name = "cart.size" + + exception_rules { + name = "rule1" + enabled = true + matcher { + type = "dimension" + filters { + property = "customer-spend" + property_value = [ "low" ] + not = false + } + } + restoration { + start_time = %d + } + } + + routing_rule { + destination = "Archived" + } +} `, startTime) + + archivedCartSizeRestoreUpdate := fmt.Sprintf(` +resource "signalfx_metric_ruleset" "cart_size" { + metric_name = "cart.size" + + exception_rules { + name = "rule1" + enabled = true + matcher { + type = "dimension" + filters { + property = "customer-spend" + property_value = [ "low", "medium" ] + not = false + } + } + restoration { + start_time = %d + } + } + + routing_rule { + destination = "Archived" + } +} `, startTime) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccMetricRulesetDestroy, + Steps: []resource.TestStep{ + // Validate plan + { + Config: archivedCartSizeRestore, + PlanOnly: true, + ExpectNonEmptyPlan: true, + }, + // Create a new Archived Ruleset metric cart.size with restoration + { + Config: archivedCartSizeRestore, + Check: resource.ComposeTestCheckFunc( + testAccMetricRulesetExists, + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "metric_name", "cart.size"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "version", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.name", "rule1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.enabled", "true"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.0.type", "dimension"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.0.filters.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.0.filters.0.property", "customer-spend"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.0.filters.0.property_value.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.0.filters.0.property_value.0", "low"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.0.filters.0.not", "false"), + + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.restoration.0.start_time", strconv.FormatInt(startTime, 10)), + ), + }, + // Validate plan + { + Config: archivedCartSizeRestoreUpdate, + PlanOnly: true, + ExpectNonEmptyPlan: true, + }, + // Update ruleset by adding filter property medium. + { + Config: archivedCartSizeRestoreUpdate, + Check: resource.ComposeTestCheckFunc( + testAccMetricRulesetExists, + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "metric_name", "cart.size"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "version", "2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.name", "rule1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.enabled", "true"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.0.type", "dimension"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.0.filters.#", "1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.0.filters.0.property", "customer-spend"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.0.filters.0.property_value.#", "2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.0.filters.0.property_value.0", "low"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.0.filters.0.property_value.1", "medium"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.matcher.0.filters.0.not", "false"), + + resource.TestCheckResourceAttr("signalfx_metric_ruleset.cart_size", "exception_rules.0.restoration.0.start_time", strconv.FormatInt(startTime, 10)), + ), + }, }, }) } From f5da634eb0c0631336e7916b1875f10aabb5144a Mon Sep 17 00:00:00 2001 From: Eric Choi Date: Tue, 20 Aug 2024 09:53:26 -0700 Subject: [PATCH 06/10] update signalfx-go version; update html docs --- go.mod | 4 +- go.sum | 2 + signalfx/resource_signalfx_metric_ruleset.go | 72 +++++++++++++++---- .../resource_signalfx_metric_ruleset_test.go | 34 +++++++-- website/docs/r/metric_ruleset.html.markdown | 11 ++- 5 files changed, 99 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index a6dc140a..c26a9c90 100644 --- a/go.mod +++ b/go.mod @@ -2,15 +2,13 @@ module github.com/splunk-terraform/terraform-provider-signalfx go 1.20 -replace github.com/signalfx/signalfx-go v1.39.0 => /Users/echoi/go/src/github.com/signalfx/signalfx-go - require ( github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d github.com/davecgh/go-spew v1.1.1 github.com/hashicorp/go-retryablehttp v0.7.7 github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 github.com/mitchellh/go-homedir v1.1.0 - github.com/signalfx/signalfx-go v1.39.0 + github.com/signalfx/signalfx-go v1.40.0 github.com/stretchr/testify v1.9.0 ) diff --git a/go.sum b/go.sum index 010a91bb..22db52c3 100644 --- a/go.sum +++ b/go.sum @@ -125,6 +125,8 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0= github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/signalfx/signalfx-go v1.40.0 h1:1A7zIiD4uKtafOETHZ60n+nsLrHfxO7rAv0UqWHWIV4= +github.com/signalfx/signalfx-go v1.40.0/go.mod h1:aVrA69k02raBhDtIL1l+KBu+H5eEmS5b0IFbqgKh7eg= github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= diff --git a/signalfx/resource_signalfx_metric_ruleset.go b/signalfx/resource_signalfx_metric_ruleset.go index 9eead18d..49b12ccf 100644 --- a/signalfx/resource_signalfx_metric_ruleset.go +++ b/signalfx/resource_signalfx_metric_ruleset.go @@ -26,6 +26,11 @@ func metricRulesetResource() *schema.Resource { Computed: true, Description: "Version of the ruleset", }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Information about the metric ruleset.", + }, "aggregation_rules": { Type: schema.TypeList, Optional: true, @@ -37,6 +42,11 @@ func metricRulesetResource() *schema.Resource { Optional: true, Description: "Name of this aggregation rule", }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Information about an aggregation rule.", + }, "enabled": { Type: schema.TypeBool, Required: true, @@ -127,6 +137,11 @@ func metricRulesetResource() *schema.Resource { Optional: true, Description: "Name of this exception rule", }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Information about an exception rule.", + }, "enabled": { Type: schema.TypeBool, Required: true, @@ -258,6 +273,7 @@ func metricRulesetCreate(d *schema.ResourceData, meta interface{}) error { AggregationRules: payloadReq.AggregationRules, ExceptionRules: payloadReq.ExceptionRules, MetricName: *payloadReq.MetricName, + Description: payloadReq.Description, RoutingRule: *payloadReq.RoutingRule, } @@ -275,6 +291,7 @@ func metricRulesetCreate(d *schema.ResourceData, meta interface{}) error { MetricName: metricRulesetResp.MetricName, AggregationRules: metricRulesetResp.AggregationRules, ExceptionRules: metricRulesetResp.ExceptionRules, + Description: metricRulesetResp.Description, RoutingRule: metricRulesetResp.RoutingRule, Creator: metricRulesetResp.Creator, Created: metricRulesetResp.Created, @@ -296,6 +313,7 @@ func metricRulesetRead(d *schema.ResourceData, meta interface{}) error { Id: metricRulesetResp.Id, Version: metricRulesetResp.Version, MetricName: metricRulesetResp.MetricName, + Description: metricRulesetResp.Description, AggregationRules: metricRulesetResp.AggregationRules, ExceptionRules: metricRulesetResp.ExceptionRules, RoutingRule: metricRulesetResp.RoutingRule, @@ -322,6 +340,7 @@ func metricRulesetUpdate(d *schema.ResourceData, meta interface{}) error { AggregationRules: payloadReq.AggregationRules, ExceptionRules: payloadReq.ExceptionRules, MetricName: payloadReq.MetricName, + Description: payloadReq.Description, RoutingRule: payloadReq.RoutingRule, Version: currentMetricRuleset.Version, } @@ -348,6 +367,7 @@ func metricRulesetUpdate(d *schema.ResourceData, meta interface{}) error { LastUpdatedByName: metricRulesetResp.LastUpdatedByName, LastUpdated: metricRulesetResp.LastUpdated, MetricName: metricRulesetResp.MetricName, + Description: metricRulesetResp.Description, RoutingRule: metricRulesetResp.RoutingRule, Version: metricRulesetResp.Version, } @@ -382,6 +402,9 @@ func metricRulesetAPIToTF(d *schema.ResourceData, metricRuleset *metric_ruleset. if err := d.Set("metric_name", metricRuleset.MetricName); err != nil { return err } + if err := d.Set("description", metricRuleset.Description); err != nil { + return err + } versionStr := strconv.FormatInt(*metricRuleset.Version, 10) if err := d.Set("version", versionStr); err != nil { @@ -406,8 +429,9 @@ func metricRulesetAPIToTF(d *schema.ResourceData, metricRuleset *metric_ruleset. rules := make([]map[string]interface{}, len(metricRuleset.AggregationRules)) for i, rule := range metricRuleset.AggregationRules { aggRule := map[string]interface{}{ - "name": rule.Name, - "enabled": rule.Enabled, + "name": rule.Name, + "enabled": rule.Enabled, + "description": rule.Description, } filters := make([]map[string]interface{}, len(rule.Matcher.DimensionMatcher.Filters)) @@ -449,8 +473,9 @@ func metricRulesetAPIToTF(d *schema.ResourceData, metricRuleset *metric_ruleset. rules := make([]map[string]interface{}, len(metricRuleset.ExceptionRules)) for i, rule := range metricRuleset.ExceptionRules { excRule := map[string]interface{}{ - "name": rule.Name, - "enabled": rule.Enabled, + "name": rule.Name, + "enabled": rule.Enabled, + "description": rule.Description, } filters := make([]map[string]interface{}, len(rule.Matcher.Filters)) @@ -469,12 +494,14 @@ func metricRulesetAPIToTF(d *schema.ResourceData, metricRuleset *metric_ruleset. } excRule["matcher"] = []map[string]interface{}{matcher} - if rule.HasRestoration() { - restoration := map[string]interface{}{ - "restoration_id": *rule.Restoration.RestorationId, - "start_time": strconv.FormatInt(*rule.Restoration.StartTime, 10), + if val, ok := rule.GetRestorationOk(); ok { + if val.StartTime != nil && *val.StartTime > int64(0) { + restoration := map[string]interface{}{ + "restoration_id": *val.RestorationId, + "start_time": strconv.FormatInt(*val.StartTime, 10), + } + excRule["restoration"] = []map[string]interface{}{restoration} } - excRule["restoration"] = []map[string]interface{}{restoration} } rules[i] = excRule @@ -495,8 +522,13 @@ func metricRulesetAPIToTF(d *schema.ResourceData, metricRuleset *metric_ruleset. func getPayloadMetricRuleset(d *schema.ResourceData) (*metric_ruleset.MetricRuleset, error) { metricName := d.Get("metric_name").(string) + var description = "" + if val, ok := d.GetOk("description"); ok { + description = val.(string) + } cudr := &metric_ruleset.MetricRuleset{ MetricName: &metricName, + Description: &description, AggregationRules: []metric_ruleset.AggregationRule{}, ExceptionRules: []metric_ruleset.ExceptionRule{}, RoutingRule: &metric_ruleset.RoutingRule{}, @@ -524,11 +556,16 @@ func getAggregationRules(tfRules []interface{}) []metric_ruleset.AggregationRule for _, tfRule := range tfRules { newTfRule := tfRule.(map[string]interface{}) ruleName := newTfRule["name"].(string) + var description = "" + if val, ok := newTfRule["description"]; ok { + description = val.(string) + } rule := metric_ruleset.AggregationRule{ - Name: &ruleName, - Enabled: newTfRule["enabled"].(bool), - Matcher: getMatcher(newTfRule), - Aggregator: getAggregator(newTfRule), + Name: &ruleName, + Description: &description, + Enabled: newTfRule["enabled"].(bool), + Matcher: getMatcher(newTfRule), + Aggregator: getAggregator(newTfRule), } aggregationRulesList = append(aggregationRulesList, rule) } @@ -540,14 +577,19 @@ func getExceptionRules(tfRules []interface{}) []metric_ruleset.ExceptionRule { var exceptionRulesList []metric_ruleset.ExceptionRule for _, tfRule := range tfRules { newTfRule := tfRule.(map[string]interface{}) + var description = "" + if val, ok := newTfRule["description"]; ok { + description = val.(string) + } rule := metric_ruleset.ExceptionRule{ Name: newTfRule["name"].(string), + Description: &description, Enabled: newTfRule["enabled"].(bool), Matcher: getDimensionMatcher(newTfRule), - Restoration: &metric_ruleset.ExceptionRuleRestorationFields{}, + Restoration: metric_ruleset.ExceptionRuleRestorationFields{}, } restFields := getRestoration(newTfRule) - rule.Restoration = &restFields + rule.Restoration = restFields exceptionRulesList = append(exceptionRulesList, rule) } diff --git a/signalfx/resource_signalfx_metric_ruleset_test.go b/signalfx/resource_signalfx_metric_ruleset_test.go index 48584f5e..4baa8379 100644 --- a/signalfx/resource_signalfx_metric_ruleset_test.go +++ b/signalfx/resource_signalfx_metric_ruleset_test.go @@ -15,8 +15,9 @@ const ( demoTransLatencyRuleset = ` resource "signalfx_metric_ruleset" "demo_trans_latency_metric_ruleset" { metric_name = "demo.trans.latency" + description = "demo_trans_latency_metric_ruleset with aggregation" - aggregation_rules { + aggregation_rules { name = "rule1" enabled = true matcher { @@ -33,6 +34,7 @@ resource "signalfx_metric_ruleset" "demo_trans_latency_metric_ruleset" { drop_dimensions = false output_name = "demo_trans_latency.by.demo_datacenter.agg" } + description = "aggregation rule 1" } routing_rule { @@ -46,6 +48,7 @@ const ( demoTransLatencyRulesetUpdated = ` resource "signalfx_metric_ruleset" "demo_trans_latency_metric_ruleset" { metric_name = "demo.trans.latency" + description = "demo_trans_latency_metric_ruleset with aggregation updated" aggregation_rules { name = "newRule1" @@ -64,6 +67,7 @@ resource "signalfx_metric_ruleset" "demo_trans_latency_metric_ruleset" { drop_dimensions = false output_name = "demo_trans_latency.by.demo_datacenter.agg" } + description = "aggregation rule 1 updated" } aggregation_rules { @@ -77,6 +81,7 @@ resource "signalfx_metric_ruleset" "demo_trans_latency_metric_ruleset" { drop_dimensions = false output_name = "demo_trans_latency.by.demo_host.agg" } + description = "aggregation rule 2" } routing_rule { @@ -106,6 +111,7 @@ resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { exception_rules { name = "rule2" + description ="exception rule 2" enabled = true matcher { type = "dimension" @@ -132,6 +138,7 @@ resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { exception_rules { name = "rule1" + description = "exception rule 1" enabled = true matcher { type = "dimension" @@ -221,7 +228,7 @@ resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { ` ) -func TestAccCreateUpdateMetricRuleset(t *testing.T) { +func TestAccMetricRulesetAggregation(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -239,6 +246,7 @@ func TestAccCreateUpdateMetricRuleset(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccMetricRulesetExists, resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "metric_name", "demo.trans.latency"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "description", "demo_trans_latency_metric_ruleset with aggregation"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "version", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.0.name", "rule1"), @@ -256,6 +264,8 @@ func TestAccCreateUpdateMetricRuleset(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.0.aggregator.0.drop_dimensions", "false"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.0.aggregator.0.dimensions.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.0.aggregator.0.dimensions.0", "demo_customer"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.0.description", "aggregation rule 1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "routing_rule.0.destination", "RealTime"), ), }, @@ -265,6 +275,7 @@ func TestAccCreateUpdateMetricRuleset(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccMetricRulesetExists, resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "metric_name", "demo.trans.latency"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "description", "demo_trans_latency_metric_ruleset with aggregation updated"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "version", "2"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.#", "2"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.0.name", "newRule1"), @@ -282,6 +293,8 @@ func TestAccCreateUpdateMetricRuleset(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.0.aggregator.0.drop_dimensions", "false"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.0.aggregator.0.dimensions.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.0.aggregator.0.dimensions.0", "demo_customer"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.0.description", "aggregation rule 1 updated"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.1.name", ""), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.1.enabled", "false"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.1.matcher.#", "1"), @@ -291,14 +304,15 @@ func TestAccCreateUpdateMetricRuleset(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.1.aggregator.0.drop_dimensions", "false"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.1.aggregator.0.dimensions.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.1.aggregator.0.dimensions.0", "demo_host"), - resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "routing_rule.0.destination", "Archived"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "aggregation_rules.1.description", "aggregation rule 2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "routing_rule.0.destination", "Drop"), ), }, }, }) } -func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { +func TestAccMetricRulesetArchived(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -316,9 +330,11 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccMetricRulesetExists, resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "metric_name", "demo.trans.count"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "description", ""), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "version", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.#", "2"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.name", "rule1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.description", ""), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.enabled", "true"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.type", "dimension"), @@ -329,6 +345,7 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.not", "false"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.name", "rule2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.description", "exception rule 2"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.enabled", "true"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.type", "dimension"), @@ -354,10 +371,12 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccMetricRulesetExists, resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "metric_name", "demo.trans.count"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "description", ""), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "version", "2"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.#", "3"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.name", "rule1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.description", "exception rule 1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.enabled", "true"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.type", "dimension"), @@ -369,6 +388,7 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.not", "false"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.name", "rule2"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.description", ""), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.enabled", "true"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.type", "dimension"), @@ -379,6 +399,7 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.filters.0.not", "false"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.name", "rule3"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.description", ""), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.enabled", "true"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.matcher.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.2.matcher.0.type", "dimension"), @@ -405,10 +426,12 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccMetricRulesetExists, resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "metric_name", "demo.trans.count"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "description", ""), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "version", "3"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.#", "2"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.name", "rule1"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.description", ""), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.enabled", "true"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.type", "dimension"), @@ -420,6 +443,7 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.0.matcher.0.filters.0.not", "false"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.name", "rule3"), + resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.description", ""), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.enabled", "true"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.#", "1"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_count_metric_ruleset", "exception_rules.1.matcher.0.type", "dimension"), @@ -442,7 +466,7 @@ func TestAccCreateUpdateMetricRulesetArchived(t *testing.T) { }) } -func TestAccCreateUpdateRestoration(t *testing.T) { +func TestAccMetricRulesetRestoration(t *testing.T) { // 15 minutes ago in milliseconds startTime := (time.Now().Unix() - 900) * 1000 diff --git a/website/docs/r/metric_ruleset.html.markdown b/website/docs/r/metric_ruleset.html.markdown index 9bc371ee..c26e929d 100644 --- a/website/docs/r/metric_ruleset.html.markdown +++ b/website/docs/r/metric_ruleset.html.markdown @@ -17,9 +17,11 @@ Provides an Observability Cloud resource for managing metric rulesets. ```tf resource "signalfx_metric_ruleset" "cpu_utilization_metric_ruleset" { metric_name = "cpu.utilization" + description = "Routing ruleset for cpu.utilization" aggregation_rules { name = "cpu.utilization by service rule" + description = "Aggregates cpu.utilization data by service" enabled = true matcher { type = "dimension" @@ -38,7 +40,8 @@ resource "signalfx_metric_ruleset" "cpu_utilization_metric_ruleset" { } exception_rules { - name = "Route us-east-2 to real-time" + name = "Exception rule us-east-2" + description = "Routes us-east-2 data to real-time" enabled = true matcher { type = "dimension" @@ -60,9 +63,11 @@ resource "signalfx_metric_ruleset" "cpu_utilization_metric_ruleset" { The following arguments are supported in the resource block: * `metric_name` - (Required) Name of the input metric +* `description` - (Optional) Information about the metric ruleset * `aggregation_rules` - (Optional) List of aggregation rules for the metric * `enabled` - (Required) When false, this rule will not generate aggregated MTSs * `name` - (Optional) name of the aggregation rule + * `description` - (Optional) Information about an aggregation rule * `matcher` - (Required) Matcher object * `type` - (Required) Type of matcher. Must always be "dimension" * `filters` - (Optional) List of filters to filter the set of input MTSs @@ -77,11 +82,15 @@ The following arguments are supported in the resource block: * `exception_rules` - (Optional) List of exception rules for the metric * `enabled` - (Required) When false, this rule will not route matched data to real-time * `name` - (Required) name of the exception rule + * `description` - (Optional) Information about an exception rule * `matcher` - (Required) Matcher object * `type` - (Required) Type of matcher. Must always be "dimension" * `filters` - (Required) List of filters to filter the set of input MTSs * `property` - (Required) - Name of the dimension * `property_value` - (Required) - Value of the dimension * `not` - When true, this filter will match all values not matching the property_values + * `restoration` - (Optional) Properties of a restoration job + * `start_time` - (Required) Time from which the restoration job will restore archived data, in the form of *nix time in milliseconds + * `routing_rule` - (Required) Routing Rule object * `destination` - (Required) - end destination of the input metric. Must be `RealTime`, `Archived`, or `Drop` \ No newline at end of file From 67ee65b76effe4b3344b0e66936d209d9ed9b47a Mon Sep 17 00:00:00 2001 From: Eric Choi Date: Tue, 20 Aug 2024 13:03:14 -0700 Subject: [PATCH 07/10] fix restoration function --- signalfx/resource_signalfx_metric_ruleset.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/signalfx/resource_signalfx_metric_ruleset.go b/signalfx/resource_signalfx_metric_ruleset.go index 49b12ccf..60eb5429 100644 --- a/signalfx/resource_signalfx_metric_ruleset.go +++ b/signalfx/resource_signalfx_metric_ruleset.go @@ -586,10 +586,10 @@ func getExceptionRules(tfRules []interface{}) []metric_ruleset.ExceptionRule { Description: &description, Enabled: newTfRule["enabled"].(bool), Matcher: getDimensionMatcher(newTfRule), - Restoration: metric_ruleset.ExceptionRuleRestorationFields{}, + Restoration: &metric_ruleset.ExceptionRuleRestorationFields{}, } restFields := getRestoration(newTfRule) - rule.Restoration = restFields + rule.Restoration = &restFields exceptionRulesList = append(exceptionRulesList, rule) } From b574f188a41a24172952a2224b79893e80d9ec38 Mon Sep 17 00:00:00 2001 From: Eric Choi Date: Tue, 20 Aug 2024 13:29:51 -0700 Subject: [PATCH 08/10] fix tests --- signalfx/resource_signalfx_metric_ruleset.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signalfx/resource_signalfx_metric_ruleset.go b/signalfx/resource_signalfx_metric_ruleset.go index 60eb5429..0d73796b 100644 --- a/signalfx/resource_signalfx_metric_ruleset.go +++ b/signalfx/resource_signalfx_metric_ruleset.go @@ -495,7 +495,7 @@ func metricRulesetAPIToTF(d *schema.ResourceData, metricRuleset *metric_ruleset. excRule["matcher"] = []map[string]interface{}{matcher} if val, ok := rule.GetRestorationOk(); ok { - if val.StartTime != nil && *val.StartTime > int64(0) { + if val != nil && val.StartTime != nil && *val.StartTime > int64(0) { restoration := map[string]interface{}{ "restoration_id": *val.RestorationId, "start_time": strconv.FormatInt(*val.StartTime, 10), From 693ed16b796b23b8599f37bf1d28013fb3a64804 Mon Sep 17 00:00:00 2001 From: Eric Choi Date: Tue, 20 Aug 2024 16:55:59 -0700 Subject: [PATCH 09/10] cleanup if statements --- signalfx/resource_signalfx_metric_ruleset.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/signalfx/resource_signalfx_metric_ruleset.go b/signalfx/resource_signalfx_metric_ruleset.go index 0d73796b..0d3fe7e4 100644 --- a/signalfx/resource_signalfx_metric_ruleset.go +++ b/signalfx/resource_signalfx_metric_ruleset.go @@ -601,8 +601,7 @@ func getRestoration(tfRule map[string]interface{}) metric_ruleset.ExceptionRuleR restoration := tfRule["restoration"].(*schema.Set).List()[0].(map[string]interface{}) var restorationId = "" - val, ok := restoration["restoration_id"] - if ok { + if val, ok := restoration["restoration_id"]; ok { restorationId = val.(string) } else { log.Printf("[DEBUG] SignalFx: restoration_id does not exist.") From 15ca0a433eaeb8a3188400c4205cea7cca1df918 Mon Sep 17 00:00:00 2001 From: Eric Choi Date: Tue, 20 Aug 2024 16:59:05 -0700 Subject: [PATCH 10/10] resolve conflicts in go.sum --- go.sum | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.sum b/go.sum index 22db52c3..9baa7a60 100644 --- a/go.sum +++ b/go.sum @@ -124,10 +124,10 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0= github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/signalfx/signalfx-go v1.40.0 h1:1A7zIiD4uKtafOETHZ60n+nsLrHfxO7rAv0UqWHWIV4= github.com/signalfx/signalfx-go v1.40.0/go.mod h1:aVrA69k02raBhDtIL1l+KBu+H5eEmS5b0IFbqgKh7eg= -github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=