-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #21 from thetonymaster/loadbalancer-backend-addres…
…s-pool Loadbalancer backend address pool
- Loading branch information
Showing
6 changed files
with
591 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
245 changes: 245 additions & 0 deletions
245
azurestack/resource_arm_loadbalancer_backend_address_pool.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,245 @@ | ||
package azurestack | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2015-06-15/network" | ||
"github.com/hashicorp/errwrap" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
"github.com/terraform-providers/terraform-provider-azurestack/azurestack/utils" | ||
) | ||
|
||
func resourceArmLoadBalancerBackendAddressPool() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceArmLoadBalancerBackendAddressPoolCreate, | ||
Read: resourceArmLoadBalancerBackendAddressPoolRead, | ||
Delete: resourceArmLoadBalancerBackendAddressPoolDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: loadBalancerSubResourceStateImporter, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"name": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"resource_group_name": resourceGroupNameSchema(), | ||
|
||
"loadbalancer_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"backend_ip_configurations": { | ||
Type: schema.TypeSet, | ||
Computed: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
Set: schema.HashString, | ||
}, | ||
|
||
"load_balancing_rules": { | ||
Type: schema.TypeSet, | ||
Computed: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
Set: schema.HashString, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceArmLoadBalancerBackendAddressPoolCreate(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*ArmClient).loadBalancerClient | ||
ctx := meta.(*ArmClient).StopContext | ||
|
||
loadBalancerID := d.Get("loadbalancer_id").(string) | ||
armMutexKV.Lock(loadBalancerID) | ||
defer armMutexKV.Unlock(loadBalancerID) | ||
|
||
loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) | ||
if err != nil { | ||
return errwrap.Wrapf("Error Getting LoadBalancer By ID {{err}}", err) | ||
} | ||
if !exists { | ||
d.SetId("") | ||
log.Printf("[INFO] LoadBalancer %q not found. Removing from state", d.Get("name").(string)) | ||
return nil | ||
} | ||
|
||
backendAddressPools := append(*loadBalancer.LoadBalancerPropertiesFormat.BackendAddressPools, expandAzureRmLoadBalancerBackendAddressPools(d)) | ||
existingPool, existingPoolIndex, exists := findLoadBalancerBackEndAddressPoolByName(loadBalancer, d.Get("name").(string)) | ||
if exists { | ||
if d.Get("name").(string) == *existingPool.Name { | ||
// this pool is being updated/reapplied remove old copy from the slice | ||
backendAddressPools = append(backendAddressPools[:existingPoolIndex], backendAddressPools[existingPoolIndex+1:]...) | ||
} | ||
} | ||
|
||
loadBalancer.LoadBalancerPropertiesFormat.BackendAddressPools = &backendAddressPools | ||
resGroup, loadBalancerName, err := resourceGroupAndLBNameFromId(d.Get("loadbalancer_id").(string)) | ||
if err != nil { | ||
return fmt.Errorf("Error parsing LoadBalancer Name and Group: %+v", err) | ||
} | ||
|
||
future, err := client.CreateOrUpdate(ctx, resGroup, loadBalancerName, *loadBalancer) | ||
if err != nil { | ||
return fmt.Errorf("Error Creating/Updating LoadBalancer %q (Resource Group %q): %+v", loadBalancerName, resGroup, err) | ||
} | ||
|
||
err = future.WaitForCompletion(ctx, client.Client) | ||
if err != nil { | ||
return fmt.Errorf("Error Creating/Updating LoadBalancer %q (Resource Group %q): %+v", loadBalancerName, resGroup, err) | ||
} | ||
|
||
read, err := client.Get(ctx, resGroup, loadBalancerName, "") | ||
if err != nil { | ||
return fmt.Errorf("Error retrieving Load Balancer %q (Resource Group %q): %+v", loadBalancerName, resGroup, err) | ||
} | ||
if read.ID == nil { | ||
return fmt.Errorf("Cannot read LoadBalancer %q (Resource Group %q) ID", loadBalancerName, resGroup) | ||
} | ||
|
||
if read.LoadBalancerPropertiesFormat == nil { | ||
return fmt.Errorf("Error creating LoadBalancer (%q Resource Group %q)", loadBalancerName, resGroup) | ||
} | ||
|
||
var poolId string | ||
for _, BackendAddressPool := range *(*read.LoadBalancerPropertiesFormat).BackendAddressPools { | ||
if *BackendAddressPool.Name == d.Get("name").(string) { | ||
poolId = *BackendAddressPool.ID | ||
} | ||
} | ||
|
||
if poolId == "" { | ||
return fmt.Errorf("Cannot find created LoadBalancer Backend Address Pool ID %q", poolId) | ||
} | ||
|
||
d.SetId(poolId) | ||
|
||
// TODO: is this still needed? | ||
log.Printf("[DEBUG] Waiting for LoadBalancer (%s) to become available", loadBalancerName) | ||
stateConf := &resource.StateChangeConf{ | ||
Pending: []string{"Accepted", "Updating"}, | ||
Target: []string{"Succeeded"}, | ||
Refresh: loadbalancerStateRefreshFunc(ctx, client, resGroup, loadBalancerName), | ||
Timeout: 10 * time.Minute, | ||
} | ||
if _, err := stateConf.WaitForState(); err != nil { | ||
return fmt.Errorf("Error waiting for LoadBalancer (%q Resource Group %q) to become available: %+v", loadBalancerName, resGroup, err) | ||
} | ||
|
||
return resourceArmLoadBalancerBackendAddressPoolRead(d, meta) | ||
} | ||
|
||
func resourceArmLoadBalancerBackendAddressPoolRead(d *schema.ResourceData, meta interface{}) error { | ||
id, err := parseAzureResourceID(d.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
name := id.Path["backendAddressPools"] | ||
|
||
loadBalancer, exists, err := retrieveLoadBalancerById(d.Get("loadbalancer_id").(string), meta) | ||
if err != nil { | ||
return fmt.Errorf("Error retrieving Load Balancer by ID: %+v", err) | ||
} | ||
if !exists { | ||
d.SetId("") | ||
log.Printf("[INFO] LoadBalancer %q not found. Removing from state", name) | ||
return nil | ||
} | ||
|
||
config, _, exists := findLoadBalancerBackEndAddressPoolByName(loadBalancer, name) | ||
if !exists { | ||
d.SetId("") | ||
log.Printf("[INFO] LoadBalancer Backend Address Pool %q not found. Removing from state", name) | ||
return nil | ||
} | ||
|
||
d.Set("name", config.Name) | ||
d.Set("resource_group_name", id.ResourceGroup) | ||
|
||
var backendIpConfigurations []string | ||
var loadBalancingRules []string | ||
|
||
if props := config.BackendAddressPoolPropertiesFormat; props != nil { | ||
if configs := props.BackendIPConfigurations; configs != nil { | ||
for _, backendConfig := range *configs { | ||
backendIpConfigurations = append(backendIpConfigurations, *backendConfig.ID) | ||
} | ||
} | ||
|
||
if rules := props.LoadBalancingRules; rules != nil { | ||
for _, rule := range *rules { | ||
loadBalancingRules = append(loadBalancingRules, *rule.ID) | ||
} | ||
} | ||
} | ||
|
||
d.Set("backend_ip_configurations", backendIpConfigurations) | ||
d.Set("load_balancing_rules", loadBalancingRules) | ||
|
||
return nil | ||
} | ||
|
||
func resourceArmLoadBalancerBackendAddressPoolDelete(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*ArmClient).loadBalancerClient | ||
ctx := meta.(*ArmClient).StopContext | ||
|
||
loadBalancerID := d.Get("loadbalancer_id").(string) | ||
armMutexKV.Lock(loadBalancerID) | ||
defer armMutexKV.Unlock(loadBalancerID) | ||
|
||
loadBalancer, exists, err := retrieveLoadBalancerById(loadBalancerID, meta) | ||
if err != nil { | ||
return fmt.Errorf("Error retrieving Load Balancer by ID: %+v", err) | ||
} | ||
if !exists { | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
_, index, exists := findLoadBalancerBackEndAddressPoolByName(loadBalancer, d.Get("name").(string)) | ||
if !exists { | ||
return nil | ||
} | ||
|
||
oldBackEndPools := *loadBalancer.LoadBalancerPropertiesFormat.BackendAddressPools | ||
newBackEndPools := append(oldBackEndPools[:index], oldBackEndPools[index+1:]...) | ||
loadBalancer.LoadBalancerPropertiesFormat.BackendAddressPools = &newBackEndPools | ||
|
||
resGroup, loadBalancerName, err := resourceGroupAndLBNameFromId(d.Get("loadbalancer_id").(string)) | ||
if err != nil { | ||
return errwrap.Wrapf("Error Getting LoadBalancer Name and Group: {{err}}", err) | ||
} | ||
|
||
future, err := client.CreateOrUpdate(ctx, resGroup, loadBalancerName, *loadBalancer) | ||
if err != nil { | ||
return fmt.Errorf("Error Creating/Updating LoadBalancer: %+v", err) | ||
} | ||
|
||
err = future.WaitForCompletion(ctx, client.Client) | ||
if err != nil { | ||
return fmt.Errorf("Error waiting for the completion for the LoadBalancer: %+v", err) | ||
} | ||
|
||
read, err := client.Get(ctx, resGroup, loadBalancerName, "") | ||
if err != nil { | ||
return fmt.Errorf("Error retrieving the LoadBalancer %q (Resource Group %q): %+v", loadBalancerName, resGroup, err) | ||
} | ||
if read.ID == nil { | ||
return fmt.Errorf("Cannot read LoadBalancer %q (resource group %q) ID", loadBalancerName, resGroup) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func expandAzureRmLoadBalancerBackendAddressPools(d *schema.ResourceData) network.BackendAddressPool { | ||
return network.BackendAddressPool{ | ||
Name: utils.String(d.Get("name").(string)), | ||
} | ||
} |
Oops, something went wrong.