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 06476e5c6..1cb9b13f6 100644 --- a/stackit/internal/services/iaas/network/resource.go +++ b/stackit/internal/services/iaas/network/resource.go @@ -455,6 +455,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 228b75e78..6e057cf80 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 8171fadfc..3cf764f80 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 39301118e..4e67fa6da 100644 --- a/stackit/internal/services/logs/accesstoken/resource.go +++ b/stackit/internal/services/logs/accesstoken/resource.go @@ -296,6 +296,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 eb89b1f83..3722e7183 100644 --- a/stackit/internal/services/logs/instance/resource.go +++ b/stackit/internal/services/logs/instance/resource.go @@ -281,6 +281,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 c12e120e1..aa91e4fc1 100644 --- a/stackit/internal/services/objectstorage/credential/resource.go +++ b/stackit/internal/services/objectstorage/credential/resource.go @@ -346,6 +346,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) @@ -434,7 +439,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 49a8a3d76..68e22ca13 100644 --- a/stackit/internal/services/objectstorage/credentialsgroup/resource.go +++ b/stackit/internal/services/objectstorage/credentialsgroup/resource.go @@ -248,6 +248,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 90f349d5e..c59b4c49d 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" @@ -219,6 +220,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( @@ -267,6 +273,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 a5c5db586..7935d1e0c 100644 --- a/stackit/internal/services/observability/instance/resource.go +++ b/stackit/internal/services/observability/instance/resource.go @@ -1148,6 +1148,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..f580add5b 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 //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/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 088ab62a0..c340d0589 100644 --- a/stackit/internal/services/resourcemanager/folder/resource.go +++ b/stackit/internal/services/resourcemanager/folder/resource.go @@ -258,6 +258,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 43acfd533..6cd8cab19 100644 --- a/stackit/internal/services/resourcemanager/project/resource.go +++ b/stackit/internal/services/resourcemanager/project/resource.go @@ -259,6 +259,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.DefaultAPI.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 2ca1cb8f4..c132ea4fe 100644 --- a/stackit/internal/services/sqlserverflex/instance/resource.go +++ b/stackit/internal/services/sqlserverflex/instance/resource.go @@ -462,6 +462,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 796dcfd2d..b19656d39 100644 --- a/stackit/internal/services/sqlserverflex/user/resource.go +++ b/stackit/internal/services/sqlserverflex/user/resource.go @@ -289,6 +289,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) @@ -354,6 +359,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 }