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