diff --git a/google/provider_compute_gen.go b/google/provider_compute_gen.go index 50baf00e5b5..b5407b92192 100644 --- a/google/provider_compute_gen.go +++ b/google/provider_compute_gen.go @@ -26,6 +26,7 @@ var GeneratedComputeResourcesMap = map[string]*schema.Resource{ "google_compute_global_address": resourceComputeGlobalAddress(), "google_compute_http_health_check": resourceComputeHttpHealthCheck(), "google_compute_https_health_check": resourceComputeHttpsHealthCheck(), + "google_compute_health_check": resourceComputeHealthCheck(), "google_compute_region_autoscaler": resourceComputeRegionAutoscaler(), "google_compute_region_disk": resourceComputeRegionDisk(), "google_compute_route": resourceComputeRoute(), diff --git a/google/resource_compute_health_check.go b/google/resource_compute_health_check.go index d143d05d052..eaaeac493fb 100644 --- a/google/resource_compute_health_check.go +++ b/google/resource_compute_health_check.go @@ -1,187 +1,213 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + package google import ( "fmt" "log" + "reflect" + "strconv" + "time" "github.com/hashicorp/terraform/helper/schema" - "google.golang.org/api/compute/v1" + "github.com/hashicorp/terraform/helper/validation" + compute "google.golang.org/api/compute/v1" ) func resourceComputeHealthCheck() *schema.Resource { return &schema.Resource{ Create: resourceComputeHealthCheckCreate, Read: resourceComputeHealthCheckRead, - Delete: resourceComputeHealthCheckDelete, Update: resourceComputeHealthCheckUpdate, + Delete: resourceComputeHealthCheckDelete, + Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: resourceComputeHealthCheckImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(240 * time.Second), + Update: schema.DefaultTimeout(240 * time.Second), + Delete: schema.DefaultTimeout(240 * time.Second), }, Schema: map[string]*schema.Schema{ - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, ForceNew: true, }, - - "check_interval_sec": &schema.Schema{ + "check_interval_sec": { Type: schema.TypeInt, Optional: true, Default: 5, }, - - "description": &schema.Schema{ + "description": { Type: schema.TypeString, Optional: true, }, - - "healthy_threshold": &schema.Schema{ + "healthy_threshold": { Type: schema.TypeInt, Optional: true, Default: 2, }, - - "tcp_health_check": &schema.Schema{ - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ConflictsWith: []string{"ssl_health_check", "http_health_check", "https_health_check"}, + "timeout_sec": { + Type: schema.TypeInt, + Optional: true, + Default: 5, + }, + "unhealthy_threshold": { + Type: schema.TypeInt, + Optional: true, + Default: 2, + }, + "http_health_check": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "port": &schema.Schema{ - Type: schema.TypeInt, - Optional: true, - Default: 80, - }, - "proxy_header": &schema.Schema{ + "host": { Type: schema.TypeString, Optional: true, - Default: "NONE", }, - "request": &schema.Schema{ + "request_path": { Type: schema.TypeString, Optional: true, + Default: "/", }, - "response": &schema.Schema{ - Type: schema.TypeString, + "port": { + Type: schema.TypeInt, Optional: true, + Default: 80, + }, + "proxy_header": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"NONE", "PROXY_V1", ""}, false), + Default: "NONE", }, }, }, + ConflictsWith: []string{"https_health_check", "tcp_health_check", "ssl_health_check"}, }, - - "ssl_health_check": &schema.Schema{ - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ConflictsWith: []string{"tcp_health_check", "http_health_check", "https_health_check"}, + "https_health_check": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "port": &schema.Schema{ - Type: schema.TypeInt, - Optional: true, - Default: 443, - }, - "proxy_header": &schema.Schema{ + "host": { Type: schema.TypeString, Optional: true, - Default: "NONE", }, - "request": &schema.Schema{ + "request_path": { Type: schema.TypeString, Optional: true, + Default: "/", }, - "response": &schema.Schema{ - Type: schema.TypeString, + "port": { + Type: schema.TypeInt, Optional: true, + Default: 443, + }, + "proxy_header": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"NONE", "PROXY_V1", ""}, false), + Default: "NONE", }, }, }, + ConflictsWith: []string{"http_health_check", "tcp_health_check", "ssl_health_check"}, }, - - "http_health_check": &schema.Schema{ - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ConflictsWith: []string{"tcp_health_check", "ssl_health_check", "https_health_check"}, + "tcp_health_check": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "host": &schema.Schema{ + "request": { Type: schema.TypeString, Optional: true, }, - "port": &schema.Schema{ - Type: schema.TypeInt, - Optional: true, - Default: 80, - }, - "proxy_header": &schema.Schema{ + "response": { Type: schema.TypeString, Optional: true, - Default: "NONE", }, - "request_path": &schema.Schema{ - Type: schema.TypeString, + "port": { + Type: schema.TypeInt, Optional: true, - Default: "/", + Default: 80, + }, + "proxy_header": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"NONE", "PROXY_V1", ""}, false), + Default: "NONE", }, }, }, + ConflictsWith: []string{"http_health_check", "https_health_check", "ssl_health_check"}, }, - - "https_health_check": &schema.Schema{ - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - ConflictsWith: []string{"tcp_health_check", "ssl_health_check", "http_health_check"}, + "ssl_health_check": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "host": &schema.Schema{ + "request": { Type: schema.TypeString, Optional: true, }, - "port": &schema.Schema{ - Type: schema.TypeInt, - Optional: true, - Default: 443, - }, - "proxy_header": &schema.Schema{ + "response": { Type: schema.TypeString, Optional: true, - Default: "NONE", }, - "request_path": &schema.Schema{ - Type: schema.TypeString, + "port": { + Type: schema.TypeInt, Optional: true, - Default: "/", + Default: 443, + }, + "proxy_header": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"NONE", "PROXY_V1", ""}, false), + Default: "NONE", }, }, }, + ConflictsWith: []string{"http_health_check", "https_health_check", "tcp_health_check"}, }, - - "project": &schema.Schema{ + "creation_timestamp": { Type: schema.TypeString, - Optional: true, - ForceNew: true, Computed: true, }, - - "self_link": &schema.Schema{ + "type": { Type: schema.TypeString, Computed: true, }, - - "timeout_sec": &schema.Schema{ - Type: schema.TypeInt, + "project": { + Type: schema.TypeString, Optional: true, - Default: 5, + Computed: true, + ForceNew: true, }, - - "unhealthy_threshold": &schema.Schema{ - Type: schema.TypeInt, - Optional: true, - Default: 2, + "self_link": { + Type: schema.TypeString, + Computed: true, }, }, } @@ -190,369 +216,771 @@ func resourceComputeHealthCheck() *schema.Resource { func resourceComputeHealthCheckCreate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - project, err := getProject(d, config) + obj := make(map[string]interface{}) + checkIntervalSecProp, err := expandComputeHealthCheckCheckIntervalSec(d.Get("check_interval_sec"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("check_interval_sec"); !isEmptyValue(reflect.ValueOf(checkIntervalSecProp)) && (ok || !reflect.DeepEqual(v, checkIntervalSecProp)) { + obj["checkIntervalSec"] = checkIntervalSecProp + } + descriptionProp, err := expandComputeHealthCheckDescription(d.Get("description"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { + obj["description"] = descriptionProp + } + healthyThresholdProp, err := expandComputeHealthCheckHealthyThreshold(d.Get("healthy_threshold"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("healthy_threshold"); !isEmptyValue(reflect.ValueOf(healthyThresholdProp)) && (ok || !reflect.DeepEqual(v, healthyThresholdProp)) { + obj["healthyThreshold"] = healthyThresholdProp + } + nameProp, err := expandComputeHealthCheckName(d.Get("name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) { + obj["name"] = nameProp + } + timeoutSecProp, err := expandComputeHealthCheckTimeoutSec(d.Get("timeout_sec"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("timeout_sec"); !isEmptyValue(reflect.ValueOf(timeoutSecProp)) && (ok || !reflect.DeepEqual(v, timeoutSecProp)) { + obj["timeoutSec"] = timeoutSecProp + } + unhealthyThresholdProp, err := expandComputeHealthCheckUnhealthyThreshold(d.Get("unhealthy_threshold"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("unhealthy_threshold"); !isEmptyValue(reflect.ValueOf(unhealthyThresholdProp)) && (ok || !reflect.DeepEqual(v, unhealthyThresholdProp)) { + obj["unhealthyThreshold"] = unhealthyThresholdProp + } + httpHealthCheckProp, err := expandComputeHealthCheckHttpHealthCheck(d.Get("http_health_check"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("http_health_check"); !isEmptyValue(reflect.ValueOf(httpHealthCheckProp)) && (ok || !reflect.DeepEqual(v, httpHealthCheckProp)) { + obj["httpHealthCheck"] = httpHealthCheckProp + } + httpsHealthCheckProp, err := expandComputeHealthCheckHttpsHealthCheck(d.Get("https_health_check"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("https_health_check"); !isEmptyValue(reflect.ValueOf(httpsHealthCheckProp)) && (ok || !reflect.DeepEqual(v, httpsHealthCheckProp)) { + obj["httpsHealthCheck"] = httpsHealthCheckProp + } + tcpHealthCheckProp, err := expandComputeHealthCheckTcpHealthCheck(d.Get("tcp_health_check"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("tcp_health_check"); !isEmptyValue(reflect.ValueOf(tcpHealthCheckProp)) && (ok || !reflect.DeepEqual(v, tcpHealthCheckProp)) { + obj["tcpHealthCheck"] = tcpHealthCheckProp + } + sslHealthCheckProp, err := expandComputeHealthCheckSslHealthCheck(d.Get("ssl_health_check"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("ssl_health_check"); !isEmptyValue(reflect.ValueOf(sslHealthCheckProp)) && (ok || !reflect.DeepEqual(v, sslHealthCheckProp)) { + obj["sslHealthCheck"] = sslHealthCheckProp + } + + obj, err = resourceComputeHealthCheckEncoder(d, meta, obj) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/global/healthChecks") if err != nil { return err } - // Build the parameter - hchk := &compute.HealthCheck{ - Name: d.Get("name").(string), - } - // Optional things - if v, ok := d.GetOk("description"); ok { - hchk.Description = v.(string) - } - if v, ok := d.GetOk("check_interval_sec"); ok { - hchk.CheckIntervalSec = int64(v.(int)) - } - if v, ok := d.GetOk("healthy_threshold"); ok { - hchk.HealthyThreshold = int64(v.(int)) - } - if v, ok := d.GetOk("timeout_sec"); ok { - hchk.TimeoutSec = int64(v.(int)) - } - if v, ok := d.GetOk("unhealthy_threshold"); ok { - hchk.UnhealthyThreshold = int64(v.(int)) - } - - if v, ok := d.GetOk("tcp_health_check"); ok { - hchk.Type = "TCP" - tcpcheck := v.([]interface{})[0].(map[string]interface{}) - tcpHealthCheck := &compute.TCPHealthCheck{} - if val, ok := tcpcheck["port"]; ok { - tcpHealthCheck.Port = int64(val.(int)) - } - if val, ok := tcpcheck["proxy_header"]; ok { - tcpHealthCheck.ProxyHeader = val.(string) - } - if val, ok := tcpcheck["request"]; ok { - tcpHealthCheck.Request = val.(string) - } - if val, ok := tcpcheck["response"]; ok { - tcpHealthCheck.Response = val.(string) - } - hchk.TcpHealthCheck = tcpHealthCheck - } - - if v, ok := d.GetOk("ssl_health_check"); ok { - hchk.Type = "SSL" - sslcheck := v.([]interface{})[0].(map[string]interface{}) - sslHealthCheck := &compute.SSLHealthCheck{} - if val, ok := sslcheck["port"]; ok { - sslHealthCheck.Port = int64(val.(int)) - } - if val, ok := sslcheck["proxy_header"]; ok { - sslHealthCheck.ProxyHeader = val.(string) - } - if val, ok := sslcheck["request"]; ok { - sslHealthCheck.Request = val.(string) - } - if val, ok := sslcheck["response"]; ok { - sslHealthCheck.Response = val.(string) - } - hchk.SslHealthCheck = sslHealthCheck - } - - if v, ok := d.GetOk("http_health_check"); ok { - hchk.Type = "HTTP" - httpcheck := v.([]interface{})[0].(map[string]interface{}) - httpHealthCheck := &compute.HTTPHealthCheck{} - if val, ok := httpcheck["host"]; ok { - httpHealthCheck.Host = val.(string) - } - if val, ok := httpcheck["port"]; ok { - httpHealthCheck.Port = int64(val.(int)) - } - if val, ok := httpcheck["proxy_header"]; ok { - httpHealthCheck.ProxyHeader = val.(string) - } - if val, ok := httpcheck["request_path"]; ok { - httpHealthCheck.RequestPath = val.(string) - } - hchk.HttpHealthCheck = httpHealthCheck - } - - if v, ok := d.GetOk("https_health_check"); ok { - hchk.Type = "HTTPS" - httpscheck := v.([]interface{})[0].(map[string]interface{}) - httpsHealthCheck := &compute.HTTPSHealthCheck{} - if val, ok := httpscheck["host"]; ok { - httpsHealthCheck.Host = val.(string) - } - if val, ok := httpscheck["port"]; ok { - httpsHealthCheck.Port = int64(val.(int)) - } - if val, ok := httpscheck["proxy_header"]; ok { - httpsHealthCheck.ProxyHeader = val.(string) - } - if val, ok := httpscheck["request_path"]; ok { - httpsHealthCheck.RequestPath = val.(string) - } - hchk.HttpsHealthCheck = httpsHealthCheck - } - - log.Printf("[DEBUG] HealthCheck insert request: %#v", hchk) - op, err := config.clientCompute.HealthChecks.Insert( - project, hchk).Do() + log.Printf("[DEBUG] Creating new HealthCheck: %#v", obj) + res, err := sendRequest(config, "POST", url, obj) if err != nil { return fmt.Errorf("Error creating HealthCheck: %s", err) } - // It probably maybe worked, so store the ID now - d.SetId(hchk.Name) + // Store the ID now + id, err := replaceVars(d, config, "{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) - err = computeOperationWait(config.clientCompute, op, project, "Creating Health Check") + project, err := getProject(d, config) + if err != nil { + return err + } + op := &compute.Operation{} + err = Convert(res, op) if err != nil { return err } + waitErr := computeOperationWaitTime( + config.clientCompute, op, project, "Creating HealthCheck", + int(d.Timeout(schema.TimeoutCreate).Minutes())) + + if waitErr != nil { + // The resource didn't actually create + d.SetId("") + return fmt.Errorf("Error waiting to create HealthCheck: %s", waitErr) + } + + log.Printf("[DEBUG] Finished creating HealthCheck %q: %#v", d.Id(), res) + return resourceComputeHealthCheckRead(d, meta) } -func resourceComputeHealthCheckUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceComputeHealthCheckRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - project, err := getProject(d, config) + url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/global/healthChecks/{{name}}") if err != nil { return err } - // Build the parameter - hchk := &compute.HealthCheck{ - Name: d.Get("name").(string), - } - - nullFields := make([]string, 0, 3) - - // Optional things - if v, ok := d.GetOk("description"); ok { - hchk.Description = v.(string) - } - if v, ok := d.GetOk("check_interval_sec"); ok { - hchk.CheckIntervalSec = int64(v.(int)) - } - if v, ok := d.GetOk("healthy_threshold"); ok { - hchk.HealthyThreshold = int64(v.(int)) - } - if v, ok := d.GetOk("timeout_sec"); ok { - hchk.TimeoutSec = int64(v.(int)) - } - if v, ok := d.GetOk("unhealthy_threshold"); ok { - hchk.UnhealthyThreshold = int64(v.(int)) - } - if v, ok := d.GetOk("tcp_health_check"); ok { - hchk.Type = "TCP" - tcpcheck := v.([]interface{})[0].(map[string]interface{}) - tcpHealthCheck := &compute.TCPHealthCheck{} - if val, ok := tcpcheck["port"]; ok { - tcpHealthCheck.Port = int64(val.(int)) - } - if val, ok := tcpcheck["proxy_header"]; ok { - tcpHealthCheck.ProxyHeader = val.(string) - } - if val, ok := tcpcheck["request"]; ok { - tcpHealthCheck.Request = val.(string) - } - if val, ok := tcpcheck["response"]; ok { - tcpHealthCheck.Response = val.(string) - } - hchk.TcpHealthCheck = tcpHealthCheck - } else { - nullFields = append(nullFields, "TcpHealthCheck") - } - if v, ok := d.GetOk("ssl_health_check"); ok { - hchk.Type = "SSL" - sslcheck := v.([]interface{})[0].(map[string]interface{}) - sslHealthCheck := &compute.SSLHealthCheck{} - if val, ok := sslcheck["port"]; ok { - sslHealthCheck.Port = int64(val.(int)) - } - if val, ok := sslcheck["proxy_header"]; ok { - sslHealthCheck.ProxyHeader = val.(string) - } - if val, ok := sslcheck["request"]; ok { - sslHealthCheck.Request = val.(string) - } - if val, ok := sslcheck["response"]; ok { - sslHealthCheck.Response = val.(string) - } - hchk.SslHealthCheck = sslHealthCheck - } else { - nullFields = append(nullFields, "SslHealthCheck") - } - if v, ok := d.GetOk("http_health_check"); ok { - hchk.Type = "HTTP" - httpcheck := v.([]interface{})[0].(map[string]interface{}) - httpHealthCheck := &compute.HTTPHealthCheck{} - if val, ok := httpcheck["host"]; ok { - httpHealthCheck.Host = val.(string) - } - if val, ok := httpcheck["port"]; ok { - httpHealthCheck.Port = int64(val.(int)) - } - if val, ok := httpcheck["proxy_header"]; ok { - httpHealthCheck.ProxyHeader = val.(string) - } - if val, ok := httpcheck["request_path"]; ok { - httpHealthCheck.RequestPath = val.(string) - } - hchk.HttpHealthCheck = httpHealthCheck - } else { - nullFields = append(nullFields, "HttpHealthCheck") - } - - if v, ok := d.GetOk("https_health_check"); ok { - hchk.Type = "HTTPS" - httpscheck := v.([]interface{})[0].(map[string]interface{}) - httpsHealthCheck := &compute.HTTPSHealthCheck{} - if val, ok := httpscheck["host"]; ok { - httpsHealthCheck.Host = val.(string) - } - if val, ok := httpscheck["port"]; ok { - httpsHealthCheck.Port = int64(val.(int)) - } - if val, ok := httpscheck["proxy_header"]; ok { - httpsHealthCheck.ProxyHeader = val.(string) - } - if val, ok := httpscheck["request_path"]; ok { - httpsHealthCheck.RequestPath = val.(string) - } - hchk.HttpsHealthCheck = httpsHealthCheck - } else { - nullFields = append(nullFields, "HttpsHealthCheck") - } - - hchk.NullFields = nullFields - - log.Printf("[DEBUG] HealthCheck patch request: %#v", hchk) - op, err := config.clientCompute.HealthChecks.Patch( - project, hchk.Name, hchk).Do() - if err != nil { - return fmt.Errorf("Error patching HealthCheck: %s", err) - } - - // It probably maybe worked, so store the ID now - d.SetId(hchk.Name) - - err = computeOperationWait(config.clientCompute, op, project, "Updating Health Check") + res, err := sendRequest(config, "GET", url, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("ComputeHealthCheck %q", d.Id())) + } + + if err := d.Set("check_interval_sec", flattenComputeHealthCheckCheckIntervalSec(res["checkIntervalSec"])); err != nil { + return fmt.Errorf("Error reading HealthCheck: %s", err) + } + if err := d.Set("creation_timestamp", flattenComputeHealthCheckCreationTimestamp(res["creationTimestamp"])); err != nil { + return fmt.Errorf("Error reading HealthCheck: %s", err) + } + if err := d.Set("description", flattenComputeHealthCheckDescription(res["description"])); err != nil { + return fmt.Errorf("Error reading HealthCheck: %s", err) + } + if err := d.Set("healthy_threshold", flattenComputeHealthCheckHealthyThreshold(res["healthyThreshold"])); err != nil { + return fmt.Errorf("Error reading HealthCheck: %s", err) + } + if err := d.Set("name", flattenComputeHealthCheckName(res["name"])); err != nil { + return fmt.Errorf("Error reading HealthCheck: %s", err) + } + if err := d.Set("timeout_sec", flattenComputeHealthCheckTimeoutSec(res["timeoutSec"])); err != nil { + return fmt.Errorf("Error reading HealthCheck: %s", err) + } + if err := d.Set("unhealthy_threshold", flattenComputeHealthCheckUnhealthyThreshold(res["unhealthyThreshold"])); err != nil { + return fmt.Errorf("Error reading HealthCheck: %s", err) + } + if err := d.Set("type", flattenComputeHealthCheckType(res["type"])); err != nil { + return fmt.Errorf("Error reading HealthCheck: %s", err) + } + if err := d.Set("http_health_check", flattenComputeHealthCheckHttpHealthCheck(res["httpHealthCheck"])); err != nil { + return fmt.Errorf("Error reading HealthCheck: %s", err) + } + if err := d.Set("https_health_check", flattenComputeHealthCheckHttpsHealthCheck(res["httpsHealthCheck"])); err != nil { + return fmt.Errorf("Error reading HealthCheck: %s", err) + } + if err := d.Set("tcp_health_check", flattenComputeHealthCheckTcpHealthCheck(res["tcpHealthCheck"])); err != nil { + return fmt.Errorf("Error reading HealthCheck: %s", err) + } + if err := d.Set("ssl_health_check", flattenComputeHealthCheckSslHealthCheck(res["sslHealthCheck"])); err != nil { + return fmt.Errorf("Error reading HealthCheck: %s", err) + } + if err := d.Set("self_link", ConvertSelfLinkToV1(res["selfLink"].(string))); err != nil { + return fmt.Errorf("Error reading HealthCheck: %s", err) + } + project, err := getProject(d, config) if err != nil { return err } + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading HealthCheck: %s", err) + } - return resourceComputeHealthCheckRead(d, meta) + return nil } -func resourceComputeHealthCheckRead(d *schema.ResourceData, meta interface{}) error { +func resourceComputeHealthCheckUpdate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - project, err := getProject(d, config) + obj := make(map[string]interface{}) + checkIntervalSecProp, err := expandComputeHealthCheckCheckIntervalSec(d.Get("check_interval_sec"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("check_interval_sec"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, checkIntervalSecProp)) { + obj["checkIntervalSec"] = checkIntervalSecProp + } + descriptionProp, err := expandComputeHealthCheckDescription(d.Get("description"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { + obj["description"] = descriptionProp + } + healthyThresholdProp, err := expandComputeHealthCheckHealthyThreshold(d.Get("healthy_threshold"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("healthy_threshold"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, healthyThresholdProp)) { + obj["healthyThreshold"] = healthyThresholdProp + } + nameProp, err := expandComputeHealthCheckName(d.Get("name"), d, config) if err != nil { return err + } else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, nameProp)) { + obj["name"] = nameProp } + timeoutSecProp, err := expandComputeHealthCheckTimeoutSec(d.Get("timeout_sec"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("timeout_sec"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, timeoutSecProp)) { + obj["timeoutSec"] = timeoutSecProp + } + unhealthyThresholdProp, err := expandComputeHealthCheckUnhealthyThreshold(d.Get("unhealthy_threshold"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("unhealthy_threshold"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, unhealthyThresholdProp)) { + obj["unhealthyThreshold"] = unhealthyThresholdProp + } + httpHealthCheckProp, err := expandComputeHealthCheckHttpHealthCheck(d.Get("http_health_check"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("http_health_check"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, httpHealthCheckProp)) { + obj["httpHealthCheck"] = httpHealthCheckProp + } + httpsHealthCheckProp, err := expandComputeHealthCheckHttpsHealthCheck(d.Get("https_health_check"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("https_health_check"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, httpsHealthCheckProp)) { + obj["httpsHealthCheck"] = httpsHealthCheckProp + } + tcpHealthCheckProp, err := expandComputeHealthCheckTcpHealthCheck(d.Get("tcp_health_check"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("tcp_health_check"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, tcpHealthCheckProp)) { + obj["tcpHealthCheck"] = tcpHealthCheckProp + } + sslHealthCheckProp, err := expandComputeHealthCheckSslHealthCheck(d.Get("ssl_health_check"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("ssl_health_check"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, sslHealthCheckProp)) { + obj["sslHealthCheck"] = sslHealthCheckProp + } + + obj, err = resourceComputeHealthCheckEncoder(d, meta, obj) - hchk, err := config.clientCompute.HealthChecks.Get( - project, d.Id()).Do() + url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/global/healthChecks/{{name}}") if err != nil { - return handleNotFoundError(err, d, fmt.Sprintf("Health Check %q", d.Get("name").(string))) + return err } - d.Set("check_interval_sec", hchk.CheckIntervalSec) - d.Set("healthy_threshold", hchk.HealthyThreshold) - d.Set("timeout_sec", hchk.TimeoutSec) - d.Set("unhealthy_threshold", hchk.UnhealthyThreshold) - d.Set("tcp_health_check", flattenTcpHealthCheck(hchk.TcpHealthCheck)) - d.Set("ssl_health_check", flattenSslHealthCheck(hchk.SslHealthCheck)) - d.Set("http_health_check", flattenHttpHealthCheck(hchk.HttpHealthCheck)) - d.Set("https_health_check", flattenHttpsHealthCheck(hchk.HttpsHealthCheck)) - d.Set("self_link", hchk.SelfLink) - d.Set("name", hchk.Name) - d.Set("description", hchk.Description) - d.Set("project", project) + log.Printf("[DEBUG] Updating HealthCheck %q: %#v", d.Id(), obj) + res, err := sendRequest(config, "PUT", url, obj) - return nil + if err != nil { + return fmt.Errorf("Error updating HealthCheck %q: %s", d.Id(), err) + } + + project, err := getProject(d, config) + if err != nil { + return err + } + op := &compute.Operation{} + err = Convert(res, op) + if err != nil { + return err + } + + err = computeOperationWaitTime( + config.clientCompute, op, project, "Updating HealthCheck", + int(d.Timeout(schema.TimeoutUpdate).Minutes())) + + if err != nil { + return err + } + + return resourceComputeHealthCheckRead(d, meta) } func resourceComputeHealthCheckDelete(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - project, err := getProject(d, config) + url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/global/healthChecks/{{name}}") if err != nil { return err } - // Delete the HealthCheck - op, err := config.clientCompute.HealthChecks.Delete( - project, d.Id()).Do() + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting HealthCheck %q", d.Id()) + res, err := sendRequest(config, "DELETE", url, obj) if err != nil { - return fmt.Errorf("Error deleting HealthCheck: %s", err) + return handleNotFoundError(err, d, "HealthCheck") } - err = computeOperationWait(config.clientCompute, op, project, "Deleting Health Check") + project, err := getProject(d, config) + if err != nil { + return err + } + op := &compute.Operation{} + err = Convert(res, op) if err != nil { return err } - d.SetId("") + err = computeOperationWaitTime( + config.clientCompute, op, project, "Deleting HealthCheck", + int(d.Timeout(schema.TimeoutDelete).Minutes())) + + if err != nil { + return err + } + + log.Printf("[DEBUG] Finished deleting HealthCheck %q: %#v", d.Id(), res) return nil } -func flattenTcpHealthCheck(hchk *compute.TCPHealthCheck) []map[string]interface{} { - if hchk == nil { +func resourceComputeHealthCheckImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + parseImportId([]string{"projects/(?P[^/]+)/global/healthChecks/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config) + + // Replace import id for the resource id + id, err := replaceVars(d, config, "{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenComputeHealthCheckCheckIntervalSec(v interface{}) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil { + return intVal + } // let terraform core handle it if we can't convert the string to an int. + } + return v +} + +func flattenComputeHealthCheckCreationTimestamp(v interface{}) interface{} { + return v +} + +func flattenComputeHealthCheckDescription(v interface{}) interface{} { + return v +} + +func flattenComputeHealthCheckHealthyThreshold(v interface{}) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil { + return intVal + } // let terraform core handle it if we can't convert the string to an int. + } + return v +} + +func flattenComputeHealthCheckName(v interface{}) interface{} { + return v +} + +func flattenComputeHealthCheckTimeoutSec(v interface{}) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil { + return intVal + } // let terraform core handle it if we can't convert the string to an int. + } + return v +} + +func flattenComputeHealthCheckUnhealthyThreshold(v interface{}) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil { + return intVal + } // let terraform core handle it if we can't convert the string to an int. + } + return v +} + +func flattenComputeHealthCheckType(v interface{}) interface{} { + return v +} + +func flattenComputeHealthCheckHttpHealthCheck(v interface{}) interface{} { + if v == nil { return nil } + original := v.(map[string]interface{}) + transformed := make(map[string]interface{}) + transformed["host"] = + flattenComputeHealthCheckHttpHealthCheckHost(original["host"]) + transformed["request_path"] = + flattenComputeHealthCheckHttpHealthCheckRequestPath(original["requestPath"]) + transformed["port"] = + flattenComputeHealthCheckHttpHealthCheckPort(original["port"]) + transformed["proxy_header"] = + flattenComputeHealthCheckHttpHealthCheckProxyHeader(original["proxyHeader"]) + return []interface{}{transformed} +} +func flattenComputeHealthCheckHttpHealthCheckHost(v interface{}) interface{} { + return v +} - result := make([]map[string]interface{}, 0, 1) - data := make(map[string]interface{}) - data["port"] = hchk.Port - data["proxy_header"] = hchk.ProxyHeader - data["request"] = hchk.Request - data["response"] = hchk.Response - result = append(result, data) - return result +func flattenComputeHealthCheckHttpHealthCheckRequestPath(v interface{}) interface{} { + return v } -func flattenSslHealthCheck(hchk *compute.SSLHealthCheck) []map[string]interface{} { - if hchk == nil { +func flattenComputeHealthCheckHttpHealthCheckPort(v interface{}) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil { + return intVal + } // let terraform core handle it if we can't convert the string to an int. + } + return v +} + +func flattenComputeHealthCheckHttpHealthCheckProxyHeader(v interface{}) interface{} { + return v +} + +func flattenComputeHealthCheckHttpsHealthCheck(v interface{}) interface{} { + if v == nil { return nil } + original := v.(map[string]interface{}) + transformed := make(map[string]interface{}) + transformed["host"] = + flattenComputeHealthCheckHttpsHealthCheckHost(original["host"]) + transformed["request_path"] = + flattenComputeHealthCheckHttpsHealthCheckRequestPath(original["requestPath"]) + transformed["port"] = + flattenComputeHealthCheckHttpsHealthCheckPort(original["port"]) + transformed["proxy_header"] = + flattenComputeHealthCheckHttpsHealthCheckProxyHeader(original["proxyHeader"]) + return []interface{}{transformed} +} +func flattenComputeHealthCheckHttpsHealthCheckHost(v interface{}) interface{} { + return v +} - result := make([]map[string]interface{}, 0, 1) - data := make(map[string]interface{}) - data["port"] = hchk.Port - data["proxy_header"] = hchk.ProxyHeader - data["request"] = hchk.Request - data["response"] = hchk.Response - result = append(result, data) - return result +func flattenComputeHealthCheckHttpsHealthCheckRequestPath(v interface{}) interface{} { + return v } -func flattenHttpHealthCheck(hchk *compute.HTTPHealthCheck) []map[string]interface{} { - if hchk == nil { +func flattenComputeHealthCheckHttpsHealthCheckPort(v interface{}) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil { + return intVal + } // let terraform core handle it if we can't convert the string to an int. + } + return v +} + +func flattenComputeHealthCheckHttpsHealthCheckProxyHeader(v interface{}) interface{} { + return v +} + +func flattenComputeHealthCheckTcpHealthCheck(v interface{}) interface{} { + if v == nil { return nil } + original := v.(map[string]interface{}) + transformed := make(map[string]interface{}) + transformed["request"] = + flattenComputeHealthCheckTcpHealthCheckRequest(original["request"]) + transformed["response"] = + flattenComputeHealthCheckTcpHealthCheckResponse(original["response"]) + transformed["port"] = + flattenComputeHealthCheckTcpHealthCheckPort(original["port"]) + transformed["proxy_header"] = + flattenComputeHealthCheckTcpHealthCheckProxyHeader(original["proxyHeader"]) + return []interface{}{transformed} +} +func flattenComputeHealthCheckTcpHealthCheckRequest(v interface{}) interface{} { + return v +} + +func flattenComputeHealthCheckTcpHealthCheckResponse(v interface{}) interface{} { + return v +} + +func flattenComputeHealthCheckTcpHealthCheckPort(v interface{}) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil { + return intVal + } // let terraform core handle it if we can't convert the string to an int. + } + return v +} - result := make([]map[string]interface{}, 0, 1) - data := make(map[string]interface{}) - data["host"] = hchk.Host - data["port"] = hchk.Port - data["proxy_header"] = hchk.ProxyHeader - data["request_path"] = hchk.RequestPath - result = append(result, data) - return result +func flattenComputeHealthCheckTcpHealthCheckProxyHeader(v interface{}) interface{} { + return v } -func flattenHttpsHealthCheck(hchk *compute.HTTPSHealthCheck) []map[string]interface{} { - if hchk == nil { +func flattenComputeHealthCheckSslHealthCheck(v interface{}) interface{} { + if v == nil { return nil } + original := v.(map[string]interface{}) + transformed := make(map[string]interface{}) + transformed["request"] = + flattenComputeHealthCheckSslHealthCheckRequest(original["request"]) + transformed["response"] = + flattenComputeHealthCheckSslHealthCheckResponse(original["response"]) + transformed["port"] = + flattenComputeHealthCheckSslHealthCheckPort(original["port"]) + transformed["proxy_header"] = + flattenComputeHealthCheckSslHealthCheckProxyHeader(original["proxyHeader"]) + return []interface{}{transformed} +} +func flattenComputeHealthCheckSslHealthCheckRequest(v interface{}) interface{} { + return v +} + +func flattenComputeHealthCheckSslHealthCheckResponse(v interface{}) interface{} { + return v +} + +func flattenComputeHealthCheckSslHealthCheckPort(v interface{}) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil { + return intVal + } // let terraform core handle it if we can't convert the string to an int. + } + return v +} + +func flattenComputeHealthCheckSslHealthCheckProxyHeader(v interface{}) interface{} { + return v +} + +func expandComputeHealthCheckCheckIntervalSec(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckDescription(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckHealthyThreshold(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckName(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckTimeoutSec(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckUnhealthyThreshold(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckHttpHealthCheck(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedHost, err := expandComputeHealthCheckHttpHealthCheckHost(original["host"], d, config) + if err != nil { + return nil, err + } + transformed["host"] = transformedHost + transformedRequestPath, err := expandComputeHealthCheckHttpHealthCheckRequestPath(original["request_path"], d, config) + if err != nil { + return nil, err + } + transformed["requestPath"] = transformedRequestPath + transformedPort, err := expandComputeHealthCheckHttpHealthCheckPort(original["port"], d, config) + if err != nil { + return nil, err + } + transformed["port"] = transformedPort + transformedProxyHeader, err := expandComputeHealthCheckHttpHealthCheckProxyHeader(original["proxy_header"], d, config) + if err != nil { + return nil, err + } + transformed["proxyHeader"] = transformedProxyHeader + return transformed, nil +} + +func expandComputeHealthCheckHttpHealthCheckHost(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckHttpHealthCheckRequestPath(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckHttpHealthCheckPort(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckHttpHealthCheckProxyHeader(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckHttpsHealthCheck(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedHost, err := expandComputeHealthCheckHttpsHealthCheckHost(original["host"], d, config) + if err != nil { + return nil, err + } + transformed["host"] = transformedHost + transformedRequestPath, err := expandComputeHealthCheckHttpsHealthCheckRequestPath(original["request_path"], d, config) + if err != nil { + return nil, err + } + transformed["requestPath"] = transformedRequestPath + transformedPort, err := expandComputeHealthCheckHttpsHealthCheckPort(original["port"], d, config) + if err != nil { + return nil, err + } + transformed["port"] = transformedPort + transformedProxyHeader, err := expandComputeHealthCheckHttpsHealthCheckProxyHeader(original["proxy_header"], d, config) + if err != nil { + return nil, err + } + transformed["proxyHeader"] = transformedProxyHeader + return transformed, nil +} + +func expandComputeHealthCheckHttpsHealthCheckHost(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckHttpsHealthCheckRequestPath(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckHttpsHealthCheckPort(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckHttpsHealthCheckProxyHeader(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckTcpHealthCheck(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedRequest, err := expandComputeHealthCheckTcpHealthCheckRequest(original["request"], d, config) + if err != nil { + return nil, err + } + transformed["request"] = transformedRequest + transformedResponse, err := expandComputeHealthCheckTcpHealthCheckResponse(original["response"], d, config) + if err != nil { + return nil, err + } + transformed["response"] = transformedResponse + transformedPort, err := expandComputeHealthCheckTcpHealthCheckPort(original["port"], d, config) + if err != nil { + return nil, err + } + transformed["port"] = transformedPort + transformedProxyHeader, err := expandComputeHealthCheckTcpHealthCheckProxyHeader(original["proxy_header"], d, config) + if err != nil { + return nil, err + } + transformed["proxyHeader"] = transformedProxyHeader + return transformed, nil +} + +func expandComputeHealthCheckTcpHealthCheckRequest(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckTcpHealthCheckResponse(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckTcpHealthCheckPort(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckTcpHealthCheckProxyHeader(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckSslHealthCheck(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedRequest, err := expandComputeHealthCheckSslHealthCheckRequest(original["request"], d, config) + if err != nil { + return nil, err + } + transformed["request"] = transformedRequest + transformedResponse, err := expandComputeHealthCheckSslHealthCheckResponse(original["response"], d, config) + if err != nil { + return nil, err + } + transformed["response"] = transformedResponse + transformedPort, err := expandComputeHealthCheckSslHealthCheckPort(original["port"], d, config) + if err != nil { + return nil, err + } + transformed["port"] = transformedPort + transformedProxyHeader, err := expandComputeHealthCheckSslHealthCheckProxyHeader(original["proxy_header"], d, config) + if err != nil { + return nil, err + } + transformed["proxyHeader"] = transformedProxyHeader + return transformed, nil +} + +func expandComputeHealthCheckSslHealthCheckRequest(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckSslHealthCheckResponse(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckSslHealthCheckPort(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeHealthCheckSslHealthCheckProxyHeader(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func resourceComputeHealthCheckEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) { + if _, ok := d.GetOk("http_health_check"); ok { + obj["type"] = "HTTP" + return obj, nil + } + if _, ok := d.GetOk("https_health_check"); ok { + obj["type"] = "HTTPS" + return obj, nil + } + if _, ok := d.GetOk("tcp_health_check"); ok { + obj["type"] = "TCP" + return obj, nil + } + if _, ok := d.GetOk("ssl_health_check"); ok { + obj["type"] = "SSL" + return obj, nil + } - result := make([]map[string]interface{}, 0, 1) - data := make(map[string]interface{}) - data["host"] = hchk.Host - data["port"] = hchk.Port - data["proxy_header"] = hchk.ProxyHeader - data["request_path"] = hchk.RequestPath - result = append(result, data) - return result + return nil, fmt.Errorf("error in HealthCheck %s: No health check block specified.", d.Get("name").(string)) } diff --git a/website/docs/r/compute_health_check.html.markdown b/website/docs/r/compute_health_check.html.markdown index 26df46a053b..ec8167f802e 100644 --- a/website/docs/r/compute_health_check.html.markdown +++ b/website/docs/r/compute_health_check.html.markdown @@ -1,32 +1,56 @@ --- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- layout: "google" page_title: "Google: google_compute_health_check" sidebar_current: "docs-google-compute-health-check" description: |- - Manages a Health Check within GCE. + Health Checks determine whether instances are responsive and able to do work. --- # google\_compute\_health\_check -Manages a health check within GCE. This is used to monitor instances -behind load balancers. Timeouts or HTTP errors cause the instance to be -removed from the pool. For more information, see [the official -documentation](https://cloud.google.com/compute/docs/load-balancing/health-checks) -and -[API](https://cloud.google.com/compute/docs/reference/latest/healthChecks). +Health Checks determine whether instances are responsive and able to do work. +They are an important part of a comprehensive load balancing configuration, +as they enable monitoring instances behind load balancers. + +Health Checks poll instances at a specified interval. Instances that +do not respond successfully to some number of probes in a row are marked +as unhealthy. No new connections are sent to unhealthy instances, +though existing connections will continue. The health check will +continue to poll unhealthy instances. If an instance later responds +successfully to some number of consecutive probes, it is marked +healthy again and can receive new connections. + +To get more information about HealthCheck, see: + +* [API documentation](https://cloud.google.com/compute/docs/reference/rest/latest/healthChecks) +* How-to Guides + * [Official Documentation](https://cloud.google.com/load-balancing/docs/health-checks) ## Example Usage -```tf -resource "google_compute_health_check" "default" { - name = "internal-service-health-check" +```hcl +resource "google_compute_health_check" "internal-health-check" { + name = "internal-service-health-check" - timeout_sec = 1 - check_interval_sec = 1 + timeout_sec = 1 + check_interval_sec = 1 - tcp_health_check { - port = "80" - } + tcp_health_check { + port = "80" + } } ``` @@ -34,100 +58,190 @@ resource "google_compute_health_check" "default" { The following arguments are supported: -* `name` - (Required) A unique name for the resource, required by GCE. - Changing this forces a new resource to be created. + +* `name` - + (Required) + Name of the resource. Provided by the client when the resource is + created. The name must be 1-63 characters long, and comply with + RFC1035. Specifically, the name must be 1-63 characters long and + match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which means + the first character must be a lowercase letter, and all following + characters must be a dash, lowercase letter, or digit, except the + last character, which cannot be a dash. + - - - -* `check_interval_sec` - (Optional) The number of seconds between each poll of - the instance instance (default 5). -* `description` - (Optional) Textual description field. +* `check_interval_sec` - + (Optional) + How often (in seconds) to send a health check. The default value is 5 + seconds. -* `healthy_threshold` - (Optional) Consecutive successes required (default 2). +* `description` - + (Optional) + An optional description of this resource. Provide this property when + you create the resource. -* `http_health_check` - (Optional) An HTTP Health Check. Only one kind of Health Check can be added. - Structure is documented below. +* `healthy_threshold` - + (Optional) + A so-far unhealthy instance will be marked healthy after this many + consecutive successes. The default value is 2. -* `https_health_check` - (Optional) An HTTPS Health Check. Only one kind of Health Check can be added. - Structure is documented below. +* `timeout_sec` - + (Optional) + How long (in seconds) to wait before claiming failure. + The default value is 5 seconds. It is invalid for timeoutSec to have + greater value than checkIntervalSec. -* `ssl_health_check` - (Optional) An SSL Health Check. Only one kind of Health Check can be added. - Structure is documented below. +* `unhealthy_threshold` - + (Optional) + A so-far healthy instance will be marked unhealthy after this many + consecutive failures. The default value is 2. -* `tcp_health_check` - (Optional) A TCP Health Check. Only one kind of Health Check can be added. - Structure is documented below. +* `http_health_check` - + (Optional) + A nested object resource Structure is documented below. -* `project` - (Optional) The project in which the resource belongs. If it - is not provided, the provider project is used. +* `https_health_check` - + (Optional) + A nested object resource Structure is documented below. -* `timeout_sec` - (Optional) The number of seconds to wait before declaring - failure (default 5). +* `tcp_health_check` - + (Optional) + A nested object resource Structure is documented below. -* `unhealthy_threshold` - (Optional) Consecutive failures required (default 2). +* `ssl_health_check` - + (Optional) + A nested object resource Structure is documented below. +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. The `http_health_check` block supports: -* `host` - (Optional) HTTP host header field (default instance's public ip). +* `host` - + (Optional) + The value of the host header in the HTTP health check request. + If left empty (default value), the public IP on behalf of which this health + check is performed will be used. -* `port` - (Optional) TCP port to connect to (default 80). +* `request_path` - + (Optional) + The request path of the HTTP health check request. + The default value is /. -* `proxy_header` - (Optional) Type of proxy header to append before sending - data to the backend, either NONE or PROXY_V1 (default NONE). - -* `request_path` - (Optional) URL path to query (default /). +* `port` - + (Optional) + The TCP port number for the HTTP health check request. + The default value is 80. +* `proxy_header` - + (Optional) + Specifies the type of proxy header to append before sending data to the + backend, either NONE or PROXY_V1. The default is NONE. The `https_health_check` block supports: -* `host` - (Optional) HTTPS host header field (default instance's public ip). - -* `port` - (Optional) TCP port to connect to (default 443). +* `host` - + (Optional) + The value of the host header in the HTTPS health check request. + If left empty (default value), the public IP on behalf of which this health + check is performed will be used. -* `proxy_header` - (Optional) Type of proxy header to append before sending - data to the backend, either NONE or PROXY_V1 (default NONE). +* `request_path` - + (Optional) + The request path of the HTTPS health check request. + The default value is /. -* `request_path` - (Optional) URL path to query (default /). +* `port` - + (Optional) + The TCP port number for the HTTPS health check request. + The default value is 443. +* `proxy_header` - + (Optional) + Specifies the type of proxy header to append before sending data to the + backend, either NONE or PROXY_V1. The default is NONE. -The `ssl_health_check` block supports: - -* `port` - (Optional) TCP port to connect to (default 443). - -* `proxy_header` - (Optional) Type of proxy header to append before sending - data to the backend, either NONE or PROXY_V1 (default NONE). +The `tcp_health_check` block supports: -* `request` - (Optional) Application data to send once the SSL connection has - been established (default ""). +* `request` - + (Optional) + The application data to send once the TCP connection has been + established (default value is empty). If both request and response are + empty, the connection establishment alone will indicate health. The request + data can only be ASCII. + +* `response` - + (Optional) + The bytes to match against the beginning of the response data. If left empty + (the default value), any response will indicate health. The response data + can only be ASCII. + +* `port` - + (Optional) + The TCP port number for the TCP health check request. + The default value is 443. + +* `proxy_header` - + (Optional) + Specifies the type of proxy header to append before sending data to the + backend, either NONE or PROXY_V1. The default is NONE. -* `response` - (Optional) The response that indicates health (default "") +The `ssl_health_check` block supports: +* `request` - + (Optional) + The application data to send once the SSL connection has been + established (default value is empty). If both request and response are + empty, the connection establishment alone will indicate health. The request + data can only be ASCII. + +* `response` - + (Optional) + The bytes to match against the beginning of the response data. If left empty + (the default value), any response will indicate health. The response data + can only be ASCII. + +* `port` - + (Optional) + The TCP port number for the SSL health check request. + The default value is 443. + +* `proxy_header` - + (Optional) + Specifies the type of proxy header to append before sending data to the + backend, either NONE or PROXY_V1. The default is NONE. -The `tcp_health_check` block supports: +## Attributes Reference -* `port` - (Optional) TCP port to connect to (default 80). +In addition to the arguments listed above, the following computed attributes are exported: -* `proxy_header` - (Optional) Type of proxy header to append before sending - data to the backend, either NONE or PROXY_V1 (default NONE). -* `request` - (Optional) Application data to send once the TCP connection has - been established (default ""). +* `creation_timestamp` - + Creation timestamp in RFC3339 text format. -* `response` - (Optional) The response that indicates health (default "") +* `type` - + The type of the health check. One of HTTP, HTTPS, TCP, or SSL. +* `self_link` - The URI of the created resource. -## Attributes Reference +## Timeouts -In addition to the arguments listed above, the following computed attributes are -exported: +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: -* `self_link` - The URI of the created resource. +- `create` - Default is 4 minutes. +- `update` - Default is 4 minutes. +- `delete` - Default is 4 minutes. ## Import -Health checks can be imported using the `name`, e.g. +HealthCheck can be imported using any of these accepted formats: ``` -$ terraform import google_compute_health_check.default internal-service-health-check +$ terraform import google_compute_health_check.default projects/{{project}}/global/healthChecks/{{name}} +$ terraform import google_compute_health_check.default {{project}}/{{name}} +$ terraform import google_compute_health_check.default {{name}} ```