From 322a6cf9fefe59f5485f1d595b05f421fcbfcafc Mon Sep 17 00:00:00 2001 From: Jack Pearkes Date: Sat, 19 Jul 2014 12:33:25 -0400 Subject: [PATCH] providers/digitalocean: updates --- resource_digitalocean_droplet.go | 102 +++++++++++++++++++++++--- resource_digitalocean_droplet_test.go | 57 +++++++++++++- 2 files changed, 147 insertions(+), 12 deletions(-) diff --git a/resource_digitalocean_droplet.go b/resource_digitalocean_droplet.go index 562fc151..a40fbee4 100644 --- a/resource_digitalocean_droplet.go +++ b/resource_digitalocean_droplet.go @@ -88,17 +88,95 @@ func resource_digitalocean_droplet_update( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { - // p := meta.(*ResourceProvider) - // client := p.client - // rs := s.MergeDiff(d) + p := meta.(*ResourceProvider) + client := p.client + rs := s.MergeDiff(d) - // var err error + var err error - // if _, ok := d.Attributes["size"]; ok { + if attr, ok := d.Attributes["size"]; ok { + err = client.PowerOff(rs.ID) - // } + if err != nil && !strings.Contains(err.Error(), "Droplet is already powered off") { + return s, err + } - return nil, nil + // Wait for power off + _, err = WaitForDropletAttribute( + rs.ID, "off", []string{"active"}, "status", client) + + err = client.Resize(rs.ID, attr.New) + + if err != nil { + return rs, err + } + + // Wait for the size to change + _, err = WaitForDropletAttribute( + rs.ID, attr.New, []string{"", attr.Old}, "size", client) + + if err != nil { + return s, err + } + + err = client.PowerOn(rs.ID) + + if err != nil { + return s, err + } + + // Wait for power off + _, err = WaitForDropletAttribute( + rs.ID, "active", []string{"off"}, "status", client) + + if err != nil { + return s, err + } + } + + if attr, ok := d.Attributes["name"]; ok { + err = client.Rename(rs.ID, attr.New) + + if err != nil { + return s, err + } + + // Wait for the name to change + _, err = WaitForDropletAttribute( + rs.ID, attr.New, []string{"", attr.Old}, "name", client) + } + + if attr, ok := d.Attributes["private_networking"]; ok { + err = client.Rename(rs.ID, attr.New) + + if err != nil { + return s, err + } + + // Wait for the private_networking to turn on/off + _, err = WaitForDropletAttribute( + rs.ID, attr.New, []string{"", attr.Old}, "private_networking", client) + } + + if attr, ok := d.Attributes["ipv6"]; ok { + err = client.Rename(rs.ID, attr.New) + + if err != nil { + return s, err + } + + // Wait for ipv6 to turn on/off + _, err = WaitForDropletAttribute( + rs.ID, attr.New, []string{"", attr.Old}, "ipv6", client) + } + + droplet, err := resource_digitalocean_droplet_retrieve(rs.ID, client) + + if err != nil { + return s, err + } + + return resource_digitalocean_droplet_update_state(rs, droplet) } func resource_digitalocean_droplet_destroy( @@ -146,7 +224,7 @@ func resource_digitalocean_droplet_diff( "name": diff.AttrTypeUpdate, "private_networking": diff.AttrTypeUpdate, "region": diff.AttrTypeCreate, - "size": diff.AttrTypeCreate, + "size": diff.AttrTypeUpdate, "ssh_keys": diff.AttrTypeCreate, }, @@ -177,8 +255,12 @@ func resource_digitalocean_droplet_update_state( s.Attributes["image"] = droplet.ImageSlug() } + if droplet.IPV6Address() != "" { + s.Attributes["ipv6"] = "true" + s.Attributes["ipv6_address"] = droplet.IPV6Address() + } + s.Attributes["ipv4_address"] = droplet.IPV4Address() - s.Attributes["ipv6_address"] = droplet.IPV6Address() s.Attributes["locked"] = droplet.IsLocked() s.Attributes["private_networking"] = droplet.NetworkingType() s.Attributes["size"] = droplet.SizeSlug() @@ -220,7 +302,7 @@ func WaitForDropletAttribute(id string, target string, pending []string, attribu // Wait for the droplet so we can get the networking attributes // that show up after a while log.Printf( - "[DEBUG] Waiting for Droplet (%s) to have %s of %s", + "[INFO] Waiting for Droplet (%s) to have %s of %s", id, attribute, target) stateConf := &resource.StateChangeConf{ diff --git a/resource_digitalocean_droplet_test.go b/resource_digitalocean_droplet_test.go index 69c378d4..ea729f2c 100644 --- a/resource_digitalocean_droplet_test.go +++ b/resource_digitalocean_droplet_test.go @@ -10,7 +10,7 @@ import ( "github.com/pearkes/digitalocean" ) -func TestAccDigitalOceanDroplet(t *testing.T) { +func TestAccDigitalOceanDroplet_Basic(t *testing.T) { var droplet digitalocean.Droplet resource.Test(t, resource.TestCase{ @@ -37,6 +37,37 @@ func TestAccDigitalOceanDroplet(t *testing.T) { }) } +func TestAccDigitalOceanDroplet_Update(t *testing.T) { + var droplet digitalocean.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_RenameAndResize, + Check: resource.ComposeTestCheckFunc( + testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet), + testAccCheckDigitalOceanDropletRenamedAndResized(&droplet), + resource.TestCheckResourceAttr( + "digitalocean_droplet.foobar", "name", "foo"), + resource.TestCheckResourceAttr( + "digitalocean_droplet.foobar", "size", "1gb"), + ), + }, + }, + }) +} + func testAccCheckDigitalOceanDropletDestroy(s *terraform.State) error { client := testAccProvider.client @@ -63,7 +94,6 @@ func testAccCheckDigitalOceanDropletDestroy(s *terraform.State) error { func testAccCheckDigitalOceanDropletAttributes(droplet *digitalocean.Droplet) resource.TestCheckFunc { return func(s *terraform.State) error { - fmt.Println("droplet: %v", droplet) if droplet.ImageSlug() != "centos-5-8-x32" { return fmt.Errorf("Bad image_slug: %s", droplet.ImageSlug()) } @@ -83,6 +113,20 @@ func testAccCheckDigitalOceanDropletAttributes(droplet *digitalocean.Droplet) re } } +func testAccCheckDigitalOceanDropletRenamedAndResized(droplet *digitalocean.Droplet) resource.TestCheckFunc { + return func(s *terraform.State) error { + + if droplet.SizeSlug() != "1gb" { + return fmt.Errorf("Bad size_slug: %s", droplet.SizeSlug()) + } + + if droplet.Name != "baz" { + return fmt.Errorf("Bad name: %s", droplet.Name) + } + + return nil + } +} func testAccCheckDigitalOceanDropletExists(n string, droplet *digitalocean.Droplet) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.Resources[n] @@ -134,3 +178,12 @@ resource "digitalocean_droplet" "foobar" { region = "nyc2" } ` + +const testAccCheckDigitalOceanDropletConfig_RenameAndResize = ` +resource "digitalocean_droplet" "foobar" { + name = "baz" + size = "1gb" + image = "centos-5-8-x32" + region = "nyc2" +} +`