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