From 0ff734f1577b01bd67a51092a56fe4a2e15deb28 Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 27 Mar 2017 13:16:01 +0300 Subject: [PATCH] provider/digitalocean: Support disk only resize (#13059) Allow to resize a droplet permanently (i.e. apply disk resize) if previously it was resized temporarily (CPU and RAM only). Fixes: #13007 ``` $ make testacc TEST=./builtin/providers/digitalocean TESTARGS='-run=TestAccDigitalOceanDroplet_ResizeOnlyDisk' ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/03/25 03:54:23 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/digitalocean -v -run=TestAccDigitalOceanDroplet_ResizeOnlyDisk -timeout 120m === RUN TestAccDigitalOceanDroplet_ResizeOnlyDisk --- PASS: TestAccDigitalOceanDroplet_ResizeOnlyDisk (198.62s) PASS ok github.com/hashicorp/terraform/builtin/providers/digitalocean 198.638s ``` --- .../resource_digitalocean_droplet.go | 20 ++--- .../resource_digitalocean_droplet_test.go | 78 +++++++++++++++++++ 2 files changed, 84 insertions(+), 14 deletions(-) diff --git a/builtin/providers/digitalocean/resource_digitalocean_droplet.go b/builtin/providers/digitalocean/resource_digitalocean_droplet.go index ff57a63d9ec1..76212d579be7 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_droplet.go +++ b/builtin/providers/digitalocean/resource_digitalocean_droplet.go @@ -322,8 +322,9 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{}) return fmt.Errorf("invalid droplet id: %v", err) } - if d.HasChange("size") { - oldSize, newSize := d.GetChange("size") + resize_disk := d.Get("resize_disk").(bool) + if d.HasChange("size") || d.HasChange("resize_disk") && resize_disk { + newSize := d.Get("size") _, _, err = client.DropletActions.PowerOff(id) if err != nil && !strings.Contains(err.Error(), "Droplet is already powered off") { @@ -339,13 +340,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{}) } // Resize the droplet - resize_disk := d.Get("resize_disk") - switch { - case resize_disk == true: - _, _, err = client.DropletActions.Resize(id, newSize.(string), true) - case resize_disk == false: - _, _, err = client.DropletActions.Resize(id, newSize.(string), false) - } + action, _, err := client.DropletActions.Resize(id, newSize.(string), resize_disk) if err != nil { newErr := powerOnAndWait(d, meta) if newErr != nil { @@ -356,11 +351,8 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{}) "Error resizing droplet (%s): %s", d.Id(), err) } - // Wait for the size to change - _, err = WaitForDropletAttribute( - d, newSize.(string), []string{"", oldSize.(string)}, "size", meta) - - if err != nil { + // Wait for the resize action to complete. + if err := waitForAction(client, action); err != nil { newErr := powerOnAndWait(d, meta) if newErr != nil { return fmt.Errorf( diff --git a/builtin/providers/digitalocean/resource_digitalocean_droplet_test.go b/builtin/providers/digitalocean/resource_digitalocean_droplet_test.go index d68d7f96c76b..8b8a90efa093 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_droplet_test.go +++ b/builtin/providers/digitalocean/resource_digitalocean_droplet_test.go @@ -144,6 +144,56 @@ func TestAccDigitalOceanDroplet_ResizeWithOutDisk(t *testing.T) { }) } +func TestAccDigitalOceanDroplet_ResizeOnlyDisk(t *testing.T) { + var droplet godo.Droplet + rInt := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDigitalOceanDropletDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckDigitalOceanDropletConfig_basic(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet), + testAccCheckDigitalOceanDropletAttributes(&droplet), + resource.TestCheckResourceAttr( + "digitalocean_droplet.foobar", "name", fmt.Sprintf("foo-%d", rInt)), + ), + }, + + { + Config: testAccCheckDigitalOceanDropletConfig_resize_without_disk(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet), + testAccCheckDigitalOceanDropletResizeWithOutDisk(&droplet), + resource.TestCheckResourceAttr( + "digitalocean_droplet.foobar", "name", fmt.Sprintf("foo-%d", rInt)), + resource.TestCheckResourceAttr( + "digitalocean_droplet.foobar", "size", "1gb"), + resource.TestCheckResourceAttr( + "digitalocean_droplet.foobar", "disk", "20"), + ), + }, + + { + Config: testAccCheckDigitalOceanDropletConfig_resize_only_disk(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet), + testAccCheckDigitalOceanDropletResizeOnlyDisk(&droplet), + resource.TestCheckResourceAttr( + "digitalocean_droplet.foobar", "name", fmt.Sprintf("foo-%d", rInt)), + resource.TestCheckResourceAttr( + "digitalocean_droplet.foobar", "size", "1gb"), + resource.TestCheckResourceAttr( + "digitalocean_droplet.foobar", "disk", "30"), + ), + }, + }, + }) +} + func TestAccDigitalOceanDroplet_UpdateUserData(t *testing.T) { var afterCreate, afterUpdate godo.Droplet rInt := acctest.RandInt() @@ -321,6 +371,21 @@ func testAccCheckDigitalOceanDropletResizeWithOutDisk(droplet *godo.Droplet) res } } +func testAccCheckDigitalOceanDropletResizeOnlyDisk(droplet *godo.Droplet) resource.TestCheckFunc { + return func(s *terraform.State) error { + + if droplet.Size.Slug != "1gb" { + return fmt.Errorf("Bad size_slug: %s", droplet.SizeSlug) + } + + if droplet.Disk != 30 { + return fmt.Errorf("Bad disk: %d", droplet.Disk) + } + + return nil + } +} + func testAccCheckDigitalOceanDropletAttributes_PrivateNetworkingIpv6(droplet *godo.Droplet) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -492,6 +557,19 @@ resource "digitalocean_droplet" "foobar" { `, rInt) } +func testAccCheckDigitalOceanDropletConfig_resize_only_disk(rInt int) string { + return fmt.Sprintf(` +resource "digitalocean_droplet" "foobar" { + name = "foo-%d" + size = "1gb" + image = "centos-7-x64" + region = "nyc3" + user_data = "foobar" + resize_disk = true +} +`, rInt) +} + // IPV6 only in singapore func testAccCheckDigitalOceanDropletConfig_PrivateNetworkingIpv6(rInt int) string { return fmt.Sprintf(`