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