github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/openstack/resource_openstack_lb_monitor_v2.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_v2/monitors" 13 ) 14 15 func resourceMonitorV2() *schema.Resource { 16 return &schema.Resource{ 17 Create: resourceMonitorV2Create, 18 Read: resourceMonitorV2Read, 19 Update: resourceMonitorV2Update, 20 Delete: resourceMonitorV2Delete, 21 22 Timeouts: &schema.ResourceTimeout{ 23 Create: schema.DefaultTimeout(10 * time.Minute), 24 Delete: schema.DefaultTimeout(10 * time.Minute), 25 }, 26 27 Schema: map[string]*schema.Schema{ 28 "region": &schema.Schema{ 29 Type: schema.TypeString, 30 Required: true, 31 ForceNew: true, 32 DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""), 33 }, 34 35 "pool_id": &schema.Schema{ 36 Type: schema.TypeString, 37 Required: true, 38 ForceNew: true, 39 }, 40 41 "name": &schema.Schema{ 42 Type: schema.TypeString, 43 Optional: true, 44 }, 45 46 "tenant_id": &schema.Schema{ 47 Type: schema.TypeString, 48 Optional: true, 49 Computed: true, 50 ForceNew: true, 51 }, 52 53 "type": &schema.Schema{ 54 Type: schema.TypeString, 55 Required: true, 56 ForceNew: true, 57 }, 58 "delay": &schema.Schema{ 59 Type: schema.TypeInt, 60 Required: true, 61 }, 62 "timeout": &schema.Schema{ 63 Type: schema.TypeInt, 64 Required: true, 65 }, 66 "max_retries": &schema.Schema{ 67 Type: schema.TypeInt, 68 Required: true, 69 }, 70 "url_path": &schema.Schema{ 71 Type: schema.TypeString, 72 Optional: true, 73 Computed: true, 74 }, 75 "http_method": &schema.Schema{ 76 Type: schema.TypeString, 77 Optional: true, 78 Computed: true, 79 }, 80 "expected_codes": &schema.Schema{ 81 Type: schema.TypeString, 82 Optional: true, 83 Computed: true, 84 }, 85 "admin_state_up": &schema.Schema{ 86 Type: schema.TypeBool, 87 Default: true, 88 Optional: true, 89 }, 90 91 "id": &schema.Schema{ 92 Type: schema.TypeString, 93 Optional: true, 94 Computed: true, 95 }, 96 }, 97 } 98 } 99 100 func resourceMonitorV2Create(d *schema.ResourceData, meta interface{}) error { 101 config := meta.(*Config) 102 networkingClient, err := config.networkingV2Client(GetRegion(d)) 103 if err != nil { 104 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 105 } 106 107 adminStateUp := d.Get("admin_state_up").(bool) 108 createOpts := monitors.CreateOpts{ 109 PoolID: d.Get("pool_id").(string), 110 TenantID: d.Get("tenant_id").(string), 111 Type: d.Get("type").(string), 112 Delay: d.Get("delay").(int), 113 Timeout: d.Get("timeout").(int), 114 MaxRetries: d.Get("max_retries").(int), 115 URLPath: d.Get("url_path").(string), 116 HTTPMethod: d.Get("http_method").(string), 117 ExpectedCodes: d.Get("expected_codes").(string), 118 Name: d.Get("name").(string), 119 AdminStateUp: &adminStateUp, 120 } 121 122 log.Printf("[DEBUG] Create Options: %#v", createOpts) 123 monitor, err := monitors.Create(networkingClient, createOpts).Extract() 124 if err != nil { 125 return fmt.Errorf("Error creating OpenStack LBaaSV2 monitor: %s", err) 126 } 127 log.Printf("[INFO] monitor ID: %s", monitor.ID) 128 129 log.Printf("[DEBUG] Waiting for Openstack LBaaSV2 monitor (%s) to become available.", monitor.ID) 130 131 stateConf := &resource.StateChangeConf{ 132 Pending: []string{"PENDING_CREATE"}, 133 Target: []string{"ACTIVE"}, 134 Refresh: waitForMonitorActive(networkingClient, monitor.ID), 135 Timeout: d.Timeout(schema.TimeoutCreate), 136 Delay: 5 * time.Second, 137 MinTimeout: 3 * time.Second, 138 } 139 140 _, err = stateConf.WaitForState() 141 if err != nil { 142 return err 143 } 144 145 d.SetId(monitor.ID) 146 147 return resourceMonitorV2Read(d, meta) 148 } 149 150 func resourceMonitorV2Read(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 monitor, err := monitors.Get(networkingClient, d.Id()).Extract() 158 if err != nil { 159 return CheckDeleted(d, err, "LBV2 Monitor") 160 } 161 162 log.Printf("[DEBUG] Retrieved OpenStack LBaaSV2 Monitor %s: %+v", d.Id(), monitor) 163 164 d.Set("id", monitor.ID) 165 d.Set("tenant_id", monitor.TenantID) 166 d.Set("type", monitor.Type) 167 d.Set("delay", monitor.Delay) 168 d.Set("timeout", monitor.Timeout) 169 d.Set("max_retries", monitor.MaxRetries) 170 d.Set("url_path", monitor.URLPath) 171 d.Set("http_method", monitor.HTTPMethod) 172 d.Set("expected_codes", monitor.ExpectedCodes) 173 d.Set("admin_state_up", monitor.AdminStateUp) 174 d.Set("name", monitor.Name) 175 176 return nil 177 } 178 179 func resourceMonitorV2Update(d *schema.ResourceData, meta interface{}) error { 180 config := meta.(*Config) 181 networkingClient, err := config.networkingV2Client(GetRegion(d)) 182 if err != nil { 183 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 184 } 185 186 var updateOpts monitors.UpdateOpts 187 if d.HasChange("url_path") { 188 updateOpts.URLPath = d.Get("url_path").(string) 189 } 190 if d.HasChange("expected_codes") { 191 updateOpts.ExpectedCodes = d.Get("expected_codes").(string) 192 } 193 if d.HasChange("delay") { 194 updateOpts.Delay = d.Get("delay").(int) 195 } 196 if d.HasChange("timeout") { 197 updateOpts.Timeout = d.Get("timeout").(int) 198 } 199 if d.HasChange("max_retries") { 200 updateOpts.MaxRetries = d.Get("max_retries").(int) 201 } 202 if d.HasChange("admin_state_up") { 203 asu := d.Get("admin_state_up").(bool) 204 updateOpts.AdminStateUp = &asu 205 } 206 if d.HasChange("name") { 207 updateOpts.Name = d.Get("name").(string) 208 } 209 if d.HasChange("http_method") { 210 updateOpts.HTTPMethod = d.Get("http_method").(string) 211 } 212 213 log.Printf("[DEBUG] Updating OpenStack LBaaSV2 Monitor %s with options: %+v", d.Id(), updateOpts) 214 215 _, err = monitors.Update(networkingClient, d.Id(), updateOpts).Extract() 216 if err != nil { 217 return fmt.Errorf("Error updating OpenStack LBaaSV2 Monitor: %s", err) 218 } 219 220 return resourceMonitorV2Read(d, meta) 221 } 222 223 func resourceMonitorV2Delete(d *schema.ResourceData, meta interface{}) error { 224 config := meta.(*Config) 225 networkingClient, err := config.networkingV2Client(GetRegion(d)) 226 if err != nil { 227 return fmt.Errorf("Error creating OpenStack networking client: %s", err) 228 } 229 230 stateConf := &resource.StateChangeConf{ 231 Pending: []string{"ACTIVE", "PENDING_DELETE"}, 232 Target: []string{"DELETED"}, 233 Refresh: waitForMonitorDelete(networkingClient, d.Id()), 234 Timeout: d.Timeout(schema.TimeoutDelete), 235 Delay: 5 * time.Second, 236 MinTimeout: 3 * time.Second, 237 } 238 239 _, err = stateConf.WaitForState() 240 if err != nil { 241 return fmt.Errorf("Error deleting OpenStack LBaaSV2 Monitor: %s", err) 242 } 243 244 d.SetId("") 245 return nil 246 } 247 248 func waitForMonitorActive(networkingClient *gophercloud.ServiceClient, monitorID string) resource.StateRefreshFunc { 249 return func() (interface{}, string, error) { 250 monitor, err := monitors.Get(networkingClient, monitorID).Extract() 251 if err != nil { 252 return nil, "", err 253 } 254 255 log.Printf("[DEBUG] OpenStack LBaaSV2 Monitor: %+v", monitor) 256 return monitor, "ACTIVE", nil 257 } 258 } 259 260 func waitForMonitorDelete(networkingClient *gophercloud.ServiceClient, monitorID string) resource.StateRefreshFunc { 261 return func() (interface{}, string, error) { 262 log.Printf("[DEBUG] Attempting to delete OpenStack LBaaSV2 Monitor %s", monitorID) 263 264 monitor, err := monitors.Get(networkingClient, monitorID).Extract() 265 if err != nil { 266 if _, ok := err.(gophercloud.ErrDefault404); ok { 267 log.Printf("[DEBUG] Successfully deleted OpenStack LBaaSV2 Monitor %s", monitorID) 268 return monitor, "DELETED", nil 269 } 270 return monitor, "ACTIVE", err 271 } 272 273 log.Printf("[DEBUG] Openstack LBaaSV2 Monitor: %+v", monitor) 274 err = monitors.Delete(networkingClient, monitorID).ExtractErr() 275 if err != nil { 276 if _, ok := err.(gophercloud.ErrDefault404); ok { 277 log.Printf("[DEBUG] Successfully deleted OpenStack LBaaSV2 Monitor %s", monitorID) 278 return monitor, "DELETED", nil 279 } 280 281 if errCode, ok := err.(gophercloud.ErrUnexpectedResponseCode); ok { 282 if errCode.Actual == 409 { 283 log.Printf("[DEBUG] OpenStack LBaaSV2 Monitor (%s) is still in use.", monitorID) 284 return monitor, "ACTIVE", nil 285 } 286 } 287 288 return monitor, "ACTIVE", err 289 } 290 291 log.Printf("[DEBUG] OpenStack LBaaSV2 Monitor %s still active.", monitorID) 292 return monitor, "ACTIVE", nil 293 } 294 }