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