github.com/gmlexx/terraform@v0.9.6-0.20170514090029-1532b2a67680/builtin/providers/openstack/resource_openstack_compute_floatingip_associate_v2.go (about) 1 package openstack 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 8 "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips" 9 "github.com/hashicorp/terraform/helper/schema" 10 ) 11 12 func resourceComputeFloatingIPAssociateV2() *schema.Resource { 13 return &schema.Resource{ 14 Create: resourceComputeFloatingIPAssociateV2Create, 15 Read: resourceComputeFloatingIPAssociateV2Read, 16 Delete: resourceComputeFloatingIPAssociateV2Delete, 17 Importer: &schema.ResourceImporter{ 18 State: schema.ImportStatePassthrough, 19 }, 20 21 Schema: map[string]*schema.Schema{ 22 "region": &schema.Schema{ 23 Type: schema.TypeString, 24 Required: true, 25 ForceNew: true, 26 DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""), 27 }, 28 "floating_ip": &schema.Schema{ 29 Type: schema.TypeString, 30 Required: true, 31 ForceNew: true, 32 }, 33 "instance_id": &schema.Schema{ 34 Type: schema.TypeString, 35 Required: true, 36 ForceNew: true, 37 }, 38 "fixed_ip": &schema.Schema{ 39 Type: schema.TypeString, 40 Optional: true, 41 ForceNew: true, 42 }, 43 }, 44 } 45 } 46 47 func resourceComputeFloatingIPAssociateV2Create(d *schema.ResourceData, meta interface{}) error { 48 config := meta.(*Config) 49 computeClient, err := config.computeV2Client(GetRegion(d)) 50 if err != nil { 51 return fmt.Errorf("Error creating OpenStack compute client: %s", err) 52 } 53 54 floatingIP := d.Get("floating_ip").(string) 55 fixedIP := d.Get("fixed_ip").(string) 56 instanceId := d.Get("instance_id").(string) 57 58 associateOpts := floatingips.AssociateOpts{ 59 FloatingIP: floatingIP, 60 FixedIP: fixedIP, 61 } 62 log.Printf("[DEBUG] Associate Options: %#v", associateOpts) 63 64 err = floatingips.AssociateInstance(computeClient, instanceId, associateOpts).ExtractErr() 65 if err != nil { 66 return fmt.Errorf("Error associating Floating IP: %s", err) 67 } 68 69 // There's an API call to get this information, but it has been 70 // deprecated. The Neutron API could be used, but I'm trying not 71 // to mix service APIs. Therefore, a faux ID will be used. 72 id := fmt.Sprintf("%s/%s/%s", floatingIP, instanceId, fixedIP) 73 d.SetId(id) 74 75 // This API call is synchronous, so Create won't return until the IP 76 // is attached. No need to wait for a state. 77 78 return resourceComputeFloatingIPAssociateV2Read(d, meta) 79 } 80 81 func resourceComputeFloatingIPAssociateV2Read(d *schema.ResourceData, meta interface{}) error { 82 config := meta.(*Config) 83 computeClient, err := config.computeV2Client(GetRegion(d)) 84 if err != nil { 85 return fmt.Errorf("Error creating OpenStack compute client: %s", err) 86 } 87 88 // Obtain relevant info from parsing the ID 89 floatingIP, instanceId, fixedIP, err := parseComputeFloatingIPAssociateId(d.Id()) 90 if err != nil { 91 return err 92 } 93 94 d.Set("floating_ip", floatingIP) 95 d.Set("instance_id", instanceId) 96 d.Set("fixed_ip", fixedIP) 97 d.Set("region", GetRegion(d)) 98 99 // check whether floatingIP or associated instance deleted 100 fip, err := floatingips.Get(computeClient, floatingIP).Extract() 101 if err != nil { 102 if CheckDeleted(d, err, "floating ip") == nil { 103 return nil 104 } 105 } 106 if fip.InstanceID == "" { 107 d.SetId("") 108 } 109 110 return nil 111 } 112 113 func resourceComputeFloatingIPAssociateV2Delete(d *schema.ResourceData, meta interface{}) error { 114 config := meta.(*Config) 115 computeClient, err := config.computeV2Client(GetRegion(d)) 116 if err != nil { 117 return fmt.Errorf("Error creating OpenStack compute client: %s", err) 118 } 119 120 floatingIP := d.Get("floating_ip").(string) 121 instanceId := d.Get("instance_id").(string) 122 123 disassociateOpts := floatingips.DisassociateOpts{ 124 FloatingIP: floatingIP, 125 } 126 log.Printf("[DEBUG] Disssociate Options: %#v", disassociateOpts) 127 128 err = floatingips.DisassociateInstance(computeClient, instanceId, disassociateOpts).ExtractErr() 129 if err != nil { 130 return CheckDeleted(d, err, "floating ip association") 131 } 132 133 return nil 134 } 135 136 func parseComputeFloatingIPAssociateId(id string) (string, string, string, error) { 137 idParts := strings.Split(id, "/") 138 if len(idParts) < 3 { 139 return "", "", "", fmt.Errorf("Unable to determine floating ip association ID") 140 } 141 142 floatingIP := idParts[0] 143 instanceId := idParts[1] 144 fixedIP := idParts[2] 145 146 return floatingIP, instanceId, fixedIP, nil 147 }