From 433d10b9ced543d5d69d3fdd2da996657b83096a Mon Sep 17 00:00:00 2001 From: Stanislav Chirevko Date: Tue, 10 Oct 2023 11:24:07 +0300 Subject: [PATCH] Wait for volume to finish detaching when deleting resource vkcs_compute_volume_attach --- CHANGELOG.md | 3 +++ vkcs/blockstorage/resource_volume.go | 21 +++++++++--------- vkcs/blockstorage/resource_volume_snapshot.go | 2 +- vkcs/blockstorage/volume.go | 2 +- vkcs/compute/resource_volume_attach.go | 22 +++++++++++++++++++ 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 859fdece..1867f1f9 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ description: |- --- # VKCS Provider's changelog +#### v0.5.1 (unreleased) +- Wait for volume to finish detaching when deleting resource vkcs_compute_volume_attach + #### v0.5.0 - Add Direct Connect resources and data sources - Fix Kubernetes addon state refresh panic on error diff --git a/vkcs/blockstorage/resource_volume.go b/vkcs/blockstorage/resource_volume.go index e8c746bd..19497c0c 100644 --- a/vkcs/blockstorage/resource_volume.go +++ b/vkcs/blockstorage/resource_volume.go @@ -22,8 +22,9 @@ const ( var ( bsVolumeStatusBuild = "creating" - bsVolumeStatusActive = "available" - bsVolumeStatusInUse = "in-use" + BSVolumeStatusActive = "available" + BSVolumeStatusInUse = "in-use" + BSVolumeStatusDetaching = "detaching" bsVolumeStatusRetype = "retyping" bsVolumeStatusShutdown = "deleting" bsVolumeStatusDeleted = "deleted" @@ -159,8 +160,8 @@ func resourceBlockStorageVolumeCreate(ctx context.Context, d *schema.ResourceDat stateConf := &retry.StateChangeConf{ Pending: []string{bsVolumeStatusBuild, bsVolumeStatusDownloading}, - Target: []string{bsVolumeStatusActive}, - Refresh: blockStorageVolumeStateRefreshFunc(blockStorageClient, v.ID), + Target: []string{BSVolumeStatusActive}, + Refresh: BlockStorageVolumeStateRefreshFunc(blockStorageClient, v.ID), Timeout: d.Timeout(schema.TimeoutCreate), Delay: bsVolumeDelay, MinTimeout: bsVolumeMinTimeout, @@ -237,8 +238,8 @@ func resourceBlockStorageVolumeUpdate(ctx context.Context, d *schema.ResourceDat stateConf := &retry.StateChangeConf{ Pending: []string{bsVolumeStatusBuild, bsVolumeStatusDownloading}, - Target: []string{bsVolumeStatusActive, bsVolumeStatusInUse}, - Refresh: blockStorageVolumeStateRefreshFunc(blockStorageClient, d.Id()), + Target: []string{BSVolumeStatusActive, BSVolumeStatusInUse}, + Refresh: BlockStorageVolumeStateRefreshFunc(blockStorageClient, d.Id()), Timeout: d.Timeout(schema.TimeoutCreate), Delay: bsVolumeDelay, MinTimeout: bsVolumeMinTimeout, @@ -266,8 +267,8 @@ func resourceBlockStorageVolumeUpdate(ctx context.Context, d *schema.ResourceDat } stateConf := &retry.StateChangeConf{ Pending: []string{bsVolumeStatusBuild, bsVolumeStatusRetype}, - Target: []string{bsVolumeStatusActive, bsVolumeStatusInUse}, - Refresh: blockStorageVolumeStateRefreshFunc(blockStorageClient, d.Id()), + Target: []string{BSVolumeStatusActive, BSVolumeStatusInUse}, + Refresh: BlockStorageVolumeStateRefreshFunc(blockStorageClient, d.Id()), Timeout: d.Timeout(schema.TimeoutCreate), Delay: bsVolumeDelay, MinTimeout: bsVolumeMinTimeout, @@ -294,9 +295,9 @@ func resourceBlockStorageVolumeDelete(ctx context.Context, d *schema.ResourceDat } stateConf := &retry.StateChangeConf{ - Pending: []string{bsVolumeStatusActive, bsVolumeStatusShutdown, bsVolumeStatusInUse}, + Pending: []string{BSVolumeStatusActive, bsVolumeStatusShutdown}, Target: []string{bsVolumeStatusDeleted}, - Refresh: blockStorageVolumeStateRefreshFunc(blockStorageClient, d.Id()), + Refresh: BlockStorageVolumeStateRefreshFunc(blockStorageClient, d.Id()), Timeout: d.Timeout(schema.TimeoutDelete), Delay: bsVolumeDelay, MinTimeout: bsVolumeMinTimeout, diff --git a/vkcs/blockstorage/resource_volume_snapshot.go b/vkcs/blockstorage/resource_volume_snapshot.go index 65a53ac2..bbf51a39 100644 --- a/vkcs/blockstorage/resource_volume_snapshot.go +++ b/vkcs/blockstorage/resource_volume_snapshot.go @@ -230,7 +230,7 @@ func resourceBlockStorageSnapshotDelete(ctx context.Context, d *schema.ResourceD stateConf := &retry.StateChangeConf{ Pending: []string{bsSnapshotStatusActive, bsSnapshotStatusShutdown}, Target: []string{bsSnapshotStatusDeleted}, - Refresh: blockStorageVolumeStateRefreshFunc(blockStorageClient, d.Id()), + Refresh: BlockStorageVolumeStateRefreshFunc(blockStorageClient, d.Id()), Timeout: d.Timeout(schema.TimeoutDelete), Delay: bsSnapshotDelay, MinTimeout: bsSnapshotMinTimeout, diff --git a/vkcs/blockstorage/volume.go b/vkcs/blockstorage/volume.go index a18a56af..15d6aba4 100644 --- a/vkcs/blockstorage/volume.go +++ b/vkcs/blockstorage/volume.go @@ -19,7 +19,7 @@ func (opts volumeChangeTypeOpts) ToVolumeChangeTypeMap() (map[string]interface{} return util.BuildRequest(opts, "os-retype") } -func blockStorageVolumeStateRefreshFunc(client *gophercloud.ServiceClient, volumeID string) retry.StateRefreshFunc { +func BlockStorageVolumeStateRefreshFunc(client *gophercloud.ServiceClient, volumeID string) retry.StateRefreshFunc { return func() (interface{}, string, error) { v, err := volumes.Get(client, volumeID).Extract() if err != nil { diff --git a/vkcs/compute/resource_volume_attach.go b/vkcs/compute/resource_volume_attach.go index 9404529d..59db0832 100644 --- a/vkcs/compute/resource_volume_attach.go +++ b/vkcs/compute/resource_volume_attach.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/vk-cs/terraform-provider-vkcs/vkcs/blockstorage" "github.com/vk-cs/terraform-provider-vkcs/vkcs/internal/clients" "github.com/vk-cs/terraform-provider-vkcs/vkcs/internal/util" @@ -174,5 +175,26 @@ func resourceComputeVolumeAttachDelete(ctx context.Context, d *schema.ResourceDa return diag.FromErr(util.CheckDeleted(d, err, "Error detaching vkcs_compute_volume_attach")) } + // Volume may be still in detaching status after detach resource is deleted + blockStorageClient, err := config.BlockStorageV3Client(util.GetRegion(d, config)) + if err != nil { + return diag.Errorf("Error creating VKCS block storage client: %s", err) + } + + volumeID := d.Get("volume_id").(string) + + volumeStateConf := &retry.StateChangeConf{ + Pending: []string{blockstorage.BSVolumeStatusDetaching, blockstorage.BSVolumeStatusInUse}, + Target: []string{blockstorage.BSVolumeStatusActive}, + Refresh: blockstorage.BlockStorageVolumeStateRefreshFunc(blockStorageClient, volumeID), + Timeout: d.Timeout(schema.TimeoutDelete), + Delay: 5 * time.Second, + MinTimeout: 3 * time.Second, + } + + if _, err = volumeStateConf.WaitForStateContext(ctx); err != nil { + return diag.FromErr(util.CheckDeleted(d, err, "Error detaching vkcs_compute_volume_attach")) + } + return nil }