diff --git a/google/resource_compute_forwarding_rule.go b/google/resource_compute_forwarding_rule.go index 001836dc0d9..c2830ab8e50 100644 --- a/google/resource_compute_forwarding_rule.go +++ b/google/resource_compute_forwarding_rule.go @@ -90,7 +90,7 @@ func resourceComputeForwardingRule() *schema.Resource { Type: schema.TypeString, Optional: true, ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{"INTERNAL", "EXTERNAL", ""}, false), + ValidateFunc: validation.StringInSlice([]string{"EXTERNAL", "INTERNAL", "INTERNAL_MANAGED", ""}, false), Default: "EXTERNAL", }, "network": { diff --git a/google/resource_compute_global_forwarding_rule.go b/google/resource_compute_global_forwarding_rule.go index f2318ffef2d..264f7e1cbc5 100644 --- a/google/resource_compute_global_forwarding_rule.go +++ b/google/resource_compute_global_forwarding_rule.go @@ -82,7 +82,7 @@ func resourceComputeGlobalForwardingRule() *schema.Resource { Type: schema.TypeString, Optional: true, ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{"INTERNAL_SELF_MANAGED", "EXTERNAL", ""}, false), + ValidateFunc: validation.StringInSlice([]string{"EXTERNAL", "INTERNAL_SELF_MANAGED", ""}, false), Default: "EXTERNAL", }, "metadata_filters": { diff --git a/google/resource_compute_region_backend_service.go b/google/resource_compute_region_backend_service.go index 5e204959201..a9a917ba7ac 100644 --- a/google/resource_compute_region_backend_service.go +++ b/google/resource_compute_region_backend_service.go @@ -86,7 +86,8 @@ func resourceComputeRegionBackendService() *schema.Resource { "load_balancing_scheme": { Type: schema.TypeString, Optional: true, - ValidateFunc: validation.StringInSlice([]string{"INTERNAL", ""}, false), + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{"INTERNAL", "INTERNAL_MANAGED", ""}, false), Default: "INTERNAL", }, "protocol": { @@ -99,20 +100,23 @@ func resourceComputeRegionBackendService() *schema.Resource { Type: schema.TypeString, Computed: true, Optional: true, - ForceNew: true, DiffSuppressFunc: compareSelfLinkOrResourceName, }, "session_affinity": { Type: schema.TypeString, Computed: true, Optional: true, - ValidateFunc: validation.StringInSlice([]string{"NONE", "CLIENT_IP", "CLIENT_IP_PROTO", "CLIENT_IP_PORT_PROTO", ""}, false), + ValidateFunc: validation.StringInSlice([]string{"NONE", "CLIENT_IP", "CLIENT_IP_PORT_PROTO", "CLIENT_IP_PROTO", "GENERATED_COOKIE", "HEADER_FIELD", "HTTP_COOKIE", ""}, false), }, "timeout_sec": { Type: schema.TypeInt, Computed: true, Optional: true, }, + "creation_timestamp": { + Type: schema.TypeString, + Computed: true, + }, "fingerprint": { Type: schema.TypeString, Computed: true, @@ -134,14 +138,53 @@ func resourceComputeRegionBackendService() *schema.Resource { func computeRegionBackendServiceBackendSchema() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ + "group": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: compareSelfLinkRelativePaths, + }, + "balancing_mode": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"UTILIZATION", "RATE", "CONNECTION", ""}, false), + Default: "CONNECTION", + }, + "capacity_scaler": { + Type: schema.TypeFloat, + Computed: true, + Optional: true, + }, "description": { Type: schema.TypeString, Optional: true, }, - "group": { - Type: schema.TypeString, - Optional: true, - DiffSuppressFunc: compareSelfLinkRelativePaths, + "max_connections": { + Type: schema.TypeInt, + Optional: true, + }, + "max_connections_per_endpoint": { + Type: schema.TypeInt, + Optional: true, + }, + "max_connections_per_instance": { + Type: schema.TypeInt, + Optional: true, + }, + "max_rate": { + Type: schema.TypeInt, + Optional: true, + }, + "max_rate_per_endpoint": { + Type: schema.TypeFloat, + Optional: true, + }, + "max_rate_per_instance": { + Type: schema.TypeFloat, + Optional: true, + }, + "max_utilization": { + Type: schema.TypeFloat, + Optional: true, }, }, } @@ -151,24 +194,18 @@ func resourceComputeRegionBackendServiceCreate(d *schema.ResourceData, meta inte config := meta.(*Config) obj := make(map[string]interface{}) - nameProp, err := expandComputeRegionBackendServiceName(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 - } - healthChecksProp, err := expandComputeRegionBackendServiceHealthChecks(d.Get("health_checks"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("health_checks"); !isEmptyValue(reflect.ValueOf(healthChecksProp)) && (ok || !reflect.DeepEqual(v, healthChecksProp)) { - obj["healthChecks"] = healthChecksProp - } backendsProp, err := expandComputeRegionBackendServiceBackend(d.Get("backend"), d, config) if err != nil { return err } else if v, ok := d.GetOkExists("backend"); !isEmptyValue(reflect.ValueOf(backendsProp)) && (ok || !reflect.DeepEqual(v, backendsProp)) { obj["backends"] = backendsProp } + connectionDrainingProp, err := expandComputeRegionBackendServiceConnectionDraining(nil, d, config) + if err != nil { + return err + } else if !isEmptyValue(reflect.ValueOf(connectionDrainingProp)) { + obj["connectionDraining"] = connectionDrainingProp + } descriptionProp, err := expandComputeRegionBackendServiceDescription(d.Get("description"), d, config) if err != nil { return err @@ -181,6 +218,24 @@ func resourceComputeRegionBackendServiceCreate(d *schema.ResourceData, meta inte } else if v, ok := d.GetOkExists("fingerprint"); !isEmptyValue(reflect.ValueOf(fingerprintProp)) && (ok || !reflect.DeepEqual(v, fingerprintProp)) { obj["fingerprint"] = fingerprintProp } + healthChecksProp, err := expandComputeRegionBackendServiceHealthChecks(d.Get("health_checks"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("health_checks"); !isEmptyValue(reflect.ValueOf(healthChecksProp)) && (ok || !reflect.DeepEqual(v, healthChecksProp)) { + obj["healthChecks"] = healthChecksProp + } + loadBalancingSchemeProp, err := expandComputeRegionBackendServiceLoadBalancingScheme(d.Get("load_balancing_scheme"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("load_balancing_scheme"); !isEmptyValue(reflect.ValueOf(loadBalancingSchemeProp)) && (ok || !reflect.DeepEqual(v, loadBalancingSchemeProp)) { + obj["loadBalancingScheme"] = loadBalancingSchemeProp + } + nameProp, err := expandComputeRegionBackendServiceName(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 + } protocolProp, err := expandComputeRegionBackendServiceProtocol(d.Get("protocol"), d, config) if err != nil { return err @@ -193,29 +248,17 @@ func resourceComputeRegionBackendServiceCreate(d *schema.ResourceData, meta inte } else if v, ok := d.GetOkExists("session_affinity"); !isEmptyValue(reflect.ValueOf(sessionAffinityProp)) && (ok || !reflect.DeepEqual(v, sessionAffinityProp)) { obj["sessionAffinity"] = sessionAffinityProp } - regionProp, err := expandComputeRegionBackendServiceRegion(d.Get("region"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("region"); !isEmptyValue(reflect.ValueOf(regionProp)) && (ok || !reflect.DeepEqual(v, regionProp)) { - obj["region"] = regionProp - } timeoutSecProp, err := expandComputeRegionBackendServiceTimeoutSec(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 } - connectionDrainingProp, err := expandComputeRegionBackendServiceConnectionDraining(nil, d, config) - if err != nil { - return err - } else if !isEmptyValue(reflect.ValueOf(connectionDrainingProp)) { - obj["connectionDraining"] = connectionDrainingProp - } - loadBalancingSchemeProp, err := expandComputeRegionBackendServiceLoadBalancingScheme(d.Get("load_balancing_scheme"), d, config) + regionProp, err := expandComputeRegionBackendServiceRegion(d.Get("region"), d, config) if err != nil { return err - } else if v, ok := d.GetOkExists("load_balancing_scheme"); !isEmptyValue(reflect.ValueOf(loadBalancingSchemeProp)) && (ok || !reflect.DeepEqual(v, loadBalancingSchemeProp)) { - obj["loadBalancingScheme"] = loadBalancingSchemeProp + } else if v, ok := d.GetOkExists("region"); !isEmptyValue(reflect.ValueOf(regionProp)) && (ok || !reflect.DeepEqual(v, regionProp)) { + obj["region"] = regionProp } url, err := replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/regions/{{region}}/backendServices") @@ -282,13 +325,20 @@ func resourceComputeRegionBackendServiceRead(d *schema.ResourceData, meta interf return fmt.Errorf("Error reading RegionBackendService: %s", err) } - if err := d.Set("name", flattenComputeRegionBackendServiceName(res["name"], d)); err != nil { + if err := d.Set("backend", flattenComputeRegionBackendServiceBackend(res["backends"], d)); err != nil { return fmt.Errorf("Error reading RegionBackendService: %s", err) } - if err := d.Set("health_checks", flattenComputeRegionBackendServiceHealthChecks(res["healthChecks"], d)); err != nil { - return fmt.Errorf("Error reading RegionBackendService: %s", err) + // Terraform must set the top level schema field, but since this object contains collapsed properties + // it's difficult to know what the top level should be. Instead we just loop over the map returned from flatten. + if flattenedProp := flattenComputeRegionBackendServiceConnectionDraining(res["connectionDraining"], d); flattenedProp != nil { + casted := flattenedProp.([]interface{})[0] + if casted != nil { + for k, v := range casted.(map[string]interface{}) { + d.Set(k, v) + } + } } - if err := d.Set("backend", flattenComputeRegionBackendServiceBackend(res["backends"], d)); err != nil { + if err := d.Set("creation_timestamp", flattenComputeRegionBackendServiceCreationTimestamp(res["creationTimestamp"], d)); err != nil { return fmt.Errorf("Error reading RegionBackendService: %s", err) } if err := d.Set("description", flattenComputeRegionBackendServiceDescription(res["description"], d)); err != nil { @@ -297,29 +347,25 @@ func resourceComputeRegionBackendServiceRead(d *schema.ResourceData, meta interf if err := d.Set("fingerprint", flattenComputeRegionBackendServiceFingerprint(res["fingerprint"], d)); err != nil { return fmt.Errorf("Error reading RegionBackendService: %s", err) } - if err := d.Set("protocol", flattenComputeRegionBackendServiceProtocol(res["protocol"], d)); err != nil { + if err := d.Set("health_checks", flattenComputeRegionBackendServiceHealthChecks(res["healthChecks"], d)); err != nil { return fmt.Errorf("Error reading RegionBackendService: %s", err) } - if err := d.Set("session_affinity", flattenComputeRegionBackendServiceSessionAffinity(res["sessionAffinity"], d)); err != nil { + if err := d.Set("load_balancing_scheme", flattenComputeRegionBackendServiceLoadBalancingScheme(res["loadBalancingScheme"], d)); err != nil { return fmt.Errorf("Error reading RegionBackendService: %s", err) } - if err := d.Set("region", flattenComputeRegionBackendServiceRegion(res["region"], d)); err != nil { + if err := d.Set("name", flattenComputeRegionBackendServiceName(res["name"], d)); err != nil { return fmt.Errorf("Error reading RegionBackendService: %s", err) } - if err := d.Set("timeout_sec", flattenComputeRegionBackendServiceTimeoutSec(res["timeoutSec"], d)); err != nil { + if err := d.Set("protocol", flattenComputeRegionBackendServiceProtocol(res["protocol"], d)); err != nil { return fmt.Errorf("Error reading RegionBackendService: %s", err) } - // Terraform must set the top level schema field, but since this object contains collapsed properties - // it's difficult to know what the top level should be. Instead we just loop over the map returned from flatten. - if flattenedProp := flattenComputeRegionBackendServiceConnectionDraining(res["connectionDraining"], d); flattenedProp != nil { - casted := flattenedProp.([]interface{})[0] - if casted != nil { - for k, v := range casted.(map[string]interface{}) { - d.Set(k, v) - } - } + if err := d.Set("session_affinity", flattenComputeRegionBackendServiceSessionAffinity(res["sessionAffinity"], d)); err != nil { + return fmt.Errorf("Error reading RegionBackendService: %s", err) } - if err := d.Set("load_balancing_scheme", flattenComputeRegionBackendServiceLoadBalancingScheme(res["loadBalancingScheme"], d)); err != nil { + if err := d.Set("timeout_sec", flattenComputeRegionBackendServiceTimeoutSec(res["timeoutSec"], d)); err != nil { + return fmt.Errorf("Error reading RegionBackendService: %s", err) + } + if err := d.Set("region", flattenComputeRegionBackendServiceRegion(res["region"], d)); err != nil { return fmt.Errorf("Error reading RegionBackendService: %s", err) } if err := d.Set("self_link", ConvertSelfLinkToV1(res["selfLink"].(string))); err != nil { @@ -338,24 +384,18 @@ func resourceComputeRegionBackendServiceUpdate(d *schema.ResourceData, meta inte } obj := make(map[string]interface{}) - nameProp, err := expandComputeRegionBackendServiceName(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 - } - healthChecksProp, err := expandComputeRegionBackendServiceHealthChecks(d.Get("health_checks"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("health_checks"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, healthChecksProp)) { - obj["healthChecks"] = healthChecksProp - } backendsProp, err := expandComputeRegionBackendServiceBackend(d.Get("backend"), d, config) if err != nil { return err } else if v, ok := d.GetOkExists("backend"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, backendsProp)) { obj["backends"] = backendsProp } + connectionDrainingProp, err := expandComputeRegionBackendServiceConnectionDraining(nil, d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("connection_draining"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, connectionDrainingProp)) { + obj["connectionDraining"] = connectionDrainingProp + } descriptionProp, err := expandComputeRegionBackendServiceDescription(d.Get("description"), d, config) if err != nil { return err @@ -368,6 +408,24 @@ func resourceComputeRegionBackendServiceUpdate(d *schema.ResourceData, meta inte } else if v, ok := d.GetOkExists("fingerprint"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, fingerprintProp)) { obj["fingerprint"] = fingerprintProp } + healthChecksProp, err := expandComputeRegionBackendServiceHealthChecks(d.Get("health_checks"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("health_checks"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, healthChecksProp)) { + obj["healthChecks"] = healthChecksProp + } + loadBalancingSchemeProp, err := expandComputeRegionBackendServiceLoadBalancingScheme(d.Get("load_balancing_scheme"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("load_balancing_scheme"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, loadBalancingSchemeProp)) { + obj["loadBalancingScheme"] = loadBalancingSchemeProp + } + nameProp, err := expandComputeRegionBackendServiceName(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 + } protocolProp, err := expandComputeRegionBackendServiceProtocol(d.Get("protocol"), d, config) if err != nil { return err @@ -380,29 +438,17 @@ func resourceComputeRegionBackendServiceUpdate(d *schema.ResourceData, meta inte } else if v, ok := d.GetOkExists("session_affinity"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, sessionAffinityProp)) { obj["sessionAffinity"] = sessionAffinityProp } - regionProp, err := expandComputeRegionBackendServiceRegion(d.Get("region"), d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("region"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, regionProp)) { - obj["region"] = regionProp - } timeoutSecProp, err := expandComputeRegionBackendServiceTimeoutSec(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 } - connectionDrainingProp, err := expandComputeRegionBackendServiceConnectionDraining(nil, d, config) - if err != nil { - return err - } else if v, ok := d.GetOkExists("connection_draining"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, connectionDrainingProp)) { - obj["connectionDraining"] = connectionDrainingProp - } - loadBalancingSchemeProp, err := expandComputeRegionBackendServiceLoadBalancingScheme(d.Get("load_balancing_scheme"), d, config) + regionProp, err := expandComputeRegionBackendServiceRegion(d.Get("region"), d, config) if err != nil { return err - } else if v, ok := d.GetOkExists("load_balancing_scheme"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, loadBalancingSchemeProp)) { - obj["loadBalancingScheme"] = loadBalancingSchemeProp + } else if v, ok := d.GetOkExists("region"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, regionProp)) { + obj["region"] = regionProp } url, err := replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/regions/{{region}}/backendServices/{{name}}") @@ -494,17 +540,6 @@ func resourceComputeRegionBackendServiceImport(d *schema.ResourceData, meta inte return []*schema.ResourceData{d}, nil } -func flattenComputeRegionBackendServiceName(v interface{}, d *schema.ResourceData) interface{} { - return v -} - -func flattenComputeRegionBackendServiceHealthChecks(v interface{}, d *schema.ResourceData) interface{} { - if v == nil { - return v - } - return convertAndMapStringArr(v.([]interface{}), ConvertSelfLinkToV1) -} - func flattenComputeRegionBackendServiceBackend(v interface{}, d *schema.ResourceData) interface{} { if v == nil { return v @@ -518,12 +553,29 @@ func flattenComputeRegionBackendServiceBackend(v interface{}, d *schema.Resource continue } transformed.Add(map[string]interface{}{ - "description": flattenComputeRegionBackendServiceBackendDescription(original["description"], d), - "group": flattenComputeRegionBackendServiceBackendGroup(original["group"], d), + "balancing_mode": flattenComputeRegionBackendServiceBackendBalancingMode(original["balancingMode"], d), + "capacity_scaler": flattenComputeRegionBackendServiceBackendCapacityScaler(original["capacityScaler"], d), + "description": flattenComputeRegionBackendServiceBackendDescription(original["description"], d), + "group": flattenComputeRegionBackendServiceBackendGroup(original["group"], d), + "max_connections": flattenComputeRegionBackendServiceBackendMaxConnections(original["maxConnections"], d), + "max_connections_per_instance": flattenComputeRegionBackendServiceBackendMaxConnectionsPerInstance(original["maxConnectionsPerInstance"], d), + "max_connections_per_endpoint": flattenComputeRegionBackendServiceBackendMaxConnectionsPerEndpoint(original["maxConnectionsPerEndpoint"], d), + "max_rate": flattenComputeRegionBackendServiceBackendMaxRate(original["maxRate"], d), + "max_rate_per_instance": flattenComputeRegionBackendServiceBackendMaxRatePerInstance(original["maxRatePerInstance"], d), + "max_rate_per_endpoint": flattenComputeRegionBackendServiceBackendMaxRatePerEndpoint(original["maxRatePerEndpoint"], d), + "max_utilization": flattenComputeRegionBackendServiceBackendMaxUtilization(original["maxUtilization"], d), }) } return transformed } +func flattenComputeRegionBackendServiceBackendBalancingMode(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeRegionBackendServiceBackendCapacityScaler(v interface{}, d *schema.ResourceData) interface{} { + return v +} + func flattenComputeRegionBackendServiceBackendDescription(v interface{}, d *schema.ResourceData) interface{} { return v } @@ -535,30 +587,37 @@ func flattenComputeRegionBackendServiceBackendGroup(v interface{}, d *schema.Res return ConvertSelfLinkToV1(v.(string)) } -func flattenComputeRegionBackendServiceDescription(v interface{}, d *schema.ResourceData) interface{} { - return v -} - -func flattenComputeRegionBackendServiceFingerprint(v interface{}, d *schema.ResourceData) interface{} { - return v -} - -func flattenComputeRegionBackendServiceProtocol(v interface{}, d *schema.ResourceData) interface{} { +func flattenComputeRegionBackendServiceBackendMaxConnections(v interface{}, d *schema.ResourceData) 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 flattenComputeRegionBackendServiceSessionAffinity(v interface{}, d *schema.ResourceData) interface{} { +func flattenComputeRegionBackendServiceBackendMaxConnectionsPerInstance(v interface{}, d *schema.ResourceData) 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 flattenComputeRegionBackendServiceRegion(v interface{}, d *schema.ResourceData) interface{} { - if v == nil { - return v +func flattenComputeRegionBackendServiceBackendMaxConnectionsPerEndpoint(v interface{}, d *schema.ResourceData) 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 NameFromSelfLinkStateFunc(v) + return v } -func flattenComputeRegionBackendServiceTimeoutSec(v interface{}, d *schema.ResourceData) interface{} { +func flattenComputeRegionBackendServiceBackendMaxRate(v interface{}, d *schema.ResourceData) interface{} { // Handles the string fixed64 format if strVal, ok := v.(string); ok { if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil { @@ -568,6 +627,18 @@ func flattenComputeRegionBackendServiceTimeoutSec(v interface{}, d *schema.Resou return v } +func flattenComputeRegionBackendServiceBackendMaxRatePerInstance(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeRegionBackendServiceBackendMaxRatePerEndpoint(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeRegionBackendServiceBackendMaxUtilization(v interface{}, d *schema.ResourceData) interface{} { + return v +} + func flattenComputeRegionBackendServiceConnectionDraining(v interface{}, d *schema.ResourceData) interface{} { if v == nil { return nil @@ -591,17 +662,56 @@ func flattenComputeRegionBackendServiceConnectionDrainingConnectionDrainingTimeo return v } +func flattenComputeRegionBackendServiceCreationTimestamp(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeRegionBackendServiceDescription(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeRegionBackendServiceFingerprint(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeRegionBackendServiceHealthChecks(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return v + } + return convertAndMapStringArr(v.([]interface{}), ConvertSelfLinkToV1) +} + func flattenComputeRegionBackendServiceLoadBalancingScheme(v interface{}, d *schema.ResourceData) interface{} { return v } -func expandComputeRegionBackendServiceName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { - return v, nil +func flattenComputeRegionBackendServiceName(v interface{}, d *schema.ResourceData) interface{} { + return v } -func expandComputeRegionBackendServiceHealthChecks(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { - v = v.(*schema.Set).List() - return v, nil +func flattenComputeRegionBackendServiceProtocol(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeRegionBackendServiceSessionAffinity(v interface{}, d *schema.ResourceData) interface{} { + return v +} + +func flattenComputeRegionBackendServiceTimeoutSec(v interface{}, d *schema.ResourceData) 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 flattenComputeRegionBackendServiceRegion(v interface{}, d *schema.ResourceData) interface{} { + if v == nil { + return v + } + return NameFromSelfLinkStateFunc(v) } func expandComputeRegionBackendServiceBackend(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { @@ -615,6 +725,20 @@ func expandComputeRegionBackendServiceBackend(v interface{}, d TerraformResource original := raw.(map[string]interface{}) transformed := make(map[string]interface{}) + transformedBalancingMode, err := expandComputeRegionBackendServiceBackendBalancingMode(original["balancing_mode"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedBalancingMode); val.IsValid() && !isEmptyValue(val) { + transformed["balancingMode"] = transformedBalancingMode + } + + transformedCapacityScaler, err := expandComputeRegionBackendServiceBackendCapacityScaler(original["capacity_scaler"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCapacityScaler); val.IsValid() && !isEmptyValue(val) { + transformed["capacityScaler"] = transformedCapacityScaler + } + transformedDescription, err := expandComputeRegionBackendServiceBackendDescription(original["description"], d, config) if err != nil { return nil, err @@ -629,11 +753,68 @@ func expandComputeRegionBackendServiceBackend(v interface{}, d TerraformResource transformed["group"] = transformedGroup } + transformedMaxConnections, err := expandComputeRegionBackendServiceBackendMaxConnections(original["max_connections"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMaxConnections); val.IsValid() && !isEmptyValue(val) { + transformed["maxConnections"] = transformedMaxConnections + } + + transformedMaxConnectionsPerInstance, err := expandComputeRegionBackendServiceBackendMaxConnectionsPerInstance(original["max_connections_per_instance"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMaxConnectionsPerInstance); val.IsValid() && !isEmptyValue(val) { + transformed["maxConnectionsPerInstance"] = transformedMaxConnectionsPerInstance + } + + transformedMaxConnectionsPerEndpoint, err := expandComputeRegionBackendServiceBackendMaxConnectionsPerEndpoint(original["max_connections_per_endpoint"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMaxConnectionsPerEndpoint); val.IsValid() && !isEmptyValue(val) { + transformed["maxConnectionsPerEndpoint"] = transformedMaxConnectionsPerEndpoint + } + + transformedMaxRate, err := expandComputeRegionBackendServiceBackendMaxRate(original["max_rate"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMaxRate); val.IsValid() && !isEmptyValue(val) { + transformed["maxRate"] = transformedMaxRate + } + + transformedMaxRatePerInstance, err := expandComputeRegionBackendServiceBackendMaxRatePerInstance(original["max_rate_per_instance"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMaxRatePerInstance); val.IsValid() && !isEmptyValue(val) { + transformed["maxRatePerInstance"] = transformedMaxRatePerInstance + } + + transformedMaxRatePerEndpoint, err := expandComputeRegionBackendServiceBackendMaxRatePerEndpoint(original["max_rate_per_endpoint"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMaxRatePerEndpoint); val.IsValid() && !isEmptyValue(val) { + transformed["maxRatePerEndpoint"] = transformedMaxRatePerEndpoint + } + + transformedMaxUtilization, err := expandComputeRegionBackendServiceBackendMaxUtilization(original["max_utilization"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMaxUtilization); val.IsValid() && !isEmptyValue(val) { + transformed["maxUtilization"] = transformedMaxUtilization + } + req = append(req, transformed) } return req, nil } +func expandComputeRegionBackendServiceBackendBalancingMode(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeRegionBackendServiceBackendCapacityScaler(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + func expandComputeRegionBackendServiceBackendDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { return v, nil } @@ -642,31 +823,31 @@ func expandComputeRegionBackendServiceBackendGroup(v interface{}, d TerraformRes return v, nil } -func expandComputeRegionBackendServiceDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { +func expandComputeRegionBackendServiceBackendMaxConnections(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { return v, nil } -func expandComputeRegionBackendServiceFingerprint(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { +func expandComputeRegionBackendServiceBackendMaxConnectionsPerInstance(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { return v, nil } -func expandComputeRegionBackendServiceProtocol(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { +func expandComputeRegionBackendServiceBackendMaxConnectionsPerEndpoint(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { return v, nil } -func expandComputeRegionBackendServiceSessionAffinity(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { +func expandComputeRegionBackendServiceBackendMaxRate(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { return v, nil } -func expandComputeRegionBackendServiceRegion(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { - f, err := parseGlobalFieldValue("regions", v.(string), "project", d, config, true) - if err != nil { - return nil, fmt.Errorf("Invalid value for region: %s", err) - } - return f.RelativeLink(), nil +func expandComputeRegionBackendServiceBackendMaxRatePerInstance(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil } -func expandComputeRegionBackendServiceTimeoutSec(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { +func expandComputeRegionBackendServiceBackendMaxRatePerEndpoint(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeRegionBackendServiceBackendMaxUtilization(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { return v, nil } @@ -686,6 +867,43 @@ func expandComputeRegionBackendServiceConnectionDrainingConnectionDrainingTimeou return v, nil } +func expandComputeRegionBackendServiceDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeRegionBackendServiceFingerprint(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeRegionBackendServiceHealthChecks(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + v = v.(*schema.Set).List() + return v, nil +} + func expandComputeRegionBackendServiceLoadBalancingScheme(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { return v, nil } + +func expandComputeRegionBackendServiceName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeRegionBackendServiceProtocol(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeRegionBackendServiceSessionAffinity(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeRegionBackendServiceTimeoutSec(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeRegionBackendServiceRegion(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + f, err := parseGlobalFieldValue("regions", v.(string), "project", d, config, true) + if err != nil { + return nil, fmt.Errorf("Invalid value for region: %s", err) + } + return f.RelativeLink(), nil +} diff --git a/website/docs/r/compute_backend_service.html.markdown b/website/docs/r/compute_backend_service.html.markdown index d2c3c8c97af..7c4455991a1 100644 --- a/website/docs/r/compute_backend_service.html.markdown +++ b/website/docs/r/compute_backend_service.html.markdown @@ -259,7 +259,7 @@ The `backend` block supports: For Network Endpoint Groups this defines list of endpoints. All endpoints of Network Endpoint Group must be hosted on instances located in the same zone as the Network Endpoint Group. - Backend service can not contain mix of Instance Group and + Backend services cannot mix Instance Group and Network Endpoint Group backends. Note that you must specify an Instance Group or Network Endpoint Group resource using the fully-qualified URL, rather than a diff --git a/website/docs/r/compute_forwarding_rule.html.markdown b/website/docs/r/compute_forwarding_rule.html.markdown index 64398fa942e..24a313ed85c 100644 --- a/website/docs/r/compute_forwarding_rule.html.markdown +++ b/website/docs/r/compute_forwarding_rule.html.markdown @@ -169,11 +169,13 @@ The following arguments are supported: * `load_balancing_scheme` - (Optional) - This signifies what the ForwardingRule will be used for and can only - take the following values: INTERNAL, EXTERNAL The value of INTERNAL - means that this will be used for Internal Network Load Balancing (TCP, - UDP). The value of EXTERNAL means that this will be used for External - Load Balancing (HTTP(S) LB, External TCP/UDP LB, SSL Proxy) + This signifies what the ForwardingRule will be used for and can be + EXTERNAL, INTERNAL, or INTERNAL_MANAGED. EXTERNAL is used for Classic + Cloud VPN gateways, protocol forwarding to VMs from an external IP address, + and HTTP(S), SSL Proxy, TCP Proxy, and Network TCP/UDP load balancers. + INTERNAL is used for protocol forwarding to VMs from an internal IP address, + and internal TCP/UDP load balancers. + INTERNAL_MANAGED is used for internal HTTP(S) load balancers. * `network` - (Optional) diff --git a/website/docs/r/compute_region_backend_service.html.markdown b/website/docs/r/compute_region_backend_service.html.markdown index 514cbee9b4d..01e76263c8a 100644 --- a/website/docs/r/compute_region_backend_service.html.markdown +++ b/website/docs/r/compute_region_backend_service.html.markdown @@ -25,9 +25,6 @@ description: |- A Region Backend Service defines a regionally-scoped group of virtual machines that will serve traffic for load balancing. -Region backend services can only be used when using internal load balancing. -For external load balancing, use a global backend service instead. - To get more information about RegionBackendService, see: @@ -62,12 +59,92 @@ resource "google_compute_health_check" "default" { } } ``` +
+## Example Usage - Region Backend Service Ilb Round Robin + + +```hcl +resource "google_compute_region_backend_service" "default" { + provider = "google-beta" + + region = "us-central1" + name = "region-backend-service" + health_checks = ["${google_compute_health_check.health_check.self_link}"] + protocol = "HTTP" + load_balancing_scheme = "INTERNAL_MANAGED" + locality_lb_policy = "ROUND_ROBIN" +} + +resource "google_compute_health_check" "health_check" { + provider = "google-beta" + + name = "health-check" + http_health_check { + + } +} +``` + +## Example Usage - Region Backend Service Ilb Ring Hash + + +```hcl +resource "google_compute_region_backend_service" "default" { + provider = "google-beta" + + region = "us-central1" + name = "region-backend-service" + health_checks = ["${google_compute_health_check.health_check.self_link}"] + load_balancing_scheme = "INTERNAL_MANAGED" + locality_lb_policy = "RING_HASH" + session_affinity = "HTTP_COOKIE" + protocol = "HTTP" + circuit_breakers { + max_connections = 10 + } + consistent_hash { + http_cookie { + ttl { + seconds = 11 + nanos = 1111 + } + name = "mycookie" + } + } + outlier_detection { + consecutive_errors = 2 + } +} + +resource "google_compute_health_check" "health_check" { + provider = "google-beta" + + name = "health-check" + http_health_check { + + } +} +``` ## Argument Reference The following arguments are supported: +* `health_checks` - + (Required) + The set of URLs to HealthCheck resources for health checking + this RegionBackendService. Currently at most one health + check can be specified, and a health check is required. + * `name` - (Required) Name of the resource. Provided by the client when the resource is @@ -78,54 +155,51 @@ The following arguments are supported: characters must be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. -* `health_checks` - - (Required) - The list of HealthChecks for checking the health of the backend service. - Currently at most one health check can be specified, and a health check - is required. - - - - * `backend` - (Optional) - The list of backends that serve this RegionBackendService. Structure is documented below. + The set of backends that serve this RegionBackendService. Structure is documented below. + +* `connection_draining_timeout_sec` - + (Optional) + Time for which instance will be drained (not accept new + connections, but still work to finish started). * `description` - (Optional) An optional description of this resource. +* `load_balancing_scheme` - + (Optional) + Indicates what kind of load balancing this regional backend service + will be used for. A backend service created for one type of load + balancing cannot be used with the other(s). Must be `INTERNAL` or + `INTERNAL_MANAGED`. Defaults to `INTERNAL`. + * `protocol` - (Optional) - The protocol this BackendService uses to communicate with backends. - The possible values are TCP and UDP, and the default is TCP. + The protocol this RegionBackendService uses to communicate with backends. + Possible values are HTTP, HTTPS, HTTP2, SSL, TCP, and UDP. The default is + HTTP. **NOTE**: HTTP2 is only valid for beta HTTP/2 load balancer + types and may result in errors if used with the GA API. * `session_affinity` - (Optional) - Type of session affinity to use. The default is NONE. - Can be NONE, CLIENT_IP, CLIENT_IP_PROTO, or CLIENT_IP_PORT_PROTO. - When the protocol is UDP, this field is not used. - -* `region` - - (Optional) - The Region in which the created backend service should reside. - If it is not provided, the provider region is used. + Type of session affinity to use. The default is NONE. Session affinity is + not applicable if the protocol is UDP. * `timeout_sec` - (Optional) How many seconds to wait for the backend before considering it a failed request. Default is 30 seconds. Valid range is [1, 86400]. -* `connection_draining_timeout_sec` - - (Optional) - Time for which instance will be drained (not accept new - connections, but still work to finish started). - -* `load_balancing_scheme` - +* `region` - (Optional) - This signifies what the ForwardingRule will be used for and can only - be INTERNAL for RegionBackendServices + The Region in which the created backend service should reside. + If it is not provided, the provider region is used. * `project` - (Optional) The ID of the project in which the resource belongs. If it is not provided, the provider project is used. @@ -133,28 +207,102 @@ The following arguments are supported: The `backend` block supports: +* `balancing_mode` - + (Optional) + Specifies the balancing mode for this backend. Defaults to CONNECTION. + +* `capacity_scaler` - + (Optional) + A multiplier applied to the group's maximum servicing capacity + (based on UTILIZATION, RATE or CONNECTION). + A setting of 0 means the group is completely drained, offering + 0% of its available Capacity. Valid range is [0.0,1.0]. + * `description` - (Optional) An optional description of this resource. Provide this property when you create the resource. * `group` - - (Optional) - The fully-qualified URL of an Instance Group. This defines the list + (Required) + The fully-qualified URL of an Instance Group or Network Endpoint + Group resource. In case of instance group this defines the list of instances that serve traffic. Member virtual machine instances from each instance group must live in the same zone as the instance group itself. No two backends in a backend service are allowed to use same Instance Group resource. - Note that you must specify an Instance Group - resource using the fully-qualified URL, rather than a + For Network Endpoint Groups this defines list of endpoints. All + endpoints of Network Endpoint Group must be hosted on instances + located in the same zone as the Network Endpoint Group. + Backend services cannot mix Instance Group and + Network Endpoint Group backends. + When the `load_balancing_scheme` is INTERNAL, only instance groups + are supported. + Note that you must specify an Instance Group or Network Endpoint + Group resource using the fully-qualified URL, rather than a partial URL. - The instance group must be within the same region as the BackendService. + +* `max_connections` - + (Optional) + The max number of simultaneous connections for the group. Can + be used with either CONNECTION or UTILIZATION balancing modes. + For CONNECTION mode, either maxConnections or one + of maxConnectionsPerInstance or maxConnectionsPerEndpoint, + as appropriate for group type, must be set. + +* `max_connections_per_instance` - + (Optional) + The max number of simultaneous connections that a single + backend instance can handle. This is used to calculate the + capacity of the group. Can be used in either CONNECTION or + UTILIZATION balancing modes. + For CONNECTION mode, either maxConnections or + maxConnectionsPerInstance must be set. + +* `max_connections_per_endpoint` - + (Optional) + The max number of simultaneous connections that a single backend + network endpoint can handle. This is used to calculate the + capacity of the group. Can be used in either CONNECTION or + UTILIZATION balancing modes. + For CONNECTION mode, either + maxConnections or maxConnectionsPerEndpoint must be set. + +* `max_rate` - + (Optional) + The max requests per second (RPS) of the group. + Can be used with either RATE or UTILIZATION balancing modes, + but required if RATE mode. Either maxRate or one + of maxRatePerInstance or maxRatePerEndpoint, as appropriate for + group type, must be set. + +* `max_rate_per_instance` - + (Optional) + The max requests per second (RPS) that a single backend + instance can handle. This is used to calculate the capacity of + the group. Can be used in either balancing mode. For RATE mode, + either maxRate or maxRatePerInstance must be set. + +* `max_rate_per_endpoint` - + (Optional) + The max requests per second (RPS) that a single backend network + endpoint can handle. This is used to calculate the capacity of + the group. Can be used in either balancing mode. For RATE mode, + either maxRate or maxRatePerEndpoint must be set. + +* `max_utilization` - + (Optional) + Used when balancingMode is UTILIZATION. This ratio defines the + CPU utilization target for the group. Valid range is [0.0, 1.0]. ## Attributes Reference In addition to the arguments listed above, the following computed attributes are exported: +* `creation_timestamp` - + Creation timestamp in RFC3339 text format. + * `fingerprint` - Fingerprint of this resource. A hash of the contents stored in this object. This field is used in optimistic locking.