github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/openstack/resource_openstack_lb_member_v1.go (about) 1 package openstack 2 3 import ( 4 "fmt" 5 "log" 6 "time" 7 8 "github.com/hashicorp/terraform/helper/resource" 9 "github.com/hashicorp/terraform/helper/schema" 10 11 "github.com/gophercloud/gophercloud" 12 "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/lbaas/members" 13 ) 14 15 func resourceLBMemberV1() *schema.Resource { 16 return &schema.Resource{ 17 Create: resourceLBMemberV1Create, 18 Read: resourceLBMemberV1Read, 19 Update: resourceLBMemberV1Update, 20 Delete: resourceLBMemberV1Delete, 21 Importer: &schema.ResourceImporter{ 22 State: schema.ImportStatePassthrough, 23 }, 24 25 Timeouts: &schema.ResourceTimeout{ 26 Create: schema.DefaultTimeout(10 * time.Minute), 27 Delete: schema.DefaultTimeout(10 * time.Minute), 28 }, 29 30 Schema: map[string]*schema.Schema{ 31 "region": &schema.Schema{ 32 Type: schema.TypeString, 33 Required: true, 34 ForceNew: true, 35 DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""), 36 }, 37 "tenant_id": &schema.Schema{ 38 Type: schema.TypeString, 39 Optional: true, 40 ForceNew: true, 41 }, 42 "pool_id": &schema.Schema{ 43 Type: schema.TypeString, 44 Required: true, 45 ForceNew: true, 46 }, 47 "address": &schema.Schema{ 48 Type: schema.TypeString, 49 Required: true, 50 ForceNew: true, 51 }, 52 "port": &schema.Schema{ 53 Type: schema.TypeInt, 54 Required: true, 55 ForceNew: true, 56 }, 57 "weight": &schema.Schema{ 58 Type: schema.TypeInt, 59 Optional: true, 60 Computed: true, 61 }, 62 "admin_state_up": &schema.Schema{ 63 Type: schema.TypeBool, 64 Optional: true, 65 ForceNew: false, 66 Computed: true, 67 }, 68 }, 69 } 70 } 71 72 func resourceLBMemberV1Create(d *schema.ResourceData, meta interface{}) error { 73 config := meta.(*Config) 74 networkingClient, err := config.networkingV2Client(GetRegion(d)) 75 if err != nil { 76 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 77 } 78 79 createOpts := members.CreateOpts{ 80 TenantID: d.Get("tenant_id").(string), 81 PoolID: d.Get("pool_id").(string), 82 Address: d.Get("address").(string), 83 ProtocolPort: d.Get("port").(int), 84 } 85 86 log.Printf("[DEBUG] OpenStack LB Member Create Options: %#v", createOpts) 87 m, err := members.Create(networkingClient, createOpts).Extract() 88 if err != nil { 89 return fmt.Errorf("Error creating OpenStack LB member: %s", err) 90 } 91 log.Printf("[INFO] LB member ID: %s", m.ID) 92 93 log.Printf("[DEBUG] Waiting for OpenStack LB member (%s) to become available.", m.ID) 94 95 stateConf := &resource.StateChangeConf{ 96 Pending: []string{"PENDING_CREATE"}, 97 Target: []string{"ACTIVE", "INACTIVE", "CREATED", "DOWN"}, 98 Refresh: waitForLBMemberActive(networkingClient, m.ID), 99 Timeout: d.Timeout(schema.TimeoutCreate), 100 Delay: 5 * time.Second, 101 MinTimeout: 3 * time.Second, 102 } 103 104 _, err = stateConf.WaitForState() 105 if err != nil { 106 return err 107 } 108 109 d.SetId(m.ID) 110 111 // Due to the way Gophercloud is currently set up, AdminStateUp must be set post-create 112 asu := d.Get("admin_state_up").(bool) 113 updateOpts := members.UpdateOpts{ 114 AdminStateUp: &asu, 115 } 116 117 log.Printf("[DEBUG] OpenStack LB Member Update Options: %#v", createOpts) 118 m, err = members.Update(networkingClient, m.ID, updateOpts).Extract() 119 if err != nil { 120 return fmt.Errorf("Error updating OpenStack LB member: %s", err) 121 } 122 123 return resourceLBMemberV1Read(d, meta) 124 } 125 126 func resourceLBMemberV1Read(d *schema.ResourceData, meta interface{}) error { 127 config := meta.(*Config) 128 networkingClient, err := config.networkingV2Client(GetRegion(d)) 129 if err != nil { 130 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 131 } 132 133 m, err := members.Get(networkingClient, d.Id()).Extract() 134 if err != nil { 135 return CheckDeleted(d, err, "LB member") 136 } 137 138 log.Printf("[DEBUG] Retrieved OpenStack LB member %s: %+v", d.Id(), m) 139 140 d.Set("address", m.Address) 141 d.Set("pool_id", m.PoolID) 142 d.Set("port", m.ProtocolPort) 143 d.Set("weight", m.Weight) 144 d.Set("admin_state_up", m.AdminStateUp) 145 d.Set("region", GetRegion(d)) 146 147 return nil 148 } 149 150 func resourceLBMemberV1Update(d *schema.ResourceData, meta interface{}) error { 151 config := meta.(*Config) 152 networkingClient, err := config.networkingV2Client(GetRegion(d)) 153 if err != nil { 154 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 155 } 156 157 var updateOpts members.UpdateOpts 158 if d.HasChange("admin_state_up") { 159 asu := d.Get("admin_state_up").(bool) 160 updateOpts.AdminStateUp = &asu 161 } 162 163 log.Printf("[DEBUG] Updating LB member %s with options: %+v", d.Id(), updateOpts) 164 165 _, err = members.Update(networkingClient, d.Id(), updateOpts).Extract() 166 if err != nil { 167 return fmt.Errorf("Error updating OpenStack LB member: %s", err) 168 } 169 170 return resourceLBMemberV1Read(d, meta) 171 } 172 173 func resourceLBMemberV1Delete(d *schema.ResourceData, meta interface{}) error { 174 config := meta.(*Config) 175 networkingClient, err := config.networkingV2Client(GetRegion(d)) 176 if err != nil { 177 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 178 } 179 180 err = members.Delete(networkingClient, d.Id()).ExtractErr() 181 if err != nil { 182 CheckDeleted(d, err, "LB member") 183 } 184 185 stateConf := &resource.StateChangeConf{ 186 Pending: []string{"ACTIVE", "PENDING_DELETE"}, 187 Target: []string{"DELETED"}, 188 Refresh: waitForLBMemberDelete(networkingClient, d.Id()), 189 Timeout: d.Timeout(schema.TimeoutDelete), 190 Delay: 5 * time.Second, 191 MinTimeout: 3 * time.Second, 192 } 193 194 _, err = stateConf.WaitForState() 195 if err != nil { 196 return fmt.Errorf("Error deleting OpenStack LB member: %s", err) 197 } 198 199 d.SetId("") 200 return nil 201 } 202 203 func waitForLBMemberActive(networkingClient *gophercloud.ServiceClient, memberId string) resource.StateRefreshFunc { 204 return func() (interface{}, string, error) { 205 m, err := members.Get(networkingClient, memberId).Extract() 206 if err != nil { 207 return nil, "", err 208 } 209 210 log.Printf("[DEBUG] OpenStack LB member: %+v", m) 211 if m.Status == "ACTIVE" { 212 return m, "ACTIVE", nil 213 } 214 215 return m, m.Status, nil 216 } 217 } 218 219 func waitForLBMemberDelete(networkingClient *gophercloud.ServiceClient, memberId string) resource.StateRefreshFunc { 220 return func() (interface{}, string, error) { 221 log.Printf("[DEBUG] Attempting to delete OpenStack LB member %s", memberId) 222 223 m, err := members.Get(networkingClient, memberId).Extract() 224 if err != nil { 225 if _, ok := err.(gophercloud.ErrDefault404); ok { 226 log.Printf("[DEBUG] Successfully deleted OpenStack LB member %s", memberId) 227 return m, "DELETED", nil 228 } 229 return m, "ACTIVE", err 230 } 231 232 log.Printf("[DEBUG] OpenStack LB member %s still active.", memberId) 233 return m, "ACTIVE", nil 234 } 235 236 }