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