Skip to content

Commit

Permalink
Add max_connection/rate_per_endpoint to backend services (#1928)
Browse files Browse the repository at this point in the history
Merged PR #1928.
  • Loading branch information
emilymye authored and modular-magician committed Jun 19, 2019
1 parent 21f721f commit 3ca7271
Show file tree
Hide file tree
Showing 8 changed files with 285 additions and 9 deletions.
2 changes: 1 addition & 1 deletion build/terraform
2 changes: 1 addition & 1 deletion build/terraform-beta
2 changes: 1 addition & 1 deletion build/terraform-mapper
36 changes: 32 additions & 4 deletions products/compute/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ objects:
and CONNECTION (for TCP/SSL).
- !ruby/object:Api::Type::Double
name: 'capacityScaler'
send_empty_value: true
default_value: 1.0
description: |
A multiplier applied to the group's maximum servicing capacity
Expand Down Expand Up @@ -656,14 +657,17 @@ objects:
partial URL.
- !ruby/object:Api::Type::Integer
name: 'maxConnections'
send_empty_value: true
description: |
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
maxConnectionsPerInstance must be set.
For CONNECTION mode, either maxConnections or one
of maxConnectionsPerInstance or maxConnectionsPerEndpoint,
as appropriate for group type, must be set.
- !ruby/object:Api::Type::Integer
name: 'maxConnectionsPerInstance'
send_empty_value: true
description: |
The max number of simultaneous connections that a single
backend instance can handle. This is used to calculate the
Expand All @@ -672,23 +676,46 @@ objects:
For CONNECTION mode, either maxConnections or
maxConnectionsPerInstance must be set.
- !ruby/object:Api::Type::Integer
name: 'maxConnectionsPerEndpoint'
send_empty_value: true
description: |
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.
- !ruby/object:Api::Type::Integer
name: 'maxRate'
send_empty_value: true
description: |
The max requests per second (RPS) of the group.
Can be used with either RATE or UTILIZATION balancing modes,
but required if RATE mode. For RATE mode, either maxRate or
maxRatePerInstance must be set.
but required if RATE mode. For RATE mode, either maxRate or one
of maxRatePerInstance or maxRatePerEndpoint, as appropriate for
group type, must be set.
- !ruby/object:Api::Type::Double
name: 'maxRatePerInstance'
send_empty_value: true
description: |
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.
- !ruby/object:Api::Type::Double
name: 'maxRatePerEndpoint'
send_empty_value: true
description: |
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.
- !ruby/object:Api::Type::Double
name: 'maxUtilization'
send_empty_value: true
default_value: 0.8
description: |
Used when balancingMode is UTILIZATION. This ratio defines the
Expand Down Expand Up @@ -4974,6 +5001,7 @@ objects:
kind: 'compute#networkEndpointGroup'
base_url: 'projects/{{project}}/zones/{{zone}}/networkEndpointGroups'
input: true
has_self_link: true
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation': 'https://cloud.google.com/load-balancing/docs/negs/'
Expand Down
17 changes: 17 additions & 0 deletions templates/terraform/constants/backend_service.go.erb
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,23 @@ func resourceGoogleComputeBackendServiceBackendHash(v interface{}) int {
// the hash function doesn't return something else.
buf.WriteString(fmt.Sprintf("%f-", v.(float64)))
}
if v, ok := m["max_connections_per_endpoint"]; ok {
if v == nil {
v = 0
}

buf.WriteString(fmt.Sprintf("%v-", v))
}
if v, ok := m["max_rate_per_endpoint"]; ok {
if v == nil {
v = 0.0
}

// floats can't be added to the hash with %v as the other values are because
// %v and %f are not equivalent strings so this must remain as a float so that
// the hash function doesn't return something else.
buf.WriteString(fmt.Sprintf("%f-", v.(float64)))
}

log.Printf("[DEBUG] computed hash value of %v from %v", hashcode.String(buf.String()), buf.String())
return hashcode.String(buf.String())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,80 @@ func TestAccComputeBackendService_withMaxConnectionsPerInstance(t *testing.T) {
}
}

func TestAccComputeBackendService_withMaxRatePerEndpoint(t *testing.T) {
t.Parallel()

randSuffix := acctest.RandString(10)
service := fmt.Sprintf("tf-test-%s", randSuffix)
instance := fmt.Sprintf("tf-test-%s", randSuffix)
neg := fmt.Sprintf("tf-test-%s", randSuffix)
network := fmt.Sprintf("tf-test-%s", randSuffix)
check := fmt.Sprintf("tf-test-%s", randSuffix)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeBackendServiceDestroy,
Steps: []resource.TestStep{
{
Config: testAccComputeBackendService_withMaxRatePerEndpoint(
service, instance, neg, network, check, 0.2),
},
{
ResourceName: "google_compute_backend_service.lipsum",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccComputeBackendService_withMaxRatePerEndpoint(
service, instance, neg, network, check, 0.4),
},
{
ResourceName: "google_compute_backend_service.lipsum",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccComputeBackendService_withMaxConnectionsPerEndpoint(t *testing.T) {
t.Parallel()

randSuffix := acctest.RandString(10)
service := fmt.Sprintf("tf-test-%s", randSuffix)
instance := fmt.Sprintf("tf-test-%s", randSuffix)
neg := fmt.Sprintf("tf-test-%s", randSuffix)
network := fmt.Sprintf("tf-test-%s", randSuffix)
check := fmt.Sprintf("tf-test-%s", randSuffix)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeBackendServiceDestroy,
Steps: []resource.TestStep{
{
Config: testAccComputeBackendService_withMaxConnectionsPerEndpoint(
service, instance, neg, network, check, 5),
},
{
ResourceName: "google_compute_backend_service.lipsum",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccComputeBackendService_withMaxConnectionsPerEndpoint(
service, instance, neg, network, check, 10),
},
{
ResourceName: "google_compute_backend_service.lipsum",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

<% unless version == 'ga' -%>
func TestAccComputeBackendService_withCustomHeaders(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -1087,6 +1161,163 @@ resource "google_compute_health_check" "default" {
`, serviceName, maxConnectionsPerInstance, igName, itName, checkName)
}


func testAccComputeBackendService_withMaxConnectionsPerEndpoint(
service, instance, neg, network, check string, maxConnections int64) string {
return fmt.Sprintf(`
resource "google_compute_backend_service" "lipsum" {
name = "%s"
description = "Hello World 1234"
port_name = "http"
protocol = "TCP"

backend {
group = "${google_compute_network_endpoint_group.lb-neg.self_link}"
balancing_mode = "CONNECTION"
max_connections_per_endpoint = %v
}

health_checks = ["${google_compute_health_check.default.self_link}"]
}

data "google_compute_image" "my_image" {
family = "debian-9"
project = "debian-cloud"
}

resource "google_compute_instance" "endpoint-instance" {
name = "%s"
machine_type = "n1-standard-1"

boot_disk {
initialize_params{
image = "${data.google_compute_image.my_image.self_link}"
}
}

network_interface {
subnetwork = "${google_compute_subnetwork.default.self_link}"
access_config { }
}
}

resource "google_compute_network_endpoint_group" "lb-neg" {
name = "%s"
network = "${google_compute_network.default.self_link}"
subnetwork = "${google_compute_subnetwork.default.self_link}"
default_port = "90"
zone = "us-central1-a"
}

resource "google_compute_network_endpoint" "lb-endpoint" {
network_endpoint_group = "${google_compute_network_endpoint_group.lb-neg.name}"

instance = "${google_compute_instance.endpoint-instance.name}"
port = "${google_compute_network_endpoint_group.lb-neg.default_port}"
ip_address = "${google_compute_instance.endpoint-instance.network_interface.0.network_ip}"
}

resource "google_compute_network" "default" {
name = "%s"
auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "default" {
name = "%s"
ip_cidr_range = "10.0.0.0/16"
region = "us-central1"
network = "${google_compute_network.default.self_link}"
}

resource "google_compute_health_check" "default" {
name = "%s"
tcp_health_check {
port = "110"
}
}
`, service, maxConnections, instance, neg, network, network, check)
}

func testAccComputeBackendService_withMaxRatePerEndpoint(
service, instance, neg, network, check string, maxRate float64) string {
return fmt.Sprintf(`
resource "google_compute_backend_service" "lipsum" {
name = "%s"
description = "Hello World 1234"
port_name = "https"
protocol = "HTTPS"

backend {
group = "${google_compute_network_endpoint_group.lb-neg.self_link}"
balancing_mode = "RATE"
max_rate_per_endpoint = %v
}

health_checks = ["${google_compute_health_check.default.self_link}"]
}

data "google_compute_image" "my_image" {
family = "debian-9"
project = "debian-cloud"
}

resource "google_compute_instance" "endpoint-instance" {
name = "%s"
machine_type = "n1-standard-1"

boot_disk {
initialize_params{
image = "${data.google_compute_image.my_image.self_link}"
}
}

network_interface {
subnetwork = "${google_compute_subnetwork.default.self_link}"
access_config { }
}
}

resource "google_compute_network_endpoint_group" "lb-neg" {
name = "%s"
network = "${google_compute_network.default.self_link}"
subnetwork = "${google_compute_subnetwork.default.self_link}"
default_port = "90"
zone = "us-central1-a"
}

resource "google_compute_network_endpoint" "lb-endpoint" {
network_endpoint_group = "${google_compute_network_endpoint_group.lb-neg.name}"

instance = "${google_compute_instance.endpoint-instance.name}"
port = "${google_compute_network_endpoint_group.lb-neg.default_port}"
ip_address = "${google_compute_instance.endpoint-instance.network_interface.0.network_ip}"
}

resource "google_compute_network" "default" {
name = "%s"
auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "default" {
name = "%s"
ip_cidr_range = "10.0.0.0/16"
region = "us-central1"
network = "${google_compute_network.default.self_link}"
}

resource "google_compute_health_check" "default" {
name = "%s"
check_interval_sec = 3
healthy_threshold = 3
timeout_sec = 2
unhealthy_threshold = 3
https_health_check {
port = "443"
}
}
`, service, maxRate, instance, neg, network, network, check)
}

<% unless version == 'ga' -%>
func testAccComputeBackendService_withCustomHeaders(serviceName, checkName string) string {
return fmt.Sprintf(`
Expand Down

0 comments on commit 3ca7271

Please sign in to comment.