From 30649488b0469f5fcdd2ba8f0209b941ea174c66 Mon Sep 17 00:00:00 2001 From: Elaine Vuong Date: Wed, 29 Nov 2023 12:36:02 -0500 Subject: [PATCH] Update SLO Resources to Accept Empty Alerting and Empty Fastburn/Slowburn Fields (#1186) Update SLO Resources to Accept Empty Alerting and Empty Fastburn/Slowburn Fields --- docs/data-sources/slos.md | 4 +- docs/resources/slo.md | 13 ++- .../data-sources/grafana_slos/data-source.tf | 3 +- examples/resources/grafana_slo/resource.tf | 3 +- .../resources/grafana_slo/resource_complex.tf | 3 +- .../resources/grafana_slo/resource_ratio.tf | 3 +- .../resources/grafana_slo/resource_update.tf | 3 +- internal/resources/slo/data_source_slo.go | 1 - internal/resources/slo/resource_slo.go | 83 +++++++++++-------- internal/resources/slo/resource_slo_test.go | 3 - 10 files changed, 59 insertions(+), 60 deletions(-) diff --git a/docs/data-sources/slos.md b/docs/data-sources/slos.md index aeea87eaa..6f67c4855 100644 --- a/docs/data-sources/slos.md +++ b/docs/data-sources/slos.md @@ -32,8 +32,7 @@ resource "grafana_slo" "test" { window = "30d" } destination_datasource { - type = "mimir" - uid = "grafanacloud-prom" + uid = "grafanacloud-prom" } label { key = "custom" @@ -177,7 +176,6 @@ Read-Only: Read-Only: -- `type` (String) - `uid` (String) diff --git a/docs/resources/slo.md b/docs/resources/slo.md index 58a31e5a7..4573303f0 100644 --- a/docs/resources/slo.md +++ b/docs/resources/slo.md @@ -34,8 +34,7 @@ resource "grafana_slo" "test" { window = "30d" } destination_datasource { - type = "mimir" - uid = "grafanacloud-prom" + uid = "grafanacloud-prom" } label { key = "slo" @@ -86,8 +85,7 @@ resource "grafana_slo" "test" { window = "30d" } destination_datasource { - type = "mimir" - uid = "grafanacloud-prom" + uid = "grafanacloud-prom" } label { key = "slo" @@ -139,7 +137,7 @@ resource "grafana_slo" "test" { ### Optional -- `alerting` (Block List) Configures the alerting rules that will be generated for each +- `alerting` (Block List, Max: 1) Configures the alerting rules that will be generated for each time window associated with the SLO. Grafana SLOs can generate alerts when the short-term error budget burn is very high, the long-term error budget burn rate is high, or when the remaining @@ -200,9 +198,9 @@ Optional: Optional: - `annotation` (Block List) Annotations will be attached to all alerts generated by any of these rules. (see [below for nested schema](#nestedblock--alerting--annotation)) -- `fastburn` (Block List) Alerting Rules generated for Fast Burn alerts (see [below for nested schema](#nestedblock--alerting--fastburn)) +- `fastburn` (Block List, Max: 1) Alerting Rules generated for Fast Burn alerts (see [below for nested schema](#nestedblock--alerting--fastburn)) - `label` (Block List) Labels will be attached to all alerts generated by any of these rules. (see [below for nested schema](#nestedblock--alerting--label)) -- `slowburn` (Block List) Alerting Rules generated for Slow Burn alerts (see [below for nested schema](#nestedblock--alerting--slowburn)) +- `slowburn` (Block List, Max: 1) Alerting Rules generated for Slow Burn alerts (see [below for nested schema](#nestedblock--alerting--slowburn)) ### Nested Schema for `alerting.annotation` @@ -282,7 +280,6 @@ Required: Optional: -- `type` (String) Datasource Type - set to 'mimir' - `uid` (String) UID for the Mimir Datasource diff --git a/examples/data-sources/grafana_slos/data-source.tf b/examples/data-sources/grafana_slos/data-source.tf index 35cbc72b1..90ba12c49 100644 --- a/examples/data-sources/grafana_slos/data-source.tf +++ b/examples/data-sources/grafana_slos/data-source.tf @@ -12,8 +12,7 @@ resource "grafana_slo" "test" { window = "30d" } destination_datasource { - type = "mimir" - uid = "grafanacloud-prom" + uid = "grafanacloud-prom" } label { key = "custom" diff --git a/examples/resources/grafana_slo/resource.tf b/examples/resources/grafana_slo/resource.tf index 639484fa0..97cd715a2 100644 --- a/examples/resources/grafana_slo/resource.tf +++ b/examples/resources/grafana_slo/resource.tf @@ -12,8 +12,7 @@ resource "grafana_slo" "test" { window = "30d" } destination_datasource { - type = "mimir" - uid = "grafanacloud-prom" + uid = "grafanacloud-prom" } label { key = "slo" diff --git a/examples/resources/grafana_slo/resource_complex.tf b/examples/resources/grafana_slo/resource_complex.tf index de0d3d332..cc7434d89 100644 --- a/examples/resources/grafana_slo/resource_complex.tf +++ b/examples/resources/grafana_slo/resource_complex.tf @@ -14,8 +14,7 @@ resource "grafana_slo" "test" { window = "30d" } destination_datasource { - type = "mimir" - uid = "grafanacloud-prom" + uid = "grafanacloud-prom" } label { key = "slo" diff --git a/examples/resources/grafana_slo/resource_ratio.tf b/examples/resources/grafana_slo/resource_ratio.tf index 0fb5f9679..d989b0253 100644 --- a/examples/resources/grafana_slo/resource_ratio.tf +++ b/examples/resources/grafana_slo/resource_ratio.tf @@ -14,8 +14,7 @@ resource "grafana_slo" "ratio" { window = "30d" } destination_datasource { - type = "mimir" - uid = "grafanacloud-prom" + uid = "grafanacloud-prom" } label { key = "slo" diff --git a/examples/resources/grafana_slo/resource_update.tf b/examples/resources/grafana_slo/resource_update.tf index 31a01dd1b..01956f23c 100644 --- a/examples/resources/grafana_slo/resource_update.tf +++ b/examples/resources/grafana_slo/resource_update.tf @@ -12,8 +12,7 @@ resource "grafana_slo" "update" { window = "7d" } destination_datasource { - type = "mimir" - uid = "grafanacloud-prom" + uid = "grafanacloud-prom" } label { key = "slo" diff --git a/internal/resources/slo/data_source_slo.go b/internal/resources/slo/data_source_slo.go index 248b34d85..0c158b26e 100644 --- a/internal/resources/slo/data_source_slo.go +++ b/internal/resources/slo/data_source_slo.go @@ -195,7 +195,6 @@ func unpackDestinationDatasource(destinationDatasource *gapi.DestinationDatasour retDestinationDatasources := []map[string]interface{}{} retDestinationDatasource := make(map[string]interface{}) - retDestinationDatasource["type"] = destinationDatasource.Type retDestinationDatasource["uid"] = destinationDatasource.UID retDestinationDatasources = append(retDestinationDatasources, retDestinationDatasource) diff --git a/internal/resources/slo/resource_slo.go b/internal/resources/slo/resource_slo.go index 7e1d22258..28a563a33 100644 --- a/internal/resources/slo/resource_slo.go +++ b/internal/resources/slo/resource_slo.go @@ -54,11 +54,6 @@ Resource manages Grafana SLOs. Description: `UID for the Mimir Datasource`, Optional: true, }, - "type": &schema.Schema{ - Type: schema.TypeString, - Description: `Datasource Type - set to 'mimir'`, - Optional: true, - }, }, }, }, @@ -147,6 +142,7 @@ Resource manages Grafana SLOs. }, "alerting": &schema.Schema{ Type: schema.TypeList, + MaxItems: 1, Optional: true, Description: `Configures the alerting rules that will be generated for each time window associated with the SLO. Grafana SLOs can generate @@ -170,6 +166,7 @@ Resource manages Grafana SLOs. "fastburn": &schema.Schema{ Type: schema.TypeList, Optional: true, + MaxItems: 1, Description: "Alerting Rules generated for Fast Burn alerts", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -190,6 +187,7 @@ Resource manages Grafana SLOs. }, "slowburn": &schema.Schema{ Type: schema.TypeList, + MaxItems: 1, Optional: true, Description: "Alerting Rules generated for Slow Burn alerts", Elem: &schema.Resource{ @@ -360,13 +358,12 @@ func packSloResource(d *schema.ResourceData) (gapi.Slo, error) { // Check the Optional Alerting Field if alerting, ok := d.GetOk("alerting"); ok { - alertData := alerting.([]interface{}) - - // if the Alerting field is an empty block, alertData[0] has a value of nil - if alertData[0] != nil { - // only pack the Alerting TF fields if the user populates the Alerting field with blocks - alert := alertData[0].(map[string]interface{}) - tfalerting = packAlerting(alert) + alertData, ok := alerting.([]interface{}) + if ok && len(alertData) > 0 { + alert, ok := alertData[0].(map[string]interface{}) + if ok { + tfalerting = packAlerting(alert) + } } slo.Alerting = &tfalerting @@ -374,11 +371,9 @@ func packSloResource(d *schema.ResourceData) (gapi.Slo, error) { // Check the Optional Destination Datasource Field if rawdestinationdatasource, ok := d.GetOk("destination_datasource"); ok { - destinationDatasourceData := rawdestinationdatasource.([]interface{}) + destinationDatasourceData, ok := rawdestinationdatasource.([]interface{}) - // if the destination_datasource field is an empty block, destination[0] has a value of nil - if destinationDatasourceData[0] != nil { - // only pack the destinationDatasource TF fields if the user populates the Destination field with blocks + if ok && len(destinationDatasourceData) > 0 { destinationdatasource := destinationDatasourceData[0].(map[string]interface{}) tfdestinationdatasource, _ = packDestinationDatasource(destinationdatasource) } @@ -392,11 +387,6 @@ func packSloResource(d *schema.ResourceData) (gapi.Slo, error) { func packDestinationDatasource(destinationdatasource map[string]interface{}) (gapi.DestinationDatasource, error) { packedDestinationDatasource := gapi.DestinationDatasource{} - if destinationdatasource["type"].(string) != "" { - datasourceType := destinationdatasource["type"].(string) - packedDestinationDatasource.Type = datasourceType - } - if destinationdatasource["uid"].(string) != "" { datasourceUID := destinationdatasource["uid"].(string) packedDestinationDatasource.UID = datasourceUID @@ -487,17 +477,30 @@ func packLabels(tfLabels []interface{}) []gapi.Label { } func packAlerting(tfAlerting map[string]interface{}) gapi.Alerting { - annots := tfAlerting["annotation"].([]interface{}) - tfAnnots := packLabels(annots) + var tfAnnots []gapi.Label + var tfLabels []gapi.Label + var tfFastBurn gapi.AlertingMetadata + var tfSlowBurn gapi.AlertingMetadata + + annots, ok := tfAlerting["annotation"].([]interface{}) + if ok { + tfAnnots = packLabels(annots) + } - labels := tfAlerting["label"].([]interface{}) - tfLabels := packLabels(labels) + labels, ok := tfAlerting["label"].([]interface{}) + if ok { + tfLabels = packLabels(labels) + } - fastBurn := tfAlerting["fastburn"].([]interface{}) - tfFastBurn := packAlertMetadata(fastBurn) + fastBurn, ok := tfAlerting["fastburn"].([]interface{}) + if ok { + tfFastBurn = packAlertMetadata(fastBurn) + } - slowBurn := tfAlerting["slowburn"].([]interface{}) - tfSlowBurn := packAlertMetadata(slowBurn) + slowBurn, ok := tfAlerting["slowburn"].([]interface{}) + if ok { + tfSlowBurn = packAlertMetadata(slowBurn) + } alerting := gapi.Alerting{ Annotations: tfAnnots, @@ -510,13 +513,23 @@ func packAlerting(tfAlerting map[string]interface{}) gapi.Alerting { } func packAlertMetadata(metadata []interface{}) gapi.AlertingMetadata { - meta := metadata[0].(map[string]interface{}) - - labels := meta["label"].([]interface{}) - tflabels := packLabels(labels) + var tflabels []gapi.Label + var tfannots []gapi.Label + + if len(metadata) > 0 { + meta, ok := metadata[0].(map[string]interface{}) + if ok { + labels, ok := meta["label"].([]interface{}) + if ok { + tflabels = packLabels(labels) + } - annots := meta["annotation"].([]interface{}) - tfannots := packLabels(annots) + annots, ok := meta["annotation"].([]interface{}) + if ok { + tfannots = packLabels(annots) + } + } + } apiMetadata := gapi.AlertingMetadata{ Labels: tflabels, diff --git a/internal/resources/slo/resource_slo_test.go b/internal/resources/slo/resource_slo_test.go index 9535eebca..7143b4be4 100644 --- a/internal/resources/slo/resource_slo_test.go +++ b/internal/resources/slo/resource_slo_test.go @@ -158,7 +158,6 @@ resource "grafana_slo" "invalid" { type = "freeform" } destination_datasource { - type = "mimir" uid = "grafanacloud-prom" } objectives { @@ -178,7 +177,6 @@ func emptyAlert(name string) string { window = "28d" } destination_datasource { - type = "mimir" uid = "grafanacloud-prom" } query { @@ -202,7 +200,6 @@ resource "grafana_slo" "no_alert" { window = "28d" } destination_datasource { - type = "mimir" uid = "grafanacloud-prom" } query {