From 66d6ec2bd033ab6e0246727bd7cfff53621b00eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Palet?= Date: Tue, 23 Apr 2024 08:59:43 +0100 Subject: [PATCH] Remove deleted resources and datasources from Terraform state on Read (all remaining services) (#346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove deleted resources and datasources from state on Read * Simplify code * Fix function description Co-authored-by: Diogo Ferrão * Fix function description Co-authored-by: Diogo Ferrão * Fix whitespace --------- Co-authored-by: Diogo Ferrão --- .../services/argus/credential/resource.go | 7 ++++++ .../services/argus/instance/datasource.go | 16 ++++++++++-- .../services/argus/instance/resource.go | 11 ++++++++ .../services/argus/scrapeconfig/datasource.go | 6 +++++ .../services/argus/scrapeconfig/resource.go | 7 ++++++ .../services/dns/recordset/datasource.go | 10 ++++++-- .../services/dns/recordset/resource.go | 4 +++ .../internal/services/dns/zone/datasource.go | 6 +++++ .../internal/services/dns/zone/resource.go | 4 +++ .../mongodbflex/instance/datasource.go | 6 +++++ .../services/mongodbflex/instance/resource.go | 7 ++++++ .../services/mongodbflex/user/datasource.go | 6 +++++ .../services/mongodbflex/user/resource.go | 7 ++++++ .../objectstorage/bucket/datasource.go | 6 +++++ .../services/objectstorage/bucket/resource.go | 7 ++++++ .../objectstorage/credential/datasource.go | 7 +++++- .../objectstorage/credential/resource.go | 21 ++++++++-------- .../objectstorage/credential/resource_test.go | 24 +++++++++++++----- .../credentialsgroup/datasource.go | 9 +++++-- .../credentialsgroup/resource.go | 25 ++++++++++--------- .../credentialsgroup/resource_test.go | 22 ++++++++++++---- .../postgresflex/instance/datasource.go | 12 +++++++++ .../postgresflex/instance/resource.go | 11 ++++++++ .../services/postgresflex/user/datasource.go | 6 +++++ .../services/postgresflex/user/resource.go | 7 ++++++ .../resourcemanager/project/datasource.go | 6 +++++ .../resourcemanager/project/resource.go | 7 ++++++ .../secretsmanager/instance/datasource.go | 6 +++++ .../secretsmanager/instance/resource.go | 7 ++++++ .../secretsmanager/user/datasource.go | 6 +++++ .../services/secretsmanager/user/resource.go | 7 ++++++ .../services/ske/cluster/datasource.go | 4 +++ .../internal/services/ske/cluster/resource.go | 5 ++++ 33 files changed, 262 insertions(+), 40 deletions(-) diff --git a/stackit/internal/services/argus/credential/resource.go b/stackit/internal/services/argus/credential/resource.go index 6f595a18..54be3413 100644 --- a/stackit/internal/services/argus/credential/resource.go +++ b/stackit/internal/services/argus/credential/resource.go @@ -3,6 +3,7 @@ package argus import ( "context" "fmt" + "net/http" "strings" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" @@ -14,6 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/argus" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate" @@ -208,6 +210,11 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, userName := model.Username.ValueString() _, err := r.client.GetCredentials(ctx, instanceId, projectId, userName).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading credential", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/argus/instance/datasource.go b/stackit/internal/services/argus/instance/datasource.go index a38eca7f..0f134d3e 100644 --- a/stackit/internal/services/argus/instance/datasource.go +++ b/stackit/internal/services/argus/instance/datasource.go @@ -3,6 +3,7 @@ package argus import ( "context" "fmt" + "net/http" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/datasource" @@ -11,7 +12,9 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/argus" + "github.com/stackitcloud/stackit-sdk-go/services/argus/wait" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate" ) @@ -215,11 +218,20 @@ func (d *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques } projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() - instanceResponse, err := d.client.GetInstance(ctx, instanceId, projectId).Execute() + instanceResp, err := d.client.GetInstance(ctx, instanceId, projectId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", fmt.Sprintf("Calling API: %v", err)) return } + if instanceResp != nil && instanceResp.Status != nil && *instanceResp.Status == wait.DeleteSuccess { + resp.State.RemoveResource(ctx) + core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", "Instance was deleted successfully") + return + } aclList, err := d.client.ListACL(ctx, instanceId, projectId).Execute() if err != nil { @@ -228,7 +240,7 @@ func (d *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques } // Map response body to schema - err = mapFields(ctx, instanceResponse, &model) + err = mapFields(ctx, instanceResp, &model) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", fmt.Sprintf("Processing API payload: %v", err)) return diff --git a/stackit/internal/services/argus/instance/resource.go b/stackit/internal/services/argus/instance/resource.go index 15ceb7fa..7641a3a8 100644 --- a/stackit/internal/services/argus/instance/resource.go +++ b/stackit/internal/services/argus/instance/resource.go @@ -3,6 +3,7 @@ package argus import ( "context" "fmt" + "net/http" "strings" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" @@ -18,6 +19,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/core/utils" "github.com/stackitcloud/stackit-sdk-go/services/argus" "github.com/stackitcloud/stackit-sdk-go/services/argus/wait" @@ -370,9 +372,18 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r instanceResp, err := r.client.GetInstance(ctx, instanceId, projectId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", fmt.Sprintf("Calling API: %v", err)) return } + if instanceResp != nil && instanceResp.Status != nil && *instanceResp.Status == wait.DeleteSuccess { + resp.State.RemoveResource(ctx) + return + } aclList, err := r.client.ListACL(ctx, instanceId, projectId).Execute() if err != nil { diff --git a/stackit/internal/services/argus/scrapeconfig/datasource.go b/stackit/internal/services/argus/scrapeconfig/datasource.go index fd9937fb..6e26e7a9 100644 --- a/stackit/internal/services/argus/scrapeconfig/datasource.go +++ b/stackit/internal/services/argus/scrapeconfig/datasource.go @@ -3,6 +3,7 @@ package argus import ( "context" "fmt" + "net/http" "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" @@ -14,6 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/argus" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate" @@ -212,6 +214,10 @@ func (d *scrapeConfigDataSource) Read(ctx context.Context, req datasource.ReadRe scResp, err := d.client.GetScrapeConfig(ctx, instanceId, scName, projectId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + } core.LogAndAddError(ctx, &resp.Diagnostics, "Unable to read scrape config", err.Error()) return } diff --git a/stackit/internal/services/argus/scrapeconfig/resource.go b/stackit/internal/services/argus/scrapeconfig/resource.go index 80b0bd20..7275c37f 100644 --- a/stackit/internal/services/argus/scrapeconfig/resource.go +++ b/stackit/internal/services/argus/scrapeconfig/resource.go @@ -3,6 +3,7 @@ package argus import ( "context" "fmt" + "net/http" "strings" "time" @@ -24,6 +25,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/core/utils" "github.com/stackitcloud/stackit-sdk-go/services/argus" "github.com/stackitcloud/stackit-sdk-go/services/argus/wait" @@ -351,6 +353,11 @@ func (r *scrapeConfigResource) Read(ctx context.Context, req resource.ReadReques scResp, err := r.client.GetScrapeConfig(ctx, instanceId, scName, projectId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading scrape config", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/dns/recordset/datasource.go b/stackit/internal/services/dns/recordset/datasource.go index 1356dd41..ca2ffbe5 100644 --- a/stackit/internal/services/dns/recordset/datasource.go +++ b/stackit/internal/services/dns/recordset/datasource.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/stackit-sdk-go/core/config" "github.com/stackitcloud/stackit-sdk-go/services/dns" + "github.com/stackitcloud/stackit-sdk-go/services/dns/wait" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate" ) @@ -158,13 +159,18 @@ func (d *recordSetDataSource) Read(ctx context.Context, req datasource.ReadReque ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "zone_id", zoneId) ctx = tflog.SetField(ctx, "record_set_id", recordSetId) - zoneResp, err := d.client.GetRecordSet(ctx, projectId, zoneId, recordSetId).Execute() + recordSetResp, err := d.client.GetRecordSet(ctx, projectId, zoneId, recordSetId).Execute() if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading record set", fmt.Sprintf("Calling API: %v", err)) return } + if recordSetResp != nil && recordSetResp.Rrset.State != nil && *recordSetResp.Rrset.State == wait.DeleteSuccess { + resp.State.RemoveResource(ctx) + core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading record set", "Record set was deleted successfully") + return + } - err = mapFields(ctx, zoneResp, &model) + err = mapFields(ctx, recordSetResp, &model) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading record set", fmt.Sprintf("Processing API payload: %v", err)) return diff --git a/stackit/internal/services/dns/recordset/resource.go b/stackit/internal/services/dns/recordset/resource.go index 90ca3c36..8b047046 100644 --- a/stackit/internal/services/dns/recordset/resource.go +++ b/stackit/internal/services/dns/recordset/resource.go @@ -282,6 +282,10 @@ func (r *recordSetResource) Read(ctx context.Context, req resource.ReadRequest, core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading record set", fmt.Sprintf("Calling API: %v", err)) return } + if recordSetResp != nil && recordSetResp.Rrset.State != nil && *recordSetResp.Rrset.State == wait.DeleteSuccess { + resp.State.RemoveResource(ctx) + return + } // Map response body to schema err = mapFields(ctx, recordSetResp, &model) diff --git a/stackit/internal/services/dns/zone/datasource.go b/stackit/internal/services/dns/zone/datasource.go index 045a7598..99e23714 100644 --- a/stackit/internal/services/dns/zone/datasource.go +++ b/stackit/internal/services/dns/zone/datasource.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/stackit-sdk-go/core/config" "github.com/stackitcloud/stackit-sdk-go/services/dns" + "github.com/stackitcloud/stackit-sdk-go/services/dns/wait" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate" ) @@ -193,6 +194,11 @@ func (d *zoneDataSource) Read(ctx context.Context, req datasource.ReadRequest, r core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading zone", fmt.Sprintf("Calling API: %v", err)) return } + if zoneResp != nil && zoneResp.Zone.State != nil && *zoneResp.Zone.State == wait.DeleteSuccess { + resp.State.RemoveResource(ctx) + core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading zone", "Zone was deleted successfully") + return + } err = mapFields(ctx, zoneResp, &model) if err != nil { diff --git a/stackit/internal/services/dns/zone/resource.go b/stackit/internal/services/dns/zone/resource.go index cd994af8..58b9528f 100644 --- a/stackit/internal/services/dns/zone/resource.go +++ b/stackit/internal/services/dns/zone/resource.go @@ -361,6 +361,10 @@ func (r *zoneResource) Read(ctx context.Context, req resource.ReadRequest, resp core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading zone", fmt.Sprintf("Calling API: %v", err)) return } + if zoneResp != nil && zoneResp.Zone.State != nil && *zoneResp.Zone.State == wait.DeleteSuccess { + resp.State.RemoveResource(ctx) + return + } // Map response body to schema err = mapFields(ctx, zoneResp, &model) diff --git a/stackit/internal/services/mongodbflex/instance/datasource.go b/stackit/internal/services/mongodbflex/instance/datasource.go index fdc848be..15ab6072 100644 --- a/stackit/internal/services/mongodbflex/instance/datasource.go +++ b/stackit/internal/services/mongodbflex/instance/datasource.go @@ -3,6 +3,7 @@ package mongodbflex import ( "context" "fmt" + "net/http" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -14,6 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/mongodbflex" ) @@ -184,6 +186,10 @@ func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques ctx = tflog.SetField(ctx, "instance_id", instanceId) instanceResp, err := r.client.GetInstance(ctx, projectId, instanceId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/mongodbflex/instance/resource.go b/stackit/internal/services/mongodbflex/instance/resource.go index 63e5aa78..ae3385b4 100644 --- a/stackit/internal/services/mongodbflex/instance/resource.go +++ b/stackit/internal/services/mongodbflex/instance/resource.go @@ -3,6 +3,7 @@ package mongodbflex import ( "context" "fmt" + "net/http" "regexp" "strings" @@ -24,6 +25,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/mongodbflex" "github.com/stackitcloud/stackit-sdk-go/services/mongodbflex/wait" ) @@ -384,6 +386,11 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r instanceResp, err := r.client.GetInstance(ctx, projectId, instanceId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", err.Error()) return } diff --git a/stackit/internal/services/mongodbflex/user/datasource.go b/stackit/internal/services/mongodbflex/user/datasource.go index 74f46e23..b187a415 100644 --- a/stackit/internal/services/mongodbflex/user/datasource.go +++ b/stackit/internal/services/mongodbflex/user/datasource.go @@ -3,6 +3,7 @@ package mongodbflex import ( "context" "fmt" + "net/http" "strings" "github.com/hashicorp/terraform-plugin-framework/attr" @@ -15,6 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/mongodbflex" ) @@ -163,6 +165,10 @@ func (r *userDataSource) Read(ctx context.Context, req datasource.ReadRequest, r recordSetResp, err := r.client.GetUser(ctx, projectId, instanceId, userId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading user", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/mongodbflex/user/resource.go b/stackit/internal/services/mongodbflex/user/resource.go index 202b30b0..3f907600 100644 --- a/stackit/internal/services/mongodbflex/user/resource.go +++ b/stackit/internal/services/mongodbflex/user/resource.go @@ -3,6 +3,7 @@ package mongodbflex import ( "context" "fmt" + "net/http" "strings" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" @@ -21,6 +22,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/mongodbflex" ) @@ -261,6 +263,11 @@ func (r *userResource) Read(ctx context.Context, req resource.ReadRequest, resp recordSetResp, err := r.client.GetUser(ctx, projectId, instanceId, userId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading user", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/objectstorage/bucket/datasource.go b/stackit/internal/services/objectstorage/bucket/datasource.go index 72c61313..f2790d01 100644 --- a/stackit/internal/services/objectstorage/bucket/datasource.go +++ b/stackit/internal/services/objectstorage/bucket/datasource.go @@ -3,6 +3,7 @@ package objectstorage import ( "context" "fmt" + "net/http" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -12,6 +13,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/objectstorage" ) @@ -129,6 +131,10 @@ func (r *bucketDataSource) Read(ctx context.Context, req datasource.ReadRequest, bucketResp, err := r.client.GetBucket(ctx, projectId, bucketName).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading bucket", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/objectstorage/bucket/resource.go b/stackit/internal/services/objectstorage/bucket/resource.go index 1f1e0df5..284edbb1 100644 --- a/stackit/internal/services/objectstorage/bucket/resource.go +++ b/stackit/internal/services/objectstorage/bucket/resource.go @@ -3,6 +3,7 @@ package objectstorage import ( "context" "fmt" + "net/http" "strings" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -17,6 +18,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/objectstorage" "github.com/stackitcloud/stackit-sdk-go/services/objectstorage/wait" ) @@ -203,6 +205,11 @@ func (r *bucketResource) Read(ctx context.Context, req resource.ReadRequest, res bucketResp, err := r.client.GetBucket(ctx, projectId, bucketName).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading bucket", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/objectstorage/credential/datasource.go b/stackit/internal/services/objectstorage/credential/datasource.go index 6e6ebfa9..a99b7d00 100644 --- a/stackit/internal/services/objectstorage/credential/datasource.go +++ b/stackit/internal/services/objectstorage/credential/datasource.go @@ -131,11 +131,16 @@ func (r *credentialDataSource) Read(ctx context.Context, req datasource.ReadRequ ctx = tflog.SetField(ctx, "credentials_group_id", credentialsGroupId) ctx = tflog.SetField(ctx, "credential_id", credentialId) - err := readCredentials(ctx, &model, r.client) + found, err := readCredentials(ctx, &model, r.client) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading credential", fmt.Sprintf("Finding credential: %v", err)) return } + if !found { + resp.State.RemoveResource(ctx) + core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading credential", "Credential not found") + return + } // Set refreshed state diags = resp.State.Set(ctx, model) diff --git a/stackit/internal/services/objectstorage/credential/resource.go b/stackit/internal/services/objectstorage/credential/resource.go index 05fd0062..8172ab5f 100644 --- a/stackit/internal/services/objectstorage/credential/resource.go +++ b/stackit/internal/services/objectstorage/credential/resource.go @@ -240,11 +240,15 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, ctx = tflog.SetField(ctx, "credentials_group_id", credentialsGroupId) ctx = tflog.SetField(ctx, "credential_id", credentialId) - err := readCredentials(ctx, &model, r.client) + found, err := readCredentials(ctx, &model, r.client) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading credential", fmt.Sprintf("Finding credential: %v", err)) return } + if !found { + resp.State.RemoveResource(ctx) + return + } // Set refreshed state diags = resp.State.Set(ctx, model) @@ -388,18 +392,18 @@ func mapFields(credentialResp *objectstorage.CreateAccessKeyResponse, model *Mod // readCredentials gets all the existing credentials for the specified credentials group, // finds the credential that is being read and updates the state. -// If the credential cannot be found, it throws an error -func readCredentials(ctx context.Context, model *Model, client *objectstorage.APIClient) error { +// Returns True if the credential was found, False otherwise. +func readCredentials(ctx context.Context, model *Model, client *objectstorage.APIClient) (bool, error) { projectId := model.ProjectId.ValueString() credentialsGroupId := model.CredentialsGroupId.ValueString() credentialId := model.CredentialId.ValueString() credentialsGroupResp, err := client.ListAccessKeys(ctx, projectId).CredentialsGroup(credentialsGroupId).Execute() if err != nil { - return fmt.Errorf("getting credentials groups: %w", err) + return false, fmt.Errorf("getting credentials groups: %w", err) } if credentialsGroupResp == nil { - return fmt.Errorf("getting credentials groups: nil response") + return false, fmt.Errorf("getting credentials groups: nil response") } foundCredential := false @@ -427,15 +431,12 @@ func readCredentials(ctx context.Context, model *Model, client *objectstorage.AP // Eg. "2027-01-02T03:04:05.000Z" = "2027-01-02T03:04:05Z" expirationTimestamp, err := time.Parse(time.RFC3339, *credential.Expires) if err != nil { - return fmt.Errorf("unable to parse payload expiration timestamp '%v': %w", *credential.Expires, err) + return foundCredential, fmt.Errorf("unable to parse payload expiration timestamp '%v': %w", *credential.Expires, err) } model.ExpirationTimestamp = types.StringValue(expirationTimestamp.Format(time.RFC3339)) } break } - if !foundCredential { - return fmt.Errorf("credential could not be found") - } - return nil + return foundCredential, nil } diff --git a/stackit/internal/services/objectstorage/credential/resource_test.go b/stackit/internal/services/objectstorage/credential/resource_test.go index fd816de7..54c9cb0c 100644 --- a/stackit/internal/services/objectstorage/credential/resource_test.go +++ b/stackit/internal/services/objectstorage/credential/resource_test.go @@ -213,7 +213,8 @@ func TestReadCredentials(t *testing.T) { tests := []struct { description string mockedResp *objectstorage.ListAccessKeysResponse - expected Model + expectedModel Model + expectedFound bool getCredentialsFails bool isValid bool }{ @@ -242,6 +243,7 @@ func TestReadCredentials(t *testing.T) { SecretAccessKey: types.StringNull(), ExpirationTimestamp: types.StringNull(), }, + true, false, true, }, @@ -276,6 +278,7 @@ func TestReadCredentials(t *testing.T) { SecretAccessKey: types.StringNull(), ExpirationTimestamp: types.StringValue(now.Format(time.RFC3339)), }, + true, false, true, }, @@ -310,6 +313,7 @@ func TestReadCredentials(t *testing.T) { SecretAccessKey: types.StringNull(), ExpirationTimestamp: types.StringValue(now.Format(time.RFC3339)), }, + true, false, true, }, @@ -321,6 +325,7 @@ func TestReadCredentials(t *testing.T) { Model{}, false, false, + true, }, { "nil_response", @@ -328,6 +333,7 @@ func TestReadCredentials(t *testing.T) { Model{}, false, false, + false, }, { "non_matching_credential", @@ -348,6 +354,7 @@ func TestReadCredentials(t *testing.T) { Model{}, false, false, + true, }, { "error_response", @@ -361,6 +368,7 @@ func TestReadCredentials(t *testing.T) { }, }, Model{}, + false, true, false, }, @@ -401,11 +409,11 @@ func TestReadCredentials(t *testing.T) { } model := &Model{ - ProjectId: tt.expected.ProjectId, - CredentialsGroupId: tt.expected.CredentialsGroupId, - CredentialId: tt.expected.CredentialId, + ProjectId: tt.expectedModel.ProjectId, + CredentialsGroupId: tt.expectedModel.CredentialsGroupId, + CredentialId: tt.expectedModel.CredentialId, } - err = readCredentials(context.Background(), model, client) + found, err := readCredentials(context.Background(), model, client) if !tt.isValid && err == nil { t.Fatalf("Should have failed") } @@ -413,10 +421,14 @@ func TestReadCredentials(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(model, &tt.expected) + diff := cmp.Diff(model, &tt.expectedModel) if diff != "" { t.Fatalf("Data does not match: %s", diff) } + + if found != tt.expectedFound { + t.Fatalf("Found does not match: %v", found) + } } }) } diff --git a/stackit/internal/services/objectstorage/credentialsgroup/datasource.go b/stackit/internal/services/objectstorage/credentialsgroup/datasource.go index 3ed6d675..77fc2a51 100644 --- a/stackit/internal/services/objectstorage/credentialsgroup/datasource.go +++ b/stackit/internal/services/objectstorage/credentialsgroup/datasource.go @@ -128,9 +128,14 @@ func (r *credentialsGroupDataSource) Read(ctx context.Context, req datasource.Re ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "credentials_group_id", credentialsGroupId) - err := readCredentialsGroups(ctx, &model, r.client) + found, err := readCredentialsGroups(ctx, &model, r.client) if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading credentialsGroup", fmt.Sprintf("getting credential group from list of credentials groups: %v", err)) + core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading credentials group", fmt.Sprintf("getting credential group from list of credentials groups: %v", err)) + return + } + if !found { + resp.State.RemoveResource(ctx) + core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading credentials group", "Credentials group not found") return } diff --git a/stackit/internal/services/objectstorage/credentialsgroup/resource.go b/stackit/internal/services/objectstorage/credentialsgroup/resource.go index 7a30ab7f..5840f6be 100644 --- a/stackit/internal/services/objectstorage/credentialsgroup/resource.go +++ b/stackit/internal/services/objectstorage/credentialsgroup/resource.go @@ -198,11 +198,15 @@ func (r *credentialsGroupResource) Read(ctx context.Context, req resource.ReadRe ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "credentials_group_id", credentialsGroupId) - err := readCredentialsGroups(ctx, &model, r.client) + found, err := readCredentialsGroups(ctx, &model, r.client) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading credentialsGroup", fmt.Sprintf("getting credential group from list of credentials groups: %v", err)) return } + if !found { + resp.State.RemoveResource(ctx) + return + } // Set refreshed state diags = resp.State.Set(ctx, model) @@ -318,21 +322,22 @@ func enableProject(ctx context.Context, model *Model, client objectStorageClient } // readCredentialsGroups gets all the existing credentials groups for the specified project, -// finds the credentials group that is being read and updates the state. If the credentials group cannot be found, it throws an error -func readCredentialsGroups(ctx context.Context, model *Model, client objectStorageClient) error { +// finds the credentials group that is being read and updates the state. +// Returns True if the credential was found, False otherwise. +func readCredentialsGroups(ctx context.Context, model *Model, client objectStorageClient) (bool, error) { found := false if model.CredentialsGroupId.ValueString() == "" && model.Name.ValueString() == "" { - return fmt.Errorf("missing configuration: either name or credentials group id must be provided") + return found, fmt.Errorf("missing configuration: either name or credentials group id must be provided") } credentialsGroupsResp, err := client.ListCredentialsGroupsExecute(ctx, model.ProjectId.ValueString()) if err != nil { - return fmt.Errorf("getting credentials groups: %w", err) + return found, fmt.Errorf("getting credentials groups: %w", err) } if credentialsGroupsResp == nil { - return fmt.Errorf("nil response from GET credentials groups") + return found, fmt.Errorf("nil response from GET credentials groups") } for _, credentialsGroup := range *credentialsGroupsResp.CredentialsGroups { @@ -342,14 +347,10 @@ func readCredentialsGroups(ctx context.Context, model *Model, client objectStora found = true err = mapCredentialsGroup(credentialsGroup, model) if err != nil { - return err + return found, err } break } - if !found { - return fmt.Errorf("credentials group could not be found") - } - - return nil + return found, nil } diff --git a/stackit/internal/services/objectstorage/credentialsgroup/resource_test.go b/stackit/internal/services/objectstorage/credentialsgroup/resource_test.go index e8ba3806..3d718bf7 100644 --- a/stackit/internal/services/objectstorage/credentialsgroup/resource_test.go +++ b/stackit/internal/services/objectstorage/credentialsgroup/resource_test.go @@ -162,7 +162,8 @@ func TestReadCredentialsGroups(t *testing.T) { tests := []struct { description string mockedResp *objectstorage.ListCredentialsGroupsResponse - expected Model + expectedModel Model + expectedFound bool getCredentialsGroupsFails bool isValid bool }{ @@ -185,6 +186,7 @@ func TestReadCredentialsGroups(t *testing.T) { CredentialsGroupId: types.StringValue("cid"), URN: types.StringNull(), }, + true, false, true, }, @@ -211,6 +213,7 @@ func TestReadCredentialsGroups(t *testing.T) { CredentialsGroupId: types.StringValue("cid"), URN: types.StringValue("urn"), }, + true, false, true, }, @@ -222,6 +225,7 @@ func TestReadCredentialsGroups(t *testing.T) { Model{}, false, false, + false, }, { "nil_credentials_groups", @@ -231,6 +235,7 @@ func TestReadCredentialsGroups(t *testing.T) { Model{}, false, false, + false, }, { "nil_response", @@ -238,6 +243,7 @@ func TestReadCredentialsGroups(t *testing.T) { Model{}, false, false, + false, }, { "non_matching_credentials_group", @@ -253,6 +259,7 @@ func TestReadCredentialsGroups(t *testing.T) { Model{}, false, false, + false, }, { "error_response", @@ -266,6 +273,7 @@ func TestReadCredentialsGroups(t *testing.T) { }, }, Model{}, + false, true, false, }, @@ -277,10 +285,10 @@ func TestReadCredentialsGroups(t *testing.T) { listCredentialsGroupsResp: tt.mockedResp, } model := &Model{ - ProjectId: tt.expected.ProjectId, - CredentialsGroupId: tt.expected.CredentialsGroupId, + ProjectId: tt.expectedModel.ProjectId, + CredentialsGroupId: tt.expectedModel.CredentialsGroupId, } - err := readCredentialsGroups(context.Background(), model, client) + found, err := readCredentialsGroups(context.Background(), model, client) if !tt.isValid && err == nil { t.Fatalf("Should have failed") } @@ -288,10 +296,14 @@ func TestReadCredentialsGroups(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(model, &tt.expected) + diff := cmp.Diff(model, &tt.expectedModel) if diff != "" { t.Fatalf("Data does not match: %s", diff) } + + if found != tt.expectedFound { + t.Fatalf("Found does not match") + } } }) } diff --git a/stackit/internal/services/postgresflex/instance/datasource.go b/stackit/internal/services/postgresflex/instance/datasource.go index c40e9038..d9546735 100644 --- a/stackit/internal/services/postgresflex/instance/datasource.go +++ b/stackit/internal/services/postgresflex/instance/datasource.go @@ -3,6 +3,7 @@ package postgresflex import ( "context" "fmt" + "net/http" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -14,7 +15,9 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" + "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/wait" ) // Ensure the implementation satisfies the expected interfaces. @@ -172,9 +175,18 @@ func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques ctx = tflog.SetField(ctx, "instance_id", instanceId) instanceResp, err := r.client.GetInstance(ctx, projectId, instanceId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", fmt.Sprintf("Calling API: %v", err)) return } + if instanceResp != nil && instanceResp.Item != nil && instanceResp.Item.Status != nil && *instanceResp.Item.Status == wait.InstanceStateDeleted { + resp.State.RemoveResource(ctx) + core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", "Instance was deleted successfully") + return + } var flavor = &flavorModel{} if !(model.Flavor.IsNull() || model.Flavor.IsUnknown()) { diff --git a/stackit/internal/services/postgresflex/instance/resource.go b/stackit/internal/services/postgresflex/instance/resource.go index bc87f8d2..82119366 100644 --- a/stackit/internal/services/postgresflex/instance/resource.go +++ b/stackit/internal/services/postgresflex/instance/resource.go @@ -3,6 +3,7 @@ package postgresflex import ( "context" "fmt" + "net/http" "regexp" "strings" "time" @@ -25,6 +26,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/wait" ) @@ -344,9 +346,18 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r instanceResp, err := r.client.GetInstance(ctx, projectId, instanceId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", err.Error()) return } + if instanceResp != nil && instanceResp.Item != nil && instanceResp.Item.Status != nil && *instanceResp.Item.Status == wait.InstanceStateDeleted { + resp.State.RemoveResource(ctx) + return + } // Map response body to schema err = mapFields(ctx, instanceResp, &model, flavor, storage) diff --git a/stackit/internal/services/postgresflex/user/datasource.go b/stackit/internal/services/postgresflex/user/datasource.go index df5a7689..0258878f 100644 --- a/stackit/internal/services/postgresflex/user/datasource.go +++ b/stackit/internal/services/postgresflex/user/datasource.go @@ -3,6 +3,7 @@ package postgresflex import ( "context" "fmt" + "net/http" "strings" "github.com/hashicorp/terraform-plugin-framework/attr" @@ -15,6 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" ) @@ -159,6 +161,10 @@ func (r *userDataSource) Read(ctx context.Context, req datasource.ReadRequest, r recordSetResp, err := r.client.GetUser(ctx, projectId, instanceId, userId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading user", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/postgresflex/user/resource.go b/stackit/internal/services/postgresflex/user/resource.go index b663c973..594f5f25 100644 --- a/stackit/internal/services/postgresflex/user/resource.go +++ b/stackit/internal/services/postgresflex/user/resource.go @@ -3,6 +3,7 @@ package postgresflex import ( "context" "fmt" + "net/http" "strings" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" @@ -22,6 +23,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/postgresflex" "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/wait" ) @@ -255,6 +257,11 @@ func (r *userResource) Read(ctx context.Context, req resource.ReadRequest, resp recordSetResp, err := r.client.GetUser(ctx, projectId, instanceId, userId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading user", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/resourcemanager/project/datasource.go b/stackit/internal/services/resourcemanager/project/datasource.go index fc6de657..d12d05f9 100644 --- a/stackit/internal/services/resourcemanager/project/datasource.go +++ b/stackit/internal/services/resourcemanager/project/datasource.go @@ -3,6 +3,7 @@ package project import ( "context" "fmt" + "net/http" "regexp" "github.com/hashicorp/terraform-plugin-framework-validators/mapvalidator" @@ -18,6 +19,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/resourcemanager" ) @@ -183,6 +185,10 @@ func (d *projectDataSource) Read(ctx context.Context, req datasource.ReadRequest projectResp, err := d.client.GetProject(ctx, identifier).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusForbidden { + resp.State.RemoveResource(ctx) + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading project", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/resourcemanager/project/resource.go b/stackit/internal/services/resourcemanager/project/resource.go index 68219f31..42baf07a 100644 --- a/stackit/internal/services/resourcemanager/project/resource.go +++ b/stackit/internal/services/resourcemanager/project/resource.go @@ -3,6 +3,7 @@ package project import ( "context" "fmt" + "net/http" "regexp" "strings" @@ -23,6 +24,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/resourcemanager" "github.com/stackitcloud/stackit-sdk-go/services/resourcemanager/wait" ) @@ -252,6 +254,11 @@ func (r *projectResource) Read(ctx context.Context, req resource.ReadRequest, re projectResp, err := r.client.GetProject(ctx, containerId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusForbidden { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading project", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/secretsmanager/instance/datasource.go b/stackit/internal/services/secretsmanager/instance/datasource.go index 328e5c8a..4d9db0c7 100644 --- a/stackit/internal/services/secretsmanager/instance/datasource.go +++ b/stackit/internal/services/secretsmanager/instance/datasource.go @@ -3,6 +3,7 @@ package secretsmanager import ( "context" "fmt" + "net/http" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -13,6 +14,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/secretsmanager" ) @@ -134,6 +136,10 @@ func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques instanceResp, err := r.client.GetInstance(ctx, projectId, instanceId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/secretsmanager/instance/resource.go b/stackit/internal/services/secretsmanager/instance/resource.go index 32d559ff..2d3278e4 100644 --- a/stackit/internal/services/secretsmanager/instance/resource.go +++ b/stackit/internal/services/secretsmanager/instance/resource.go @@ -3,6 +3,7 @@ package secretsmanager import ( "context" "fmt" + "net/http" "strings" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" @@ -21,6 +22,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/core/utils" "github.com/stackitcloud/stackit-sdk-go/services/secretsmanager" ) @@ -236,6 +238,11 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r instanceResp, err := r.client.GetInstance(ctx, projectId, instanceId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/secretsmanager/user/datasource.go b/stackit/internal/services/secretsmanager/user/datasource.go index f3d6c602..c40daef0 100644 --- a/stackit/internal/services/secretsmanager/user/datasource.go +++ b/stackit/internal/services/secretsmanager/user/datasource.go @@ -3,6 +3,7 @@ package secretsmanager import ( "context" "fmt" + "net/http" "strings" "github.com/hashicorp/terraform-plugin-framework/datasource" @@ -14,6 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/secretsmanager" ) @@ -160,6 +162,10 @@ func (r *userDataSource) Read(ctx context.Context, req datasource.ReadRequest, r userResp, err := r.client.GetUser(ctx, projectId, instanceId, userId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading user", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/secretsmanager/user/resource.go b/stackit/internal/services/secretsmanager/user/resource.go index ad1bbb54..c6c43d5c 100644 --- a/stackit/internal/services/secretsmanager/user/resource.go +++ b/stackit/internal/services/secretsmanager/user/resource.go @@ -3,6 +3,7 @@ package secretsmanager import ( "context" "fmt" + "net/http" "strings" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -18,6 +19,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/stackitcloud/stackit-sdk-go/core/config" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/secretsmanager" ) @@ -234,6 +236,11 @@ func (r *userResource) Read(ctx context.Context, req resource.ReadRequest, resp userResp, err := r.client.GetUser(ctx, projectId, instanceId, userId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading user", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/ske/cluster/datasource.go b/stackit/internal/services/ske/cluster/datasource.go index c717cc55..795b814a 100644 --- a/stackit/internal/services/ske/cluster/datasource.go +++ b/stackit/internal/services/ske/cluster/datasource.go @@ -296,6 +296,10 @@ func (r *clusterDataSource) Read(ctx context.Context, req datasource.ReadRequest ctx = tflog.SetField(ctx, "name", name) clusterResp, err := r.client.GetCluster(ctx, projectId, name).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading cluster", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/ske/cluster/resource.go b/stackit/internal/services/ske/cluster/resource.go index f2194ca6..2a5330f2 100644 --- a/stackit/internal/services/ske/cluster/resource.go +++ b/stackit/internal/services/ske/cluster/resource.go @@ -1403,6 +1403,11 @@ func (r *clusterResource) Read(ctx context.Context, req resource.ReadRequest, re clResp, err := r.client.GetCluster(ctx, projectId, name).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped + if ok && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading cluster", fmt.Sprintf("Calling API: %v", err)) return }