From 94850ceb23aebd767d14f477a7fae1b2c8ac9a1c Mon Sep 17 00:00:00 2001 From: Dominik Pildner Date: Wed, 18 Mar 2026 07:43:24 +0100 Subject: [PATCH 1/5] fix: handle missing resource ID in Read and graceful delete for non-existing resources --- .../services/authorization/customrole/resource.go | 9 ++++++++- .../internal/services/cdn/distribution/resource.go | 5 +++++ stackit/internal/services/dns/recordset/resource.go | 12 ++++++++++++ stackit/internal/services/dns/zone/resource.go | 5 +++++ .../internal/services/edgecloud/instance/resource.go | 5 +++++ stackit/internal/services/git/instance/resource.go | 5 +++++ .../internal/services/iaas/affinitygroup/resource.go | 5 +++++ stackit/internal/services/iaas/image/resource.go | 5 +++++ stackit/internal/services/iaas/network/resource.go | 5 +++++ .../internal/services/iaas/networkarea/resource.go | 5 +++++ .../services/iaas/networkarearegion/resource.go | 4 ++++ .../services/iaas/networkarearoute/resource.go | 9 +++++++++ .../services/iaas/networkinterface/resource.go | 9 +++++++++ .../services/iaas/networkinterfaceattach/resource.go | 4 ++++ stackit/internal/services/iaas/publicip/resource.go | 5 +++++ .../services/iaas/routingtable/route/resource.go | 5 +++++ .../services/iaas/routingtable/table/resource.go | 5 +++++ .../internal/services/iaas/securitygroup/resource.go | 5 +++++ .../services/iaas/securitygrouprule/resource.go | 5 +++++ stackit/internal/services/iaas/server/resource.go | 5 +++++ stackit/internal/services/iaas/volume/resource.go | 5 +++++ .../internal/services/iaas/volumeattach/resource.go | 4 ++++ stackit/internal/services/kms/key/resource.go | 10 ++++++++++ stackit/internal/services/kms/keyring/resource.go | 5 +++++ .../internal/services/kms/wrapping-key/resource.go | 10 ++++++++++ .../internal/services/logme/credential/resource.go | 10 ++++++++++ stackit/internal/services/logme/instance/resource.go | 5 +++++ .../internal/services/logs/accesstoken/resource.go | 5 +++++ stackit/internal/services/logs/instance/resource.go | 5 +++++ .../internal/services/mariadb/credential/resource.go | 10 ++++++++++ .../internal/services/mariadb/instance/resource.go | 5 +++++ .../internal/services/modelserving/token/resource.go | 5 +++++ .../services/mongodbflex/instance/resource.go | 5 +++++ .../internal/services/mongodbflex/user/resource.go | 9 +++++++++ .../services/objectstorage/credential/resource.go | 10 ++++++++++ .../objectstorage/credentialsgroup/resource.go | 5 +++++ .../services/observability/credential/resource.go | 10 ++++++++++ .../services/observability/instance/resource.go | 5 +++++ .../services/opensearch/credential/resource.go | 10 ++++++++++ .../services/opensearch/instance/resource.go | 5 +++++ .../services/postgresflex/database/resource.go | 10 ++++++++++ .../services/postgresflex/instance/resource.go | 5 +++++ .../internal/services/postgresflex/user/resource.go | 10 ++++++++++ .../services/rabbitmq/credential/resource.go | 10 ++++++++++ .../internal/services/rabbitmq/instance/resource.go | 5 +++++ .../internal/services/redis/credential/resource.go | 10 ++++++++++ stackit/internal/services/redis/instance/resource.go | 5 +++++ .../services/resourcemanager/folder/resource.go | 5 +++++ .../services/resourcemanager/project/resource.go | 5 +++++ .../internal/services/scf/organization/resource.go | 5 +++++ .../services/secretsmanager/instance/resource.go | 5 +++++ .../services/secretsmanager/user/resource.go | 10 ++++++++++ .../services/serverbackup/schedule/resource.go | 5 +++++ .../services/serverupdate/schedule/resource.go | 5 +++++ .../internal/services/serviceaccount/key/resource.go | 9 +++++++++ .../internal/services/sfs/export-policy/resource.go | 5 +++++ .../internal/services/sfs/resourcepool/resource.go | 5 +++++ stackit/internal/services/sfs/share/resource.go | 5 +++++ .../services/sqlserverflex/instance/resource.go | 5 +++++ .../internal/services/sqlserverflex/user/resource.go | 9 +++++++++ 60 files changed, 387 insertions(+), 1 deletion(-) diff --git a/stackit/internal/services/authorization/customrole/resource.go b/stackit/internal/services/authorization/customrole/resource.go index fde1618e3..60447c369 100644 --- a/stackit/internal/services/authorization/customrole/resource.go +++ b/stackit/internal/services/authorization/customrole/resource.go @@ -212,7 +212,14 @@ func (r *customRoleResource) Read(ctx context.Context, req resource.ReadRequest, ctx = r.annotateLogger(ctx, &model) - roleResp, err := r.client.GetRoleExecute(ctx, r.resourceType, model.ResourceId.ValueString(), model.RoleId.ValueString()) + roleId := model.RoleId.ValueString() + if roleId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } + + roleResp, err := r.client.GetRoleExecute(ctx, r.resourceType, model.ResourceId.ValueString(), roleId) if err != nil { var oapiErr *oapierror.GenericOpenAPIError diff --git a/stackit/internal/services/cdn/distribution/resource.go b/stackit/internal/services/cdn/distribution/resource.go index 47e36ffa4..0628fdd76 100644 --- a/stackit/internal/services/cdn/distribution/resource.go +++ b/stackit/internal/services/cdn/distribution/resource.go @@ -479,6 +479,11 @@ func (r *distributionResource) Read(ctx context.Context, req resource.ReadReques projectId := model.ProjectId.ValueString() distributionId := model.DistributionId.ValueString() + if distributionId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "distribution_id", distributionId) diff --git a/stackit/internal/services/dns/recordset/resource.go b/stackit/internal/services/dns/recordset/resource.go index badf20bf2..2c9e8962b 100644 --- a/stackit/internal/services/dns/recordset/resource.go +++ b/stackit/internal/services/dns/recordset/resource.go @@ -3,6 +3,7 @@ package dns import ( "context" "fmt" + "net/http" "strings" "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" @@ -16,6 +17,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "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/conversion" @@ -267,6 +269,11 @@ func (r *recordSetResource) Read(ctx context.Context, req resource.ReadRequest, projectId := model.ProjectId.ValueString() zoneId := model.ZoneId.ValueString() recordSetId := model.RecordSetId.ValueString() + if recordSetId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "zone_id", zoneId) ctx = tflog.SetField(ctx, "record_set_id", recordSetId) @@ -374,7 +381,12 @@ func (r *recordSetResource) Delete(ctx context.Context, req resource.DeleteReque // Delete existing record set _, err := r.client.DeleteRecordSet(ctx, projectId, zoneId, recordSetId).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting record set", fmt.Sprintf("Calling API: %v", err)) + return } ctx = core.LogResponse(ctx) diff --git a/stackit/internal/services/dns/zone/resource.go b/stackit/internal/services/dns/zone/resource.go index ce82f22f1..f4c9037bc 100644 --- a/stackit/internal/services/dns/zone/resource.go +++ b/stackit/internal/services/dns/zone/resource.go @@ -355,6 +355,11 @@ func (r *zoneResource) Read(ctx context.Context, req resource.ReadRequest, resp projectId := model.ProjectId.ValueString() zoneId := model.ZoneId.ValueString() + if zoneId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "zone_id", zoneId) diff --git a/stackit/internal/services/edgecloud/instance/resource.go b/stackit/internal/services/edgecloud/instance/resource.go index 8a90cda18..b1f9f6143 100644 --- a/stackit/internal/services/edgecloud/instance/resource.go +++ b/stackit/internal/services/edgecloud/instance/resource.go @@ -321,6 +321,11 @@ func (i *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() region := i.providerData.GetRegionWithOverride(model.Region) instanceId := model.InstanceId.ValueString() + if instanceId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) ctx = tflog.SetField(ctx, "region", region) diff --git a/stackit/internal/services/git/instance/resource.go b/stackit/internal/services/git/instance/resource.go index eca38f669..43a870f0e 100644 --- a/stackit/internal/services/git/instance/resource.go +++ b/stackit/internal/services/git/instance/resource.go @@ -270,6 +270,11 @@ func (g *gitResource) Read(ctx context.Context, req resource.ReadRequest, resp * // Extract the project ID and instance id of the model projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() + if instanceId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } // Read the current git instance via id gitInstanceResp, err := g.client.GetInstance(ctx, projectId, instanceId).Execute() diff --git a/stackit/internal/services/iaas/affinitygroup/resource.go b/stackit/internal/services/iaas/affinitygroup/resource.go index 726ac8eeb..0aa64cd54 100644 --- a/stackit/internal/services/iaas/affinitygroup/resource.go +++ b/stackit/internal/services/iaas/affinitygroup/resource.go @@ -245,6 +245,11 @@ func (r *affinityGroupResource) Read(ctx context.Context, req resource.ReadReque projectId := model.ProjectId.ValueString() region := r.providerData.GetRegionWithOverride(model.Region) affinityGroupId := model.AffinityGroupId.ValueString() + if affinityGroupId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = core.InitProviderContext(ctx) diff --git a/stackit/internal/services/iaas/image/resource.go b/stackit/internal/services/iaas/image/resource.go index 7581bd383..47d300f3f 100644 --- a/stackit/internal/services/iaas/image/resource.go +++ b/stackit/internal/services/iaas/image/resource.go @@ -509,6 +509,11 @@ func (r *imageResource) Read(ctx context.Context, req resource.ReadRequest, resp projectId := model.ProjectId.ValueString() region := r.providerData.GetRegionWithOverride(model.Region) imageId := model.ImageId.ValueString() + if imageId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = core.InitProviderContext(ctx) diff --git a/stackit/internal/services/iaas/network/resource.go b/stackit/internal/services/iaas/network/resource.go index 84d91bf2a..f80a9cba9 100644 --- a/stackit/internal/services/iaas/network/resource.go +++ b/stackit/internal/services/iaas/network/resource.go @@ -475,6 +475,11 @@ func (r *networkResource) Read(ctx context.Context, req resource.ReadRequest, re } projectId := model.ProjectId.ValueString() networkId := model.NetworkId.ValueString() + if networkId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "network_id", networkId) diff --git a/stackit/internal/services/iaas/networkarea/resource.go b/stackit/internal/services/iaas/networkarea/resource.go index f88e6b670..986f6b70b 100644 --- a/stackit/internal/services/iaas/networkarea/resource.go +++ b/stackit/internal/services/iaas/networkarea/resource.go @@ -443,6 +443,11 @@ func (r *networkAreaResource) Read(ctx context.Context, req resource.ReadRequest organizationId := model.OrganizationId.ValueString() networkAreaId := model.NetworkAreaId.ValueString() + if networkAreaId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = core.InitProviderContext(ctx) diff --git a/stackit/internal/services/iaas/networkarearegion/resource.go b/stackit/internal/services/iaas/networkarearegion/resource.go index 2207e349d..4ce1aa9e4 100644 --- a/stackit/internal/services/iaas/networkarearegion/resource.go +++ b/stackit/internal/services/iaas/networkarearegion/resource.go @@ -454,6 +454,10 @@ func (r *networkAreaRegionResource) Delete(ctx context.Context, req resource.Del // Delete network area region configuration err = r.client.DeleteNetworkAreaRegion(ctx, organizationId, networkAreaId, region).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting network area region", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/networkarearoute/resource.go b/stackit/internal/services/iaas/networkarearoute/resource.go index 3694312ec..e57084ef8 100644 --- a/stackit/internal/services/iaas/networkarearoute/resource.go +++ b/stackit/internal/services/iaas/networkarearoute/resource.go @@ -406,6 +406,11 @@ func (r *networkAreaRouteResource) Read(ctx context.Context, req resource.ReadRe networkAreaId := model.NetworkAreaId.ValueString() region := r.providerData.GetRegionWithOverride(model.Region) networkAreaRouteId := model.NetworkAreaRouteId.ValueString() + if networkAreaRouteId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = core.InitProviderContext(ctx) @@ -467,6 +472,10 @@ func (r *networkAreaRouteResource) Delete(ctx context.Context, req resource.Dele // Delete existing network err := r.client.DeleteNetworkAreaRoute(ctx, organizationId, networkAreaId, region, networkAreaRouteId).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting network area route", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/networkinterface/resource.go b/stackit/internal/services/iaas/networkinterface/resource.go index 007e17f0c..516ad7a79 100644 --- a/stackit/internal/services/iaas/networkinterface/resource.go +++ b/stackit/internal/services/iaas/networkinterface/resource.go @@ -336,6 +336,11 @@ func (r *networkInterfaceResource) Read(ctx context.Context, req resource.ReadRe region := r.providerData.GetRegionWithOverride(model.Region) networkId := model.NetworkId.ValueString() networkInterfaceId := model.NetworkInterfaceId.ValueString() + if networkInterfaceId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = core.InitProviderContext(ctx) @@ -454,6 +459,10 @@ func (r *networkInterfaceResource) Delete(ctx context.Context, req resource.Dele // Delete existing network interface err := r.client.DeleteNic(ctx, projectId, region, networkId, networkInterfaceId).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting network interface", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/networkinterfaceattach/resource.go b/stackit/internal/services/iaas/networkinterfaceattach/resource.go index 7c7f8c04b..78f57353b 100644 --- a/stackit/internal/services/iaas/networkinterfaceattach/resource.go +++ b/stackit/internal/services/iaas/networkinterfaceattach/resource.go @@ -295,6 +295,10 @@ func (r *networkInterfaceAttachResource) Delete(ctx context.Context, req resourc // Remove network_interface from server err := r.client.RemoveNicFromServer(ctx, projectId, region, serverId, network_interfaceId).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error removing network interface from server", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/publicip/resource.go b/stackit/internal/services/iaas/publicip/resource.go index 0d69eab1d..e9bda8f3b 100644 --- a/stackit/internal/services/iaas/publicip/resource.go +++ b/stackit/internal/services/iaas/publicip/resource.go @@ -239,6 +239,11 @@ func (r *publicIpResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() region := r.providerData.GetRegionWithOverride(model.Region) publicIpId := model.PublicIpId.ValueString() + if publicIpId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = core.InitProviderContext(ctx) diff --git a/stackit/internal/services/iaas/routingtable/route/resource.go b/stackit/internal/services/iaas/routingtable/route/resource.go index 6324b1bce..7a285396b 100644 --- a/stackit/internal/services/iaas/routingtable/route/resource.go +++ b/stackit/internal/services/iaas/routingtable/route/resource.go @@ -301,6 +301,11 @@ func (r *routeResource) Read(ctx context.Context, req resource.ReadRequest, resp routingTableId := model.RoutingTableId.ValueString() networkAreaId := model.NetworkAreaId.ValueString() routeId := model.RouteId.ValueString() + if routeId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "organization_id", organizationId) diff --git a/stackit/internal/services/iaas/routingtable/table/resource.go b/stackit/internal/services/iaas/routingtable/table/resource.go index f891a3839..4d7ac6cd1 100644 --- a/stackit/internal/services/iaas/routingtable/table/resource.go +++ b/stackit/internal/services/iaas/routingtable/table/resource.go @@ -283,6 +283,11 @@ func (r *routingTableResource) Read(ctx context.Context, req resource.ReadReques organizationId := model.OrganizationId.ValueString() routingTableId := model.RoutingTableId.ValueString() + if routingTableId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } networkAreaId := model.NetworkAreaId.ValueString() region := r.providerData.GetRegionWithOverride(model.Region) diff --git a/stackit/internal/services/iaas/securitygroup/resource.go b/stackit/internal/services/iaas/securitygroup/resource.go index 07554fe3a..ea7ede61f 100644 --- a/stackit/internal/services/iaas/securitygroup/resource.go +++ b/stackit/internal/services/iaas/securitygroup/resource.go @@ -258,6 +258,11 @@ func (r *securityGroupResource) Read(ctx context.Context, req resource.ReadReque projectId := model.ProjectId.ValueString() region := r.providerData.GetRegionWithOverride(model.Region) securityGroupId := model.SecurityGroupId.ValueString() + if securityGroupId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = core.InitProviderContext(ctx) diff --git a/stackit/internal/services/iaas/securitygrouprule/resource.go b/stackit/internal/services/iaas/securitygrouprule/resource.go index 866580e73..d9273a73e 100644 --- a/stackit/internal/services/iaas/securitygrouprule/resource.go +++ b/stackit/internal/services/iaas/securitygrouprule/resource.go @@ -517,6 +517,11 @@ func (r *securityGroupRuleResource) Read(ctx context.Context, req resource.ReadR region := r.providerData.GetRegionWithOverride(model.Region) securityGroupId := model.SecurityGroupId.ValueString() securityGroupRuleId := model.SecurityGroupRuleId.ValueString() + if securityGroupRuleId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = core.InitProviderContext(ctx) diff --git a/stackit/internal/services/iaas/server/resource.go b/stackit/internal/services/iaas/server/resource.go index a10fe9386..94620970f 100644 --- a/stackit/internal/services/iaas/server/resource.go +++ b/stackit/internal/services/iaas/server/resource.go @@ -670,6 +670,11 @@ func (r *serverResource) Read(ctx context.Context, req resource.ReadRequest, res projectId := model.ProjectId.ValueString() region := r.providerData.GetRegionWithOverride(model.Region) serverId := model.ServerId.ValueString() + if serverId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = core.InitProviderContext(ctx) diff --git a/stackit/internal/services/iaas/volume/resource.go b/stackit/internal/services/iaas/volume/resource.go index f68590832..b05571986 100644 --- a/stackit/internal/services/iaas/volume/resource.go +++ b/stackit/internal/services/iaas/volume/resource.go @@ -513,6 +513,11 @@ func (r *volumeResource) Read(ctx context.Context, req resource.ReadRequest, res projectId := model.ProjectId.ValueString() region := r.providerData.GetRegionWithOverride(model.Region) volumeId := model.VolumeId.ValueString() + if volumeId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = core.InitProviderContext(ctx) diff --git a/stackit/internal/services/iaas/volumeattach/resource.go b/stackit/internal/services/iaas/volumeattach/resource.go index a726e5fac..6007fde6a 100644 --- a/stackit/internal/services/iaas/volumeattach/resource.go +++ b/stackit/internal/services/iaas/volumeattach/resource.go @@ -301,6 +301,10 @@ func (r *volumeAttachResource) Delete(ctx context.Context, req resource.DeleteRe // Remove volume from server err := r.client.RemoveVolumeFromServer(ctx, projectId, region, serverId, volumeId).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error removing volume from server", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/kms/key/resource.go b/stackit/internal/services/kms/key/resource.go index 41707dc7d..9eb3194b3 100644 --- a/stackit/internal/services/kms/key/resource.go +++ b/stackit/internal/services/kms/key/resource.go @@ -315,6 +315,11 @@ func (r *keyResource) Read(ctx context.Context, req resource.ReadRequest, resp * keyRingId := model.KeyRingId.ValueString() region := r.providerData.GetRegionWithOverride(model.Region) keyId := model.KeyId.ValueString() + if keyId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "keyring_id", keyRingId) ctx = tflog.SetField(ctx, "project_id", projectId) @@ -370,7 +375,12 @@ func (r *keyResource) Delete(ctx context.Context, req resource.DeleteRequest, re err := r.client.DeleteKey(ctx, projectId, region, keyRingId, keyId).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting key", fmt.Sprintf("Calling API: %v", err)) + return } ctx = core.LogResponse(ctx) diff --git a/stackit/internal/services/kms/keyring/resource.go b/stackit/internal/services/kms/keyring/resource.go index 6b2f8e9aa..df1d91884 100644 --- a/stackit/internal/services/kms/keyring/resource.go +++ b/stackit/internal/services/kms/keyring/resource.go @@ -244,6 +244,11 @@ func (r *keyRingResource) Read(ctx context.Context, req resource.ReadRequest, re projectId := model.ProjectId.ValueString() keyRingId := model.KeyRingId.ValueString() + if keyRingId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "keyring_id", keyRingId) diff --git a/stackit/internal/services/kms/wrapping-key/resource.go b/stackit/internal/services/kms/wrapping-key/resource.go index 3d2cfc62c..961f36381 100644 --- a/stackit/internal/services/kms/wrapping-key/resource.go +++ b/stackit/internal/services/kms/wrapping-key/resource.go @@ -321,6 +321,11 @@ func (r *wrappingKeyResource) Read(ctx context.Context, request resource.ReadReq keyRingId := model.KeyRingId.ValueString() region := r.providerData.GetRegionWithOverride(model.Region) wrappingKeyId := model.WrappingKeyId.ValueString() + if wrappingKeyId == "" { + // Resource not yet created; ID is unknown. + response.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "keyring_id", keyRingId) ctx = tflog.SetField(ctx, "project_id", projectId) @@ -376,7 +381,12 @@ func (r *wrappingKeyResource) Delete(ctx context.Context, request resource.Delet err := r.client.DeleteWrappingKey(ctx, projectId, region, keyRingId, wrappingKeyId).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 { + return + } core.LogAndAddError(ctx, &response.Diagnostics, "Error deleting wrapping key", fmt.Sprintf("Calling API: %v", err)) + return } ctx = core.LogResponse(ctx) diff --git a/stackit/internal/services/logme/credential/resource.go b/stackit/internal/services/logme/credential/resource.go index ff146e56f..6057abf10 100644 --- a/stackit/internal/services/logme/credential/resource.go +++ b/stackit/internal/services/logme/credential/resource.go @@ -225,6 +225,11 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() credentialId := model.CredentialId.ValueString() + if credentialId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) ctx = tflog.SetField(ctx, "credential_id", credentialId) @@ -285,7 +290,12 @@ func (r *credentialResource) Delete(ctx context.Context, req resource.DeleteRequ // Delete existing record set err := r.client.DeleteCredentials(ctx, projectId, instanceId, credentialId).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credential", fmt.Sprintf("Calling API: %v", err)) + return } ctx = core.LogResponse(ctx) diff --git a/stackit/internal/services/logme/instance/resource.go b/stackit/internal/services/logme/instance/resource.go index cc7427c1b..281cae1f1 100644 --- a/stackit/internal/services/logme/instance/resource.go +++ b/stackit/internal/services/logme/instance/resource.go @@ -470,6 +470,11 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() + if instanceId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) diff --git a/stackit/internal/services/logs/accesstoken/resource.go b/stackit/internal/services/logs/accesstoken/resource.go index 326823774..67ec8d182 100644 --- a/stackit/internal/services/logs/accesstoken/resource.go +++ b/stackit/internal/services/logs/accesstoken/resource.go @@ -302,6 +302,11 @@ func (r *logsAccessTokenResource) Read(ctx context.Context, req resource.ReadReq region := r.providerData.GetRegionWithOverride(model.Region) instanceID := model.InstanceID.ValueString() accessTokenID := model.AccessTokenID.ValueString() + if accessTokenID == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectID) ctx = tflog.SetField(ctx, "region", region) diff --git a/stackit/internal/services/logs/instance/resource.go b/stackit/internal/services/logs/instance/resource.go index 7d4fe60dd..c692cc52e 100644 --- a/stackit/internal/services/logs/instance/resource.go +++ b/stackit/internal/services/logs/instance/resource.go @@ -282,6 +282,11 @@ func (r *logsInstanceResource) Read(ctx context.Context, req resource.ReadReques projectID := model.ProjectID.ValueString() region := model.Region.ValueString() instanceID := model.InstanceID.ValueString() + if instanceID == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectID) ctx = tflog.SetField(ctx, "region", region) diff --git a/stackit/internal/services/mariadb/credential/resource.go b/stackit/internal/services/mariadb/credential/resource.go index d106d9d4a..e0d023c55 100644 --- a/stackit/internal/services/mariadb/credential/resource.go +++ b/stackit/internal/services/mariadb/credential/resource.go @@ -226,6 +226,11 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() credentialId := model.CredentialId.ValueString() + if credentialId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) ctx = tflog.SetField(ctx, "credential_id", credentialId) @@ -286,7 +291,12 @@ func (r *credentialResource) Delete(ctx context.Context, req resource.DeleteRequ // Delete existing record set err := r.client.DeleteCredentials(ctx, projectId, instanceId, credentialId).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credential", fmt.Sprintf("Calling API: %v", err)) + return } ctx = core.LogResponse(ctx) diff --git a/stackit/internal/services/mariadb/instance/resource.go b/stackit/internal/services/mariadb/instance/resource.go index de563b789..5e308bc6f 100644 --- a/stackit/internal/services/mariadb/instance/resource.go +++ b/stackit/internal/services/mariadb/instance/resource.go @@ -356,6 +356,11 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() + if instanceId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) diff --git a/stackit/internal/services/modelserving/token/resource.go b/stackit/internal/services/modelserving/token/resource.go index 23531bf99..4d5f42e54 100644 --- a/stackit/internal/services/modelserving/token/resource.go +++ b/stackit/internal/services/modelserving/token/resource.go @@ -354,6 +354,11 @@ func (r *tokenResource) Read(ctx context.Context, req resource.ReadRequest, resp projectId := model.ProjectId.ValueString() tokenId := model.TokenId.ValueString() + if tokenId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) diff --git a/stackit/internal/services/mongodbflex/instance/resource.go b/stackit/internal/services/mongodbflex/instance/resource.go index b74f8e912..07d527b01 100644 --- a/stackit/internal/services/mongodbflex/instance/resource.go +++ b/stackit/internal/services/mongodbflex/instance/resource.go @@ -492,6 +492,11 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() region := r.providerData.GetRegionWithOverride(model.Region) instanceId := model.InstanceId.ValueString() + if instanceId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "region", region) ctx = tflog.SetField(ctx, "instance_id", instanceId) diff --git a/stackit/internal/services/mongodbflex/user/resource.go b/stackit/internal/services/mongodbflex/user/resource.go index 7c11d2d2d..49f706388 100644 --- a/stackit/internal/services/mongodbflex/user/resource.go +++ b/stackit/internal/services/mongodbflex/user/resource.go @@ -300,6 +300,11 @@ func (r *userResource) Read(ctx context.Context, req resource.ReadRequest, resp region := r.providerData.GetRegionWithOverride(model.Region) instanceId := model.InstanceId.ValueString() userId := model.UserId.ValueString() + if userId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "region", region) ctx = tflog.SetField(ctx, "instance_id", instanceId) @@ -434,6 +439,10 @@ func (r *userResource) Delete(ctx context.Context, req resource.DeleteRequest, r // Delete user err := r.client.DeleteUser(ctx, projectId, instanceId, userId, region).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting user", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/objectstorage/credential/resource.go b/stackit/internal/services/objectstorage/credential/resource.go index a2125a1e1..8e8af53e2 100644 --- a/stackit/internal/services/objectstorage/credential/resource.go +++ b/stackit/internal/services/objectstorage/credential/resource.go @@ -337,6 +337,11 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, projectId := model.ProjectId.ValueString() credentialsGroupId := model.CredentialsGroupId.ValueString() credentialId := model.CredentialId.ValueString() + if credentialId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) @@ -425,7 +430,12 @@ func (r *credentialResource) Delete(ctx context.Context, req resource.DeleteRequ // Delete existing credential _, err := r.client.DeleteAccessKey(ctx, projectId, region, credentialId).CredentialsGroup(credentialsGroupId).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credential", fmt.Sprintf("Calling API: %v", err)) + return } ctx = core.LogResponse(ctx) diff --git a/stackit/internal/services/objectstorage/credentialsgroup/resource.go b/stackit/internal/services/objectstorage/credentialsgroup/resource.go index 9973ba800..18422f355 100644 --- a/stackit/internal/services/objectstorage/credentialsgroup/resource.go +++ b/stackit/internal/services/objectstorage/credentialsgroup/resource.go @@ -234,6 +234,11 @@ func (r *credentialsGroupResource) Read(ctx context.Context, req resource.ReadRe projectId := model.ProjectId.ValueString() credentialsGroupId := model.CredentialsGroupId.ValueString() + if credentialsGroupId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) diff --git a/stackit/internal/services/observability/credential/resource.go b/stackit/internal/services/observability/credential/resource.go index fc989d878..72116f924 100644 --- a/stackit/internal/services/observability/credential/resource.go +++ b/stackit/internal/services/observability/credential/resource.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/observability" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils" @@ -204,6 +205,11 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() userName := model.Username.ValueString() + if userName == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } _, err := r.client.GetCredentials(ctx, instanceId, projectId, userName).Execute() if err != nil { utils.LogError( @@ -252,6 +258,10 @@ func (r *credentialResource) Delete(ctx context.Context, req resource.DeleteRequ userName := model.Username.ValueString() _, err := r.client.DeleteCredentials(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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credential", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/observability/instance/resource.go b/stackit/internal/services/observability/instance/resource.go index 234699d66..2f3315bf6 100644 --- a/stackit/internal/services/observability/instance/resource.go +++ b/stackit/internal/services/observability/instance/resource.go @@ -1149,6 +1149,11 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() + if instanceId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) diff --git a/stackit/internal/services/opensearch/credential/resource.go b/stackit/internal/services/opensearch/credential/resource.go index 1510cd89a..1b0e7ae61 100644 --- a/stackit/internal/services/opensearch/credential/resource.go +++ b/stackit/internal/services/opensearch/credential/resource.go @@ -229,6 +229,11 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() credentialId := model.CredentialId.ValueString() + if credentialId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) ctx = tflog.SetField(ctx, "credential_id", credentialId) @@ -289,7 +294,12 @@ func (r *credentialResource) Delete(ctx context.Context, req resource.DeleteRequ // Delete existing record set err := r.client.DeleteCredentials(ctx, projectId, instanceId, credentialId).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credential", fmt.Sprintf("Calling API: %v", err)) + return } ctx = core.LogResponse(ctx) diff --git a/stackit/internal/services/opensearch/instance/resource.go b/stackit/internal/services/opensearch/instance/resource.go index 844216c79..f29e04cff 100644 --- a/stackit/internal/services/opensearch/instance/resource.go +++ b/stackit/internal/services/opensearch/instance/resource.go @@ -410,6 +410,11 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() + if instanceId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) diff --git a/stackit/internal/services/postgresflex/database/resource.go b/stackit/internal/services/postgresflex/database/resource.go index cd2e88e05..20f1427a9 100644 --- a/stackit/internal/services/postgresflex/database/resource.go +++ b/stackit/internal/services/postgresflex/database/resource.go @@ -264,6 +264,11 @@ func (r *databaseResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() databaseId := model.DatabaseId.ValueString() + if databaseId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) @@ -329,7 +334,12 @@ func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteReques // Delete existing record set err := r.client.DeleteDatabase(ctx, projectId, region, instanceId, databaseId).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting database", fmt.Sprintf("Calling API: %v", err)) + return } ctx = core.LogResponse(ctx) diff --git a/stackit/internal/services/postgresflex/instance/resource.go b/stackit/internal/services/postgresflex/instance/resource.go index 399a61189..5c3536533 100644 --- a/stackit/internal/services/postgresflex/instance/resource.go +++ b/stackit/internal/services/postgresflex/instance/resource.go @@ -378,6 +378,11 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() + if instanceId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) diff --git a/stackit/internal/services/postgresflex/user/resource.go b/stackit/internal/services/postgresflex/user/resource.go index 4d5e9ffc1..913bd7f12 100644 --- a/stackit/internal/services/postgresflex/user/resource.go +++ b/stackit/internal/services/postgresflex/user/resource.go @@ -283,6 +283,11 @@ func (r *userResource) Read(ctx context.Context, req resource.ReadRequest, resp projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() userId := model.UserId.ValueString() + if userId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) @@ -418,7 +423,12 @@ func (r *userResource) Delete(ctx context.Context, req resource.DeleteRequest, r // Delete existing record set err := r.client.DeleteUser(ctx, projectId, region, instanceId, userId).Execute() if err != nil { + oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint + if ok && oapiErr.StatusCode == http.StatusNotFound { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting user", fmt.Sprintf("Calling API: %v", err)) + return } ctx = core.LogResponse(ctx) diff --git a/stackit/internal/services/rabbitmq/credential/resource.go b/stackit/internal/services/rabbitmq/credential/resource.go index 50b5fecaa..9ac599da5 100644 --- a/stackit/internal/services/rabbitmq/credential/resource.go +++ b/stackit/internal/services/rabbitmq/credential/resource.go @@ -246,6 +246,11 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() credentialId := model.CredentialId.ValueString() + if credentialId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) ctx = tflog.SetField(ctx, "credential_id", credentialId) @@ -306,7 +311,12 @@ func (r *credentialResource) Delete(ctx context.Context, req resource.DeleteRequ // Delete existing record set err := r.client.DeleteCredentials(ctx, projectId, instanceId, credentialId).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credential", fmt.Sprintf("Calling API: %v", err)) + return } ctx = core.LogResponse(ctx) diff --git a/stackit/internal/services/rabbitmq/instance/resource.go b/stackit/internal/services/rabbitmq/instance/resource.go index 8d853dcab..f12cd2506 100644 --- a/stackit/internal/services/rabbitmq/instance/resource.go +++ b/stackit/internal/services/rabbitmq/instance/resource.go @@ -411,6 +411,11 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() + if instanceId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) diff --git a/stackit/internal/services/redis/credential/resource.go b/stackit/internal/services/redis/credential/resource.go index bec8f926d..cc57b2052 100644 --- a/stackit/internal/services/redis/credential/resource.go +++ b/stackit/internal/services/redis/credential/resource.go @@ -235,6 +235,11 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() credentialId := model.CredentialId.ValueString() + if credentialId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) ctx = tflog.SetField(ctx, "credential_id", credentialId) @@ -295,7 +300,12 @@ func (r *credentialResource) Delete(ctx context.Context, req resource.DeleteRequ // Delete existing record set err := r.client.DeleteCredentials(ctx, projectId, instanceId, credentialId).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credential", fmt.Sprintf("Calling API: %v", err)) + return } ctx = core.LogResponse(ctx) diff --git a/stackit/internal/services/redis/instance/resource.go b/stackit/internal/services/redis/instance/resource.go index b928e14b9..73261b636 100644 --- a/stackit/internal/services/redis/instance/resource.go +++ b/stackit/internal/services/redis/instance/resource.go @@ -480,6 +480,11 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() + if instanceId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) diff --git a/stackit/internal/services/resourcemanager/folder/resource.go b/stackit/internal/services/resourcemanager/folder/resource.go index 9d237baaa..3683b4905 100644 --- a/stackit/internal/services/resourcemanager/folder/resource.go +++ b/stackit/internal/services/resourcemanager/folder/resource.go @@ -253,6 +253,11 @@ func (r *folderResource) Read(ctx context.Context, req resource.ReadRequest, res ctx = core.InitProviderContext(ctx) containerId := model.ContainerId.ValueString() + if containerId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } folderName := model.Name.ValueString() ctx = tflog.SetField(ctx, "folder_name", folderName) ctx = tflog.SetField(ctx, "container_id", containerId) diff --git a/stackit/internal/services/resourcemanager/project/resource.go b/stackit/internal/services/resourcemanager/project/resource.go index e0e2da842..6fa179a72 100644 --- a/stackit/internal/services/resourcemanager/project/resource.go +++ b/stackit/internal/services/resourcemanager/project/resource.go @@ -265,6 +265,11 @@ func (r *projectResource) Read(ctx context.Context, req resource.ReadRequest, re ctx = core.InitProviderContext(ctx) containerId := model.ContainerId.ValueString() + if containerId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "container_id", containerId) projectResp, err := r.client.GetProject(ctx, containerId).Execute() diff --git a/stackit/internal/services/scf/organization/resource.go b/stackit/internal/services/scf/organization/resource.go index 15c4dc3a1..ad044d128 100644 --- a/stackit/internal/services/scf/organization/resource.go +++ b/stackit/internal/services/scf/organization/resource.go @@ -333,6 +333,11 @@ func (s *scfOrganizationResource) Read(ctx context.Context, request resource.Rea // Extract the project ID and instance id of the model projectId := model.ProjectId.ValueString() orgId := model.OrgId.ValueString() + if orgId == "" { + // Resource not yet created; ID is unknown. + response.State.RemoveResource(ctx) + return + } // Extract the region region := s.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) diff --git a/stackit/internal/services/secretsmanager/instance/resource.go b/stackit/internal/services/secretsmanager/instance/resource.go index cb56df6a2..97814260e 100644 --- a/stackit/internal/services/secretsmanager/instance/resource.go +++ b/stackit/internal/services/secretsmanager/instance/resource.go @@ -230,6 +230,11 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() + if instanceId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) diff --git a/stackit/internal/services/secretsmanager/user/resource.go b/stackit/internal/services/secretsmanager/user/resource.go index d49b62dfe..5958d331c 100644 --- a/stackit/internal/services/secretsmanager/user/resource.go +++ b/stackit/internal/services/secretsmanager/user/resource.go @@ -224,6 +224,11 @@ func (r *userResource) Read(ctx context.Context, req resource.ReadRequest, resp projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() userId := model.UserId.ValueString() + if userId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) ctx = tflog.SetField(ctx, "user_id", userId) @@ -338,7 +343,12 @@ func (r *userResource) Delete(ctx context.Context, req resource.DeleteRequest, r // Delete existing user err := r.client.DeleteUser(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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting user", fmt.Sprintf("Calling API: %v", err)) + return } ctx = core.LogResponse(ctx) diff --git a/stackit/internal/services/serverbackup/schedule/resource.go b/stackit/internal/services/serverbackup/schedule/resource.go index fe9bd9b70..1ec6a0157 100644 --- a/stackit/internal/services/serverbackup/schedule/resource.go +++ b/stackit/internal/services/serverbackup/schedule/resource.go @@ -299,6 +299,11 @@ func (r *scheduleResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() serverId := model.ServerId.ValueString() backupScheduleId := model.BackupScheduleId.ValueInt64() + if backupScheduleId == 0 { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) diff --git a/stackit/internal/services/serverupdate/schedule/resource.go b/stackit/internal/services/serverupdate/schedule/resource.go index c359e9d0c..115de49bb 100644 --- a/stackit/internal/services/serverupdate/schedule/resource.go +++ b/stackit/internal/services/serverupdate/schedule/resource.go @@ -275,6 +275,11 @@ func (r *scheduleResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() serverId := model.ServerId.ValueString() updateScheduleId := model.UpdateScheduleId.ValueInt64() + if updateScheduleId == 0 { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "server_id", serverId) diff --git a/stackit/internal/services/serviceaccount/key/resource.go b/stackit/internal/services/serviceaccount/key/resource.go index ea254c94c..87ba31d8f 100644 --- a/stackit/internal/services/serviceaccount/key/resource.go +++ b/stackit/internal/services/serviceaccount/key/resource.go @@ -222,6 +222,11 @@ func (r *serviceAccountKeyResource) Read(ctx context.Context, req resource.ReadR projectId := model.ProjectId.ValueString() serviceAccountEmail := model.ServiceAccountEmail.ValueString() keyId := model.KeyId.ValueString() + if keyId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } _, err := r.client.GetServiceAccountKey(ctx, projectId, serviceAccountEmail, keyId).Execute() if err != nil { @@ -280,6 +285,10 @@ func (r *serviceAccountKeyResource) Delete(ctx context.Context, req resource.Del // Call API to delete the existing service account key. err := r.client.DeleteServiceAccountKey(ctx, projectId, serviceAccountEmail, keyId).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting service account key", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/sfs/export-policy/resource.go b/stackit/internal/services/sfs/export-policy/resource.go index 01f6cc3d4..b7a187e11 100644 --- a/stackit/internal/services/sfs/export-policy/resource.go +++ b/stackit/internal/services/sfs/export-policy/resource.go @@ -328,6 +328,11 @@ func (r *exportPolicyResource) Read(ctx context.Context, req resource.ReadReques } projectId := model.ProjectId.ValueString() exportPolicyId := model.ExportPolicyId.ValueString() + if exportPolicyId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "policy_id", exportPolicyId) diff --git a/stackit/internal/services/sfs/resourcepool/resource.go b/stackit/internal/services/sfs/resourcepool/resource.go index 8e37a2157..821a81725 100644 --- a/stackit/internal/services/sfs/resourcepool/resource.go +++ b/stackit/internal/services/sfs/resourcepool/resource.go @@ -301,6 +301,11 @@ func (r *resourcePoolResource) Read(ctx context.Context, req resource.ReadReques } projectId := model.ProjectId.ValueString() resourcePoolId := model.ResourcePoolId.ValueString() + if resourcePoolId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "resource_pool_id", resourcePoolId) diff --git a/stackit/internal/services/sfs/share/resource.go b/stackit/internal/services/sfs/share/resource.go index 56b021bd1..4776d64ba 100644 --- a/stackit/internal/services/sfs/share/resource.go +++ b/stackit/internal/services/sfs/share/resource.go @@ -300,6 +300,11 @@ func (r *shareResource) Read(ctx context.Context, req resource.ReadRequest, resp projectId := model.ProjectId.ValueString() resourcePoolId := model.ResourcePoolId.ValueString() shareId := model.ShareId.ValueString() + if shareId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "resource_pool_id", resourcePoolId) diff --git a/stackit/internal/services/sqlserverflex/instance/resource.go b/stackit/internal/services/sqlserverflex/instance/resource.go index 72a0de305..4446a33fb 100644 --- a/stackit/internal/services/sqlserverflex/instance/resource.go +++ b/stackit/internal/services/sqlserverflex/instance/resource.go @@ -450,6 +450,11 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() + if instanceId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) diff --git a/stackit/internal/services/sqlserverflex/user/resource.go b/stackit/internal/services/sqlserverflex/user/resource.go index e73fb9b06..43f850721 100644 --- a/stackit/internal/services/sqlserverflex/user/resource.go +++ b/stackit/internal/services/sqlserverflex/user/resource.go @@ -286,6 +286,11 @@ func (r *userResource) Read(ctx context.Context, req resource.ReadRequest, resp projectId := model.ProjectId.ValueString() instanceId := model.InstanceId.ValueString() userId := model.UserId.ValueString() + if userId == "" { + // Resource not yet created; ID is unknown. + resp.State.RemoveResource(ctx) + return + } region := r.providerData.GetRegionWithOverride(model.Region) ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) @@ -351,6 +356,10 @@ func (r *userResource) Delete(ctx context.Context, req resource.DeleteRequest, r // Delete existing record set err := r.client.DeleteUser(ctx, projectId, instanceId, userId, region).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 { + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting user", fmt.Sprintf("Calling API: %v", err)) return } From 2326ba3f87a3655dbef7bd9de872ad2246375371 Mon Sep 17 00:00:00 2001 From: Dominik Pildner Date: Wed, 18 Mar 2026 07:58:00 +0100 Subject: [PATCH 2/5] fix: add nolint explanation --- stackit/internal/services/postgresflex/user/resource.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stackit/internal/services/postgresflex/user/resource.go b/stackit/internal/services/postgresflex/user/resource.go index 913bd7f12..f580add5b 100644 --- a/stackit/internal/services/postgresflex/user/resource.go +++ b/stackit/internal/services/postgresflex/user/resource.go @@ -423,7 +423,7 @@ func (r *userResource) Delete(ctx context.Context, req resource.DeleteRequest, r // Delete existing record set err := r.client.DeleteUser(ctx, projectId, region, instanceId, userId).Execute() if err != nil { - oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint + 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 { return } From ed1b2592e76927c982850dfef0a2f8fda3a935bf Mon Sep 17 00:00:00 2001 From: Dominik Pildner Date: Tue, 31 Mar 2026 08:53:20 +0200 Subject: [PATCH 3/5] feat: apply similar 404 check to every applicable resource type --- .../alb/applicationloadbalancer/resource.go | 5 ++++ .../authorization/roleassignments/resource.go | 7 +++++ .../services/cdn/customdomain/resource.go | 6 ++++ .../services/dns/recordset/resource.go | 10 +++++-- .../internal/services/dns/zone/resource.go | 13 +++++++++ .../services/iaas/affinitygroup/resource.go | 10 +++++-- .../internal/services/iaas/image/resource.go | 10 +++++-- .../services/iaas/keypair/resource.go | 10 +++++-- .../services/iaas/network/resource.go | 10 +++++-- .../services/iaas/networkarea/resource.go | 28 +++++++++++++++---- .../services/iaas/publicip/resource.go | 10 +++++-- .../iaas/publicipassociate/resource.go | 10 +++++-- .../iaas/routingtable/table/resource.go | 7 +++++ .../services/iaas/securitygroup/resource.go | 10 +++++-- .../iaas/securitygrouprule/resource.go | 10 +++++-- .../internal/services/iaas/server/resource.go | 10 +++++-- .../iaas/serviceaccountattach/resource.go | 10 +++++-- .../internal/services/iaas/volume/resource.go | 10 +++++-- .../loadbalancer/loadbalancer/resource.go | 10 +++++-- .../observability-credential/resource.go | 10 +++++-- .../services/logme/instance/resource.go | 10 +++++-- .../services/mariadb/instance/resource.go | 10 +++++-- .../services/mongodbflex/instance/resource.go | 10 +++++-- .../services/objectstorage/bucket/resource.go | 8 ++++-- .../credentialsgroup/resource.go | 11 ++++++-- .../observability/alertgroup/resource.go | 8 ++++-- .../observability/credential/resource.go | 13 ++++++--- .../observability/instance/resource.go | 10 +++++-- .../observability/log-alertgroup/resource.go | 8 ++++-- .../observability/scrapeconfig/resource.go | 10 +++++-- .../services/opensearch/instance/resource.go | 10 +++++-- .../postgresflex/instance/resource.go | 10 +++++-- .../services/rabbitmq/instance/resource.go | 10 +++++-- .../services/redis/instance/resource.go | 10 +++++-- .../resourcemanager/folder/resource.go | 10 +++++-- .../resourcemanager/project/resource.go | 10 +++++-- .../scf/organizationmanager/resource.go | 6 ++-- .../secretsmanager/instance/resource.go | 10 +++++-- .../serviceaccount/account/resource.go | 13 +++++++++ .../internal/services/ske/cluster/resource.go | 10 +++++-- .../services/ske/kubeconfig/resource.go | 10 +++++-- .../sqlserverflex/instance/resource.go | 10 +++++-- 42 files changed, 343 insertions(+), 80 deletions(-) diff --git a/stackit/internal/services/alb/applicationloadbalancer/resource.go b/stackit/internal/services/alb/applicationloadbalancer/resource.go index eb9b647a0..4113a5e4d 100644 --- a/stackit/internal/services/alb/applicationloadbalancer/resource.go +++ b/stackit/internal/services/alb/applicationloadbalancer/resource.go @@ -1342,6 +1342,11 @@ func (r *applicationLoadBalancerResource) Delete(ctx context.Context, req resour // Delete Application Load Balancer _, err := r.client.DeleteLoadBalancer(ctx, projectId, region, name).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } errStr := utils.PrettyApiErr(ctx, &resp.Diagnostics, err) core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting Application Load Balancer", fmt.Sprintf("Calling API for delete: %v", errStr)) return diff --git a/stackit/internal/services/authorization/roleassignments/resource.go b/stackit/internal/services/authorization/roleassignments/resource.go index 46259617f..6f243515e 100644 --- a/stackit/internal/services/authorization/roleassignments/resource.go +++ b/stackit/internal/services/authorization/roleassignments/resource.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "net/http" "strings" "time" @@ -15,6 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/authorization" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" @@ -315,6 +317,11 @@ func (r *roleAssignmentResource) Delete(ctx context.Context, req resource.Delete // Delete existing project role assignment _, err := r.authorizationClient.RemoveMembers(ctx, model.ResourceId.ValueString()).RemoveMembersPayload(payload).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, fmt.Sprintf("Error deleting %s role assignment", r.apiName), fmt.Sprintf("Calling API: %v", err)) } diff --git a/stackit/internal/services/cdn/customdomain/resource.go b/stackit/internal/services/cdn/customdomain/resource.go index 5544b686f..e1b1059ea 100644 --- a/stackit/internal/services/cdn/customdomain/resource.go +++ b/stackit/internal/services/cdn/customdomain/resource.go @@ -371,7 +371,13 @@ func (r *customDomainResource) Delete(ctx context.Context, req resource.DeleteRe _, err := r.client.DeleteCustomDomain(ctx, projectId, distributionId, name).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Delete CDN custom domain", fmt.Sprintf("Delete custom domain: %v", err)) + return } ctx = core.LogResponse(ctx) diff --git a/stackit/internal/services/dns/recordset/resource.go b/stackit/internal/services/dns/recordset/resource.go index 2c9e8962b..83d2867bc 100644 --- a/stackit/internal/services/dns/recordset/resource.go +++ b/stackit/internal/services/dns/recordset/resource.go @@ -2,6 +2,7 @@ package dns import ( "context" + "errors" "fmt" "net/http" "strings" @@ -280,6 +281,11 @@ func (r *recordSetResource) Read(ctx context.Context, req resource.ReadRequest, recordSetResp, err := r.client.GetRecordSet(ctx, projectId, zoneId, recordSetId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading record set", fmt.Sprintf("Calling API: %v", err)) return } @@ -381,8 +387,8 @@ func (r *recordSetResource) Delete(ctx context.Context, req resource.DeleteReque // Delete existing record set _, err := r.client.DeleteRecordSet(ctx, projectId, zoneId, recordSetId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting record set", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/dns/zone/resource.go b/stackit/internal/services/dns/zone/resource.go index f4c9037bc..1c5ee9d48 100644 --- a/stackit/internal/services/dns/zone/resource.go +++ b/stackit/internal/services/dns/zone/resource.go @@ -2,8 +2,10 @@ package dns import ( "context" + "errors" "fmt" "math" + "net/http" "regexp" "strings" @@ -22,6 +24,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "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/conversion" @@ -365,6 +368,11 @@ func (r *zoneResource) Read(ctx context.Context, req resource.ReadRequest, resp zoneResp, err := r.client.GetZone(ctx, projectId, zoneId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading zone", fmt.Sprintf("Calling API: %v", err)) return } @@ -462,6 +470,11 @@ func (r *zoneResource) Delete(ctx context.Context, req resource.DeleteRequest, r // Delete existing zone _, err := r.client.DeleteZone(ctx, projectId, zoneId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting zone", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/affinitygroup/resource.go b/stackit/internal/services/iaas/affinitygroup/resource.go index 0aa64cd54..c788e97ac 100644 --- a/stackit/internal/services/iaas/affinitygroup/resource.go +++ b/stackit/internal/services/iaas/affinitygroup/resource.go @@ -2,6 +2,7 @@ package affinitygroup import ( "context" + "errors" "fmt" "net/http" "regexp" @@ -259,8 +260,8 @@ func (r *affinityGroupResource) Read(ctx context.Context, req resource.ReadReque affinityGroupResp, err := r.client.GetAffinityGroupExecute(ctx, projectId, region, affinityGroupId) 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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -310,6 +311,11 @@ func (r *affinityGroupResource) Delete(ctx context.Context, req resource.DeleteR // Delete existing affinity group err := r.client.DeleteAffinityGroupExecute(ctx, projectId, region, affinityGroupId) if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting affinity group", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/image/resource.go b/stackit/internal/services/iaas/image/resource.go index 47d300f3f..ccd87459c 100644 --- a/stackit/internal/services/iaas/image/resource.go +++ b/stackit/internal/services/iaas/image/resource.go @@ -3,6 +3,7 @@ package image import ( "bufio" "context" + "errors" "fmt" "net/http" "os" @@ -523,8 +524,8 @@ func (r *imageResource) Read(ctx context.Context, req resource.ReadRequest, resp imageResp, err := r.client.GetImage(ctx, projectId, region, imageId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -627,6 +628,11 @@ func (r *imageResource) Delete(ctx context.Context, req resource.DeleteRequest, // Delete existing image err := r.client.DeleteImage(ctx, projectId, region, imageId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting image", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/keypair/resource.go b/stackit/internal/services/iaas/keypair/resource.go index 4c709b33d..f362be7f0 100644 --- a/stackit/internal/services/iaas/keypair/resource.go +++ b/stackit/internal/services/iaas/keypair/resource.go @@ -2,6 +2,7 @@ package keypair import ( "context" + "errors" "fmt" "net/http" "strings" @@ -199,8 +200,8 @@ func (r *keyPairResource) Read(ctx context.Context, req resource.ReadRequest, re keyPairResp, err := r.client.GetKeyPair(ctx, 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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -295,6 +296,11 @@ func (r *keyPairResource) Delete(ctx context.Context, req resource.DeleteRequest // Delete existing key pair err := r.client.DeleteKeyPair(ctx, name).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting key pair", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/network/resource.go b/stackit/internal/services/iaas/network/resource.go index 1cb9b13f6..3f926ee1e 100644 --- a/stackit/internal/services/iaas/network/resource.go +++ b/stackit/internal/services/iaas/network/resource.go @@ -2,6 +2,7 @@ package network import ( "context" + "errors" "fmt" "net" "net/http" @@ -467,8 +468,8 @@ func (r *networkResource) Read(ctx context.Context, req resource.ReadRequest, re networkResp, err := r.client.GetNetwork(ctx, projectId, region, networkId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -574,6 +575,11 @@ func (r *networkResource) Delete(ctx context.Context, req resource.DeleteRequest // Delete existing network err := r.client.DeleteNetwork(ctx, projectId, region, networkId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting network", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/networkarea/resource.go b/stackit/internal/services/iaas/networkarea/resource.go index 6e057cf80..ad079b34c 100644 --- a/stackit/internal/services/iaas/networkarea/resource.go +++ b/stackit/internal/services/iaas/networkarea/resource.go @@ -457,8 +457,7 @@ func (r *networkAreaResource) Read(ctx context.Context, req resource.ReadRequest networkAreaResp, err := r.client.GetNetworkArea(ctx, organizationId, networkAreaId).Execute() if err != nil { var oapiErr *oapierror.GenericOpenAPIError - ok := errors.As(err, &oapiErr) - if ok && oapiErr.StatusCode == http.StatusNotFound { + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -483,8 +482,7 @@ func (r *networkAreaResource) Read(ctx context.Context, req resource.ReadRequest networkAreaRegionResp, err := r.client.GetNetworkAreaRegion(ctx, organizationId, networkAreaId, "eu01").Execute() if err != nil { var oapiErr *oapierror.GenericOpenAPIError - ok := errors.As(err, &oapiErr) - if !(ok && (oapiErr.StatusCode == http.StatusNotFound || oapiErr.StatusCode == http.StatusBadRequest)) { // TODO: iaas api returns http 400 in case network area region is not found + if !(errors.As(err, &oapiErr) && (oapiErr.StatusCode == http.StatusNotFound || oapiErr.StatusCode == http.StatusBadRequest)) { // TODO: iaas api returns http 400 in case network area region is not found core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading network area region", fmt.Sprintf("Calling API: %v", err)) return } @@ -610,8 +608,7 @@ func (r *networkAreaResource) Update(ctx context.Context, req resource.UpdateReq networkAreaRegionResp, err := r.client.GetNetworkAreaRegion(ctx, organizationId, networkAreaId, "eu01").Execute() if err != nil { var oapiErr *oapierror.GenericOpenAPIError - ok := errors.As(err, &oapiErr) - if ok && (oapiErr.StatusCode == http.StatusNotFound || oapiErr.StatusCode == http.StatusBadRequest) { // TODO: iaas api returns http 400 in case network area region is not found + if errors.As(err, &oapiErr) && (oapiErr.StatusCode == http.StatusNotFound || oapiErr.StatusCode == http.StatusBadRequest) { // TODO: iaas api returns http 400 in case network area region is not found return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading network area region", fmt.Sprintf("Calling API: %v", err)) @@ -661,6 +658,11 @@ func (r *networkAreaResource) Delete(ctx context.Context, req resource.DeleteReq _, err := wait.ReadyForNetworkAreaDeletionWaitHandler(ctx, r.client, r.resourceManagerClient, organizationId, networkAreaId).WaitWithContext(ctx) if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting network area", fmt.Sprintf("Network area ready for deletion waiting: %v", err)) return } @@ -668,6 +670,11 @@ func (r *networkAreaResource) Delete(ctx context.Context, req resource.DeleteReq // Get all configured regions so we can delete them one by one before deleting the network area regionsListResp, err := r.client.ListNetworkAreaRegions(ctx, organizationId, networkAreaId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting network area region", fmt.Sprintf("Calling API to list configured regions: %v", err)) return } @@ -676,6 +683,10 @@ func (r *networkAreaResource) Delete(ctx context.Context, req resource.DeleteReq for region := range *regionsListResp.Regions { err = r.client.DeleteNetworkAreaRegion(ctx, organizationId, networkAreaId, region).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + continue + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting network area region", fmt.Sprintf("Calling API: %v", err)) return } @@ -690,6 +701,11 @@ func (r *networkAreaResource) Delete(ctx context.Context, req resource.DeleteReq // Delete existing network area err = r.client.DeleteNetworkArea(ctx, organizationId, networkAreaId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting network area", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/publicip/resource.go b/stackit/internal/services/iaas/publicip/resource.go index e9bda8f3b..b93a8a9fa 100644 --- a/stackit/internal/services/iaas/publicip/resource.go +++ b/stackit/internal/services/iaas/publicip/resource.go @@ -2,6 +2,7 @@ package publicip import ( "context" + "errors" "fmt" "net/http" "strings" @@ -253,8 +254,8 @@ func (r *publicIpResource) Read(ctx context.Context, req resource.ReadRequest, r publicIpResp, err := r.client.GetPublicIP(ctx, projectId, region, publicIpId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -357,6 +358,11 @@ func (r *publicIpResource) Delete(ctx context.Context, req resource.DeleteReques // Delete existing publicIp err := r.client.DeletePublicIP(ctx, projectId, region, publicIpId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting public IP", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/publicipassociate/resource.go b/stackit/internal/services/iaas/publicipassociate/resource.go index 6d13bc1fd..90784c895 100644 --- a/stackit/internal/services/iaas/publicipassociate/resource.go +++ b/stackit/internal/services/iaas/publicipassociate/resource.go @@ -2,6 +2,7 @@ package publicipassociate import ( "context" + "errors" "fmt" "net/http" "strings" @@ -254,8 +255,8 @@ func (r *publicIpAssociateResource) Read(ctx context.Context, req resource.ReadR publicIpResp, err := r.client.GetPublicIP(ctx, projectId, region, publicIpId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -313,6 +314,11 @@ func (r *publicIpAssociateResource) Delete(ctx context.Context, req resource.Del _, err := r.client.UpdatePublicIP(ctx, projectId, region, publicIpId).UpdatePublicIPPayload(*payload).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting public IP association", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/routingtable/table/resource.go b/stackit/internal/services/iaas/routingtable/table/resource.go index 4d7ac6cd1..4e623ef05 100644 --- a/stackit/internal/services/iaas/routingtable/table/resource.go +++ b/stackit/internal/services/iaas/routingtable/table/resource.go @@ -2,6 +2,7 @@ package table import ( "context" + "errors" "fmt" "net/http" "strings" @@ -21,6 +22,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/features" @@ -413,6 +415,11 @@ func (r *routingTableResource) Delete(ctx context.Context, req resource.DeleteRe // Delete existing routing table err := r.client.DeleteRoutingTableFromArea(ctx, organizationId, networkAreaId, region, routingTableId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting routing table", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/securitygroup/resource.go b/stackit/internal/services/iaas/securitygroup/resource.go index ea7ede61f..da09f5b7b 100644 --- a/stackit/internal/services/iaas/securitygroup/resource.go +++ b/stackit/internal/services/iaas/securitygroup/resource.go @@ -2,6 +2,7 @@ package securitygroup import ( "context" + "errors" "fmt" "net/http" "regexp" @@ -272,8 +273,8 @@ func (r *securityGroupResource) Read(ctx context.Context, req resource.ReadReque securityGroupResp, err := r.client.GetSecurityGroup(ctx, projectId, region, securityGroupId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -376,6 +377,11 @@ func (r *securityGroupResource) Delete(ctx context.Context, req resource.DeleteR // Delete existing security group err := r.client.DeleteSecurityGroup(ctx, projectId, region, securityGroupId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting security group", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/securitygrouprule/resource.go b/stackit/internal/services/iaas/securitygrouprule/resource.go index d9273a73e..de2061cdd 100644 --- a/stackit/internal/services/iaas/securitygrouprule/resource.go +++ b/stackit/internal/services/iaas/securitygrouprule/resource.go @@ -2,6 +2,7 @@ package securitygrouprule import ( "context" + "errors" "fmt" "net/http" "regexp" @@ -532,8 +533,8 @@ func (r *securityGroupRuleResource) Read(ctx context.Context, req resource.ReadR securityGroupRuleResp, err := r.client.GetSecurityGroupRule(ctx, projectId, region, securityGroupId, securityGroupRuleId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -589,6 +590,11 @@ func (r *securityGroupRuleResource) Delete(ctx context.Context, req resource.Del // Delete existing security group rule err := r.client.DeleteSecurityGroupRule(ctx, projectId, region, securityGroupId, securityGroupRuleId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting security group rule", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/server/resource.go b/stackit/internal/services/iaas/server/resource.go index 94620970f..276cf68d7 100644 --- a/stackit/internal/services/iaas/server/resource.go +++ b/stackit/internal/services/iaas/server/resource.go @@ -2,6 +2,7 @@ package server import ( "context" + "errors" "encoding/base64" "fmt" "net/http" @@ -686,8 +687,8 @@ func (r *serverResource) Read(ctx context.Context, req resource.ReadRequest, res serverReq = serverReq.Details(true) serverResp, err := serverReq.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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -861,6 +862,11 @@ func (r *serverResource) Delete(ctx context.Context, req resource.DeleteRequest, // Delete existing server err := r.client.DeleteServer(ctx, projectId, region, serverId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting server", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/serviceaccountattach/resource.go b/stackit/internal/services/iaas/serviceaccountattach/resource.go index bf6d31e91..7059a3568 100644 --- a/stackit/internal/services/iaas/serviceaccountattach/resource.go +++ b/stackit/internal/services/iaas/serviceaccountattach/resource.go @@ -2,6 +2,7 @@ package serviceaccountattach import ( "context" + "errors" "fmt" "net/http" "strings" @@ -222,8 +223,8 @@ func (r *serviceAccountAttachResource) Read(ctx context.Context, req resource.Re serviceAccounts, err := r.client.ListServerServiceAccounts(ctx, projectId, region, serverId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -290,6 +291,11 @@ func (r *serviceAccountAttachResource) Delete(ctx context.Context, req resource. // Remove service_account from server _, err := r.client.RemoveServiceAccountFromServer(ctx, projectId, region, serverId, service_accountId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error removing service account from server", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/iaas/volume/resource.go b/stackit/internal/services/iaas/volume/resource.go index b05571986..3d84ee370 100644 --- a/stackit/internal/services/iaas/volume/resource.go +++ b/stackit/internal/services/iaas/volume/resource.go @@ -2,6 +2,7 @@ package volume import ( "context" + "errors" "fmt" "net/http" "regexp" @@ -527,8 +528,8 @@ func (r *volumeResource) Read(ctx context.Context, req resource.ReadRequest, res volumeResp, err := r.client.GetVolume(ctx, projectId, region, volumeId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -649,6 +650,11 @@ func (r *volumeResource) Delete(ctx context.Context, req resource.DeleteRequest, // Delete existing volume err := r.client.DeleteVolume(ctx, projectId, region, volumeId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting volume", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/loadbalancer/loadbalancer/resource.go b/stackit/internal/services/loadbalancer/loadbalancer/resource.go index 2a0fe0401..4b37d468b 100644 --- a/stackit/internal/services/loadbalancer/loadbalancer/resource.go +++ b/stackit/internal/services/loadbalancer/loadbalancer/resource.go @@ -2,6 +2,7 @@ package loadbalancer import ( "context" + "errors" "fmt" "net/http" "strings" @@ -831,8 +832,8 @@ func (r *loadBalancerResource) Read(ctx context.Context, req resource.ReadReques lbResp, err := r.client.GetLoadBalancer(ctx, projectId, region, 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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -951,6 +952,11 @@ func (r *loadBalancerResource) Delete(ctx context.Context, req resource.DeleteRe // Delete load balancer _, err := r.client.DeleteLoadBalancer(ctx, projectId, region, name).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting load balancer", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/loadbalancer/observability-credential/resource.go b/stackit/internal/services/loadbalancer/observability-credential/resource.go index e4613c062..2048a22f8 100644 --- a/stackit/internal/services/loadbalancer/observability-credential/resource.go +++ b/stackit/internal/services/loadbalancer/observability-credential/resource.go @@ -2,6 +2,7 @@ package loadbalancer import ( "context" + "errors" "fmt" "net/http" "strings" @@ -252,8 +253,8 @@ func (r *observabilityCredentialResource) Read(ctx context.Context, req resource // Get credentials credResp, err := r.client.GetCredentials(ctx, projectId, region, credentialsRef).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -305,6 +306,11 @@ func (r *observabilityCredentialResource) Delete(ctx context.Context, req resour // Delete credentials _, err := r.client.DeleteCredentials(ctx, projectId, region, credentialsRef).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting observability credential", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/logme/instance/resource.go b/stackit/internal/services/logme/instance/resource.go index 281cae1f1..63cfcc7ed 100644 --- a/stackit/internal/services/logme/instance/resource.go +++ b/stackit/internal/services/logme/instance/resource.go @@ -2,6 +2,7 @@ package logme import ( "context" + "errors" "fmt" "net/http" "slices" @@ -480,8 +481,8 @@ 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 || oapiErr.StatusCode == http.StatusGone) { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && (oapiErr.StatusCode == http.StatusNotFound || oapiErr.StatusCode == http.StatusGone) { resp.State.RemoveResource(ctx) return } @@ -602,6 +603,11 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques // Delete existing instance err := r.client.DeleteInstance(ctx, projectId, instanceId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting instance", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/mariadb/instance/resource.go b/stackit/internal/services/mariadb/instance/resource.go index 5e308bc6f..dc1d596f8 100644 --- a/stackit/internal/services/mariadb/instance/resource.go +++ b/stackit/internal/services/mariadb/instance/resource.go @@ -2,6 +2,7 @@ package mariadb import ( "context" + "errors" "fmt" "net/http" "strings" @@ -366,8 +367,8 @@ 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 || oapiErr.StatusCode == http.StatusGone) { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && (oapiErr.StatusCode == http.StatusNotFound || oapiErr.StatusCode == http.StatusGone) { resp.State.RemoveResource(ctx) return } @@ -488,6 +489,11 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques // Delete existing instance err := r.client.DeleteInstance(ctx, projectId, instanceId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting 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 07d527b01..132968def 100644 --- a/stackit/internal/services/mongodbflex/instance/resource.go +++ b/stackit/internal/services/mongodbflex/instance/resource.go @@ -2,6 +2,7 @@ package mongodbflex import ( "context" + "errors" "fmt" "net/http" "regexp" @@ -529,8 +530,8 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r instanceResp, err := r.client.GetInstance(ctx, projectId, instanceId, region).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -688,6 +689,11 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques // Delete existing instance err := r.client.DeleteInstance(ctx, projectId, instanceId, region).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting instance", 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 e6bd2eca9..1f45d69a3 100644 --- a/stackit/internal/services/objectstorage/bucket/resource.go +++ b/stackit/internal/services/objectstorage/bucket/resource.go @@ -255,8 +255,8 @@ func (r *bucketResource) Read(ctx context.Context, req resource.ReadRequest, res bucketResp, err := r.client.GetBucket(ctx, projectId, region, 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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -312,6 +312,10 @@ func (r *bucketResource) Delete(ctx context.Context, req resource.DeleteRequest, if err != nil { var oapiErr *oapierror.GenericOpenAPIError if errors.As(err, &oapiErr) { + if oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } if oapiErr.StatusCode == http.StatusUnprocessableEntity { core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting bucket", "Bucket isn't empty and cannot be deleted") return diff --git a/stackit/internal/services/objectstorage/credentialsgroup/resource.go b/stackit/internal/services/objectstorage/credentialsgroup/resource.go index 68e22ca13..64f6649f9 100644 --- a/stackit/internal/services/objectstorage/credentialsgroup/resource.go +++ b/stackit/internal/services/objectstorage/credentialsgroup/resource.go @@ -2,6 +2,7 @@ package objectstorage import ( "context" + "errors" "fmt" "net/http" "strings" @@ -311,7 +312,13 @@ func (r *credentialsGroupResource) Delete(ctx context.Context, req resource.Dele // Delete existing credentials group _, err := r.client.DeleteCredentialsGroup(ctx, projectId, region, credentialsGroupId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credentials group", fmt.Sprintf("Calling API: %v", err)) + return } ctx = core.LogResponse(ctx) @@ -405,8 +412,8 @@ func readCredentialsGroups(ctx context.Context, model *Model, region string, cli credentialsGroupsResp, err := client.ListCredentialsGroupsExecute(ctx, model.ProjectId.ValueString(), region) 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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return found, nil } return found, fmt.Errorf("getting credentials groups: %w", err) diff --git a/stackit/internal/services/observability/alertgroup/resource.go b/stackit/internal/services/observability/alertgroup/resource.go index c0b24fb15..458480f43 100644 --- a/stackit/internal/services/observability/alertgroup/resource.go +++ b/stackit/internal/services/observability/alertgroup/resource.go @@ -366,8 +366,7 @@ func (a *alertGroupResource) Read(ctx context.Context, req resource.ReadRequest, readAlertGroupResp, err := a.client.GetAlertgroup(ctx, alertGroupName, instanceId, projectId).Execute() if err != nil { var oapiErr *oapierror.GenericOpenAPIError - ok := errors.As(err, &oapiErr) - if ok && oapiErr.StatusCode == http.StatusNotFound { + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -417,6 +416,11 @@ func (a *alertGroupResource) Delete(ctx context.Context, req resource.DeleteRequ _, err := a.client.DeleteAlertgroup(ctx, alertGroupName, instanceId, projectId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting alert group", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/observability/credential/resource.go b/stackit/internal/services/observability/credential/resource.go index c59b4c49d..cf9101ebb 100644 --- a/stackit/internal/services/observability/credential/resource.go +++ b/stackit/internal/services/observability/credential/resource.go @@ -2,6 +2,7 @@ package observability import ( "context" + "errors" "fmt" "net/http" @@ -227,17 +228,21 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, } _, err := r.client.GetCredentials(ctx, instanceId, projectId, userName).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } utils.LogError( ctx, &resp.Diagnostics, err, "Reading credential", - fmt.Sprintf("Credential with username %q or instance with ID %q does not exist in project %q.", userName, instanceId, projectId), + fmt.Sprintf("Error reading credential with username %q for instance %q in project %q.", userName, instanceId, projectId), map[int]string{ http.StatusForbidden: fmt.Sprintf("Project with ID %q not found or forbidden access", projectId), }, ) - resp.State.RemoveResource(ctx) return } @@ -273,8 +278,8 @@ func (r *credentialResource) Delete(ctx context.Context, req resource.DeleteRequ userName := model.Username.ValueString() _, err := r.client.DeleteCredentials(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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credential", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/observability/instance/resource.go b/stackit/internal/services/observability/instance/resource.go index 7935d1e0c..1c439c079 100644 --- a/stackit/internal/services/observability/instance/resource.go +++ b/stackit/internal/services/observability/instance/resource.go @@ -2,6 +2,7 @@ package observability import ( "context" + "errors" "fmt" "net/http" "strconv" @@ -1158,8 +1159,8 @@ 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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -1511,6 +1512,11 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques // Delete existing instance _, err := r.client.DeleteInstance(ctx, instanceId, projectId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting instance", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/observability/log-alertgroup/resource.go b/stackit/internal/services/observability/log-alertgroup/resource.go index 27d90bd66..b1d2f6fbf 100644 --- a/stackit/internal/services/observability/log-alertgroup/resource.go +++ b/stackit/internal/services/observability/log-alertgroup/resource.go @@ -314,8 +314,7 @@ func (l *logAlertGroupResource) Read(ctx context.Context, req resource.ReadReque readAlertGroupResp, err := l.client.GetLogsAlertgroup(ctx, alertGroupName, instanceId, projectId).Execute() if err != nil { var oapiErr *oapierror.GenericOpenAPIError - ok := errors.As(err, &oapiErr) - if ok && oapiErr.StatusCode == http.StatusNotFound { + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -365,6 +364,11 @@ func (l *logAlertGroupResource) Delete(ctx context.Context, req resource.DeleteR _, err := l.client.DeleteLogsAlertgroup(ctx, alertGroupName, instanceId, projectId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting log alert group", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/observability/scrapeconfig/resource.go b/stackit/internal/services/observability/scrapeconfig/resource.go index af1f0654e..2e3e0a449 100644 --- a/stackit/internal/services/observability/scrapeconfig/resource.go +++ b/stackit/internal/services/observability/scrapeconfig/resource.go @@ -2,6 +2,7 @@ package observability import ( "context" + "errors" "fmt" "net/http" "strings" @@ -404,8 +405,8 @@ 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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -528,6 +529,11 @@ func (r *scrapeConfigResource) Delete(ctx context.Context, req resource.DeleteRe // Delete existing ScrapeConfig _, err := r.client.DeleteScrapeConfig(ctx, instanceId, scName, projectId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting scrape config", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/opensearch/instance/resource.go b/stackit/internal/services/opensearch/instance/resource.go index f29e04cff..f5ec686c8 100644 --- a/stackit/internal/services/opensearch/instance/resource.go +++ b/stackit/internal/services/opensearch/instance/resource.go @@ -2,6 +2,7 @@ package opensearch import ( "context" + "errors" "fmt" "net/http" "slices" @@ -420,8 +421,8 @@ 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 || oapiErr.StatusCode == http.StatusGone) { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && (oapiErr.StatusCode == http.StatusNotFound || oapiErr.StatusCode == http.StatusGone) { resp.State.RemoveResource(ctx) return } @@ -541,6 +542,11 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques // Delete existing instance err := r.client.DeleteInstance(ctx, projectId, instanceId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting instance", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/postgresflex/instance/resource.go b/stackit/internal/services/postgresflex/instance/resource.go index 5c3536533..a6fc05978 100644 --- a/stackit/internal/services/postgresflex/instance/resource.go +++ b/stackit/internal/services/postgresflex/instance/resource.go @@ -2,6 +2,7 @@ package postgresflex import ( "context" + "errors" "fmt" "net/http" "regexp" @@ -407,8 +408,8 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r instanceResp, err := r.client.GetInstance(ctx, projectId, region, 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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -544,6 +545,11 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques // Delete existing instance err := r.client.DeleteInstance(ctx, projectId, region, instanceId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting instance", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/rabbitmq/instance/resource.go b/stackit/internal/services/rabbitmq/instance/resource.go index f12cd2506..dde60a3cf 100644 --- a/stackit/internal/services/rabbitmq/instance/resource.go +++ b/stackit/internal/services/rabbitmq/instance/resource.go @@ -2,6 +2,7 @@ package rabbitmq import ( "context" + "errors" "fmt" "net/http" "strings" @@ -421,8 +422,8 @@ 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 || oapiErr.StatusCode == http.StatusGone) { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && (oapiErr.StatusCode == http.StatusNotFound || oapiErr.StatusCode == http.StatusGone) { resp.State.RemoveResource(ctx) return } @@ -543,6 +544,11 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques // Delete existing instance err := r.client.DeleteInstance(ctx, projectId, instanceId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting instance", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/redis/instance/resource.go b/stackit/internal/services/redis/instance/resource.go index 73261b636..4533de7b5 100644 --- a/stackit/internal/services/redis/instance/resource.go +++ b/stackit/internal/services/redis/instance/resource.go @@ -2,6 +2,7 @@ package redis import ( "context" + "errors" "fmt" "net/http" "slices" @@ -490,8 +491,8 @@ 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 || oapiErr.StatusCode == http.StatusGone) { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && (oapiErr.StatusCode == http.StatusNotFound || oapiErr.StatusCode == http.StatusGone) { resp.State.RemoveResource(ctx) return } @@ -612,6 +613,11 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques // Delete existing instance err := r.client.DeleteInstance(ctx, projectId, instanceId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting instance", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/resourcemanager/folder/resource.go b/stackit/internal/services/resourcemanager/folder/resource.go index c340d0589..bbb8abf52 100644 --- a/stackit/internal/services/resourcemanager/folder/resource.go +++ b/stackit/internal/services/resourcemanager/folder/resource.go @@ -2,6 +2,7 @@ package folder import ( "context" + "errors" "fmt" "net/http" "regexp" @@ -269,8 +270,8 @@ func (r *folderResource) Read(ctx context.Context, req resource.ReadRequest, res folderResp, err := r.client.DefaultAPI.GetFolderDetails(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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusForbidden { resp.State.RemoveResource(ctx) return } @@ -364,6 +365,11 @@ func (r *folderResource) Delete(ctx context.Context, req resource.DeleteRequest, // Delete existing folder err := r.client.DefaultAPI.DeleteFolder(ctx, containerId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError( ctx, &resp.Diagnostics, diff --git a/stackit/internal/services/resourcemanager/project/resource.go b/stackit/internal/services/resourcemanager/project/resource.go index 6cd8cab19..1fd6c6881 100644 --- a/stackit/internal/services/resourcemanager/project/resource.go +++ b/stackit/internal/services/resourcemanager/project/resource.go @@ -2,6 +2,7 @@ package project import ( "context" + "errors" "fmt" "net/http" "regexp" @@ -268,8 +269,8 @@ func (r *projectResource) Read(ctx context.Context, req resource.ReadRequest, re projectResp, err := r.client.DefaultAPI.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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusForbidden { resp.State.RemoveResource(ctx) return } @@ -363,6 +364,11 @@ func (r *projectResource) Delete(ctx context.Context, req resource.DeleteRequest // Delete existing project err := r.client.DefaultAPI.DeleteProject(ctx, containerId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting project", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/scf/organizationmanager/resource.go b/stackit/internal/services/scf/organizationmanager/resource.go index ad8e9ae14..925b9ebc0 100644 --- a/stackit/internal/services/scf/organizationmanager/resource.go +++ b/stackit/internal/services/scf/organizationmanager/resource.go @@ -287,8 +287,7 @@ func (s *scfOrganizationManagerResource) Read(ctx context.Context, request resou scfOrgManager, err := s.client.GetOrgManagerExecute(ctx, projectId, region, orgId) if err != nil { var oapiErr *oapierror.GenericOpenAPIError - ok := errors.As(err, &oapiErr) - if ok && oapiErr.StatusCode == http.StatusNotFound { + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { core.LogAndAddWarning(ctx, &response.Diagnostics, "SCF Organization manager not found", "SCF Organization manager not found, remove from state") response.State.RemoveResource(ctx) return @@ -338,8 +337,7 @@ func (s *scfOrganizationManagerResource) Delete(ctx context.Context, request res _, err := s.client.DeleteOrgManagerExecute(ctx, projectId, region, orgId) if err != nil { var oapiErr *oapierror.GenericOpenAPIError - ok := errors.As(err, &oapiErr) - if ok && oapiErr.StatusCode == http.StatusGone { + if errors.As(err, &oapiErr) && (oapiErr.StatusCode == http.StatusGone || oapiErr.StatusCode == http.StatusNotFound) { tflog.Info(ctx, "Scf organization manager was already deleted") return } diff --git a/stackit/internal/services/secretsmanager/instance/resource.go b/stackit/internal/services/secretsmanager/instance/resource.go index 97814260e..79635b7e9 100644 --- a/stackit/internal/services/secretsmanager/instance/resource.go +++ b/stackit/internal/services/secretsmanager/instance/resource.go @@ -2,6 +2,7 @@ package secretsmanager import ( "context" + "errors" "fmt" "net/http" "strings" @@ -240,8 +241,8 @@ 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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -354,6 +355,11 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques // Delete existing instance err := r.client.DeleteInstance(ctx, projectId, instanceId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting instance", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/serviceaccount/account/resource.go b/stackit/internal/services/serviceaccount/account/resource.go index ebb234f27..200b1365d 100644 --- a/stackit/internal/services/serviceaccount/account/resource.go +++ b/stackit/internal/services/serviceaccount/account/resource.go @@ -2,7 +2,9 @@ package account import ( "context" + "errors" "fmt" + "net/http" "regexp" "strings" "time" @@ -20,6 +22,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" "github.com/stackitcloud/stackit-sdk-go/services/serviceaccount" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" @@ -199,6 +202,11 @@ func (r *serviceAccountResource) Read(ctx context.Context, req resource.ReadRequ // Fetch the list of service accounts from the API. listSaResp, err := r.client.ListServiceAccounts(ctx, projectId).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading service account", fmt.Sprintf("Error calling API: %v", err)) return } @@ -256,6 +264,11 @@ func (r *serviceAccountResource) Delete(ctx context.Context, req resource.Delete // Call API to delete the existing service account. err := r.client.DeleteServiceAccount(ctx, projectId, serviceAccountEmail).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting service account", 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 6f69b54da..598aabd76 100644 --- a/stackit/internal/services/ske/cluster/resource.go +++ b/stackit/internal/services/ske/cluster/resource.go @@ -2,6 +2,7 @@ package ske import ( "context" + "errors" "fmt" "net/http" "regexp" @@ -2193,8 +2194,8 @@ func (r *clusterResource) Read(ctx context.Context, req resource.ReadRequest, re clResp, err := r.skeClient.GetCluster(ctx, projectId, region, 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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -2275,6 +2276,11 @@ func (r *clusterResource) Delete(ctx context.Context, req resource.DeleteRequest c := r.skeClient _, err := c.DeleteCluster(ctx, projectId, region, name).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting cluster", fmt.Sprintf("Calling API: %v", err)) return } diff --git a/stackit/internal/services/ske/kubeconfig/resource.go b/stackit/internal/services/ske/kubeconfig/resource.go index b738456c1..0ed088393 100644 --- a/stackit/internal/services/ske/kubeconfig/resource.go +++ b/stackit/internal/services/ske/kubeconfig/resource.go @@ -2,6 +2,7 @@ package ske import ( "context" + "errors" "fmt" "net/http" "strconv" @@ -27,6 +28,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/stackitcloud/stackit-sdk-go/core/oapierror" sdkUtils "github.com/stackitcloud/stackit-sdk-go/core/utils" "github.com/stackitcloud/stackit-sdk-go/services/ske" ) @@ -314,17 +316,21 @@ func (r *kubeconfigResource) Read(ctx context.Context, req resource.ReadRequest, cluster, err := r.client.GetClusterExecute(ctx, projectId, region, clusterName) if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } utils.LogError( ctx, &resp.Diagnostics, err, "Reading kubeconfig", - fmt.Sprintf("Kubeconfig with ID %q or cluster with name %q does not exist in project %q.", kubeconfigUUID, clusterName, projectId), + fmt.Sprintf("Error reading kubeconfig with ID %q for cluster %q in project %q.", kubeconfigUUID, clusterName, projectId), map[int]string{ http.StatusForbidden: fmt.Sprintf("Project with ID %q not found or forbidden access", projectId), }, ) - resp.State.RemoveResource(ctx) return } diff --git a/stackit/internal/services/sqlserverflex/instance/resource.go b/stackit/internal/services/sqlserverflex/instance/resource.go index c132ea4fe..52d91ad59 100644 --- a/stackit/internal/services/sqlserverflex/instance/resource.go +++ b/stackit/internal/services/sqlserverflex/instance/resource.go @@ -2,6 +2,7 @@ package sqlserverflex import ( "context" + "errors" "fmt" "net/http" "regexp" @@ -501,8 +502,8 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r instanceResp, err := r.client.GetInstance(ctx, projectId, instanceId, region).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -643,6 +644,11 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques // Delete existing instance err := r.client.DeleteInstance(ctx, projectId, instanceId, region).Execute() if err != nil { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { + resp.State.RemoveResource(ctx) + return + } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting instance", fmt.Sprintf("Calling API: %v", err)) return } From 0e364b885ea36b67ded9a57ec51a3768e5cc8a42 Mon Sep 17 00:00:00 2001 From: Dominik Pildner Date: Tue, 31 Mar 2026 09:14:11 +0200 Subject: [PATCH 4/5] refactor: use error.as instead of silencing linter --- .../internal/services/iaas/networkarearegion/resource.go | 7 +++---- .../internal/services/iaas/networkarearoute/resource.go | 9 +++++---- .../internal/services/iaas/networkinterface/resource.go | 9 +++++---- .../services/iaas/networkinterfaceattach/resource.go | 9 +++++---- stackit/internal/services/iaas/volumeattach/resource.go | 9 +++++---- stackit/internal/services/kms/key/resource.go | 7 +++---- stackit/internal/services/kms/wrapping-key/resource.go | 7 +++---- stackit/internal/services/logme/credential/resource.go | 9 +++++---- stackit/internal/services/mariadb/credential/resource.go | 9 +++++---- stackit/internal/services/mongodbflex/user/resource.go | 9 +++++---- .../services/objectstorage/credential/resource.go | 9 +++++---- .../internal/services/opensearch/credential/resource.go | 9 +++++---- .../internal/services/postgresflex/database/resource.go | 8 ++++---- stackit/internal/services/postgresflex/user/resource.go | 9 +++++---- .../internal/services/rabbitmq/credential/resource.go | 9 +++++---- stackit/internal/services/redis/credential/resource.go | 9 +++++---- .../internal/services/secretsmanager/user/resource.go | 9 +++++---- .../internal/services/serverbackup/schedule/resource.go | 5 +++-- .../internal/services/serverupdate/schedule/resource.go | 5 +++-- stackit/internal/services/serviceaccount/key/resource.go | 7 +++---- stackit/internal/services/sqlserverflex/user/resource.go | 9 +++++---- 21 files changed, 92 insertions(+), 80 deletions(-) diff --git a/stackit/internal/services/iaas/networkarearegion/resource.go b/stackit/internal/services/iaas/networkarearegion/resource.go index 6e38125e8..37beadba6 100644 --- a/stackit/internal/services/iaas/networkarearegion/resource.go +++ b/stackit/internal/services/iaas/networkarearegion/resource.go @@ -335,8 +335,7 @@ func (r *networkAreaRegionResource) Read(ctx context.Context, req resource.ReadR networkAreaRegionResp, err := r.client.GetNetworkAreaRegion(ctx, organizationId, networkAreaId, region).Execute() if err != nil { var oapiErr *oapierror.GenericOpenAPIError - ok := errors.As(err, &oapiErr) - if ok && oapiErr.StatusCode == http.StatusNotFound { + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -452,8 +451,8 @@ func (r *networkAreaRegionResource) Delete(ctx context.Context, req resource.Del // Delete network area region configuration err = r.client.DeleteNetworkAreaRegion(ctx, organizationId, networkAreaId, region).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting network area region", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/iaas/networkarearoute/resource.go b/stackit/internal/services/iaas/networkarearoute/resource.go index ce43133b8..f253b8a98 100644 --- a/stackit/internal/services/iaas/networkarearoute/resource.go +++ b/stackit/internal/services/iaas/networkarearoute/resource.go @@ -1,6 +1,7 @@ package networkarearoute import ( + "errors" "context" "fmt" "net/http" @@ -419,8 +420,8 @@ func (r *networkAreaRouteResource) Read(ctx context.Context, req resource.ReadRe networkAreaRouteResp, err := r.client.GetNetworkAreaRoute(ctx, organizationId, networkAreaId, region, networkAreaRouteId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -470,8 +471,8 @@ func (r *networkAreaRouteResource) Delete(ctx context.Context, req resource.Dele // Delete existing network err := r.client.DeleteNetworkAreaRoute(ctx, organizationId, networkAreaId, region, networkAreaRouteId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting network area route", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/iaas/networkinterface/resource.go b/stackit/internal/services/iaas/networkinterface/resource.go index 396c738c0..7a84c19cd 100644 --- a/stackit/internal/services/iaas/networkinterface/resource.go +++ b/stackit/internal/services/iaas/networkinterface/resource.go @@ -1,6 +1,7 @@ package networkinterface import ( + "errors" "context" "fmt" "net/http" @@ -351,8 +352,8 @@ func (r *networkInterfaceResource) Read(ctx context.Context, req resource.ReadRe networkInterfaceResp, err := r.client.GetNic(ctx, projectId, region, networkId, networkInterfaceId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -459,8 +460,8 @@ func (r *networkInterfaceResource) Delete(ctx context.Context, req resource.Dele // Delete existing network interface err := r.client.DeleteNic(ctx, projectId, region, networkId, networkInterfaceId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting network interface", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/iaas/networkinterfaceattach/resource.go b/stackit/internal/services/iaas/networkinterfaceattach/resource.go index 18a102611..78505a973 100644 --- a/stackit/internal/services/iaas/networkinterfaceattach/resource.go +++ b/stackit/internal/services/iaas/networkinterfaceattach/resource.go @@ -1,6 +1,7 @@ package networkinterfaceattach import ( + "errors" "context" "fmt" "net/http" @@ -225,8 +226,8 @@ func (r *networkInterfaceAttachResource) Read(ctx context.Context, req resource. nics, err := r.client.ListServerNICs(ctx, projectId, region, serverId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -295,8 +296,8 @@ func (r *networkInterfaceAttachResource) Delete(ctx context.Context, req resourc // Remove network_interface from server err := r.client.RemoveNicFromServer(ctx, projectId, region, serverId, network_interfaceId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error removing network interface from server", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/iaas/volumeattach/resource.go b/stackit/internal/services/iaas/volumeattach/resource.go index 1074faaca..b7494c733 100644 --- a/stackit/internal/services/iaas/volumeattach/resource.go +++ b/stackit/internal/services/iaas/volumeattach/resource.go @@ -1,6 +1,7 @@ package volumeattach import ( + "errors" "context" "fmt" "net/http" @@ -247,8 +248,8 @@ func (r *volumeAttachResource) Read(ctx context.Context, req resource.ReadReques _, err := r.client.GetAttachedVolume(ctx, projectId, region, serverId, volumeId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -300,8 +301,8 @@ func (r *volumeAttachResource) Delete(ctx context.Context, req resource.DeleteRe // Remove volume from server err := r.client.RemoveVolumeFromServer(ctx, projectId, region, serverId, volumeId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error removing volume from server", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/kms/key/resource.go b/stackit/internal/services/kms/key/resource.go index 9eb3194b3..5cb1a92fb 100644 --- a/stackit/internal/services/kms/key/resource.go +++ b/stackit/internal/services/kms/key/resource.go @@ -329,8 +329,7 @@ func (r *keyResource) Read(ctx context.Context, req resource.ReadRequest, resp * keyResponse, err := r.client.GetKey(ctx, projectId, region, keyRingId, keyId).Execute() if err != nil { var oapiErr *oapierror.GenericOpenAPIError - ok := errors.As(err, &oapiErr) - if ok && oapiErr.StatusCode == http.StatusNotFound { + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -375,8 +374,8 @@ func (r *keyResource) Delete(ctx context.Context, req resource.DeleteRequest, re err := r.client.DeleteKey(ctx, projectId, region, keyRingId, keyId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting key", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/kms/wrapping-key/resource.go b/stackit/internal/services/kms/wrapping-key/resource.go index 4138c76c3..d5323be41 100644 --- a/stackit/internal/services/kms/wrapping-key/resource.go +++ b/stackit/internal/services/kms/wrapping-key/resource.go @@ -335,8 +335,7 @@ func (r *wrappingKeyResource) Read(ctx context.Context, request resource.ReadReq wrappingKeyResponse, err := r.client.GetWrappingKey(ctx, projectId, region, keyRingId, wrappingKeyId).Execute() if err != nil { var oapiErr *oapierror.GenericOpenAPIError - ok := errors.As(err, &oapiErr) - if ok && oapiErr.StatusCode == http.StatusNotFound { + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { response.State.RemoveResource(ctx) return } @@ -381,8 +380,8 @@ func (r *wrappingKeyResource) Delete(ctx context.Context, request resource.Delet err := r.client.DeleteWrappingKey(ctx, projectId, region, keyRingId, wrappingKeyId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &response.Diagnostics, "Error deleting wrapping key", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/logme/credential/resource.go b/stackit/internal/services/logme/credential/resource.go index 0ee110a90..7fe44be3d 100644 --- a/stackit/internal/services/logme/credential/resource.go +++ b/stackit/internal/services/logme/credential/resource.go @@ -1,6 +1,7 @@ package logme import ( + "errors" "context" "fmt" "net/http" @@ -236,8 +237,8 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, recordSetResp, err := r.client.GetCredentials(ctx, projectId, instanceId, credentialId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -290,8 +291,8 @@ func (r *credentialResource) Delete(ctx context.Context, req resource.DeleteRequ // Delete existing record set err := r.client.DeleteCredentials(ctx, projectId, instanceId, credentialId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credential", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/mariadb/credential/resource.go b/stackit/internal/services/mariadb/credential/resource.go index d8832f66f..4af392ff5 100644 --- a/stackit/internal/services/mariadb/credential/resource.go +++ b/stackit/internal/services/mariadb/credential/resource.go @@ -1,6 +1,7 @@ package mariadb import ( + "errors" "context" "fmt" "net/http" @@ -244,8 +245,8 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, recordSetResp, err := r.client.GetCredentials(ctx, projectId, instanceId, credentialId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -298,8 +299,8 @@ func (r *credentialResource) Delete(ctx context.Context, req resource.DeleteRequ // Delete existing record set err := r.client.DeleteCredentials(ctx, projectId, instanceId, credentialId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credential", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/mongodbflex/user/resource.go b/stackit/internal/services/mongodbflex/user/resource.go index 49f706388..90127198f 100644 --- a/stackit/internal/services/mongodbflex/user/resource.go +++ b/stackit/internal/services/mongodbflex/user/resource.go @@ -1,6 +1,7 @@ package mongodbflex import ( + "errors" "context" "fmt" "net/http" @@ -312,8 +313,8 @@ func (r *userResource) Read(ctx context.Context, req resource.ReadRequest, resp recordSetResp, err := r.client.GetUser(ctx, projectId, instanceId, userId, region).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -439,8 +440,8 @@ func (r *userResource) Delete(ctx context.Context, req resource.DeleteRequest, r // Delete user err := r.client.DeleteUser(ctx, projectId, instanceId, userId, region).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting user", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/objectstorage/credential/resource.go b/stackit/internal/services/objectstorage/credential/resource.go index aa91e4fc1..95005a997 100644 --- a/stackit/internal/services/objectstorage/credential/resource.go +++ b/stackit/internal/services/objectstorage/credential/resource.go @@ -1,6 +1,7 @@ package objectstorage import ( + "errors" "context" "fmt" "net/http" @@ -439,8 +440,8 @@ func (r *credentialResource) Delete(ctx context.Context, req resource.DeleteRequ // Delete existing credential _, err := r.client.DeleteAccessKey(ctx, projectId, region, credentialId).CredentialsGroup(credentialsGroupId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credential", fmt.Sprintf("Calling API: %v", err)) @@ -561,8 +562,8 @@ func readCredentials(ctx context.Context, model *Model, region string, client *o credentialsGroupResp, err := client.ListAccessKeys(ctx, projectId, region).CredentialsGroup(credentialsGroupId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return false, nil } return false, fmt.Errorf("getting credentials groups: %w", err) diff --git a/stackit/internal/services/opensearch/credential/resource.go b/stackit/internal/services/opensearch/credential/resource.go index 1b0e7ae61..e11a98838 100644 --- a/stackit/internal/services/opensearch/credential/resource.go +++ b/stackit/internal/services/opensearch/credential/resource.go @@ -1,6 +1,7 @@ package opensearch import ( + "errors" "context" "fmt" "net/http" @@ -240,8 +241,8 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, recordSetResp, err := r.client.GetCredentials(ctx, projectId, instanceId, credentialId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -294,8 +295,8 @@ func (r *credentialResource) Delete(ctx context.Context, req resource.DeleteRequ // Delete existing record set err := r.client.DeleteCredentials(ctx, projectId, instanceId, credentialId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credential", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/postgresflex/database/resource.go b/stackit/internal/services/postgresflex/database/resource.go index 4fe401bb2..ddd0b1fac 100644 --- a/stackit/internal/services/postgresflex/database/resource.go +++ b/stackit/internal/services/postgresflex/database/resource.go @@ -277,8 +277,8 @@ func (r *databaseResource) Read(ctx context.Context, req resource.ReadRequest, r databaseResp, err := getDatabase(ctx, r.client, projectId, region, instanceId, databaseId) 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) || errors.Is(err, errDatabaseNotFound) { + var oapiErr *oapierror.GenericOpenAPIError + if (errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound) || errors.Is(err, errDatabaseNotFound) { resp.State.RemoveResource(ctx) return } @@ -334,8 +334,8 @@ func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteReques // Delete existing record set err := r.client.DeleteDatabase(ctx, projectId, region, instanceId, databaseId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting database", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/postgresflex/user/resource.go b/stackit/internal/services/postgresflex/user/resource.go index f580add5b..aa93d8800 100644 --- a/stackit/internal/services/postgresflex/user/resource.go +++ b/stackit/internal/services/postgresflex/user/resource.go @@ -1,6 +1,7 @@ package postgresflex import ( + "errors" "context" "fmt" "net/http" @@ -296,8 +297,8 @@ func (r *userResource) Read(ctx context.Context, req resource.ReadRequest, resp recordSetResp, err := r.client.GetUser(ctx, projectId, region, 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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -423,8 +424,8 @@ func (r *userResource) Delete(ctx context.Context, req resource.DeleteRequest, r // Delete existing record set err := r.client.DeleteUser(ctx, projectId, region, 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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting user", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/rabbitmq/credential/resource.go b/stackit/internal/services/rabbitmq/credential/resource.go index 9ac599da5..8c8c17558 100644 --- a/stackit/internal/services/rabbitmq/credential/resource.go +++ b/stackit/internal/services/rabbitmq/credential/resource.go @@ -1,6 +1,7 @@ package rabbitmq import ( + "errors" "context" "fmt" "net/http" @@ -257,8 +258,8 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, recordSetResp, err := r.client.GetCredentials(ctx, projectId, instanceId, credentialId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -311,8 +312,8 @@ func (r *credentialResource) Delete(ctx context.Context, req resource.DeleteRequ // Delete existing record set err := r.client.DeleteCredentials(ctx, projectId, instanceId, credentialId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credential", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/redis/credential/resource.go b/stackit/internal/services/redis/credential/resource.go index cc57b2052..fd0a7a09e 100644 --- a/stackit/internal/services/redis/credential/resource.go +++ b/stackit/internal/services/redis/credential/resource.go @@ -1,6 +1,7 @@ package redis import ( + "errors" "context" "fmt" "net/http" @@ -246,8 +247,8 @@ func (r *credentialResource) Read(ctx context.Context, req resource.ReadRequest, recordSetResp, err := r.client.GetCredentials(ctx, projectId, instanceId, credentialId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -300,8 +301,8 @@ func (r *credentialResource) Delete(ctx context.Context, req resource.DeleteRequ // Delete existing record set err := r.client.DeleteCredentials(ctx, projectId, instanceId, credentialId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting credential", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/secretsmanager/user/resource.go b/stackit/internal/services/secretsmanager/user/resource.go index 5958d331c..625d509e1 100644 --- a/stackit/internal/services/secretsmanager/user/resource.go +++ b/stackit/internal/services/secretsmanager/user/resource.go @@ -1,6 +1,7 @@ package secretsmanager import ( + "errors" "context" "fmt" "net/http" @@ -235,8 +236,8 @@ 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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -343,8 +344,8 @@ func (r *userResource) Delete(ctx context.Context, req resource.DeleteRequest, r // Delete existing user err := r.client.DeleteUser(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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting user", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/serverbackup/schedule/resource.go b/stackit/internal/services/serverbackup/schedule/resource.go index 98acba376..e991e44cb 100644 --- a/stackit/internal/services/serverbackup/schedule/resource.go +++ b/stackit/internal/services/serverbackup/schedule/resource.go @@ -1,6 +1,7 @@ package schedule import ( + "errors" "context" "fmt" "net/http" @@ -319,8 +320,8 @@ func (r *scheduleResource) Read(ctx context.Context, req resource.ReadRequest, r scheduleResp, err := r.client.GetBackupSchedule(ctx, projectId, serverId, region, strconv.FormatInt(backupScheduleId, 10)).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } diff --git a/stackit/internal/services/serverupdate/schedule/resource.go b/stackit/internal/services/serverupdate/schedule/resource.go index d07d12139..7933d99e5 100644 --- a/stackit/internal/services/serverupdate/schedule/resource.go +++ b/stackit/internal/services/serverupdate/schedule/resource.go @@ -1,6 +1,7 @@ package schedule import ( + "errors" "context" "fmt" "net/http" @@ -294,8 +295,8 @@ func (r *scheduleResource) Read(ctx context.Context, req resource.ReadRequest, r scheduleResp, err := r.client.GetUpdateSchedule(ctx, projectId, serverId, strconv.FormatInt(updateScheduleId, 10), region).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } diff --git a/stackit/internal/services/serviceaccount/key/resource.go b/stackit/internal/services/serviceaccount/key/resource.go index 87ba31d8f..3ea5ac7bf 100644 --- a/stackit/internal/services/serviceaccount/key/resource.go +++ b/stackit/internal/services/serviceaccount/key/resource.go @@ -231,9 +231,8 @@ func (r *serviceAccountKeyResource) Read(ctx context.Context, req resource.ReadR _, err := r.client.GetServiceAccountKey(ctx, projectId, serviceAccountEmail, keyId).Execute() if err != nil { var oapiErr *oapierror.GenericOpenAPIError - ok := errors.As(err, &oapiErr) // due to security purposes, attempting to get access key for a non-existent Service Account will return 403. - if ok && oapiErr.StatusCode == http.StatusNotFound || oapiErr.StatusCode == http.StatusForbidden || oapiErr.StatusCode == http.StatusBadRequest { + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound || oapiErr.StatusCode == http.StatusForbidden || oapiErr.StatusCode == http.StatusBadRequest { resp.State.RemoveResource(ctx) return } @@ -285,8 +284,8 @@ func (r *serviceAccountKeyResource) Delete(ctx context.Context, req resource.Del // Call API to delete the existing service account key. err := r.client.DeleteServiceAccountKey(ctx, projectId, serviceAccountEmail, keyId).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting service account key", fmt.Sprintf("Calling API: %v", err)) diff --git a/stackit/internal/services/sqlserverflex/user/resource.go b/stackit/internal/services/sqlserverflex/user/resource.go index b19656d39..42677cc3f 100644 --- a/stackit/internal/services/sqlserverflex/user/resource.go +++ b/stackit/internal/services/sqlserverflex/user/resource.go @@ -1,6 +1,7 @@ package sqlserverflex import ( + "errors" "context" "fmt" "net/http" @@ -302,8 +303,8 @@ func (r *userResource) Read(ctx context.Context, req resource.ReadRequest, resp recordSetResp, err := r.client.GetUser(ctx, projectId, instanceId, userId, region).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { resp.State.RemoveResource(ctx) return } @@ -359,8 +360,8 @@ func (r *userResource) Delete(ctx context.Context, req resource.DeleteRequest, r // Delete existing record set err := r.client.DeleteUser(ctx, projectId, instanceId, userId, region).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 { + var oapiErr *oapierror.GenericOpenAPIError + if errors.As(err, &oapiErr) && oapiErr.StatusCode == http.StatusNotFound { return } core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting user", fmt.Sprintf("Calling API: %v", err)) From 937cb6eaae39c0a32dc51099681e5997ab333cbd Mon Sep 17 00:00:00 2001 From: Dominik Pildner Date: Tue, 31 Mar 2026 09:32:03 +0200 Subject: [PATCH 5/5] chore: gofmt --- stackit/internal/services/iaas/networkarearoute/resource.go | 2 +- stackit/internal/services/iaas/networkinterface/resource.go | 2 +- .../internal/services/iaas/networkinterfaceattach/resource.go | 2 +- stackit/internal/services/iaas/server/resource.go | 2 +- stackit/internal/services/iaas/volumeattach/resource.go | 2 +- stackit/internal/services/logme/credential/resource.go | 2 +- stackit/internal/services/mariadb/credential/resource.go | 2 +- stackit/internal/services/mongodbflex/user/resource.go | 2 +- stackit/internal/services/objectstorage/credential/resource.go | 2 +- stackit/internal/services/opensearch/credential/resource.go | 2 +- stackit/internal/services/postgresflex/user/resource.go | 2 +- stackit/internal/services/rabbitmq/credential/resource.go | 2 +- stackit/internal/services/redis/credential/resource.go | 2 +- stackit/internal/services/secretsmanager/user/resource.go | 2 +- stackit/internal/services/serverbackup/schedule/resource.go | 2 +- stackit/internal/services/serverupdate/schedule/resource.go | 2 +- stackit/internal/services/sqlserverflex/user/resource.go | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/stackit/internal/services/iaas/networkarearoute/resource.go b/stackit/internal/services/iaas/networkarearoute/resource.go index f253b8a98..03f6af1eb 100644 --- a/stackit/internal/services/iaas/networkarearoute/resource.go +++ b/stackit/internal/services/iaas/networkarearoute/resource.go @@ -1,8 +1,8 @@ package networkarearoute import ( - "errors" "context" + "errors" "fmt" "net/http" "strings" diff --git a/stackit/internal/services/iaas/networkinterface/resource.go b/stackit/internal/services/iaas/networkinterface/resource.go index 7a84c19cd..d9cb473bc 100644 --- a/stackit/internal/services/iaas/networkinterface/resource.go +++ b/stackit/internal/services/iaas/networkinterface/resource.go @@ -1,8 +1,8 @@ package networkinterface import ( - "errors" "context" + "errors" "fmt" "net/http" "regexp" diff --git a/stackit/internal/services/iaas/networkinterfaceattach/resource.go b/stackit/internal/services/iaas/networkinterfaceattach/resource.go index 78505a973..a2c57a641 100644 --- a/stackit/internal/services/iaas/networkinterfaceattach/resource.go +++ b/stackit/internal/services/iaas/networkinterfaceattach/resource.go @@ -1,8 +1,8 @@ package networkinterfaceattach import ( - "errors" "context" + "errors" "fmt" "net/http" "strings" diff --git a/stackit/internal/services/iaas/server/resource.go b/stackit/internal/services/iaas/server/resource.go index dcb19f5fc..76f89ee6f 100644 --- a/stackit/internal/services/iaas/server/resource.go +++ b/stackit/internal/services/iaas/server/resource.go @@ -2,8 +2,8 @@ package server import ( "context" - "errors" "encoding/base64" + "errors" "fmt" "net/http" "regexp" diff --git a/stackit/internal/services/iaas/volumeattach/resource.go b/stackit/internal/services/iaas/volumeattach/resource.go index b7494c733..68806b884 100644 --- a/stackit/internal/services/iaas/volumeattach/resource.go +++ b/stackit/internal/services/iaas/volumeattach/resource.go @@ -1,8 +1,8 @@ package volumeattach import ( - "errors" "context" + "errors" "fmt" "net/http" "strings" diff --git a/stackit/internal/services/logme/credential/resource.go b/stackit/internal/services/logme/credential/resource.go index 7fe44be3d..0bcc856c2 100644 --- a/stackit/internal/services/logme/credential/resource.go +++ b/stackit/internal/services/logme/credential/resource.go @@ -1,8 +1,8 @@ package logme import ( - "errors" "context" + "errors" "fmt" "net/http" "strings" diff --git a/stackit/internal/services/mariadb/credential/resource.go b/stackit/internal/services/mariadb/credential/resource.go index 4af392ff5..bd3f2d92a 100644 --- a/stackit/internal/services/mariadb/credential/resource.go +++ b/stackit/internal/services/mariadb/credential/resource.go @@ -1,8 +1,8 @@ package mariadb import ( - "errors" "context" + "errors" "fmt" "net/http" "strings" diff --git a/stackit/internal/services/mongodbflex/user/resource.go b/stackit/internal/services/mongodbflex/user/resource.go index 90127198f..ae924b019 100644 --- a/stackit/internal/services/mongodbflex/user/resource.go +++ b/stackit/internal/services/mongodbflex/user/resource.go @@ -1,8 +1,8 @@ package mongodbflex import ( - "errors" "context" + "errors" "fmt" "net/http" "strings" diff --git a/stackit/internal/services/objectstorage/credential/resource.go b/stackit/internal/services/objectstorage/credential/resource.go index 95005a997..8db2a2a8f 100644 --- a/stackit/internal/services/objectstorage/credential/resource.go +++ b/stackit/internal/services/objectstorage/credential/resource.go @@ -1,8 +1,8 @@ package objectstorage import ( - "errors" "context" + "errors" "fmt" "net/http" "strings" diff --git a/stackit/internal/services/opensearch/credential/resource.go b/stackit/internal/services/opensearch/credential/resource.go index e11a98838..668ab1859 100644 --- a/stackit/internal/services/opensearch/credential/resource.go +++ b/stackit/internal/services/opensearch/credential/resource.go @@ -1,8 +1,8 @@ package opensearch import ( - "errors" "context" + "errors" "fmt" "net/http" "strings" diff --git a/stackit/internal/services/postgresflex/user/resource.go b/stackit/internal/services/postgresflex/user/resource.go index aa93d8800..e9843cfac 100644 --- a/stackit/internal/services/postgresflex/user/resource.go +++ b/stackit/internal/services/postgresflex/user/resource.go @@ -1,8 +1,8 @@ package postgresflex import ( - "errors" "context" + "errors" "fmt" "net/http" "strings" diff --git a/stackit/internal/services/rabbitmq/credential/resource.go b/stackit/internal/services/rabbitmq/credential/resource.go index 8c8c17558..abd56045d 100644 --- a/stackit/internal/services/rabbitmq/credential/resource.go +++ b/stackit/internal/services/rabbitmq/credential/resource.go @@ -1,8 +1,8 @@ package rabbitmq import ( - "errors" "context" + "errors" "fmt" "net/http" "strings" diff --git a/stackit/internal/services/redis/credential/resource.go b/stackit/internal/services/redis/credential/resource.go index fd0a7a09e..707fa3e97 100644 --- a/stackit/internal/services/redis/credential/resource.go +++ b/stackit/internal/services/redis/credential/resource.go @@ -1,8 +1,8 @@ package redis import ( - "errors" "context" + "errors" "fmt" "net/http" "strings" diff --git a/stackit/internal/services/secretsmanager/user/resource.go b/stackit/internal/services/secretsmanager/user/resource.go index 625d509e1..f7fdf8e4c 100644 --- a/stackit/internal/services/secretsmanager/user/resource.go +++ b/stackit/internal/services/secretsmanager/user/resource.go @@ -1,8 +1,8 @@ package secretsmanager import ( - "errors" "context" + "errors" "fmt" "net/http" "strings" diff --git a/stackit/internal/services/serverbackup/schedule/resource.go b/stackit/internal/services/serverbackup/schedule/resource.go index e991e44cb..7e92a6a5e 100644 --- a/stackit/internal/services/serverbackup/schedule/resource.go +++ b/stackit/internal/services/serverbackup/schedule/resource.go @@ -1,8 +1,8 @@ package schedule import ( - "errors" "context" + "errors" "fmt" "net/http" "strconv" diff --git a/stackit/internal/services/serverupdate/schedule/resource.go b/stackit/internal/services/serverupdate/schedule/resource.go index 7933d99e5..f87eaaf05 100644 --- a/stackit/internal/services/serverupdate/schedule/resource.go +++ b/stackit/internal/services/serverupdate/schedule/resource.go @@ -1,8 +1,8 @@ package schedule import ( - "errors" "context" + "errors" "fmt" "net/http" "strconv" diff --git a/stackit/internal/services/sqlserverflex/user/resource.go b/stackit/internal/services/sqlserverflex/user/resource.go index 42677cc3f..a55787566 100644 --- a/stackit/internal/services/sqlserverflex/user/resource.go +++ b/stackit/internal/services/sqlserverflex/user/resource.go @@ -1,8 +1,8 @@ package sqlserverflex import ( - "errors" "context" + "errors" "fmt" "net/http" "strings"