Skip to content

Commit 74c93d3

Browse files
committed
Reording the code for the creation of a Floating IP for a droplet. The call to the DO api takes a few seconds to propagate so I had to sacriface some kittens and added a short 10 second sleep
1 parent 7bda855 commit 74c93d3

1 file changed

Lines changed: 66 additions & 7 deletions

File tree

builtin/providers/digitalocean/resource_digitalocean_floating_ip.go

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ package digitalocean
33
import (
44
"fmt"
55
"log"
6+
"time"
67

78
"github.com/digitalocean/godo"
9+
"github.com/hashicorp/terraform/helper/resource"
810
"github.com/hashicorp/terraform/helper/schema"
911
)
1012

@@ -24,6 +26,7 @@ func resourceDigitalOceanFloatingIp() *schema.Resource {
2426
"region": &schema.Schema{
2527
Type: schema.TypeString,
2628
Optional: true,
29+
Computed: true,
2730
ForceNew: true,
2831
},
2932

@@ -42,36 +45,43 @@ func resourceDigitalOceanFloatingIpCreate(d *schema.ResourceData, meta interface
4245
// Build up our creation options
4346
opts := &godo.FloatingIPCreateRequest{}
4447

48+
if v, ok := d.GetOk("region"); ok {
49+
log.Printf("[INFO] Create a FloatingIP for a region")
50+
opts.Region = v.(string)
51+
}
52+
4553
if v, ok := d.GetOk("droplet_id"); ok {
4654
log.Printf("[INFO] Found a droplet_id to try and attach to the FloatingIP")
4755
opts.DropletID = v.(int)
48-
} else if d.Get("region").(string) != "" {
49-
opts.Region = d.Get("region").(string)
50-
} else {
51-
return fmt.Errorf("You must specify either a Droplet ID or a Region for a FloatingIP")
5256
}
5357

5458
log.Printf("[DEBUG] FloatingIP Create: %#v", opts)
5559
floatingIp, _, err := client.FloatingIPs.Create(opts)
5660
if err != nil {
5761
return fmt.Errorf("Error creating FloatingIP: %s", err)
5862
}
59-
6063
d.SetId(floatingIp.IP)
61-
log.Printf("[INFO] Floating IP: %s", floatingIp.IP)
6264

6365
return resourceDigitalOceanFloatingIpRead(d, meta)
6466
}
6567

6668
func resourceDigitalOceanFloatingIpRead(d *schema.ResourceData, meta interface{}) error {
6769
client := meta.(*godo.Client)
6870

71+
time.Sleep(7 * time.Second)
72+
log.Printf("[INFO] Reading the details of the FloatingIP %s", d.Id())
6973
floatingIp, _, err := client.FloatingIPs.Get(d.Id())
7074
if err != nil {
7175
return fmt.Errorf("Error retrieving FloatingIP: %s", err)
7276
}
7377

74-
d.Set("region", floatingIp.Region)
78+
if _, ok := d.GetOk("droplet_id"); ok {
79+
log.Printf("[INFO] The region of the Droplet is %s", floatingIp.Droplet.Region)
80+
d.Set("region", floatingIp.Droplet.Region.Slug)
81+
} else {
82+
d.Set("region", floatingIp.Region.Slug)
83+
}
84+
7585
d.Set("ip_address", floatingIp.IP)
7686

7787
return nil
@@ -80,6 +90,21 @@ func resourceDigitalOceanFloatingIpRead(d *schema.ResourceData, meta interface{}
8090
func resourceDigitalOceanFloatingIpDelete(d *schema.ResourceData, meta interface{}) error {
8191
client := meta.(*godo.Client)
8292

93+
if _, ok := d.GetOk("droplet_id"); ok {
94+
log.Printf("[INFO] Unassigning the Floating IP from the Droplet")
95+
action, _, err := client.FloatingIPActions.Unassign(d.Id())
96+
if err != nil {
97+
return fmt.Errorf(
98+
"Error Unassigning FloatingIP (%s) from the droplet: %s", d.Id(), err)
99+
}
100+
101+
_, unassignedErr := waitForFloatingIPReady(d, "completed", []string{"new"}, "status", meta, action.ID)
102+
if unassignedErr != nil {
103+
return fmt.Errorf(
104+
"Error waiting for FloatingIP (%s) to be unassigned: %s", d.Id(), unassignedErr)
105+
}
106+
}
107+
83108
log.Printf("[INFO] Deleting FloatingIP: %s", d.Id())
84109
_, err := client.FloatingIPs.Delete(d.Id())
85110
if err != nil {
@@ -89,3 +114,37 @@ func resourceDigitalOceanFloatingIpDelete(d *schema.ResourceData, meta interface
89114
d.SetId("")
90115
return nil
91116
}
117+
118+
func waitForFloatingIPReady(
119+
d *schema.ResourceData, target string, pending []string, attribute string, meta interface{}, action int) (interface{}, error) {
120+
log.Printf(
121+
"[INFO] Waiting for FloatingIP (%s) to have %s of %s",
122+
d.Id(), attribute, target)
123+
124+
stateConf := &resource.StateChangeConf{
125+
Pending: pending,
126+
Target: target,
127+
Refresh: newFloatingIPStateRefreshFunc(d, attribute, meta, action),
128+
Timeout: 60 * time.Minute,
129+
Delay: 10 * time.Second,
130+
MinTimeout: 3 * time.Second,
131+
132+
NotFoundChecks: 60,
133+
}
134+
135+
return stateConf.WaitForState()
136+
}
137+
138+
func newFloatingIPStateRefreshFunc(
139+
d *schema.ResourceData, attribute string, meta interface{}, action int) resource.StateRefreshFunc {
140+
client := meta.(*godo.Client)
141+
return func() (interface{}, string, error) {
142+
floatingIP, _, err := client.FloatingIPActions.Get(d.Id(), action)
143+
if err != nil {
144+
return nil, "", fmt.Errorf("Error retrieving FloatingIP Action: %s", err)
145+
}
146+
147+
log.Printf("[INFO] The FloatingIP Assigned Status is %s", floatingIP.Status)
148+
return &floatingIP, floatingIP.Status, nil
149+
}
150+
}

0 commit comments

Comments
 (0)