From 9d0988736376af5b6a2bc20f6f1a3d1bc6074432 Mon Sep 17 00:00:00 2001 From: Anton Kachurin Date: Mon, 1 Feb 2021 17:29:05 +0300 Subject: [PATCH 1/2] Add volume type validation for EVS v1 --- .../resource_opentelekomcloud_evs_v3.go | 47 ++++++------ .../resource_opentelekomcloud_evs_v3_test.go | 71 ++++++++++++------- 2 files changed, 73 insertions(+), 45 deletions(-) diff --git a/opentelekomcloud/resource_opentelekomcloud_evs_v3.go b/opentelekomcloud/resource_opentelekomcloud_evs_v3.go index c116e5fb4..7fc2161dd 100644 --- a/opentelekomcloud/resource_opentelekomcloud_evs_v3.go +++ b/opentelekomcloud/resource_opentelekomcloud_evs_v3.go @@ -6,11 +6,12 @@ import ( "log" "time" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/hashcode" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" - volumes_v2 "github.com/opentelekomcloud/gophertelekomcloud/openstack/blockstorage/v2/volumes" + volumesV2 "github.com/opentelekomcloud/gophertelekomcloud/openstack/blockstorage/v2/volumes" "github.com/opentelekomcloud/gophertelekomcloud/openstack/evs/v3/volumes" ) @@ -29,6 +30,8 @@ func resourceEvsStorageVolumeV3() *schema.Resource { Delete: schema.DefaultTimeout(3 * time.Minute), }, + CustomizeDiff: validateVolumeType("volume_type"), + Schema: map[string]*schema.Schema{ "backup_id": { Type: schema.TypeString, @@ -70,9 +73,6 @@ func resourceEvsStorageVolumeV3() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{ - "SATA", "SAS", "SSD", "co-p1", "uh-l1", - }, true), }, "device_type": { Type: schema.TypeString, @@ -145,11 +145,11 @@ func resourceEvsVolumeV3Create(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) blockStorageClient, err := config.blockStorageV3Client(GetRegion(d, config)) if err != nil { - return fmt.Errorf("Error creating OpenTelekomCloud EVS storage client: %s", err) + return fmt.Errorf("error creating OpenTelekomCloud EVS storage client: %s", err) } if !hasFilledOpt(d, "backup_id") && !hasFilledOpt(d, "size") { - return fmt.Errorf("Missing required argument: 'size' is required, but no definition was found.") + return fmt.Errorf("missing required argument: 'size' is required, but no definition was found") } tags := resourceContainerTags(d) createOpts := &volumes.CreateOpts{ @@ -179,7 +179,7 @@ func resourceEvsVolumeV3Create(d *schema.ResourceData, meta interface{}) error { log.Printf("[DEBUG] Create Options: %#v", createOpts) v, err := volumes.Create(blockStorageClient, createOpts).ExtractJobResponse() if err != nil { - return fmt.Errorf("Error creating OpenTelekomCloud EVS volume: %s", err) + return fmt.Errorf("error creating OpenTelekomCloud EVS volume: %s", err) } log.Printf("[INFO] Volume Job ID: %s", v.JobID) @@ -201,14 +201,14 @@ func resourceEvsVolumeV3Create(d *schema.ResourceData, meta interface{}) error { d.SetId(id) return resourceEvsVolumeV3Read(d, meta) } - return fmt.Errorf("Unexpected conversion error in resourceEvsVolumeV3Create.") + return fmt.Errorf("unexpected conversion error in resourceEvsVolumeV3Create") } func resourceEvsVolumeV3Read(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) blockStorageClient, err := config.blockStorageV3Client(GetRegion(d, config)) if err != nil { - return fmt.Errorf("Error creating OpenTelekomCloud EVS storage client: %s", err) + return fmt.Errorf("error creating OpenTelekomCloud EVS storage client: %s", err) } v, err := volumes.Get(blockStorageClient, d.Id()).Extract() @@ -218,14 +218,19 @@ func resourceEvsVolumeV3Read(d *schema.ResourceData, meta interface{}) error { log.Printf("[DEBUG] Retrieved volume %s: %+v", d.Id(), v) - d.Set("size", v.Size) - d.Set("description", v.Description) - d.Set("availability_zone", v.AvailabilityZone) - d.Set("name", v.Name) - d.Set("snapshot_id", v.SnapshotID) - d.Set("source_vol_id", v.SourceVolID) - d.Set("volume_type", v.VolumeType) - d.Set("wwn", v.WWN) + mErr := multierror.Append( + d.Set("size", v.Size), + d.Set("description", v.Description), + d.Set("availability_zone", v.AvailabilityZone), + d.Set("name", v.Name), + d.Set("snapshot_id", v.SnapshotID), + d.Set("source_vol_id", v.SourceVolID), + d.Set("volume_type", v.VolumeType), + d.Set("wwn", v.WWN), + ) + if err := mErr.ErrorOrNil(); err != nil { + return err + } // set tags tags := make(map[string]string) @@ -257,17 +262,17 @@ func resourceEvsVolumeV3Update(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) blockStorageClient, err := config.blockStorageV2Client(GetRegion(d, config)) if err != nil { - return fmt.Errorf("Error creating OpenTelekomCloud block storage client: %s", err) + return fmt.Errorf("error creating OpenTelekomCloud block storage client: %s", err) } - updateOpts := volumes_v2.UpdateOpts{ + updateOpts := volumesV2.UpdateOpts{ Name: d.Get("name").(string), Description: d.Get("description").(string), } - _, err = volumes_v2.Update(blockStorageClient, d.Id(), updateOpts).Extract() + _, err = volumesV2.Update(blockStorageClient, d.Id(), updateOpts).Extract() if err != nil { - return fmt.Errorf("Error updating OpenTelekomCloud volume: %s", err) + return fmt.Errorf("error updating OpenTelekomCloud volume: %s", err) } if d.HasChange("tags") { diff --git a/opentelekomcloud/resource_opentelekomcloud_evs_v3_test.go b/opentelekomcloud/resource_opentelekomcloud_evs_v3_test.go index 8514f41ec..dc83031aa 100644 --- a/opentelekomcloud/resource_opentelekomcloud_evs_v3_test.go +++ b/opentelekomcloud/resource_opentelekomcloud_evs_v3_test.go @@ -2,6 +2,7 @@ package opentelekomcloud import ( "fmt" + "regexp" "testing" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" @@ -100,11 +101,26 @@ func TestAccEvsStorageV3Volume_timeout(t *testing.T) { }) } +func TestAccEvsStorageV3Volume_volumeType(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckEvsStorageV3VolumeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEvsStorageV3Volume_volumeType, + PlanOnly: true, + ExpectError: regexp.MustCompile(`volume type .+ doesn't exist`), + }, + }, + }) +} + func testAccCheckEvsStorageV3VolumeDestroy(s *terraform.State) error { config := testAccProvider.Meta().(*Config) blockStorageClient, err := config.blockStorageV3Client(OS_REGION_NAME) if err != nil { - return fmt.Errorf("Error creating OpenTelekomCloud evs storage client: %s", err) + return fmt.Errorf("error creating OpenTelekomCloud evs storage client: %s", err) } for _, rs := range s.RootModule().Resources { @@ -114,7 +130,7 @@ func testAccCheckEvsStorageV3VolumeDestroy(s *terraform.State) error { _, err := volumes.Get(blockStorageClient, rs.Primary.ID).Extract() if err == nil { - return fmt.Errorf("Volume still exists") + return fmt.Errorf("volume still exists") } } @@ -125,17 +141,17 @@ func testAccCheckEvsStorageV3VolumeExists(n string, volume *volumes.Volume) reso return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not found: %s", n) + return fmt.Errorf("not found: %s", n) } if rs.Primary.ID == "" { - return fmt.Errorf("No ID is set") + return fmt.Errorf("no ID is set") } config := testAccProvider.Meta().(*Config) blockStorageClient, err := config.blockStorageV3Client(OS_REGION_NAME) if err != nil { - return fmt.Errorf("Error creating OpenTelekomCloud evs storage client: %s", err) + return fmt.Errorf("error creating OpenTelekomCloud evs storage client: %s", err) } found, err := volumes.Get(blockStorageClient, rs.Primary.ID).Extract() @@ -144,7 +160,7 @@ func testAccCheckEvsStorageV3VolumeExists(n string, volume *volumes.Volume) reso } if found.ID != rs.Primary.ID { - return fmt.Errorf("Volume not found") + return fmt.Errorf("volume not found") } *volume = *found @@ -157,17 +173,17 @@ func testAccCheckEvsStorageV3VolumeTags(n string, k string, v string) resource.T return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not found: %s", n) + return fmt.Errorf("not found: %s", n) } if rs.Primary.ID == "" { - return fmt.Errorf("No ID is set") + return fmt.Errorf("no ID is set") } config := testAccProvider.Meta().(*Config) blockStorageClient, err := config.blockStorageV3Client(OS_REGION_NAME) if err != nil { - return fmt.Errorf("Error creating OpenTelekomCloud block storage client: %s", err) + return fmt.Errorf("error creating OpenTelekomCloud block storage client: %s", err) } found, err := volumes.Get(blockStorageClient, rs.Primary.ID).Extract() @@ -176,11 +192,11 @@ func testAccCheckEvsStorageV3VolumeTags(n string, k string, v string) resource.T } if found.ID != rs.Primary.ID { - return fmt.Errorf("Volume not found") + return fmt.Errorf("volume not found") } if found.Tags == nil { - return fmt.Errorf("No Tags") + return fmt.Errorf("no Tags") } for key, value := range found.Tags { @@ -191,13 +207,14 @@ func testAccCheckEvsStorageV3VolumeTags(n string, k string, v string) resource.T if v == value { return nil } - return fmt.Errorf("Bad value for %s: %s", k, value) + return fmt.Errorf("bad value for %s: %s", k, value) } - return fmt.Errorf("Tag not found: %s", k) + return fmt.Errorf("tag not found: %s", k) } } -var testAccEvsStorageV3Volume_basic = fmt.Sprintf(` +var ( + testAccEvsStorageV3Volume_basic = fmt.Sprintf(` resource "opentelekomcloud_evs_volume_v3" "volume_1" { name = "volume_1" description = "first test volume" @@ -206,8 +223,7 @@ resource "opentelekomcloud_evs_volume_v3" "volume_1" { size = 12 } `, OS_AVAILABILITY_ZONE) - -var testAccEvsStorageV3Volume_update = fmt.Sprintf(` + testAccEvsStorageV3Volume_update = fmt.Sprintf(` resource "opentelekomcloud_evs_volume_v3" "volume_1" { name = "volume_1-updated" description = "first test volume" @@ -216,8 +232,7 @@ resource "opentelekomcloud_evs_volume_v3" "volume_1" { size = 12 } `, OS_AVAILABILITY_ZONE) - -var testAccEvsStorageV3Volume_tags = fmt.Sprintf(` + testAccEvsStorageV3Volume_tags = fmt.Sprintf(` resource "opentelekomcloud_evs_volume_v3" "volume_tags" { name = "volume_tags" description = "test volume with tags" @@ -230,8 +245,7 @@ resource "opentelekomcloud_evs_volume_v3" "volume_tags" { size = 12 } `, OS_AVAILABILITY_ZONE) - -var testAccEvsStorageV3Volume_tags_update = fmt.Sprintf(` + testAccEvsStorageV3Volume_tags_update = fmt.Sprintf(` resource "opentelekomcloud_evs_volume_v3" "volume_tags" { name = "volume_tags-updated" description = "test volume with tags" @@ -244,8 +258,7 @@ resource "opentelekomcloud_evs_volume_v3" "volume_tags" { size = 12 } `, OS_AVAILABILITY_ZONE) - -var testAccEvsStorageV3Volume_image = fmt.Sprintf(` + testAccEvsStorageV3Volume_image = fmt.Sprintf(` resource "opentelekomcloud_evs_volume_v3" "volume_1" { name = "volume_1" availability_zone = "%s" @@ -254,8 +267,7 @@ resource "opentelekomcloud_evs_volume_v3" "volume_1" { image_id = "%s" } `, OS_AVAILABILITY_ZONE, OS_IMAGE_ID) - -var testAccEvsStorageV3Volume_timeout = fmt.Sprintf(` + testAccEvsStorageV3Volume_timeout = fmt.Sprintf(` resource "opentelekomcloud_evs_volume_v3" "volume_1" { name = "volume_1" description = "first test volume" @@ -269,3 +281,14 @@ resource "opentelekomcloud_evs_volume_v3" "volume_1" { } } `, OS_AVAILABILITY_ZONE) + + testAccEvsStorageV3Volume_volumeType = fmt.Sprintf(` +resource "opentelekomcloud_evs_volume_v3" "volume_1" { + name = "volume_1" + description = "first test volume" + availability_zone = "%s" + volume_type = "asfddasf" + size = 12 +} +`, OS_AVAILABILITY_ZONE) +) From a4bc02885e1a21e20d4091ac8b8c73497540bf9e Mon Sep 17 00:00:00 2001 From: Anton Kachurin Date: Mon, 1 Feb 2021 17:43:23 +0300 Subject: [PATCH 2/2] Remove setting `source_vol_id` --- opentelekomcloud/resource_opentelekomcloud_evs_v3.go | 1 - 1 file changed, 1 deletion(-) diff --git a/opentelekomcloud/resource_opentelekomcloud_evs_v3.go b/opentelekomcloud/resource_opentelekomcloud_evs_v3.go index 7fc2161dd..c447f199c 100644 --- a/opentelekomcloud/resource_opentelekomcloud_evs_v3.go +++ b/opentelekomcloud/resource_opentelekomcloud_evs_v3.go @@ -224,7 +224,6 @@ func resourceEvsVolumeV3Read(d *schema.ResourceData, meta interface{}) error { d.Set("availability_zone", v.AvailabilityZone), d.Set("name", v.Name), d.Set("snapshot_id", v.SnapshotID), - d.Set("source_vol_id", v.SourceVolID), d.Set("volume_type", v.VolumeType), d.Set("wwn", v.WWN), )