Skip to content

Commit

Permalink
fix(SLO): Handle resource 404 gracefully (#1784)
Browse files Browse the repository at this point in the history
* fix(SLO): Handle resource 404 gracefully

Terraform providers should react to a 404 as a "remove from tf state"
command, but the SLO resource was not handling this correctly. This
change fixes that in the SLO read path.

* Fix trailing whitespace for lint
  • Loading branch information
joeblubaugh authored Sep 9, 2024
1 parent 78c55ad commit c54e729
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
5 changes: 4 additions & 1 deletion internal/resources/slo/resource_slo.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,11 @@ func resourceSloRead(ctx context.Context, d *schema.ResourceData, client *slo.AP
sloID := d.Id()

req := client.DefaultAPI.V1SloIdGet(ctx, sloID)
slo, _, err := req.Execute()
slo, r, err := req.Execute()
if err != nil {
if r != nil && r.StatusCode == 404 {
return common.WarnMissing("SLO", d)
}
return apiError("Unable to read SLO - API", err)
}

Expand Down
63 changes: 63 additions & 0 deletions internal/resources/slo/resource_slo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/stretchr/testify/require"
)

func TestAccResourceSlo(t *testing.T) {
Expand Down Expand Up @@ -135,6 +136,68 @@ func TestAccResourceSlo(t *testing.T) {
})
}

// Tests that recreating an out-of-band deleted SLO works without error.
func TestAccSLO_recreate(t *testing.T) {
testutils.CheckCloudInstanceTestsEnabled(t)
var slo slo.SloV00Slo
randomName := acctest.RandomWithPrefix("SLO Terraform Testing")
config := testutils.TestAccExampleWithReplace(t, "resources/grafana_slo/resource.tf", map[string]string{
"Terraform Testing": randomName,
})
resource.ParallelTest(t, resource.TestCase{
ProtoV5ProviderFactories: testutils.ProtoV5ProviderFactories,

// Implicitly tests destroy
CheckDestroy: testAccSloCheckDestroy(&slo),
Steps: []resource.TestStep{
// Create
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testAccSloCheckExists("grafana_slo.test", &slo),
resource.TestCheckResourceAttrSet("grafana_slo.test", "id"),
resource.TestCheckResourceAttr("grafana_slo.test", "name", randomName),
resource.TestCheckResourceAttr("grafana_slo.test", "description", "Terraform Description"),
resource.TestCheckResourceAttr("grafana_slo.test", "query.0.type", "freeform"),
resource.TestCheckResourceAttr("grafana_slo.test", "query.0.freeform.0.query", "sum(rate(apiserver_request_total{code!=\"500\"}[$__rate_interval])) / sum(rate(apiserver_request_total[$__rate_interval]))"),
resource.TestCheckResourceAttr("grafana_slo.test", "objectives.0.value", "0.995"),
resource.TestCheckResourceAttr("grafana_slo.test", "objectives.0.window", "30d"),
resource.TestCheckNoResourceAttr("grafana_slo.test", "folder_uid"),
testutils.CheckLister("grafana_slo.test"),
),
},
// Delete out-of-band
{
PreConfig: func() {
client := testutils.Provider.Meta().(*common.Client).SLOClient
req := client.DefaultAPI.V1SloIdDelete(context.Background(), slo.Uuid)
_, err := req.Execute()
require.NoError(t, err)
},
Config: config,
PlanOnly: true,
ExpectNonEmptyPlan: true,
},
// Re-create
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testAccSloCheckExists("grafana_slo.test", &slo),
resource.TestCheckResourceAttrSet("grafana_slo.test", "id"),
resource.TestCheckResourceAttr("grafana_slo.test", "name", randomName),
resource.TestCheckResourceAttr("grafana_slo.test", "description", "Terraform Description"),
resource.TestCheckResourceAttr("grafana_slo.test", "query.0.type", "freeform"),
resource.TestCheckResourceAttr("grafana_slo.test", "query.0.freeform.0.query", "sum(rate(apiserver_request_total{code!=\"500\"}[$__rate_interval])) / sum(rate(apiserver_request_total[$__rate_interval]))"),
resource.TestCheckResourceAttr("grafana_slo.test", "objectives.0.value", "0.995"),
resource.TestCheckResourceAttr("grafana_slo.test", "objectives.0.window", "30d"),
resource.TestCheckNoResourceAttr("grafana_slo.test", "folder_uid"),
testutils.CheckLister("grafana_slo.test"),
),
},
},
})
}

func testAccSloCheckExists(rn string, slo *slo.SloV00Slo) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[rn]
Expand Down

0 comments on commit c54e729

Please sign in to comment.