github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/azurerm/resource_arm_loadbalancer_probe.go (about) 1 package azurerm 2 3 import ( 4 "fmt" 5 "log" 6 "time" 7 8 "github.com/Azure/azure-sdk-for-go/arm/network" 9 "github.com/hashicorp/errwrap" 10 "github.com/hashicorp/terraform/helper/resource" 11 "github.com/hashicorp/terraform/helper/schema" 12 "github.com/jen20/riviera/azure" 13 ) 14 15 func resourceArmLoadBalancerProbe() *schema.Resource { 16 return &schema.Resource{ 17 Create: resourceArmLoadBalancerProbeCreate, 18 Read: resourceArmLoadBalancerProbeRead, 19 Update: resourceArmLoadBalancerProbeCreate, 20 Delete: resourceArmLoadBalancerProbeDelete, 21 Importer: &schema.ResourceImporter{ 22 State: loadBalancerSubResourceStateImporter, 23 }, 24 25 Schema: map[string]*schema.Schema{ 26 "name": { 27 Type: schema.TypeString, 28 Required: true, 29 ForceNew: true, 30 }, 31 32 "location": deprecatedLocationSchema(), 33 34 "resource_group_name": { 35 Type: schema.TypeString, 36 Required: true, 37 ForceNew: true, 38 }, 39 40 "loadbalancer_id": { 41 Type: schema.TypeString, 42 Required: true, 43 ForceNew: true, 44 }, 45 46 "protocol": { 47 Type: schema.TypeString, 48 Computed: true, 49 Optional: true, 50 StateFunc: ignoreCaseStateFunc, 51 DiffSuppressFunc: ignoreCaseDiffSuppressFunc, 52 }, 53 54 "port": { 55 Type: schema.TypeInt, 56 Required: true, 57 }, 58 59 "request_path": { 60 Type: schema.TypeString, 61 Optional: true, 62 }, 63 64 "interval_in_seconds": { 65 Type: schema.TypeInt, 66 Optional: true, 67 Default: 15, 68 }, 69 70 "number_of_probes": { 71 Type: schema.TypeInt, 72 Optional: true, 73 Default: 2, 74 }, 75 76 "load_balancer_rules": { 77 Type: schema.TypeSet, 78 Computed: true, 79 Elem: &schema.Schema{Type: schema.TypeString}, 80 Set: schema.HashString, 81 }, 82 }, 83 } 84 } 85 86 func resourceArmLoadBalancerProbeCreate(d *schema.ResourceData, meta interface{}) error { 87 client := meta.(*ArmClient) 88 lbClient := client.loadBalancerClient 89 90 loadBalancerID := d.Get("loadbalancer_id").(string) 91 armMutexKV.Lock(loadBalancerID) 92 defer armMutexKV.Unlock(loadBalancerID) 93 94 loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) 95 if err != nil { 96 return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err) 97 } 98 if !exists { 99 d.SetId("") 100 log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string)) 101 return nil 102 } 103 104 newProbe, err := expandAzureRmLoadBalancerProbe(d, loadBalancer) 105 if err != nil { 106 return errwrap.Wrapf("Error Expanding Probe {{err}}", err) 107 } 108 109 probes := append(*loadBalancer.LoadBalancerPropertiesFormat.Probes, *newProbe) 110 111 existingProbe, existingProbeIndex, exists := findLoadBalancerProbeByName(loadBalancer, d.Get("name").(string)) 112 if exists { 113 if d.Get("name").(string) == *existingProbe.Name { 114 // this probe is being updated/reapplied remove old copy from the slice 115 probes = append(probes[:existingProbeIndex], probes[existingProbeIndex+1:]...) 116 } 117 } 118 119 loadBalancer.LoadBalancerPropertiesFormat.Probes = &probes 120 resGroup, loadBalancerName, err := resourceGroupAndLBNameFromId(d.Get("loadbalancer_id").(string)) 121 if err != nil { 122 return errwrap.Wrapf("Error Getting LoadBalancer Name and Group: {{err}}", err) 123 } 124 125 _, error := lbClient.CreateOrUpdate(resGroup, loadBalancerName, *loadBalancer, make(chan struct{})) 126 err = <-error 127 if err != nil { 128 return errwrap.Wrapf("Error Creating/Updating LoadBalancer {{err}}", err) 129 } 130 131 read, err := lbClient.Get(resGroup, loadBalancerName, "") 132 if err != nil { 133 return errwrap.Wrapf("Error Getting LoadBalancer {{err}}", err) 134 } 135 if read.ID == nil { 136 return fmt.Errorf("Cannot read LoadBalancer %s (resource group %s) ID", loadBalancerName, resGroup) 137 } 138 139 var createdProbe_id string 140 for _, Probe := range *(*read.LoadBalancerPropertiesFormat).Probes { 141 if *Probe.Name == d.Get("name").(string) { 142 createdProbe_id = *Probe.ID 143 } 144 } 145 146 if createdProbe_id != "" { 147 d.SetId(createdProbe_id) 148 } else { 149 return fmt.Errorf("Cannot find created LoadBalancer Probe ID %q", createdProbe_id) 150 } 151 152 log.Printf("[DEBUG] Waiting for LoadBalancer (%s) to become available", loadBalancerName) 153 stateConf := &resource.StateChangeConf{ 154 Pending: []string{"Accepted", "Updating"}, 155 Target: []string{"Succeeded"}, 156 Refresh: loadbalancerStateRefreshFunc(client, resGroup, loadBalancerName), 157 Timeout: 10 * time.Minute, 158 } 159 if _, err := stateConf.WaitForState(); err != nil { 160 return fmt.Errorf("Error waiting for LoadBalancer (%s) to become available: %s", loadBalancerName, err) 161 } 162 163 return resourceArmLoadBalancerProbeRead(d, meta) 164 } 165 166 func resourceArmLoadBalancerProbeRead(d *schema.ResourceData, meta interface{}) error { 167 id, err := parseAzureResourceID(d.Id()) 168 if err != nil { 169 return err 170 } 171 name := id.Path["probes"] 172 173 loadBalancer, exists, err := retrieveLoadBalancerById(d.Get("loadbalancer_id").(string), meta) 174 if err != nil { 175 return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err) 176 } 177 if !exists { 178 d.SetId("") 179 log.Printf("[INFO] LoadBalancer %q not found. Removing from state", name) 180 return nil 181 } 182 183 config, _, exists := findLoadBalancerProbeByName(loadBalancer, name) 184 if !exists { 185 d.SetId("") 186 log.Printf("[INFO] LoadBalancer Probe %q not found. Removing from state", name) 187 return nil 188 } 189 190 d.Set("name", config.Name) 191 d.Set("resource_group_name", id.ResourceGroup) 192 d.Set("protocol", config.ProbePropertiesFormat.Protocol) 193 d.Set("interval_in_seconds", config.ProbePropertiesFormat.IntervalInSeconds) 194 d.Set("number_of_probes", config.ProbePropertiesFormat.NumberOfProbes) 195 d.Set("port", config.ProbePropertiesFormat.Port) 196 d.Set("request_path", config.ProbePropertiesFormat.RequestPath) 197 198 var load_balancer_rules []string 199 if config.ProbePropertiesFormat.LoadBalancingRules != nil { 200 for _, ruleConfig := range *config.ProbePropertiesFormat.LoadBalancingRules { 201 load_balancer_rules = append(load_balancer_rules, *ruleConfig.ID) 202 } 203 } 204 d.Set("load_balancer_rules", load_balancer_rules) 205 206 return nil 207 } 208 209 func resourceArmLoadBalancerProbeDelete(d *schema.ResourceData, meta interface{}) error { 210 client := meta.(*ArmClient) 211 lbClient := client.loadBalancerClient 212 213 loadBalancerID := d.Get("loadbalancer_id").(string) 214 armMutexKV.Lock(loadBalancerID) 215 defer armMutexKV.Unlock(loadBalancerID) 216 217 loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) 218 if err != nil { 219 return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err) 220 } 221 if !exists { 222 d.SetId("") 223 return nil 224 } 225 226 _, index, exists := findLoadBalancerProbeByName(loadBalancer, d.Get("name").(string)) 227 if !exists { 228 return nil 229 } 230 231 oldProbes := *loadBalancer.LoadBalancerPropertiesFormat.Probes 232 newProbes := append(oldProbes[:index], oldProbes[index+1:]...) 233 loadBalancer.LoadBalancerPropertiesFormat.Probes = &newProbes 234 235 resGroup, loadBalancerName, err := resourceGroupAndLBNameFromId(d.Get("loadbalancer_id").(string)) 236 if err != nil { 237 return errwrap.Wrapf("Error Getting LoadBalancer Name and Group: {{err}}", err) 238 } 239 240 _, error := lbClient.CreateOrUpdate(resGroup, loadBalancerName, *loadBalancer, make(chan struct{})) 241 err = <-error 242 if err != nil { 243 return errwrap.Wrapf("Error Creating/Updating LoadBalancer {{err}}", err) 244 } 245 246 read, err := lbClient.Get(resGroup, loadBalancerName, "") 247 if err != nil { 248 return errwrap.Wrapf("Error Getting LoadBalancer {{err}}", err) 249 } 250 if read.ID == nil { 251 return fmt.Errorf("Cannot read LoadBalancer %s (resource group %s) ID", loadBalancerName, resGroup) 252 } 253 254 return nil 255 } 256 257 func expandAzureRmLoadBalancerProbe(d *schema.ResourceData, lb *network.LoadBalancer) (*network.Probe, error) { 258 259 properties := network.ProbePropertiesFormat{ 260 NumberOfProbes: azure.Int32(int32(d.Get("number_of_probes").(int))), 261 IntervalInSeconds: azure.Int32(int32(d.Get("interval_in_seconds").(int))), 262 Port: azure.Int32(int32(d.Get("port").(int))), 263 } 264 265 if v, ok := d.GetOk("protocol"); ok { 266 properties.Protocol = network.ProbeProtocol(v.(string)) 267 } 268 269 if v, ok := d.GetOk("request_path"); ok { 270 properties.RequestPath = azure.String(v.(string)) 271 } 272 273 probe := network.Probe{ 274 Name: azure.String(d.Get("name").(string)), 275 ProbePropertiesFormat: &properties, 276 } 277 278 return &probe, nil 279 }