github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/google/resource_compute_region_backend_service.go (about)

     1  package google
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"regexp"
     8  
     9  	"github.com/hashicorp/terraform/helper/hashcode"
    10  	"github.com/hashicorp/terraform/helper/schema"
    11  	"google.golang.org/api/compute/v1"
    12  	"google.golang.org/api/googleapi"
    13  )
    14  
    15  func resourceComputeRegionBackendService() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceComputeRegionBackendServiceCreate,
    18  		Read:   resourceComputeRegionBackendServiceRead,
    19  		Update: resourceComputeRegionBackendServiceUpdate,
    20  		Delete: resourceComputeRegionBackendServiceDelete,
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"name": &schema.Schema{
    24  				Type:     schema.TypeString,
    25  				Required: true,
    26  				ForceNew: true,
    27  				ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
    28  					value := v.(string)
    29  					re := `^(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)$`
    30  					if !regexp.MustCompile(re).MatchString(value) {
    31  						errors = append(errors, fmt.Errorf(
    32  							"%q (%q) doesn't match regexp %q", k, value, re))
    33  					}
    34  					return
    35  				},
    36  			},
    37  
    38  			"health_checks": &schema.Schema{
    39  				Type:     schema.TypeSet,
    40  				Elem:     &schema.Schema{Type: schema.TypeString},
    41  				Required: true,
    42  				Set:      schema.HashString,
    43  			},
    44  
    45  			"backend": &schema.Schema{
    46  				Type: schema.TypeSet,
    47  				Elem: &schema.Resource{
    48  					Schema: map[string]*schema.Schema{
    49  						"group": &schema.Schema{
    50  							Type:     schema.TypeString,
    51  							Optional: true,
    52  						},
    53  						"description": &schema.Schema{
    54  							Type:     schema.TypeString,
    55  							Optional: true,
    56  						},
    57  					},
    58  				},
    59  				Optional: true,
    60  				Set:      resourceGoogleComputeRegionBackendServiceBackendHash,
    61  			},
    62  
    63  			"description": &schema.Schema{
    64  				Type:     schema.TypeString,
    65  				Optional: true,
    66  			},
    67  
    68  			"fingerprint": &schema.Schema{
    69  				Type:     schema.TypeString,
    70  				Computed: true,
    71  			},
    72  
    73  			"project": &schema.Schema{
    74  				Type:     schema.TypeString,
    75  				Optional: true,
    76  				ForceNew: true,
    77  			},
    78  
    79  			"protocol": &schema.Schema{
    80  				Type:     schema.TypeString,
    81  				Optional: true,
    82  				Computed: true,
    83  			},
    84  
    85  			"session_affinity": &schema.Schema{
    86  				Type:     schema.TypeString,
    87  				Optional: true,
    88  				Computed: true,
    89  			},
    90  
    91  			"region": &schema.Schema{
    92  				Type:     schema.TypeString,
    93  				Optional: true,
    94  				ForceNew: true,
    95  			},
    96  
    97  			"self_link": &schema.Schema{
    98  				Type:     schema.TypeString,
    99  				Computed: true,
   100  			},
   101  
   102  			"timeout_sec": &schema.Schema{
   103  				Type:     schema.TypeInt,
   104  				Optional: true,
   105  				Computed: true,
   106  			},
   107  		},
   108  	}
   109  }
   110  
   111  func resourceComputeRegionBackendServiceCreate(d *schema.ResourceData, meta interface{}) error {
   112  	config := meta.(*Config)
   113  
   114  	hc := d.Get("health_checks").(*schema.Set).List()
   115  	healthChecks := make([]string, 0, len(hc))
   116  	for _, v := range hc {
   117  		healthChecks = append(healthChecks, v.(string))
   118  	}
   119  
   120  	service := compute.BackendService{
   121  		Name:                d.Get("name").(string),
   122  		HealthChecks:        healthChecks,
   123  		LoadBalancingScheme: "INTERNAL",
   124  	}
   125  
   126  	if v, ok := d.GetOk("backend"); ok {
   127  		service.Backends = expandBackends(v.(*schema.Set).List())
   128  	}
   129  
   130  	if v, ok := d.GetOk("description"); ok {
   131  		service.Description = v.(string)
   132  	}
   133  
   134  	if v, ok := d.GetOk("protocol"); ok {
   135  		service.Protocol = v.(string)
   136  	}
   137  
   138  	if v, ok := d.GetOk("session_affinity"); ok {
   139  		service.SessionAffinity = v.(string)
   140  	}
   141  
   142  	if v, ok := d.GetOk("timeout_sec"); ok {
   143  		service.TimeoutSec = int64(v.(int))
   144  	}
   145  
   146  	project, err := getProject(d, config)
   147  	if err != nil {
   148  		return err
   149  	}
   150  
   151  	region, err := getRegion(d, config)
   152  	if err != nil {
   153  		return err
   154  	}
   155  
   156  	log.Printf("[DEBUG] Creating new Region Backend Service: %#v", service)
   157  
   158  	op, err := config.clientCompute.RegionBackendServices.Insert(
   159  		project, region, &service).Do()
   160  	if err != nil {
   161  		return fmt.Errorf("Error creating backend service: %s", err)
   162  	}
   163  
   164  	log.Printf("[DEBUG] Waiting for new backend service, operation: %#v", op)
   165  
   166  	d.SetId(service.Name)
   167  
   168  	err = computeOperationWaitRegion(config, op, project, region, "Creating Region Backend Service")
   169  	if err != nil {
   170  		return err
   171  	}
   172  
   173  	return resourceComputeRegionBackendServiceRead(d, meta)
   174  }
   175  
   176  func resourceComputeRegionBackendServiceRead(d *schema.ResourceData, meta interface{}) error {
   177  	config := meta.(*Config)
   178  
   179  	project, err := getProject(d, config)
   180  	if err != nil {
   181  		return err
   182  	}
   183  
   184  	region, err := getRegion(d, config)
   185  	if err != nil {
   186  		return err
   187  	}
   188  
   189  	service, err := config.clientCompute.RegionBackendServices.Get(
   190  		project, region, d.Id()).Do()
   191  	if err != nil {
   192  		if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
   193  			// The resource doesn't exist anymore
   194  			log.Printf("[WARN] Removing Backend Service %q because it's gone", d.Get("name").(string))
   195  			d.SetId("")
   196  
   197  			return nil
   198  		}
   199  
   200  		return fmt.Errorf("Error reading service: %s", err)
   201  	}
   202  
   203  	d.Set("description", service.Description)
   204  	d.Set("protocol", service.Protocol)
   205  	d.Set("session_affinity", service.SessionAffinity)
   206  	d.Set("timeout_sec", service.TimeoutSec)
   207  	d.Set("fingerprint", service.Fingerprint)
   208  	d.Set("self_link", service.SelfLink)
   209  
   210  	d.Set("backend", flattenBackends(service.Backends))
   211  	d.Set("health_checks", service.HealthChecks)
   212  
   213  	return nil
   214  }
   215  
   216  func resourceComputeRegionBackendServiceUpdate(d *schema.ResourceData, meta interface{}) error {
   217  	config := meta.(*Config)
   218  
   219  	project, err := getProject(d, config)
   220  	if err != nil {
   221  		return err
   222  	}
   223  
   224  	region, err := getRegion(d, config)
   225  	if err != nil {
   226  		return err
   227  	}
   228  
   229  	hc := d.Get("health_checks").(*schema.Set).List()
   230  	healthChecks := make([]string, 0, len(hc))
   231  	for _, v := range hc {
   232  		healthChecks = append(healthChecks, v.(string))
   233  	}
   234  
   235  	service := compute.BackendService{
   236  		Name:                d.Get("name").(string),
   237  		Fingerprint:         d.Get("fingerprint").(string),
   238  		HealthChecks:        healthChecks,
   239  		LoadBalancingScheme: "INTERNAL",
   240  	}
   241  
   242  	// Optional things
   243  	if v, ok := d.GetOk("backend"); ok {
   244  		service.Backends = expandBackends(v.(*schema.Set).List())
   245  	}
   246  	if v, ok := d.GetOk("description"); ok {
   247  		service.Description = v.(string)
   248  	}
   249  	if v, ok := d.GetOk("protocol"); ok {
   250  		service.Protocol = v.(string)
   251  	}
   252  	if v, ok := d.GetOk("session_affinity"); ok {
   253  		service.SessionAffinity = v.(string)
   254  	}
   255  	if v, ok := d.GetOk("timeout_sec"); ok {
   256  		service.TimeoutSec = int64(v.(int))
   257  	}
   258  
   259  	log.Printf("[DEBUG] Updating existing Backend Service %q: %#v", d.Id(), service)
   260  	op, err := config.clientCompute.RegionBackendServices.Update(
   261  		project, region, d.Id(), &service).Do()
   262  	if err != nil {
   263  		return fmt.Errorf("Error updating backend service: %s", err)
   264  	}
   265  
   266  	d.SetId(service.Name)
   267  
   268  	err = computeOperationWaitRegion(config, op, project, region, "Updating Backend Service")
   269  	if err != nil {
   270  		return err
   271  	}
   272  
   273  	return resourceComputeRegionBackendServiceRead(d, meta)
   274  }
   275  
   276  func resourceComputeRegionBackendServiceDelete(d *schema.ResourceData, meta interface{}) error {
   277  	config := meta.(*Config)
   278  
   279  	project, err := getProject(d, config)
   280  	if err != nil {
   281  		return err
   282  	}
   283  
   284  	region, err := getRegion(d, config)
   285  	if err != nil {
   286  		return err
   287  	}
   288  
   289  	log.Printf("[DEBUG] Deleting backend service %s", d.Id())
   290  	op, err := config.clientCompute.RegionBackendServices.Delete(
   291  		project, region, d.Id()).Do()
   292  	if err != nil {
   293  		return fmt.Errorf("Error deleting backend service: %s", err)
   294  	}
   295  
   296  	err = computeOperationWaitRegion(config, op, project, region, "Deleting Backend Service")
   297  	if err != nil {
   298  		return err
   299  	}
   300  
   301  	d.SetId("")
   302  	return nil
   303  }
   304  
   305  func resourceGoogleComputeRegionBackendServiceBackendHash(v interface{}) int {
   306  	if v == nil {
   307  		return 0
   308  	}
   309  
   310  	var buf bytes.Buffer
   311  	m := v.(map[string]interface{})
   312  
   313  	buf.WriteString(fmt.Sprintf("%s-", m["group"].(string)))
   314  
   315  	if v, ok := m["description"]; ok {
   316  		buf.WriteString(fmt.Sprintf("%s-", v.(string)))
   317  	}
   318  
   319  	return hashcode.String(buf.String())
   320  }