diff --git a/go.mod b/go.mod index 46873bdf..6848634f 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.7 github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.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 78b9b52b..3b7bf3b6 100644 --- a/go.sum +++ b/go.sum @@ -121,8 +121,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.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -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/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.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= diff --git a/signalfx/resource_signalfx_metric_ruleset.go b/signalfx/resource_signalfx_metric_ruleset.go index a3ebf0cd..0d3fe7e4 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 { @@ -25,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, @@ -36,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, @@ -115,6 +126,90 @@ 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", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Information about an 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}, + }, + }, + }, + }, + }, + }, + }, + "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.", + }, + }, + }, + }, + }, + }, + }, "routing_rule": { Type: schema.TypeSet, Required: true, @@ -125,7 +220,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,7 +271,9 @@ func metricRulesetCreate(d *schema.ResourceData, meta interface{}) error { } payload := metric_ruleset.CreateMetricRulesetRequest{ AggregationRules: payloadReq.AggregationRules, + ExceptionRules: payloadReq.ExceptionRules, MetricName: *payloadReq.MetricName, + Description: payloadReq.Description, RoutingRule: *payloadReq.RoutingRule, } @@ -193,6 +290,8 @@ func metricRulesetCreate(d *schema.ResourceData, meta interface{}) error { Version: metricRulesetResp.Version, MetricName: metricRulesetResp.MetricName, AggregationRules: metricRulesetResp.AggregationRules, + ExceptionRules: metricRulesetResp.ExceptionRules, + Description: metricRulesetResp.Description, RoutingRule: metricRulesetResp.RoutingRule, Creator: metricRulesetResp.Creator, Created: metricRulesetResp.Created, @@ -214,7 +313,9 @@ 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, Creator: metricRulesetResp.Creator, Created: metricRulesetResp.Created, @@ -237,7 +338,9 @@ 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, + Description: payloadReq.Description, RoutingRule: payloadReq.RoutingRule, Version: currentMetricRuleset.Version, } @@ -255,6 +358,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, @@ -263,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, } @@ -297,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 { @@ -321,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)) @@ -360,6 +469,48 @@ 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, + "description": rule.Description, + } + + 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, + "not": *filter.NOT, + } + filters[j] = entry + } + + matcher := map[string]interface{}{ + "type": rule.Matcher.Type, + "filters": filters, + } + excRule["matcher"] = []map[string]interface{}{matcher} + + if val, ok := rule.GetRestorationOk(); ok { + 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), + } + excRule["restoration"] = []map[string]interface{}{restoration} + } + } + + 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 { @@ -371,9 +522,15 @@ 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{}, } @@ -381,6 +538,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) @@ -395,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) } @@ -407,6 +573,56 @@ 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{}) + 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{}, + } + 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 = "" + if val, ok := restoration["restoration_id"]; 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) @@ -424,6 +640,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 ec1a68b8..4baa8379 100644 --- a/signalfx/resource_signalfx_metric_ruleset_test.go +++ b/signalfx/resource_signalfx_metric_ruleset_test.go @@ -3,17 +3,21 @@ 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" - "testing" ) 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 { @@ -30,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 { @@ -43,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" @@ -61,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 { @@ -74,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 { @@ -83,7 +91,144 @@ resource "signalfx_metric_ruleset" "demo_trans_latency_metric_ruleset" { ` ) -func TestAccCreateUpdateMetricRuleset(t *testing.T) { +const ( + archivedDemoTransCountRuleset = ` +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" ] + not = false + } + } + } + + exception_rules { + name = "rule2" + description ="exception rule 2" + enabled = true + matcher { + type = "dimension" + filters { + property = "demo_host" + property_value = [ "server1", "server3" ] + not = false + } + } + } + + routing_rule { + destination = "Archived" + } +} +` +) + +// Update: rule 1 - add Tokyo; rule 2 - replace filters with server3; add rule 3 +const ( + archivedDemoTransCountRulesetUpdated = ` +resource "signalfx_metric_ruleset" "demo_trans_count_metric_ruleset" { + metric_name = "demo.trans.count" + + exception_rules { + name = "rule1" + description = "exception rule 1" + enabled = true + matcher { + type = "dimension" + filters { + property = "demo_datacenter" + property_value = [ "Paris", "Tokyo" ] + not = false + } + } + } + + exception_rules { + name = "rule2" + enabled = true + matcher { + type = "dimension" + filters { + property = "demo_host" + 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 + } + } + } + + routing_rule { + destination = "Archived" + } +} +` +) + +// 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 TestAccMetricRulesetAggregation(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -101,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"), @@ -118,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"), ), }, @@ -127,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"), @@ -144,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"), @@ -153,6 +304,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", "aggregation_rules.1.description", "aggregation rule 2"), resource.TestCheckResourceAttr("signalfx_metric_ruleset.demo_trans_latency_metric_ruleset", "routing_rule.0.destination", "Drop"), ), }, @@ -160,6 +312,278 @@ func TestAccCreateUpdateMetricRuleset(t *testing.T) { }) } +func TestAccMetricRulesetArchived(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccMetricRulesetDestroy, + Steps: []resource.TestStep{ + // Validate plan + { + Config: archivedDemoTransCountRuleset, + PlanOnly: true, + ExpectNonEmptyPlan: true, + }, + // Create a new Archived Ruleset: metric demo.trans.count + { + Config: archivedDemoTransCountRuleset, + 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"), + 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", "Paris"), + 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"), + 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"), + ), + }, + // Validate plan + { + Config: archivedDemoTransCountRulesetUpdated, + PlanOnly: true, + ExpectNonEmptyPlan: true, + }, + // Update: add Paris to rule 1, replace with server3 in rule 2, add rule 3 + { + Config: archivedDemoTransCountRulesetUpdated, + 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"), + 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.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"), + 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.#", "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", "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"), + 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"), + ), + }, + // 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", "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"), + 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.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"), + 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 TestAccMetricRulesetRestoration(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)), + ), + }, + }, + }) +} + func testAccMetricRulesetExists(s *terraform.State) error { client := newTestClient() for _, rs := range s.RootModule().Resources { diff --git a/website/docs/r/metric_ruleset.html.markdown b/website/docs/r/metric_ruleset.html.markdown index 6485b314..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" @@ -37,8 +39,21 @@ resource "signalfx_metric_ruleset" "cpu_utilization_metric_ruleset" { } } + exception_rules { + name = "Exception rule us-east-2" + description = "Routes us-east-2 data to real-time" + enabled = true + matcher { + type = "dimension" + filters { + property = "realm" + property_value = [ "us-east-2" ] + not = false + } + } + } routing_rule { - destination = "RealTime" + destination = "Archived" } } ``` @@ -48,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 @@ -62,5 +79,18 @@ 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 + * `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` 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