-
Notifications
You must be signed in to change notification settings - Fork 162
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add huaweicloud_evs_snapshot resource and docs (#289)
Signed-off-by: ShiChangkuo <[email protected]>
- Loading branch information
1 parent
d256405
commit 6a71417
Showing
12 changed files
with
651 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
package huaweicloud | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
"github.com/huaweicloud/golangsdk" | ||
"github.com/huaweicloud/golangsdk/openstack/evs/v2/snapshots" | ||
) | ||
|
||
func resourceEvsSnapshotV2() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceEvsSnapshotV2Create, | ||
Read: resourceEvsSnapshotV2Read, | ||
Update: resourceEvsSnapshotV2Update, | ||
Delete: resourceEvsSnapshotV2Delete, | ||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Timeouts: &schema.ResourceTimeout{ | ||
Create: schema.DefaultTimeout(10 * time.Minute), | ||
Delete: schema.DefaultTimeout(3 * time.Minute), | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"volume_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: false, | ||
}, | ||
"description": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
ForceNew: false, | ||
}, | ||
"force": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Default: false, | ||
}, | ||
"status": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"size": { | ||
Type: schema.TypeInt, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceEvsSnapshotV2Create(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
evsClient, err := config.blockStorageV2Client(GetRegion(d, config)) | ||
if err != nil { | ||
return fmt.Errorf("Error creating HuaweiCloud EVS storage client: %s", err) | ||
} | ||
|
||
createOpts := &snapshots.CreateOpts{ | ||
VolumeID: d.Get("volume_id").(string), | ||
Name: d.Get("name").(string), | ||
Description: d.Get("description").(string), | ||
Force: d.Get("force").(bool), | ||
} | ||
|
||
log.Printf("[DEBUG] Create Options: %#v", createOpts) | ||
v, err := snapshots.Create(evsClient, createOpts).Extract() | ||
if err != nil { | ||
return fmt.Errorf("Error creating HuaweiCloud EVS snapshot: %s", err) | ||
} | ||
|
||
// Wait for the snapshot to become available. | ||
log.Printf("[DEBUG] Waiting for volume to become available") | ||
err = snapshots.WaitForStatus(evsClient, v.ID, "available", int(d.Timeout(schema.TimeoutCreate)/time.Second)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Store the ID now | ||
d.SetId(v.ID) | ||
return resourceEvsSnapshotV2Read(d, meta) | ||
} | ||
|
||
func resourceEvsSnapshotV2Read(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
evsClient, err := config.blockStorageV2Client(GetRegion(d, config)) | ||
if err != nil { | ||
return fmt.Errorf("Error creating HuaweiCloud EVS storage client: %s", err) | ||
} | ||
|
||
v, err := snapshots.Get(evsClient, d.Id()).Extract() | ||
if err != nil { | ||
return CheckDeleted(d, err, "snapshot") | ||
} | ||
|
||
log.Printf("[DEBUG] Retrieved volume %s: %+v", d.Id(), v) | ||
|
||
d.Set("volume_id", v.VolumeID) | ||
d.Set("name", v.Name) | ||
d.Set("description", v.Description) | ||
d.Set("status", v.Status) | ||
d.Set("size", v.Size) | ||
|
||
return nil | ||
} | ||
|
||
func resourceEvsSnapshotV2Update(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
evsClient, err := config.blockStorageV2Client(GetRegion(d, config)) | ||
if err != nil { | ||
return fmt.Errorf("Error creating HuaweiCloud EVS storage client: %s", err) | ||
} | ||
|
||
updateOpts := snapshots.UpdateOpts{ | ||
Name: d.Get("name").(string), | ||
Description: d.Get("description").(string), | ||
} | ||
|
||
_, err = snapshots.Update(evsClient, d.Id(), updateOpts).Extract() | ||
if err != nil { | ||
return fmt.Errorf("Error updating HuaweiCloud EVS snapshot: %s", err) | ||
} | ||
|
||
return resourceEvsSnapshotV2Read(d, meta) | ||
} | ||
|
||
func resourceEvsSnapshotV2Delete(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
evsClient, err := config.blockStorageV2Client(GetRegion(d, config)) | ||
if err != nil { | ||
return fmt.Errorf("Error creating HuaweiCloud EVS storage client: %s", err) | ||
} | ||
|
||
if err := snapshots.Delete(evsClient, d.Id()).ExtractErr(); err != nil { | ||
return CheckDeleted(d, err, "snapshot") | ||
} | ||
|
||
// Wait for the snapshot to delete before moving on. | ||
log.Printf("[DEBUG] Waiting for snapshot (%s) to delete", d.Id()) | ||
|
||
stateConf := &resource.StateChangeConf{ | ||
Pending: []string{"available", "deleting"}, | ||
Target: []string{"deleted"}, | ||
Refresh: snapshotStateRefreshFunc(evsClient, d.Id()), | ||
Timeout: d.Timeout(schema.TimeoutDelete), | ||
Delay: 2 * time.Second, | ||
MinTimeout: 3 * time.Second, | ||
} | ||
|
||
_, err = stateConf.WaitForState() | ||
if err != nil { | ||
return fmt.Errorf( | ||
"Error waiting for snapshot (%s) to delete: %s", | ||
d.Id(), err) | ||
} | ||
|
||
d.SetId("") | ||
return nil | ||
} | ||
|
||
// snapshotStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch | ||
// an HuaweiCloud snapshot. | ||
func snapshotStateRefreshFunc(client *golangsdk.ServiceClient, id string) resource.StateRefreshFunc { | ||
return func() (interface{}, string, error) { | ||
v, err := snapshots.Get(client, id).Extract() | ||
if err != nil { | ||
if _, ok := err.(golangsdk.ErrDefault404); ok { | ||
return v, "deleted", nil | ||
} | ||
return nil, "", err | ||
} | ||
|
||
if v.Status == "error" || v.Status == "error_deleting" { | ||
return v, v.Status, fmt.Errorf("There was an error creating or deleting the snapshot. " + | ||
"Please check with your cloud admin or check the API logs " + | ||
"to see why this error occurred.") | ||
} | ||
|
||
return v, v.Status, nil | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package huaweicloud | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/terraform" | ||
|
||
"github.com/huaweicloud/golangsdk/openstack/evs/v2/snapshots" | ||
) | ||
|
||
func TestAccEvsSnapshotV2_basic(t *testing.T) { | ||
var snapshot snapshots.Snapshot | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckEvsSnapshotV2Destroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccEvsSnapshotV2_basic, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckEvsSnapshotV2Exists("huaweicloud_evs_snapshot.snapshot_1", &snapshot), | ||
resource.TestCheckResourceAttr( | ||
"huaweicloud_evs_snapshot.snapshot_1", "name", "snapshot_acc"), | ||
resource.TestCheckResourceAttr( | ||
"huaweicloud_evs_snapshot.snapshot_1", "description", "Daily backup"), | ||
resource.TestCheckResourceAttr( | ||
"huaweicloud_evs_snapshot.snapshot_1", "status", "available"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckEvsSnapshotV2Destroy(s *terraform.State) error { | ||
config := testAccProvider.Meta().(*Config) | ||
evsClient, err := config.blockStorageV2Client(OS_REGION_NAME) | ||
if err != nil { | ||
return fmt.Errorf("Error creating Huaweicloud EVS storage client: %s", err) | ||
} | ||
|
||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "huaweicloud_evs_snapshot" { | ||
continue | ||
} | ||
|
||
_, err := snapshots.Get(evsClient, rs.Primary.ID).Extract() | ||
if err == nil { | ||
return fmt.Errorf("EVS snapshot still exists") | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func testAccCheckEvsSnapshotV2Exists(n string, sp *snapshots.Snapshot) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
rs, ok := s.RootModule().Resources[n] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", n) | ||
} | ||
|
||
if rs.Primary.ID == "" { | ||
return fmt.Errorf("No ID is set") | ||
} | ||
|
||
config := testAccProvider.Meta().(*Config) | ||
evsClient, err := config.blockStorageV2Client(OS_REGION_NAME) | ||
if err != nil { | ||
return fmt.Errorf("Error creating Huaweicloud EVS storage client: %s", err) | ||
} | ||
|
||
found, err := snapshots.Get(evsClient, rs.Primary.ID).Extract() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if found.ID != rs.Primary.ID { | ||
return fmt.Errorf("EVS snapshot not found") | ||
} | ||
|
||
*sp = *found | ||
|
||
return nil | ||
} | ||
} | ||
|
||
const testAccEvsSnapshotV2_basic = ` | ||
resource "huaweicloud_blockstorage_volume_v2" "volume_1" { | ||
name = "volume_acc" | ||
description = "volume for snapshot testing" | ||
size = 40 | ||
cascade = true | ||
} | ||
resource "huaweicloud_evs_snapshot" "snapshot_1" { | ||
volume_id = huaweicloud_blockstorage_volume_v2.volume_1.id | ||
name = "snapshot_acc" | ||
description = "Daily backup" | ||
} | ||
` |
Oops, something went wrong.