github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/openstack/resource_openstack_lb_monitor_v1.go (about) 1 package openstack 2 3 import ( 4 "fmt" 5 "log" 6 "strconv" 7 "time" 8 9 "github.com/hashicorp/terraform/helper/resource" 10 "github.com/hashicorp/terraform/helper/schema" 11 12 "github.com/rackspace/gophercloud" 13 "github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas/monitors" 14 ) 15 16 func resourceLBMonitorV1() *schema.Resource { 17 return &schema.Resource{ 18 Create: resourceLBMonitorV1Create, 19 Read: resourceLBMonitorV1Read, 20 Update: resourceLBMonitorV1Update, 21 Delete: resourceLBMonitorV1Delete, 22 23 Schema: map[string]*schema.Schema{ 24 "region": &schema.Schema{ 25 Type: schema.TypeString, 26 Required: true, 27 ForceNew: true, 28 DefaultFunc: envDefaultFuncAllowMissing("OS_REGION_NAME"), 29 }, 30 "tenant_id": &schema.Schema{ 31 Type: schema.TypeString, 32 Optional: true, 33 ForceNew: true, 34 Computed: true, 35 }, 36 "type": &schema.Schema{ 37 Type: schema.TypeString, 38 Required: true, 39 ForceNew: true, 40 }, 41 "delay": &schema.Schema{ 42 Type: schema.TypeInt, 43 Required: true, 44 ForceNew: false, 45 }, 46 "timeout": &schema.Schema{ 47 Type: schema.TypeInt, 48 Required: true, 49 ForceNew: false, 50 }, 51 "max_retries": &schema.Schema{ 52 Type: schema.TypeInt, 53 Required: true, 54 ForceNew: false, 55 }, 56 "url_path": &schema.Schema{ 57 Type: schema.TypeString, 58 Optional: true, 59 ForceNew: false, 60 }, 61 "http_method": &schema.Schema{ 62 Type: schema.TypeString, 63 Optional: true, 64 ForceNew: false, 65 }, 66 "expected_codes": &schema.Schema{ 67 Type: schema.TypeString, 68 Optional: true, 69 ForceNew: false, 70 }, 71 "admin_state_up": &schema.Schema{ 72 Type: schema.TypeString, 73 Optional: true, 74 ForceNew: false, 75 Computed: true, 76 }, 77 }, 78 } 79 } 80 81 func resourceLBMonitorV1Create(d *schema.ResourceData, meta interface{}) error { 82 config := meta.(*Config) 83 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 84 if err != nil { 85 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 86 } 87 88 createOpts := monitors.CreateOpts{ 89 TenantID: d.Get("tenant_id").(string), 90 Type: d.Get("type").(string), 91 Delay: d.Get("delay").(int), 92 Timeout: d.Get("timeout").(int), 93 MaxRetries: d.Get("max_retries").(int), 94 URLPath: d.Get("url_path").(string), 95 ExpectedCodes: d.Get("expected_codes").(string), 96 HTTPMethod: d.Get("http_method").(string), 97 } 98 99 asuRaw := d.Get("admin_state_up").(string) 100 if asuRaw != "" { 101 asu, err := strconv.ParseBool(asuRaw) 102 if err != nil { 103 return fmt.Errorf("admin_state_up, if provided, must be either 'true' or 'false'") 104 } 105 createOpts.AdminStateUp = &asu 106 } 107 108 log.Printf("[DEBUG] Create Options: %#v", createOpts) 109 m, err := monitors.Create(networkingClient, createOpts).Extract() 110 if err != nil { 111 return fmt.Errorf("Error creating OpenStack LB Monitor: %s", err) 112 } 113 log.Printf("[INFO] LB Monitor ID: %s", m.ID) 114 115 log.Printf("[DEBUG] Waiting for OpenStack LB Monitor (%s) to become available.", m.ID) 116 117 stateConf := &resource.StateChangeConf{ 118 Pending: []string{"PENDING"}, 119 Target: "ACTIVE", 120 Refresh: waitForLBMonitorActive(networkingClient, m.ID), 121 Timeout: 2 * time.Minute, 122 Delay: 5 * time.Second, 123 MinTimeout: 3 * time.Second, 124 } 125 126 _, err = stateConf.WaitForState() 127 if err != nil { 128 return err 129 } 130 131 d.SetId(m.ID) 132 133 return resourceLBMonitorV1Read(d, meta) 134 } 135 136 func resourceLBMonitorV1Read(d *schema.ResourceData, meta interface{}) error { 137 config := meta.(*Config) 138 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 139 if err != nil { 140 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 141 } 142 143 m, err := monitors.Get(networkingClient, d.Id()).Extract() 144 if err != nil { 145 return CheckDeleted(d, err, "LB monitor") 146 } 147 148 log.Printf("[DEBUG] Retreived OpenStack LB Monitor %s: %+v", d.Id(), m) 149 150 d.Set("type", m.Type) 151 d.Set("delay", m.Delay) 152 d.Set("timeout", m.Timeout) 153 d.Set("max_retries", m.MaxRetries) 154 d.Set("tenant_id", m.TenantID) 155 d.Set("url_path", m.URLPath) 156 d.Set("http_method", m.HTTPMethod) 157 d.Set("expected_codes", m.ExpectedCodes) 158 d.Set("admin_state_up", strconv.FormatBool(m.AdminStateUp)) 159 160 return nil 161 } 162 163 func resourceLBMonitorV1Update(d *schema.ResourceData, meta interface{}) error { 164 config := meta.(*Config) 165 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 166 if err != nil { 167 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 168 } 169 170 updateOpts := monitors.UpdateOpts{ 171 Delay: d.Get("delay").(int), 172 Timeout: d.Get("timeout").(int), 173 MaxRetries: d.Get("max_retries").(int), 174 URLPath: d.Get("url_path").(string), 175 HTTPMethod: d.Get("http_method").(string), 176 ExpectedCodes: d.Get("expected_codes").(string), 177 } 178 179 if d.HasChange("admin_state_up") { 180 asuRaw := d.Get("admin_state_up").(string) 181 if asuRaw != "" { 182 asu, err := strconv.ParseBool(asuRaw) 183 if err != nil { 184 return fmt.Errorf("admin_state_up, if provided, must be either 'true' or 'false'") 185 } 186 updateOpts.AdminStateUp = &asu 187 } 188 } 189 190 log.Printf("[DEBUG] Updating OpenStack LB Monitor %s with options: %+v", d.Id(), updateOpts) 191 192 _, err = monitors.Update(networkingClient, d.Id(), updateOpts).Extract() 193 if err != nil { 194 return fmt.Errorf("Error updating OpenStack LB Monitor: %s", err) 195 } 196 197 return resourceLBMonitorV1Read(d, meta) 198 } 199 200 func resourceLBMonitorV1Delete(d *schema.ResourceData, meta interface{}) error { 201 config := meta.(*Config) 202 networkingClient, err := config.networkingV2Client(d.Get("region").(string)) 203 if err != nil { 204 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 205 } 206 207 stateConf := &resource.StateChangeConf{ 208 Pending: []string{"ACTIVE", "PENDING"}, 209 Target: "DELETED", 210 Refresh: waitForLBMonitorDelete(networkingClient, d.Id()), 211 Timeout: 2 * time.Minute, 212 Delay: 5 * time.Second, 213 MinTimeout: 3 * time.Second, 214 } 215 216 _, err = stateConf.WaitForState() 217 if err != nil { 218 return fmt.Errorf("Error deleting OpenStack LB Monitor: %s", err) 219 } 220 221 d.SetId("") 222 return nil 223 } 224 225 func waitForLBMonitorActive(networkingClient *gophercloud.ServiceClient, monitorId string) resource.StateRefreshFunc { 226 return func() (interface{}, string, error) { 227 m, err := monitors.Get(networkingClient, monitorId).Extract() 228 if err != nil { 229 return nil, "", err 230 } 231 232 // The monitor resource has no Status attribute, so a successful Get is the best we can do 233 log.Printf("[DEBUG] OpenStack LB Monitor: %+v", m) 234 return m, "ACTIVE", nil 235 } 236 } 237 238 func waitForLBMonitorDelete(networkingClient *gophercloud.ServiceClient, monitorId string) resource.StateRefreshFunc { 239 return func() (interface{}, string, error) { 240 log.Printf("[DEBUG] Attempting to delete OpenStack LB Monitor %s", monitorId) 241 242 m, err := monitors.Get(networkingClient, monitorId).Extract() 243 if err != nil { 244 errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError) 245 if !ok { 246 return m, "ACTIVE", err 247 } 248 if errCode.Actual == 404 { 249 log.Printf("[DEBUG] Successfully deleted OpenStack LB Monitor %s", monitorId) 250 return m, "DELETED", nil 251 } 252 if errCode.Actual == 409 { 253 log.Printf("[DEBUG] OpenStack LB Monitor (%s) is waiting for Pool to delete.", monitorId) 254 return m, "PENDING", nil 255 } 256 } 257 258 log.Printf("[DEBUG] OpenStack LB Monitor: %+v", m) 259 err = monitors.Delete(networkingClient, monitorId).ExtractErr() 260 if err != nil { 261 errCode, ok := err.(*gophercloud.UnexpectedResponseCodeError) 262 if !ok { 263 return m, "ACTIVE", err 264 } 265 if errCode.Actual == 404 { 266 log.Printf("[DEBUG] Successfully deleted OpenStack LB Monitor %s", monitorId) 267 return m, "DELETED", nil 268 } 269 if errCode.Actual == 409 { 270 log.Printf("[DEBUG] OpenStack LB Monitor (%s) is waiting for Pool to delete.", monitorId) 271 return m, "PENDING", nil 272 } 273 } 274 275 log.Printf("[DEBUG] OpenStack LB Monitor %s still active.", monitorId) 276 return m, "ACTIVE", nil 277 } 278 279 }