@@ -3,8 +3,10 @@ package digitalocean
33import (
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
6668func 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{}
8090func 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