providers/digitalocean: WaitForAttribute

This commit is contained in:
Jack Pearkes 2014-07-19 09:45:42 -04:00
parent 5c6ef7ff06
commit 0965332b88
2 changed files with 61 additions and 36 deletions

View File

@ -71,20 +71,7 @@ func resource_digitalocean_droplet_create(
log.Printf("[INFO] Droplet ID: %s", id)
// 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 become running",
id)
stateConf := &resource.StateChangeConf{
Pending: []string{"new"},
Target: "active",
Refresh: DropletStateRefreshFunc(client, id),
Timeout: 10 * time.Minute,
}
dropletRaw, err := stateConf.WaitForState()
dropletRaw, err := WaitForDropletAttribute(id, "active", []string{"new"}, "status", client)
if err != nil {
return rs, fmt.Errorf(
@ -101,8 +88,15 @@ 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)
panic("No update")
// var err error
// if _, ok := d.Attributes["size"]; ok {
// }
return nil, nil
}
@ -222,23 +216,48 @@ func resource_digitalocean_droplet_validation() *config.Validator {
}
}
// DropletStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch
// a droplet.
func DropletStateRefreshFunc(client *digitalocean.Client, id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
droplet, err := resource_digitalocean_droplet_retrieve(id, client)
func WaitForDropletAttribute(id string, target string, pending []string, attribute string, client *digitalocean.Client) (interface{}, error) {
// 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",
id, attribute, target)
// It's not actually "active"
// until we can see the image slug
if droplet.ImageSlug() == "" {
return nil, "", nil
stateConf := &resource.StateChangeConf{
Pending: pending,
Target: target,
Refresh: new_droplet_state_refresh_func(id, attribute, client),
Timeout: 10 * time.Minute,
}
return stateConf.WaitForState()
}
func new_droplet_state_refresh_func(id string, attribute string, client *digitalocean.Client) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
// Retrieve the ELB properties for updating the state
droplet, err := client.RetrieveDroplet(id)
if err != nil {
log.Printf("Error on DropletStateRefresh: %s", err)
log.Printf("Error on retrieving droplet when waiting: %s", err)
return nil, "", err
}
return droplet, droplet.Status, nil
// Use our mapping to get back a map of the
// droplet properties
resourceMap, err := resource_digitalocean_droplet_update_state(
&terraform.ResourceState{Attributes: map[string]string{}}, &droplet)
if err != nil {
log.Printf("Error creating map from droplet: %s", err)
return nil, "", err
}
// See if we can access our attribute
if attr, ok := resourceMap.Attributes[attribute]; ok {
return &droplet, attr, nil
}
return nil, "", nil
}
}

View File

@ -4,7 +4,6 @@ import (
"fmt"
"strings"
"testing"
"time"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
@ -49,14 +48,7 @@ func testAccCheckDigitalOceanDropletDestroy(s *terraform.State) error {
// Try to find the Droplet
_, err := client.RetrieveDroplet(rs.ID)
stateConf := &resource.StateChangeConf{
Pending: []string{"new"},
Target: "off",
Refresh: DropletStateRefreshFunc(client, rs.ID),
Timeout: 10 * time.Minute,
}
_, err = stateConf.WaitForState()
// Wait
if err != nil && !strings.Contains(err.Error(), "404") {
return fmt.Errorf(
@ -120,6 +112,20 @@ func testAccCheckDigitalOceanDropletExists(n string, droplet *digitalocean.Dropl
}
}
func Test_new_droplet_state_refresh_func(t *testing.T) {
droplet := digitalocean.Droplet{
Name: "foobar",
}
resourceMap, _ := resource_digitalocean_droplet_update_state(
&terraform.ResourceState{Attributes: map[string]string{}}, &droplet)
// See if we can access our attribute
if _, ok := resourceMap.Attributes["name"]; !ok {
t.Fatalf("bad name: %s", resourceMap.Attributes)
}
}
const testAccCheckDigitalOceanDropletConfig_basic = `
resource "digitalocean_droplet" "foobar" {
name = "foo"