Skip to content

Commit

Permalink
Allow for Timeouts to be set for Droplet Create Operations (#839)
Browse files Browse the repository at this point in the history
* Changes

* Fix timeouts

* Replace test image slug with a slug for an image that existings according to ID           Name                  Type        Distribution    Slug                   Public    Min Disk
78547182     1.5.8 x64             snapshot    RancherOS       rancheros              true      15
106421231    18.04 (LTS) x64       snapshot    Ubuntu          ubuntu-18-04-x64       true      7
106421232    20.04 (LTS) x64       snapshot    Ubuntu          ubuntu-20-04-x64       true      7
106427349    21.10 x64             snapshot    Ubuntu          ubuntu-21-10-x64       true      7
106433672    7 x64                 snapshot    CentOS          centos-7-x64           true      9
106434098    9 Stream x64          snapshot    CentOS          centos-stream-9-x64    true      10
106434191    8 Stream x64          snapshot    CentOS          centos-stream-8-x64    true      10
106557160    11 x64                snapshot    Debian          debian-11-x64          true      7
106569079    9 x64                 snapshot    Debian          debian-9-x64           true      7
106569146    10 x64                snapshot    Debian          debian-10-x64          true      7
106926987    22.04 (LTS) x64       snapshot    Ubuntu          ubuntu-22-04-x64       true      7
108396493    36 x64                snapshot    Fedora          fedora-36-x64          true      7
108962668    35 x64                snapshot    Fedora          fedora-35-x64          true      7
108962679    RockyLinux 8.4 x64    snapshot    Rocky Linux     rockylinux-8-4-x64     true      10
108962770    34 x64                snapshot    Fedora          fedora-34-x64          true      7
108964453    RockyLinux 8.5 x64    snapshot    Rocky Linux     rockylinux-8-x64       true      10

* Use an Ubuntu LTS release and fix prices.

Co-authored-by: Andrew Starr-Bochicchio <andrewsomething@users.noreply.github.com>
Co-authored-by: Andrew Starr-Bochicchio <a.starr.b@gmail.com>
  • Loading branch information
3 people authored Aug 4, 2022
1 parent 53f3313 commit 5acd3d3
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 42 deletions.
36 changes: 23 additions & 13 deletions digitalocean/resource_digitalocean_droplet.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ func resourceDigitalOceanDroplet() *schema.Resource {
MigrateState: resourceDigitalOceanDropletMigrateState,
SchemaVersion: 1,

// We are using these timeouts to be the minimum timeout for an operation.
// This is how long an operation will wait for a state update, however
// implementation of updates and deletes contain multiple instances of waiting for a state update
// so the true timeout of an operation could be a multiple of the set value.
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(60 * time.Minute),
Update: schema.DefaultTimeout(60 * time.Minute),
Delete: schema.DefaultTimeout(60 * time.Second),
},

Schema: map[string]*schema.Schema{
"image": {
Type: schema.TypeString,
Expand Down Expand Up @@ -307,7 +317,7 @@ func resourceDigitalOceanDropletCreate(ctx context.Context, d *schema.ResourceDa
}

// Ensure Droplet status has moved to "active."
_, err = waitForDropletAttribute(ctx, d, "active", []string{"new"}, "status", meta)
_, err = waitForDropletAttribute(ctx, d, "active", []string{"new"}, "status", schema.TimeoutCreate, meta)
if err != nil {
return diag.Errorf("Error waiting for droplet (%s) to become ready: %s", d.Id(), err)
}
Expand Down Expand Up @@ -460,7 +470,7 @@ func resourceDigitalOceanDropletUpdate(ctx context.Context, d *schema.ResourceDa
}

// Wait for power off
_, err = waitForDropletAttribute(ctx, d, "off", []string{"active"}, "status", meta)
_, err = waitForDropletAttribute(ctx, d, "off", []string{"active"}, "status", schema.TimeoutUpdate, meta)
if err != nil {
return diag.Errorf(
"Error waiting for droplet (%s) to become powered off: %s", d.Id(), err)
Expand Down Expand Up @@ -497,8 +507,8 @@ func resourceDigitalOceanDropletUpdate(ctx context.Context, d *schema.ResourceDa
"Error powering on droplet (%s) after resize: %s", d.Id(), err)
}

// Wait for power off
_, err = waitForDropletAttribute(ctx, d, "active", []string{"off"}, "status", meta)
// Wait for power on
_, err = waitForDropletAttribute(ctx, d, "active", []string{"off"}, "status", schema.TimeoutUpdate, meta)
if err != nil {
return diag.FromErr(err)
}
Expand All @@ -517,7 +527,7 @@ func resourceDigitalOceanDropletUpdate(ctx context.Context, d *schema.ResourceDa

// Wait for the name to change
_, err = waitForDropletAttribute(
ctx, d, newName.(string), []string{"", oldName.(string)}, "name", meta)
ctx, d, newName.(string), []string{"", oldName.(string)}, "name", schema.TimeoutUpdate, meta)

if err != nil {
return diag.Errorf(
Expand Down Expand Up @@ -563,7 +573,7 @@ func resourceDigitalOceanDropletUpdate(ctx context.Context, d *schema.ResourceDa

// Wait for the private_networking to turn on
_, err = waitForDropletAttribute(
ctx, d, "true", []string{"", "false"}, "private_networking", meta)
ctx, d, "true", []string{"", "false"}, "private_networking", schema.TimeoutUpdate, meta)

if err != nil {
return diag.Errorf(
Expand All @@ -582,7 +592,7 @@ func resourceDigitalOceanDropletUpdate(ctx context.Context, d *schema.ResourceDa

// Wait for ipv6 to turn on
_, err = waitForDropletAttribute(
ctx, d, "true", []string{"", "false"}, "ipv6", meta)
ctx, d, "true", []string{"", "false"}, "ipv6", schema.TimeoutUpdate, meta)

if err != nil {
return diag.Errorf(
Expand Down Expand Up @@ -645,7 +655,7 @@ func resourceDigitalOceanDropletDelete(ctx context.Context, d *schema.ResourceDa
}

_, err = waitForDropletAttribute(
ctx, d, "false", []string{"", "true"}, "locked", meta)
ctx, d, "false", []string{"", "true"}, "locked", schema.TimeoutDelete, meta)

if err != nil {
return diag.Errorf(
Expand All @@ -665,7 +675,7 @@ func resourceDigitalOceanDropletDelete(ctx context.Context, d *schema.ResourceDa
}

// Wait for shutdown
_, err = waitForDropletAttribute(ctx, d, "off", []string{"active"}, "status", meta)
_, err = waitForDropletAttribute(ctx, d, "off", []string{"active"}, "status", schema.TimeoutDelete, meta)
if err != nil {
return diag.Errorf("Error waiting for droplet (%s) to become off: %s", d.Id(), err)
}
Expand Down Expand Up @@ -714,7 +724,7 @@ func waitForDropletDestroy(ctx context.Context, d *schema.ResourceData, meta int
}

func waitForDropletAttribute(
ctx context.Context, d *schema.ResourceData, target string, pending []string, attribute string, meta interface{}) (interface{}, error) {
ctx context.Context, d *schema.ResourceData, target string, pending []string, attribute string, timeoutKey string, meta interface{}) (interface{}, error) {
// Wait for the droplet so we can get the networking attributes
// that show up after a while
log.Printf(
Expand All @@ -725,7 +735,7 @@ func waitForDropletAttribute(
Pending: pending,
Target: []string{target},
Refresh: dropletStateRefreshFunc(ctx, d, attribute, meta),
Timeout: 60 * time.Minute,
Timeout: d.Timeout(timeoutKey),
Delay: 10 * time.Second,
MinTimeout: 3 * time.Second,

Expand Down Expand Up @@ -794,9 +804,9 @@ func powerOnAndWait(ctx context.Context, d *schema.ResourceData, meta interface{
if err != nil {
return err
}

// this method is only used for droplet updates so use that as the timeout parameter
// Wait for power on
_, err = waitForDropletAttribute(ctx, d, "active", []string{"off"}, "status", meta)
_, err = waitForDropletAttribute(ctx, d, "active", []string{"off"}, "status", schema.TimeoutUpdate, meta)
if err != nil {
return err
}
Expand Down
58 changes: 29 additions & 29 deletions digitalocean/resource_digitalocean_droplet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ func TestAccDigitalOceanDroplet_Basic(t *testing.T) {
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "size", "s-1vcpu-1gb"),
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "price_hourly", "0.00744"),
"digitalocean_droplet.foobar", "price_hourly", "0.00893"),
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "price_monthly", "5"),
"digitalocean_droplet.foobar", "price_monthly", "6"),
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "image", "centos-8-x64"),
"digitalocean_droplet.foobar", "image", "ubuntu-22-04-x64"),
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "region", "nyc3"),
resource.TestCheckResourceAttr(
Expand All @@ -96,7 +96,7 @@ func TestAccDigitalOceanDroplet_Basic(t *testing.T) {
func TestAccDigitalOceanDroplet_WithID(t *testing.T) {
var droplet godo.Droplet
rInt := acctest.RandInt()
slug := "centos-8-x64"
slug := "ubuntu-22-04-x64"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand Down Expand Up @@ -136,7 +136,7 @@ func TestAccDigitalOceanDroplet_withSSH(t *testing.T) {
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "size", "s-1vcpu-1gb"),
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "image", "centos-8-x64"),
"digitalocean_droplet.foobar", "image", "ubuntu-22-04-x64"),
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "region", "nyc3"),
resource.TestCheckResourceAttr(
Expand Down Expand Up @@ -599,15 +599,15 @@ func TestAccDigitalOceanDroplet_withDropletAgentSetFalse(t *testing.T) {
CheckDestroy: testAccCheckDigitalOceanDropletDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckDigitalOceanDropletConfig_DropletAgent(keyName, publicKeyMaterial, dropletName, "freebsd-12-x64-zfs", agent),
Config: testAccCheckDigitalOceanDropletConfig_DropletAgent(keyName, publicKeyMaterial, dropletName, "rancheros", agent),
Check: resource.ComposeTestCheckFunc(
testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet),
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "name", dropletName),
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "droplet_agent", "false"),
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "image", "freebsd-12-x64-zfs"),
"digitalocean_droplet.foobar", "image", "rancheros"),
),
},
},
Expand All @@ -632,15 +632,15 @@ func TestAccDigitalOceanDroplet_withDropletAgentNotSet(t *testing.T) {
CheckDestroy: testAccCheckDigitalOceanDropletDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckDigitalOceanDropletConfig_DropletAgent(keyName, publicKeyMaterial, dropletName, "freebsd-12-x64-zfs", ""),
Config: testAccCheckDigitalOceanDropletConfig_DropletAgent(keyName, publicKeyMaterial, dropletName, "rancheros", ""),
Check: resource.ComposeTestCheckFunc(
testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet),
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "name", dropletName),
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "size", "s-1vcpu-1gb"),
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "image", "freebsd-12-x64-zfs"),
"digitalocean_droplet.foobar", "image", "rancheros"),
resource.TestCheckResourceAttr(
"digitalocean_droplet.foobar", "region", "nyc3"),
),
Expand All @@ -667,7 +667,7 @@ func TestAccDigitalOceanDroplet_withDropletAgentExpectError(t *testing.T) {
CheckDestroy: testAccCheckDigitalOceanDropletDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckDigitalOceanDropletConfig_DropletAgent(keyName, publicKeyMaterial, dropletName, "freebsd-12-x64-zfs", agent),
Config: testAccCheckDigitalOceanDropletConfig_DropletAgent(keyName, publicKeyMaterial, dropletName, "rancheros", agent),
ExpectError: regexp.MustCompile(`is not supported`),
},
},
Expand Down Expand Up @@ -709,19 +709,19 @@ func testAccCheckDigitalOceanDropletAttributes(droplet *godo.Droplet) resource.T
return fmt.Errorf("Bad URN: %s", droplet.URN())
}

if droplet.Image.Slug != "centos-8-x64" {
if droplet.Image.Slug != "ubuntu-22-04-x64" {
return fmt.Errorf("Bad image_slug: %s", droplet.Image.Slug)
}

if droplet.Size.Slug != "s-1vcpu-1gb" {
return fmt.Errorf("Bad size_slug: %s", droplet.Size.Slug)
}

if droplet.Size.PriceHourly != 0.00744 {
if droplet.Size.PriceHourly != 0.00893 {
return fmt.Errorf("Bad price_hourly: %v", droplet.Size.PriceHourly)
}

if droplet.Size.PriceMonthly != 5.0 {
if droplet.Size.PriceMonthly != 6.0 {
return fmt.Errorf("Bad price_monthly: %v", droplet.Size.PriceMonthly)
}

Expand Down Expand Up @@ -781,7 +781,7 @@ func testAccCheckDigitalOceanDropletResizeSmaller(droplet *godo.Droplet) resourc
func testAccCheckDigitalOceanDropletAttributes_PrivateNetworkingIpv6(droplet *godo.Droplet) resource.TestCheckFunc {
return func(s *terraform.State) error {

if droplet.Image.Slug != "centos-8-x64" {
if droplet.Image.Slug != "ubuntu-22-04-x64" {
return fmt.Errorf("Bad image_slug: %s", droplet.Image.Slug)
}

Expand Down Expand Up @@ -869,7 +869,7 @@ func testAccCheckDigitalOceanDropletConfig_basic(rInt int) string {
resource "digitalocean_droplet" "foobar" {
name = "foo-%d"
size = "s-1vcpu-1gb"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
region = "nyc3"
user_data = "foobar"
}`, rInt)
Expand Down Expand Up @@ -900,7 +900,7 @@ resource "digitalocean_ssh_key" "foobar" {
resource "digitalocean_droplet" "foobar" {
name = "foo-%d"
size = "s-1vcpu-1gb"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
region = "nyc3"
user_data = "foobar"
ssh_keys = ["${digitalocean_ssh_key.foobar.id}"]
Expand All @@ -916,7 +916,7 @@ resource "digitalocean_tag" "barbaz" {
resource "digitalocean_droplet" "foobar" {
name = "foo-%d"
size = "s-1vcpu-1gb"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
region = "nyc3"
user_data = "foobar"
tags = ["${digitalocean_tag.barbaz.id}"]
Expand All @@ -929,7 +929,7 @@ func testAccCheckDigitalOceanDropletConfig_userdata_update(rInt int) string {
resource "digitalocean_droplet" "foobar" {
name = "foo-%d"
size = "s-1vcpu-1gb"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
region = "nyc3"
user_data = "foobar foobar"
}
Expand All @@ -941,7 +941,7 @@ func testAccCheckDigitalOceanDropletConfig_RenameAndResize(rInt int) string {
resource "digitalocean_droplet" "foobar" {
name = "baz-%d"
size = "s-1vcpu-2gb"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
region = "nyc3"
}
`, rInt)
Expand All @@ -952,7 +952,7 @@ func testAccCheckDigitalOceanDropletConfig_resize_without_disk(rInt int) string
resource "digitalocean_droplet" "foobar" {
name = "foo-%d"
size = "s-1vcpu-2gb"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
region = "nyc3"
user_data = "foobar"
resize_disk = false
Expand All @@ -965,7 +965,7 @@ func testAccCheckDigitalOceanDropletConfig_resize(rInt int) string {
resource "digitalocean_droplet" "foobar" {
name = "foo-%d"
size = "s-1vcpu-2gb"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
region = "nyc3"
user_data = "foobar"
resize_disk = true
Expand All @@ -978,7 +978,7 @@ func testAccCheckDigitalOceanDropletConfig_PrivateNetworkingIpv6(rInt int) strin
resource "digitalocean_droplet" "foobar" {
name = "foo-%d"
size = "s-1vcpu-1gb"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
region = "nyc3"
ipv6 = true
private_networking = true
Expand All @@ -996,7 +996,7 @@ resource "digitalocean_vpc" "foobar" {
resource "digitalocean_droplet" "foobar" {
name = "foo-%d"
size = "s-1vcpu-1gb"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
region = "nyc3"
ipv6 = true
vpc_uuid = digitalocean_vpc.foobar.id
Expand All @@ -1009,7 +1009,7 @@ func testAccCheckDigitalOceanDropletConfig_Monitoring(rInt int) string {
resource "digitalocean_droplet" "foobar" {
name = "foo-%d"
size = "s-1vcpu-1gb"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
region = "nyc3"
monitoring = true
}
Expand All @@ -1036,7 +1036,7 @@ resource "digitalocean_droplet" "foobar" {
count = 2
name = "tf-acc-test-%d-${count.index}"
region = "sfo3"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
size = "s-1vcpu-1gb"
volume_ids = ["${count.index == 0 ? digitalocean_volume.myvol-01.id : digitalocean_volume.myvol-02.id}"]
}
Expand All @@ -1048,7 +1048,7 @@ func testAccCheckDigitalOceanDropletConfig_EnableBackups(rInt int) string {
resource "digitalocean_droplet" "foobar" {
name = "foo-%d"
size = "s-1vcpu-1gb"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
region = "nyc3"
user_data = "foobar"
backups = true
Expand All @@ -1060,7 +1060,7 @@ func testAccCheckDigitalOceanDropletConfig_DisableBackups(rInt int) string {
resource "digitalocean_droplet" "foobar" {
name = "foo-%d"
size = "s-1vcpu-1gb"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
region = "nyc3"
user_data = "foobar"
backups = false
Expand Down Expand Up @@ -1089,7 +1089,7 @@ func testAccCheckDigitalOceanDropletConfig_EnableGracefulShutdown(rInt int) stri
resource "digitalocean_droplet" "foobar" {
name = "foo-%d"
size = "s-1vcpu-1gb"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
region = "nyc3"
user_data = "foobar"
graceful_shutdown = true
Expand All @@ -1101,7 +1101,7 @@ func testAccCheckDigitalOceanDropletConfig_DisableGracefulShutdown(rInt int) str
resource "digitalocean_droplet" "foobar" {
name = "foo-%d"
size = "s-1vcpu-1gb"
image = "centos-8-x64"
image = "ubuntu-22-04-x64"
region = "nyc3"
user_data = "foobar"
graceful_shutdown = false
Expand Down

0 comments on commit 5acd3d3

Please sign in to comment.