Skip to content

Commit

Permalink
[Refactor] Volume Attach
Browse files Browse the repository at this point in the history
  • Loading branch information
ismirlia committed Nov 15, 2024
1 parent f542550 commit 1b9e90a
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 118 deletions.
6 changes: 1 addition & 5 deletions ibm/service/power/ibm_pi_constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ const (
State_Creating = "creating"
State_Deleted = "deleted"
State_Deleting = "deleting"
State_Detaching = "detaching"
State_Down = "down"
State_Error = "error"
State_ERROR = "ERROR"
Expand All @@ -568,11 +569,6 @@ const (
State_Up = "up"
State_Updating = "updating"
State_VerifyResize = "verify_resize"
Status_Active = "ACTIVE"
Status_Deleting = "deleting"
Status_Error = "ERROR"
Status_Pending = "PENDING"
Status_Shutoff = "SHUTOFF"

// Timeout values
Timeout_Active = 2 * time.Minute
Expand Down
100 changes: 50 additions & 50 deletions ibm/service/power/resource_ibm_pi_volume_attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import (
"log"
"time"

st "github.com/IBM-Cloud/power-go-client/clients/instance"
"github.com/IBM-Cloud/power-go-client/helpers"
"github.com/IBM-Cloud/power-go-client/clients/instance"
"github.com/IBM-Cloud/power-go-client/power/client/p_cloud_volumes"
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns"
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

func ResourceIBMPIVolumeAttach() *schema.Resource {
Expand All @@ -33,32 +33,32 @@ func ResourceIBMPIVolumeAttach() *schema.Resource {
},

Schema: map[string]*schema.Schema{

helpers.PICloudInstanceId: {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: " Cloud Instance ID - This is the service_instance_id.",
// Arguments
Arg_CloudInstanceID: {
Description: "The GUID of the service instance associated with an account.",
ForceNew: true,
Required: true,
Type: schema.TypeString,
ValidateFunc: validation.NoZeroValues,
},

helpers.PIVolumeId: {
Type: schema.TypeString,
Required: true,
Arg_InstanceID: {
Description: "PI Instance Id",
ForceNew: true,
Description: "Id of the volume to attach. Note these volumes should have been created",
},

helpers.PIInstanceId: {
Type: schema.TypeString,
Required: true,
Type: schema.TypeString,
},
Arg_VolumeID: {
Description: "Id of the volume to attach. Note these volumes should have been created",
ForceNew: true,
Description: "PI Instance Id",
Required: true,
Type: schema.TypeString,
},

// Computed Attribute
helpers.PIVolumeAttachStatus: {
Type: schema.TypeString,
Computed: true,
// Attribute
Attr_Status: {
Computed: true,
Description: "The status of the volume.",
Type: schema.TypeString,
},
},
}
Expand All @@ -70,26 +70,26 @@ func resourceIBMPIVolumeAttachCreate(ctx context.Context, d *schema.ResourceData
return diag.FromErr(err)
}

volumeID := d.Get(helpers.PIVolumeId).(string)
pvmInstanceID := d.Get(helpers.PIInstanceId).(string)
cloudInstanceID := d.Get(helpers.PICloudInstanceId).(string)
cloudInstanceID := d.Get(Arg_CloudInstanceID).(string)
pvmInstanceID := d.Get(Arg_InstanceID).(string)
volumeID := d.Get(Arg_VolumeID).(string)

volClient := st.NewIBMPIVolumeClient(ctx, sess, cloudInstanceID)
volClient := instance.NewIBMPIVolumeClient(ctx, sess, cloudInstanceID)
volinfo, err := volClient.Get(volumeID)
if err != nil {
return diag.FromErr(err)
}

if volinfo.State == "available" || *volinfo.Shareable {
if volinfo.State == State_Available || *volinfo.Shareable {
log.Printf(" In the current state the volume can be attached to the instance ")
}

if volinfo.State == "in-use" && *volinfo.Shareable {
if volinfo.State == State_InUse && *volinfo.Shareable {

log.Printf("Volume State /Status is permitted and hence attaching the volume to the instance")
}

if volinfo.State == helpers.PIVolumeAllowableAttachStatus && !*volinfo.Shareable {
if volinfo.State == State_InUse && !*volinfo.Shareable {
return diag.Errorf("the volume cannot be attached in the current state. The volume must be in the *available* state. No other states are permissible")
}

Expand Down Expand Up @@ -121,14 +121,14 @@ func resourceIBMPIVolumeAttachRead(ctx context.Context, d *schema.ResourceData,
}
cloudInstanceID, pvmInstanceID, volumeID := ids[0], ids[1], ids[2]

client := st.NewIBMPIVolumeClient(ctx, sess, cloudInstanceID)
client := instance.NewIBMPIVolumeClient(ctx, sess, cloudInstanceID)

vol, err := client.CheckVolumeAttach(pvmInstanceID, volumeID)
if err != nil {
return diag.FromErr(err)
}

d.Set(helpers.PIVolumeAttachStatus, vol.State)
d.Set(Attr_Status, vol.State)
return nil
}

Expand All @@ -143,7 +143,7 @@ func resourceIBMPIVolumeAttachDelete(ctx context.Context, d *schema.ResourceData
return diag.FromErr(err)
}
cloudInstanceID, pvmInstanceID, volumeID := ids[0], ids[1], ids[2]
client := st.NewIBMPIVolumeClient(ctx, sess, cloudInstanceID)
client := instance.NewIBMPIVolumeClient(ctx, sess, cloudInstanceID)

log.Printf("the id of the volume to detach is %s ", volumeID)

Expand All @@ -170,12 +170,12 @@ func resourceIBMPIVolumeAttachDelete(ctx context.Context, d *schema.ResourceData
return nil
}

func isWaitForIBMPIVolumeAttachAvailable(ctx context.Context, client *st.IBMPIVolumeClient, id, cloudInstanceID, pvmInstanceID string, timeout time.Duration) (interface{}, error) {
func isWaitForIBMPIVolumeAttachAvailable(ctx context.Context, client *instance.IBMPIVolumeClient, id, cloudInstanceID, pvmInstanceID string, timeout time.Duration) (interface{}, error) {
log.Printf("Waiting for Volume (%s) to be available for attachment", id)

stateConf := &resource.StateChangeConf{
Pending: []string{"retry", helpers.PIVolumeProvisioning},
Target: []string{helpers.PIVolumeAllowableAttachStatus},
stateConf := &retry.StateChangeConf{
Pending: []string{State_Retry, State_Creating},
Target: []string{State_InUse},
Refresh: isIBMPIVolumeAttachRefreshFunc(client, id, cloudInstanceID, pvmInstanceID),
Delay: 10 * time.Second,
MinTimeout: 30 * time.Second,
Expand All @@ -185,27 +185,27 @@ func isWaitForIBMPIVolumeAttachAvailable(ctx context.Context, client *st.IBMPIVo
return stateConf.WaitForStateContext(ctx)
}

func isIBMPIVolumeAttachRefreshFunc(client *st.IBMPIVolumeClient, id, cloudInstanceID, pvmInstanceID string) resource.StateRefreshFunc {
func isIBMPIVolumeAttachRefreshFunc(client *instance.IBMPIVolumeClient, id, cloudInstanceID, pvmInstanceID string) retry.StateRefreshFunc {
return func() (interface{}, string, error) {
vol, err := client.Get(id)
if err != nil {
return nil, "", err
}

if vol.State == "in-use" && flex.StringContains(vol.PvmInstanceIDs, pvmInstanceID) {
return vol, helpers.PIVolumeAllowableAttachStatus, nil
if vol.State == State_InUse && flex.StringContains(vol.PvmInstanceIDs, pvmInstanceID) {
return vol, State_InUse, nil
}

return vol, helpers.PIVolumeProvisioning, nil
return vol, State_Creating, nil
}
}

func isWaitForIBMPIVolumeDetach(ctx context.Context, client *st.IBMPIVolumeClient, id, cloudInstanceID, pvmInstanceID string, timeout time.Duration) (interface{}, error) {
func isWaitForIBMPIVolumeDetach(ctx context.Context, client *instance.IBMPIVolumeClient, id, cloudInstanceID, pvmInstanceID string, timeout time.Duration) (interface{}, error) {
log.Printf("Waiting for Volume (%s) to be available after detachment", id)

stateConf := &resource.StateChangeConf{
Pending: []string{"detaching", helpers.PowerVolumeAttachDeleting},
Target: []string{helpers.PIVolumeProvisioningDone},
stateConf := &retry.StateChangeConf{
Pending: []string{State_Detaching, State_Deleting},
Target: []string{State_Available},
Refresh: isIBMPIVolumeDetachRefreshFunc(client, id, cloudInstanceID, pvmInstanceID),
Delay: 10 * time.Second,
MinTimeout: 30 * time.Second,
Expand All @@ -215,15 +215,15 @@ func isWaitForIBMPIVolumeDetach(ctx context.Context, client *st.IBMPIVolumeClien
return stateConf.WaitForStateContext(ctx)
}

func isIBMPIVolumeDetachRefreshFunc(client *st.IBMPIVolumeClient, id, cloudInstanceID, pvmInstanceID string) resource.StateRefreshFunc {
func isIBMPIVolumeDetachRefreshFunc(client *instance.IBMPIVolumeClient, id, cloudInstanceID, pvmInstanceID string) retry.StateRefreshFunc {
return func() (interface{}, string, error) {
vol, err := client.Get(id)
if err != nil {
uErr := errors.Unwrap(err)
switch uErr.(type) {
case *p_cloud_volumes.PcloudCloudinstancesVolumesGetNotFound:
log.Printf("[DEBUG] volume does not exist while detaching %v", err)
return vol, helpers.PIVolumeProvisioningDone, nil
return vol, State_Available, nil
}
return nil, "", err
}
Expand All @@ -232,10 +232,10 @@ func isIBMPIVolumeDetachRefreshFunc(client *st.IBMPIVolumeClient, id, cloudInsta
// Also validate the Volume state is 'available' when it is not Sharable
// In case of Sharable Volume it can be `in-use` state
if !flex.StringContains(vol.PvmInstanceIDs, pvmInstanceID) &&
(*vol.Shareable || (!*vol.Shareable && vol.State == "available")) {
return vol, helpers.PIVolumeProvisioningDone, nil
(*vol.Shareable || (!*vol.Shareable && vol.State == State_Available)) {
return vol, State_Available, nil
}

return vol, "detaching", nil
return vol, State_Detaching, nil
}
}
103 changes: 57 additions & 46 deletions ibm/service/power/resource_ibm_pi_volume_attach_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import (
"log"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"

st "github.com/IBM-Cloud/power-go-client/clients/instance"
acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest"

"github.com/IBM-Cloud/power-go-client/clients/instance"
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns"
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func TestAccIBMPIVolumeAttachbasic(t *testing.T) {
Expand Down Expand Up @@ -71,7 +71,7 @@ func testAccCheckIBMPIVolumeAttachDestroy(s *terraform.State) error {
return err
}
cloudInstanceID, pvmInstanceID, volumeID := ids[0], ids[1], ids[2]
client := st.NewIBMPIVolumeClient(context.Background(), sess, cloudInstanceID)
client := instance.NewIBMPIVolumeClient(context.Background(), sess, cloudInstanceID)
volumeAttach, err := client.CheckVolumeAttach(pvmInstanceID, volumeID)
if err == nil {
log.Println("volume attach*****", volumeAttach.State)
Expand All @@ -83,7 +83,6 @@ func testAccCheckIBMPIVolumeAttachDestroy(s *terraform.State) error {
}
func testAccCheckIBMPIVolumeAttachExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {

rs, ok := s.RootModule().Resources[n]

if !ok {
Expand All @@ -104,7 +103,7 @@ func testAccCheckIBMPIVolumeAttachExists(n string) resource.TestCheckFunc {
return err
}
cloudInstanceID, pvmInstanceID, volumeID := ids[0], ids[1], ids[2]
client := st.NewIBMPIVolumeClient(context.Background(), sess, cloudInstanceID)
client := instance.NewIBMPIVolumeClient(context.Background(), sess, cloudInstanceID)

_, err = client.CheckVolumeAttach(pvmInstanceID, volumeID)
if err != nil {
Expand All @@ -115,24 +114,30 @@ func testAccCheckIBMPIVolumeAttachExists(n string) resource.TestCheckFunc {
}
func testAccCheckIBMPIVolumeAttachConfig(name string) string {
return fmt.Sprintf(`
resource "ibm_pi_volume" "power_volume" {
pi_volume_size = 2
pi_volume_name = "%[2]s"
pi_volume_shareable = true
pi_volume_pool = "Tier3-Flash-1"
pi_cloud_instance_id = "%[1]s"
}
resource "ibm_pi_instance" "power_instance" {
pi_memory = "2"
pi_processors = "0.25"
pi_instance_name = "%[2]s"
pi_proc_type = "shared"
pi_image_id = "%[3]s"
pi_sys_type = "s922"
pi_cloud_instance_id = "%[1]s"
pi_storage_pool = "Tier3-Flash-1"
pi_network {
network_id = "%[4]s"
resource "ibm_pi_volume" "power_volume" {
pi_volume_size = 2
pi_volume_name = "%[2]s"
pi_volume_shareable = true
pi_volume_pool = "General-Flash-12"
pi_cloud_instance_id = "%[1]s"
}
resource "ibm_pi_instance" "power_instance" {
pi_memory = "2"
pi_processors = "0.25"
pi_instance_name = "%[2]s"
pi_proc_type = "shared"
pi_image_id = "%[3]s"
pi_sys_type = "s922"
pi_cloud_instance_id = "%[1]s"
pi_storage_pool = "General-Flash-12"
pi_network {
network_id = "%[4]s"
}
}
resource "ibm_pi_volume_attach" "power_attach_volume"{
pi_cloud_instance_id = "%[1]s"
pi_volume_id = ibm_pi_volume.power_volume.volume_id
pi_instance_id = ibm_pi_instance.power_instance.instance_id
}
}
resource "ibm_pi_volume_attach" "power_attach_volume"{
Expand All @@ -145,26 +150,32 @@ func testAccCheckIBMPIVolumeAttachConfig(name string) string {

func testAccCheckIBMPIShareableVolumeAttachConfig(name string) string {
return fmt.Sprintf(`
resource "ibm_pi_volume" "power_volume" {
pi_volume_size = 2
pi_volume_name = "%[2]s"
pi_volume_shareable = true
pi_volume_pool = "Tier3-Flash-1"
pi_cloud_instance_id = "%[1]s"
}
resource "ibm_pi_instance" "power_instance" {
count = 2
pi_memory = "2"
pi_processors = "0.25"
pi_instance_name = "%[2]s-${count.index}"
pi_proc_type = "shared"
pi_image_id = "%[3]s"
pi_sys_type = "s922"
pi_cloud_instance_id = "%[1]s"
pi_storage_pool = "Tier3-Flash-1"
pi_volume_ids = count.index == 0 ? [ibm_pi_volume.power_volume.volume_id] : null
pi_network {
network_id = "%[4]s"
resource "ibm_pi_volume" "power_volume" {
pi_volume_size = 2
pi_volume_name = "%[2]s"
pi_volume_shareable = true
pi_volume_pool = "General-Flash-12"
pi_cloud_instance_id = "%[1]s"
}
resource "ibm_pi_instance" "power_instance" {
count = 2
pi_memory = "2"
pi_processors = "0.25"
pi_instance_name = "%[2]s-${count.index}"
pi_proc_type = "shared"
pi_image_id = "%[3]s"
pi_sys_type = "s922"
pi_cloud_instance_id = "%[1]s"
pi_storage_pool = "General-Flash-12"
pi_volume_ids = count.index == 0 ? [ibm_pi_volume.power_volume.volume_id] : null
pi_network {
network_id = "%[4]s"
}
}
resource "ibm_pi_volume_attach" "power_attach_volume"{
pi_cloud_instance_id = "%[1]s"
pi_volume_id = ibm_pi_volume.power_volume.volume_id
pi_instance_id = ibm_pi_instance.power_instance[1].instance_id
}
}
resource "ibm_pi_volume_attach" "power_attach_volume"{
Expand Down
Loading

0 comments on commit 1b9e90a

Please sign in to comment.