From ccff5af8e78e8ec7eb84a3e5294347123ea58bbb Mon Sep 17 00:00:00 2001 From: Andrew Starr-Bochicchio Date: Mon, 24 Oct 2016 20:00:04 -0400 Subject: [PATCH] Allow resizing DigitalOcean Droplets without increasing disk size. --- .../resource_digitalocean_droplet.go | 26 ++++++- .../resource_digitalocean_droplet_test.go | 68 +++++++++++++++++++ .../docs/providers/do/r/droplet.html.markdown | 9 ++- 3 files changed, 99 insertions(+), 4 deletions(-) diff --git a/builtin/providers/digitalocean/resource_digitalocean_droplet.go b/builtin/providers/digitalocean/resource_digitalocean_droplet.go index a33e20d88..31da94748 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_droplet.go +++ b/builtin/providers/digitalocean/resource_digitalocean_droplet.go @@ -53,6 +53,22 @@ func resourceDigitalOceanDroplet() *schema.Resource { }, }, + "disk": &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + }, + + "vcpus": &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + }, + + "resize_disk": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "status": &schema.Schema{ Type: schema.TypeString, Computed: true, @@ -243,6 +259,8 @@ func resourceDigitalOceanDropletRead(d *schema.ResourceData, meta interface{}) e d.Set("name", droplet.Name) d.Set("region", droplet.Region.Slug) d.Set("size", droplet.Size.Slug) + d.Set("disk", droplet.Disk) + d.Set("vcpus", droplet.Vcpus) d.Set("status", droplet.Status) d.Set("locked", strconv.FormatBool(droplet.Locked)) @@ -321,7 +339,13 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{}) } // Resize the droplet - _, _, err = client.DropletActions.Resize(id, newSize.(string), true) + 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) + } if err != nil { newErr := powerOnAndWait(d, meta) if newErr != nil { diff --git a/builtin/providers/digitalocean/resource_digitalocean_droplet_test.go b/builtin/providers/digitalocean/resource_digitalocean_droplet_test.go index 9ac1473c1..acb7c86bf 100644 --- a/builtin/providers/digitalocean/resource_digitalocean_droplet_test.go +++ b/builtin/providers/digitalocean/resource_digitalocean_droplet_test.go @@ -65,6 +65,39 @@ func TestAccDigitalOceanDroplet_Update(t *testing.T) { "digitalocean_droplet.foobar", "name", "baz"), resource.TestCheckResourceAttr( "digitalocean_droplet.foobar", "size", "1gb"), + resource.TestCheckResourceAttr( + "digitalocean_droplet.foobar", "disk", "30"), + ), + }, + }, + }) +} + +func TestAccDigitalOceanDroplet_ResizeWithOutDisk(t *testing.T) { + var droplet godo.Droplet + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDigitalOceanDropletDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckDigitalOceanDropletConfig_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet), + testAccCheckDigitalOceanDropletAttributes(&droplet), + ), + }, + + resource.TestStep{ + Config: testAccCheckDigitalOceanDropletConfig_resize_without_disk, + Check: resource.ComposeTestCheckFunc( + testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet), + testAccCheckDigitalOceanDropletResizeWithOutDisk(&droplet), + resource.TestCheckResourceAttr( + "digitalocean_droplet.foobar", "size", "1gb"), + resource.TestCheckResourceAttr( + "digitalocean_droplet.foobar", "disk", "20"), ), }, }, @@ -221,6 +254,25 @@ func testAccCheckDigitalOceanDropletRenamedAndResized(droplet *godo.Droplet) res return fmt.Errorf("Bad name: %s", droplet.Name) } + if droplet.Disk != 30 { + return fmt.Errorf("Bad disk: %s", droplet.Disk) + } + + return nil + } +} + +func testAccCheckDigitalOceanDropletResizeWithOutDisk(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 != 20 { + return fmt.Errorf("Bad disk: %s", droplet.Disk) + } + return nil } } @@ -405,6 +457,22 @@ resource "digitalocean_droplet" "foobar" { } `, testAccValidPublicKey) +var testAccCheckDigitalOceanDropletConfig_resize_without_disk = fmt.Sprintf(` +resource "digitalocean_ssh_key" "foobar" { + name = "foobar" + public_key = "%s" +} + +resource "digitalocean_droplet" "foobar" { + name = "foo" + size = "1gb" + image = "centos-7-x64" + region = "nyc3" + ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] + resize_disk = false +} +`, testAccValidPublicKey) + // IPV6 only in singapore var testAccCheckDigitalOceanDropletConfig_PrivateNetworkingIpv6 = fmt.Sprintf(` resource "digitalocean_ssh_key" "foobar" { diff --git a/website/source/docs/providers/do/r/droplet.html.markdown b/website/source/docs/providers/do/r/droplet.html.markdown index 7c98a9731..312a4f2b6 100644 --- a/website/source/docs/providers/do/r/droplet.html.markdown +++ b/website/source/docs/providers/do/r/droplet.html.markdown @@ -32,9 +32,6 @@ The following arguments are supported: * `name` - (Required) The Droplet name * `region` - (Required) The region to start in * `size` - (Required) The instance size to start - --> **Note:** When resizing a Droplet, only a bigger Droplet size can be chosen. - * `backups` - (Optional) Boolean controlling if backups are made. Defaults to false. * `ipv6` - (Optional) Boolean controlling if IPv6 is enabled. Defaults to false. @@ -44,6 +41,10 @@ The following arguments are supported: the format `[12345, 123456]`. To retrieve this info, use a tool such as `curl` with the [DigitalOcean API](https://developers.digitalocean.com/#keys), to retrieve them. +* `resize_disk` - (Optional) Boolean controlling whether to increase the disk + size when resizing a Droplet. It defaults to `true`. When set to `false`, + only the Droplet's RAM and CPU will be resized. **Increasing a Droplet's disk + size is a permanent change**. Increasing only RAM and CPU is reversible. * `tags` - (Optional) A list of the tags to label this droplet. A tag resource must exist before it can be associated with a droplet. * `user_data` (Optional) - A string of the desired User Data for the Droplet. @@ -67,6 +68,8 @@ The following attributes are exported: * `locked` - Is the Droplet locked * `private_networking` - Is private networking enabled * `size` - The instance size +* `disk` - The size of the instance's disk in GB +* `vcpus` - The number of the instance's virtual CPUs * `status` - The status of the droplet * `tags` - The tags associated with the droplet * `volume_ids` - A list of the attached block storage volumes