From b5d8206ee3fc0ed962bc63a92104f9e7b488c3bd Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sat, 18 Jan 2020 17:54:40 -0500 Subject: [PATCH 01/17] r/aws_appmesh_route: Add support for retry policies. --- aws/resource_aws_appmesh_route.go | 55 +++++++++++++++++ aws/resource_aws_appmesh_route_test.go | 81 ++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/aws/resource_aws_appmesh_route.go b/aws/resource_aws_appmesh_route.go index 5419b31f7e9f..2cb53eec2ead 100644 --- a/aws/resource_aws_appmesh_route.go +++ b/aws/resource_aws_appmesh_route.go @@ -257,6 +257,61 @@ func resourceAwsAppmeshRoute() *schema.Resource { }, }, }, + + "retry_policy": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "http_retry_events": { + Type: schema.TypeSet, + Optional: true, + MinItems: 0, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + + "max_retries": { + Type: schema.TypeInt, + Required: true, + }, + + "per_retry_timeout": { + Type: schema.TypeList, + Required: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unit": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + appmesh.DurationUnitMs, + appmesh.DurationUnitS, + }, false), + }, + + "value": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + + "tcp_retry_events": { + Type: schema.TypeSet, + Optional: true, + MinItems: 0, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + }, + }, + }, }, }, }, diff --git a/aws/resource_aws_appmesh_route_test.go b/aws/resource_aws_appmesh_route_test.go index faf58bab1b30..388000635bd4 100644 --- a/aws/resource_aws_appmesh_route_test.go +++ b/aws/resource_aws_appmesh_route_test.go @@ -1666,3 +1666,84 @@ resource "aws_appmesh_route" "test" { } `, rName)) } + +func testAccAwsAppmeshRouteConfig_httpRetryPolicy(meshName, vrName, vn1Name, vn2Name, rName string) string { + return testAccAppmeshRouteConfigBase(meshName, vrName, vn1Name, vn2Name) + fmt.Sprintf(` +resource "aws_appmesh_route" "test" { + name = %[1]q + mesh_name = "${aws_appmesh_mesh.test.id}" + virtual_router_name = "${aws_appmesh_virtual_router.test.name}" + + spec { + http_route { + match { + prefix = "/" + } + + retry_policy { + http_retry_events = [ + "server-error", + ] + + max_retries = 1 + + per_retry_timeout { + unit = "s" + value = 15 + } + } + + action { + weighted_target { + virtual_node = "${aws_appmesh_virtual_node.foo.name}" + weight = 100 + } + } + } + } +} +`, rName) +} + +func testAccAwsAppmeshRouteConfig_httpRetryPolicyUpdated(meshName, vrName, vn1Name, vn2Name, rName string) string { + return testAccAppmeshRouteConfigBase(meshName, vrName, vn1Name, vn2Name) + fmt.Sprintf(` +resource "aws_appmesh_route" "test" { + name = %[1]q + mesh_name = "${aws_appmesh_mesh.test.id}" + virtual_router_name = "${aws_appmesh_virtual_router.test.name}" + + spec { + http_route { + match { + prefix = "/" + } + + retry_policy { + http_retry_events = [ + "client-error", + "gateway-error", + ] + + max_retries = 3 + + per_retry_timeout { + unit = "ms" + value = 250000 + } + + tcp_retry_events = [ + "connection-error", + ] + } + + action { + weighted_target { + virtual_node = "${aws_appmesh_virtual_node.foo.name}" + weight = 100 + } + } + } + } +} +`, rName) +} From 7ec8be0370c7489ca4c4fe1390279f59ae4b6427 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sat, 18 Jan 2020 17:54:40 -0500 Subject: [PATCH 02/17] r/aws_appmesh_route: Add support for retry policies. --- website/docs/r/appmesh_route.html.markdown | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/website/docs/r/appmesh_route.html.markdown b/website/docs/r/appmesh_route.html.markdown index 19fc844b79e4..fbca527439e0 100644 --- a/website/docs/r/appmesh_route.html.markdown +++ b/website/docs/r/appmesh_route.html.markdown @@ -114,6 +114,43 @@ resource "aws_appmesh_route" "serviceb" { } ``` +### Retry Policy + +```hcl +resource "aws_appmesh_route" "serviceb" { + name = "serviceB-route" + mesh_name = "${aws_appmesh_mesh.simple.id}" + virtual_router_name = "${aws_appmesh_virtual_router.serviceb.name}" + + spec { + http_route { + match { + prefix = "/" + } + + retry_policy { + http_retry_events = [ + "server-error", + ] + max_retries = 1 + + per_retry_timeout { + unit = "s" + value = 15 + } + } + + action { + weighted_target { + virtual_node = "${aws_appmesh_virtual_node.serviceb.name}" + weight = 100 + } + } + } + } +} +``` + ### TCP Routing ```hcl From 9120d0abb117802a67d6e2b5fbd10c6e231c1e5c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sat, 18 Jan 2020 18:36:12 -0500 Subject: [PATCH 03/17] r/aws_appmesh_route: Support gRPC and HTTP/2 services. --- aws/resource_aws_appmesh_route.go | 14 ++ aws/resource_aws_appmesh_route_test.go | 216 +++++++++++++++++++++++++ 2 files changed, 230 insertions(+) diff --git a/aws/resource_aws_appmesh_route.go b/aws/resource_aws_appmesh_route.go index 2cb53eec2ead..e1e4390b3d0f 100644 --- a/aws/resource_aws_appmesh_route.go +++ b/aws/resource_aws_appmesh_route.go @@ -185,6 +185,12 @@ func resourceAwsAppmeshRoute() *schema.Resource { }, "method_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice(appmesh.HttpMethod_Values(), false), + }, + + "prefix": { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringLenBetween(0, 50), @@ -265,6 +271,14 @@ func resourceAwsAppmeshRoute() *schema.Resource { MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "grpc_retry_events": { + Type: schema.TypeSet, + Optional: true, + MinItems: 0, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + "http_retry_events": { Type: schema.TypeSet, Optional: true, diff --git a/aws/resource_aws_appmesh_route_test.go b/aws/resource_aws_appmesh_route_test.go index 388000635bd4..db1ef78f5e36 100644 --- a/aws/resource_aws_appmesh_route_test.go +++ b/aws/resource_aws_appmesh_route_test.go @@ -1296,6 +1296,222 @@ resource "aws_appmesh_route" "test" { `, rName)) } +func testAccAwsAppmeshRouteConfig_grpcRoute(meshName, vrName, vn1Name, vn2Name, rName string) string { + return testAccAppmeshRouteConfigBase(meshName, vrName, vn1Name, vn2Name) + fmt.Sprintf(` +resource "aws_appmesh_route" "test" { + name = %[1]q + mesh_name = "${aws_appmesh_mesh.test.id}" + virtual_router_name = "${aws_appmesh_virtual_router.test.name}" + + spec { + grpc_route { + match { + metadata { + name = "X-Testing1" + } + } + + retry_policy { + grpc_retry_events = [ + "deadline-exceeded", + "resource-exhausted", + ] + + http_retry_events = [ + "server-error", + ] + + max_retries = 1 + + per_retry_timeout { + unit = "s" + value = 15 + } + } + + action { + weighted_target { + virtual_node = "${aws_appmesh_virtual_node.foo.name}" + weight = 100 + } + } + } + } +} +`, rName) +} + +func testAccAwsAppmeshRouteConfig_grpcRouteUpdated(meshName, vrName, vn1Name, vn2Name, rName string) string { + return testAccAppmeshRouteConfigBase(meshName, vrName, vn1Name, vn2Name) + fmt.Sprintf(` +resource "aws_appmesh_route" "test" { + name = %[1]q + mesh_name = "${aws_appmesh_mesh.test.id}" + virtual_router_name = "${aws_appmesh_virtual_router.test.name}" + + spec { + grpc_route { + match { + method_name = "test" + service_name = "test.local" + + metadata { + name = "X-Testing1" + invert = true + } + + metadata { + name = "X-Testing2" + invert = false + + match { + range { + start = 2 + end = 7 + } + } + } + } + + retry_policy { + grpc_retry_events = [ + "cancelled", + ] + + http_retry_events = [ + "client-error", + "gateway-error", + ] + + max_retries = 3 + + per_retry_timeout { + unit = "ms" + value = 250000 + } + + tcp_retry_events = [ + "connection-error", + ] + } + + action { + weighted_target { + virtual_node = "${aws_appmesh_virtual_node.foo.name}" + weight = 100 + } + } + } + } +} +`, rName) +} + +func testAccAwsAppmeshRouteConfig_http2Route(meshName, vrName, vn1Name, vn2Name, rName string) string { + return testAccAppmeshRouteConfigBase(meshName, vrName, vn1Name, vn2Name) + fmt.Sprintf(` +resource "aws_appmesh_route" "test" { + name = %[1]q + mesh_name = "${aws_appmesh_mesh.test.id}" + virtual_router_name = "${aws_appmesh_virtual_router.test.name}" + + spec { + http2_route { + match { + prefix = "/" + method = "POST" + scheme = "http" + + header { + name = "X-Testing1" + } + } + + retry_policy { + http_retry_events = [ + "server-error", + ] + + max_retries = 1 + + per_retry_timeout { + unit = "s" + value = 15 + } + } + + action { + weighted_target { + virtual_node = "${aws_appmesh_virtual_node.foo.name}" + weight = 100 + } + } + } + } +} +`, rName) +} + +func testAccAwsAppmeshRouteConfig_http2RouteUpdated(meshName, vrName, vn1Name, vn2Name, rName string) string { + return testAccAppmeshRouteConfigBase(meshName, vrName, vn1Name, vn2Name) + fmt.Sprintf(` +resource "aws_appmesh_route" "test" { + name = %[1]q + mesh_name = "${aws_appmesh_mesh.test.id}" + virtual_router_name = "${aws_appmesh_virtual_router.test.name}" + + spec { + http2_route { + match { + prefix = "/path" + method = "PUT" + scheme = "https" + + header { + name = "X-Testing1" + invert = true + } + + header { + name = "X-Testing2" + invert = false + + match { + range { + start = 2 + end = 7 + } + } + } + } + + retry_policy { + http_retry_events = [ + "client-error", + "gateway-error", + ] + + max_retries = 3 + + per_retry_timeout { + unit = "ms" + value = 250000 + } + + tcp_retry_events = [ + "connection-error", + ] + } + + action { + weighted_target { + virtual_node = "${aws_appmesh_virtual_node.foo.name}" + weight = 100 + } + } + } + } +} +`, rName) +} + func testAccAppmeshRouteConfig_httpRoute(meshName, vrName, vn1Name, vn2Name, rName string) string { return composeConfig(testAccAppmeshRouteConfigBase(meshName, vrName, "http", vn1Name, vn2Name), fmt.Sprintf(` resource "aws_appmesh_route" "test" { From e64113ee05d167b57a8d374943919194a2cc1c46 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sat, 18 Jan 2020 18:36:12 -0500 Subject: [PATCH 04/17] r/aws_appmesh_route: Support gRPC and HTTP/2 services. --- aws/structure.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/aws/structure.go b/aws/structure.go index 58f3a43e30b5..5e9223bf04e7 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -5618,6 +5618,15 @@ func expandAppmeshHttpRoute(vHttpRoute []interface{}) *appmesh.HttpRoute { if vSuffix, ok := mMatch["suffix"].(string); ok && vSuffix != "" { httpRouteHeader.Match.Suffix = aws.String(vSuffix) } + if vRegex, ok := mMatch["regex"].(string); ok && vRegex != "" { + httpRouteHeader.Match.Regex = aws.String(vRegex) + } + if vSuffix, ok := mMatch["suffix"].(string); ok && vSuffix != "" { + httpRouteHeader.Match.Suffix = aws.String(vSuffix) + } + + if vRange, ok := mMatch["range"].([]interface{}); ok && len(vRange) > 0 && vRange[0] != nil { + httpRouteHeader.Match.Range = &appmesh.MatchRange{} if vRange, ok := mMatch["range"].([]interface{}); ok && len(vRange) > 0 && vRange[0] != nil { httpRouteHeader.Match.Range = &appmesh.MatchRange{} From 9b7b246b2ee5e4f400b9822501ec264952141fbe Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 16 Apr 2020 17:13:29 -0400 Subject: [PATCH 05/17] r/aws_appmesh_virtual_router: Test gRPC and HTTP/2 listener protocols. --- aws/resource_aws_appmesh_route_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_appmesh_route_test.go b/aws/resource_aws_appmesh_route_test.go index db1ef78f5e36..a37113e5b087 100644 --- a/aws/resource_aws_appmesh_route_test.go +++ b/aws/resource_aws_appmesh_route_test.go @@ -1884,7 +1884,7 @@ resource "aws_appmesh_route" "test" { } func testAccAwsAppmeshRouteConfig_httpRetryPolicy(meshName, vrName, vn1Name, vn2Name, rName string) string { - return testAccAppmeshRouteConfigBase(meshName, vrName, vn1Name, vn2Name) + fmt.Sprintf(` + return testAccAppmeshRouteConfigBase(meshName, vrName, "http", vn1Name, vn2Name) + fmt.Sprintf(` resource "aws_appmesh_route" "test" { name = %[1]q mesh_name = "${aws_appmesh_mesh.test.id}" @@ -1922,7 +1922,7 @@ resource "aws_appmesh_route" "test" { } func testAccAwsAppmeshRouteConfig_httpRetryPolicyUpdated(meshName, vrName, vn1Name, vn2Name, rName string) string { - return testAccAppmeshRouteConfigBase(meshName, vrName, vn1Name, vn2Name) + fmt.Sprintf(` + return testAccAppmeshRouteConfigBase(meshName, vrName, "http", vn1Name, vn2Name) + fmt.Sprintf(` resource "aws_appmesh_route" "test" { name = %[1]q mesh_name = "${aws_appmesh_mesh.test.id}" From f6901c233502b1f8786683785786e31fb702d292 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 27 Jul 2020 17:06:38 -0400 Subject: [PATCH 06/17] r/aws_appmesh_route: Add gRPC route timeout configuration support. Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/Route/grpcRoute' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/Route/grpcRoute -timeout 120m === RUN TestAccAWSAppmesh_serial === RUN TestAccAWSAppmesh_serial/Route === RUN TestAccAWSAppmesh_serial/Route/grpcRouteTimeout === RUN TestAccAWSAppmesh_serial/Route/grpcRoute === RUN TestAccAWSAppmesh_serial/VirtualRouter --- PASS: TestAccAWSAppmesh_serial (66.22s) --- PASS: TestAccAWSAppmesh_serial/Route (66.22s) --- PASS: TestAccAWSAppmesh_serial/Route/grpcRouteTimeout (27.92s) --- PASS: TestAccAWSAppmesh_serial/Route/grpcRoute (38.30s) --- PASS: TestAccAWSAppmesh_serial/VirtualRouter (0.00s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 66.266s --- aws/resource_aws_appmesh_route.go | 58 +++++++ aws/resource_aws_appmesh_route_test.go | 170 +++++++++++++++++++++ aws/resource_aws_appmesh_test.go | 17 ++- aws/structure.go | 62 ++++++++ website/docs/r/appmesh_route.html.markdown | 11 ++ 5 files changed, 310 insertions(+), 8 deletions(-) diff --git a/aws/resource_aws_appmesh_route.go b/aws/resource_aws_appmesh_route.go index e1e4390b3d0f..736db01bfec8 100644 --- a/aws/resource_aws_appmesh_route.go +++ b/aws/resource_aws_appmesh_route.go @@ -326,6 +326,64 @@ func resourceAwsAppmeshRoute() *schema.Resource { }, }, }, + + "timeout": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "idle": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unit": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + appmesh.DurationUnitMs, + appmesh.DurationUnitS, + }, false), + }, + + "value": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + + "per_request": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unit": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + appmesh.DurationUnitMs, + appmesh.DurationUnitS, + }, false), + }, + + "value": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + }, + }, + }, }, }, }, diff --git a/aws/resource_aws_appmesh_route_test.go b/aws/resource_aws_appmesh_route_test.go index a37113e5b087..3c8c2a1d46db 100644 --- a/aws/resource_aws_appmesh_route_test.go +++ b/aws/resource_aws_appmesh_route_test.go @@ -146,6 +146,7 @@ func testAccAwsAppmeshRoute_grpcRoute(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.retry_policy.0.per_retry_timeout.0.unit", "s"), resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.retry_policy.0.per_retry_timeout.0.value", "15"), resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.retry_policy.0.tcp_retry_events.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), @@ -197,6 +198,7 @@ func testAccAwsAppmeshRoute_grpcRoute(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.retry_policy.0.per_retry_timeout.0.value", "250000"), resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.retry_policy.0.tcp_retry_events.#", "1"), tfawsresource.TestCheckTypeSetElemAttr(resourceName, "spec.0.grpc_route.0.retry_policy.0.tcp_retry_events.*", "connection-error"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), @@ -248,6 +250,101 @@ func testAccAwsAppmeshRoute_grpcRoute(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.retry_policy.0.per_retry_timeout.0.value", "250000"), resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.retry_policy.0.tcp_retry_events.#", "1"), tfawsresource.TestCheckTypeSetElemAttr(resourceName, "spec.0.grpc_route.0.retry_policy.0.tcp_retry_events.*", "connection-error"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), + ), + }, + { + ResourceName: resourceName, + ImportStateIdFunc: testAccAwsAppmeshRouteImportStateIdFunc(resourceName), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAwsAppmeshRoute_grpcRoute_timeout(t *testing.T) { + var r appmesh.RouteData + resourceName := "aws_appmesh_route.test" + meshName := acctest.RandomWithPrefix("tf-acc-test") + vrName := acctest.RandomWithPrefix("tf-acc-test") + vn1Name := acctest.RandomWithPrefix("tf-acc-test") + vn2Name := acctest.RandomWithPrefix("tf-acc-test") + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAppmeshRouteDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsAppmeshRouteConfig_grpcRouteWithTimeout(meshName, vrName, vn1Name, vn2Name, rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshRouteExists(resourceName, &r), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.action.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.action.0.weighted_target.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.match.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.match.0.metadata.#", "1"), + tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.grpc_route.0.match.0.metadata.*", map[string]string{ + "invert": "false", + "match.#": "0", + "name": "X-Testing1", + }), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.match.0.method_name", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.match.0.service_name", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.0.idle.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.0.idle.0.unit", "ms"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.0.idle.0.value", "250000"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.0.per_request.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), + ), + }, + { + Config: testAccAwsAppmeshRouteConfig_grpcRouteWithTimeoutUpdated(meshName, vrName, vn1Name, vn2Name, rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshRouteExists(resourceName, &r), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.action.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.action.0.weighted_target.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.match.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.match.0.metadata.#", "1"), + tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.grpc_route.0.match.0.metadata.*", map[string]string{ + "invert": "false", + "match.#": "0", + "name": "X-Testing1", + }), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.match.0.method_name", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.match.0.service_name", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.0.idle.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.0.idle.0.unit", "s"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.0.idle.0.value", "10"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.0.per_request.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.0.per_request.0.unit", "s"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.0.timeout.0.per_request.0.value", "5"), resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), @@ -1190,6 +1287,79 @@ resource "aws_appmesh_route" "test" { `, rName)) } +func testAccAwsAppmeshRouteConfig_grpcRouteWithTimeout(meshName, vrName, vn1Name, vn2Name, rName string) string { + return testAccAppmeshRouteConfigBase(meshName, vrName, "grpc", vn1Name, vn2Name) + fmt.Sprintf(` +resource "aws_appmesh_route" "test" { + name = %[1]q + mesh_name = aws_appmesh_mesh.test.id + virtual_router_name = aws_appmesh_virtual_router.test.name + + spec { + grpc_route { + match { + metadata { + name = "X-Testing1" + } + } + + action { + weighted_target { + virtual_node = aws_appmesh_virtual_node.foo.name + weight = 100 + } + } + + timeout { + idle { + unit = "ms" + value = 250000 + } + } + } + } +} +`, rName) +} + +func testAccAwsAppmeshRouteConfig_grpcRouteWithTimeoutUpdated(meshName, vrName, vn1Name, vn2Name, rName string) string { + return testAccAppmeshRouteConfigBase(meshName, vrName, "grpc", vn1Name, vn2Name) + fmt.Sprintf(` +resource "aws_appmesh_route" "test" { + name = %[1]q + mesh_name = aws_appmesh_mesh.test.id + virtual_router_name = aws_appmesh_virtual_router.test.name + + spec { + grpc_route { + match { + metadata { + name = "X-Testing1" + } + } + + action { + weighted_target { + virtual_node = aws_appmesh_virtual_node.foo.name + weight = 100 + } + } + + timeout { + idle { + unit = "s" + value = 10 + } + + per_request { + unit = "s" + value = 5 + } + } + } + } +} +`, rName) +} + func testAccAwsAppmeshRouteConfig_http2Route(meshName, vrName, vn1Name, vn2Name, rName string) string { return composeConfig(testAccAppmeshRouteConfigBase(meshName, vrName, "http2", vn1Name, vn2Name), fmt.Sprintf(` resource "aws_appmesh_route" "test" { diff --git a/aws/resource_aws_appmesh_test.go b/aws/resource_aws_appmesh_test.go index 023035297cf8..3d6cf028b4cb 100644 --- a/aws/resource_aws_appmesh_test.go +++ b/aws/resource_aws_appmesh_test.go @@ -12,14 +12,15 @@ func TestAccAWSAppmesh_serial(t *testing.T) { "tags": testAccAwsAppmeshMesh_tags, }, "Route": { - "grpcRoute": testAccAwsAppmeshRoute_grpcRoute, - "http2Route": testAccAwsAppmeshRoute_http2Route, - "httpHeader": testAccAwsAppmeshRoute_httpHeader, - "httpRetryPolicy": testAccAwsAppmeshRoute_httpRetryPolicy, - "httpRoute": testAccAwsAppmeshRoute_httpRoute, - "routePriority": testAccAwsAppmeshRoute_routePriority, - "tcpRoute": testAccAwsAppmeshRoute_tcpRoute, - "tags": testAccAwsAppmeshRoute_tags, + "grpcRoute": testAccAwsAppmeshRoute_grpcRoute, + "grpcRouteTimeout": testAccAwsAppmeshRoute_grpcRoute_timeout, + "http2Route": testAccAwsAppmeshRoute_http2Route, + "httpHeader": testAccAwsAppmeshRoute_httpHeader, + "httpRetryPolicy": testAccAwsAppmeshRoute_httpRetryPolicy, + "httpRoute": testAccAwsAppmeshRoute_httpRoute, + "routePriority": testAccAwsAppmeshRoute_routePriority, + "tcpRoute": testAccAwsAppmeshRoute_tcpRoute, + "tags": testAccAwsAppmeshRoute_tags, }, "VirtualNode": { "basic": testAccAwsAppmeshVirtualNode_basic, diff --git a/aws/structure.go b/aws/structure.go index 5e9223bf04e7..163348fe20fe 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -5532,6 +5532,44 @@ func expandAppmeshGrpcRoute(vGrpcRoute []interface{}) *appmesh.GrpcRoute { grpcRoute.RetryPolicy = grpcRetryPolicy } + if vGrpcTimeout, ok := mGrpcRoute["timeout"].([]interface{}); ok && len(vGrpcTimeout) > 0 && vGrpcTimeout[0] != nil { + grpcTimeout := &appmesh.GrpcTimeout{} + + mGrpcTimeout := vGrpcTimeout[0].(map[string]interface{}) + + if vIdleTimeout, ok := mGrpcTimeout["idle"].([]interface{}); ok && len(vIdleTimeout) > 0 && vIdleTimeout[0] != nil { + idleTimeout := &appmesh.Duration{} + + mIdleTimeout := vIdleTimeout[0].(map[string]interface{}) + + if vUnit, ok := mIdleTimeout["unit"].(string); ok && vUnit != "" { + idleTimeout.Unit = aws.String(vUnit) + } + if vValue, ok := mIdleTimeout["value"].(int); ok && vValue > 0 { + idleTimeout.Value = aws.Int64(int64(vValue)) + } + + grpcTimeout.Idle = idleTimeout + } + + if vPerRequestTimeout, ok := mGrpcTimeout["per_request"].([]interface{}); ok && len(vPerRequestTimeout) > 0 && vPerRequestTimeout[0] != nil { + perRequestTimeout := &appmesh.Duration{} + + mPerRequestTimeout := vPerRequestTimeout[0].(map[string]interface{}) + + if vUnit, ok := mPerRequestTimeout["unit"].(string); ok && vUnit != "" { + perRequestTimeout.Unit = aws.String(vUnit) + } + if vValue, ok := mPerRequestTimeout["value"].(int); ok && vValue > 0 { + perRequestTimeout.Value = aws.Int64(int64(vValue)) + } + + grpcTimeout.PerRequest = perRequestTimeout + } + + grpcRoute.Timeout = grpcTimeout + } + return grpcRoute } @@ -5833,6 +5871,30 @@ func flattenAppmeshGrpcRoute(grpcRoute *appmesh.GrpcRoute) []interface{} { mGrpcRoute["retry_policy"] = []interface{}{mGrpcRetryPolicy} } + if grpcTimeout := grpcRoute.Timeout; grpcTimeout != nil { + mGrpcTimeout := map[string]interface{}{} + + if idleTimeout := grpcTimeout.Idle; idleTimeout != nil { + mIdleTimeout := map[string]interface{}{ + "unit": aws.StringValue(idleTimeout.Unit), + "value": int(aws.Int64Value(idleTimeout.Value)), + } + + mGrpcTimeout["idle"] = []interface{}{mIdleTimeout} + } + + if perRequestTimeout := grpcTimeout.PerRequest; perRequestTimeout != nil { + mPerRequestTimeout := map[string]interface{}{ + "unit": aws.StringValue(perRequestTimeout.Unit), + "value": int(aws.Int64Value(perRequestTimeout.Value)), + } + + mGrpcTimeout["per_request"] = []interface{}{mPerRequestTimeout} + } + + mGrpcRoute["timeout"] = []interface{}{mGrpcTimeout} + } + return []interface{}{mGrpcRoute} } diff --git a/website/docs/r/appmesh_route.html.markdown b/website/docs/r/appmesh_route.html.markdown index fbca527439e0..25cab4a8b317 100644 --- a/website/docs/r/appmesh_route.html.markdown +++ b/website/docs/r/appmesh_route.html.markdown @@ -197,6 +197,7 @@ The `grpc_route` object supports the following: * `action` - (Required) The action to take if a match is determined. * `match` - (Required) The criteria for determining an gRPC request match. * `rety_policy` - (Optional) The retry policy. +* `timeout` - (Optional) The types of timeouts. The `http2_route` and `http_route` objects supports the following: @@ -243,6 +244,16 @@ Valid values: `client-error` (HTTP status code 409), `gateway-error` (HTTP statu * `per_retry_timeout` - (Required) The per-retry timeout. * `tcp_retry_events` - (Optional) List of TCP retry events. The only valid value is `connection-error`. +The `grpc_route`'s `timeout` object supports the following: + +* `idle` - (Optional) The idle timeout. An idle timeout bounds the amount of time that a connection may be idle. The default value is none. +* `per_request` - (Optional) The per request timeout. The default value is 15 seconds. + +The `idle` and `per_request` objects support the following: + +* `unit` - (Required) The unit of time. Valid values: `ms`, `s`. +* `value` - (Required) The number of time units. Minimum value of `0`. + The `http2_route` and `http_route`'s `match` object supports the following: * `prefix` - (Required) Specifies the path with which to match requests. From 3040745bd0899d0ec56169387dbf2d271b6323f2 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 27 Jul 2020 17:49:03 -0400 Subject: [PATCH 07/17] r/aws_appmesh_route: Add TCP route timeout configuration support. Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/Route/tcpRoute' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/Route/tcpRoute -timeout 120m === RUN TestAccAWSAppmesh_serial === RUN TestAccAWSAppmesh_serial/VirtualRouter === RUN TestAccAWSAppmesh_serial/Route === RUN TestAccAWSAppmesh_serial/Route/tcpRoute === RUN TestAccAWSAppmesh_serial/Route/tcpRouteTimeout --- PASS: TestAccAWSAppmesh_serial (64.63s) --- PASS: TestAccAWSAppmesh_serial/VirtualRouter (0.00s) --- PASS: TestAccAWSAppmesh_serial/Route (64.63s) --- PASS: TestAccAWSAppmesh_serial/Route/tcpRoute (37.42s) --- PASS: TestAccAWSAppmesh_serial/Route/tcpRouteTimeout (27.20s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 64.686s --- aws/resource_aws_appmesh_route.go | 34 ++++++ aws/resource_aws_appmesh_route_test.go | 133 +++++++++++++++++++++ aws/resource_aws_appmesh_test.go | 1 + aws/structure.go | 38 ++++++ website/docs/r/appmesh_route.html.markdown | 10 ++ 5 files changed, 216 insertions(+) diff --git a/aws/resource_aws_appmesh_route.go b/aws/resource_aws_appmesh_route.go index 736db01bfec8..a0f7c7743bae 100644 --- a/aws/resource_aws_appmesh_route.go +++ b/aws/resource_aws_appmesh_route.go @@ -445,6 +445,40 @@ func resourceAwsAppmeshRoute() *schema.Resource { }, }, }, + + "timeout": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "idle": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unit": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + appmesh.DurationUnitMs, + appmesh.DurationUnitS, + }, false), + }, + + "value": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + }, + }, + }, }, }, }, diff --git a/aws/resource_aws_appmesh_route_test.go b/aws/resource_aws_appmesh_route_test.go index 3c8c2a1d46db..7be21a4fbe83 100644 --- a/aws/resource_aws_appmesh_route_test.go +++ b/aws/resource_aws_appmesh_route_test.go @@ -616,6 +616,7 @@ func testAccAwsAppmeshRoute_tcpRoute(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.action.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.action.0.weighted_target.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.timeout.#", "0"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), @@ -639,6 +640,7 @@ func testAccAwsAppmeshRoute_tcpRoute(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.action.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.action.0.weighted_target.#", "2"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.timeout.#", "0"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), @@ -660,6 +662,81 @@ func testAccAwsAppmeshRoute_tcpRoute(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.action.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.action.0.weighted_target.#", "2"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.timeout.#", "0"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), + ), + }, + { + ResourceName: resourceName, + ImportStateIdFunc: testAccAwsAppmeshRouteImportStateIdFunc(resourceName), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAwsAppmeshRoute_tcpRoute_timeout(t *testing.T) { + var r appmesh.RouteData + resourceName := "aws_appmesh_route.test" + meshName := acctest.RandomWithPrefix("tf-acc-test") + vrName := acctest.RandomWithPrefix("tf-acc-test") + vn1Name := acctest.RandomWithPrefix("tf-acc-test") + vn2Name := acctest.RandomWithPrefix("tf-acc-test") + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAppmeshRouteDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAppmeshRouteConfig_tcpRouteWithTimeout(meshName, vrName, vn1Name, vn2Name, rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshRouteExists(resourceName, &r), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.priority", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.action.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.action.0.weighted_target.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.timeout.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.timeout.0.idle.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.timeout.0.idle.0.unit", "ms"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.timeout.0.idle.0.value", "250000"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), + ), + }, + { + Config: testAccAppmeshRouteConfig_tcpRouteWithTimeoutUpdated(meshName, vrName, vn1Name, vn2Name, rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshRouteExists(resourceName, &r), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.priority", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.action.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.action.0.weighted_target.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.timeout.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.timeout.0.idle.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.timeout.0.idle.0.unit", "s"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.timeout.0.idle.0.value", "10"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), @@ -1840,6 +1917,62 @@ resource "aws_appmesh_route" "test" { `, rName)) } +func testAccAppmeshRouteConfig_tcpRouteWithTimeout(meshName, vrName, vn1Name, vn2Name, rName string) string { + return testAccAppmeshRouteConfigBase(meshName, vrName, "tcp", vn1Name, vn2Name) + fmt.Sprintf(` +resource "aws_appmesh_route" "test" { + name = %[1]q + mesh_name = aws_appmesh_mesh.test.id + virtual_router_name = aws_appmesh_virtual_router.test.name + + spec { + tcp_route { + action { + weighted_target { + virtual_node = aws_appmesh_virtual_node.foo.name + weight = 100 + } + } + + timeout { + idle { + unit = "ms" + value = 250000 + } + } + } + } +} +`, rName) +} + +func testAccAppmeshRouteConfig_tcpRouteWithTimeoutUpdated(meshName, vrName, vn1Name, vn2Name, rName string) string { + return testAccAppmeshRouteConfigBase(meshName, vrName, "tcp", vn1Name, vn2Name) + fmt.Sprintf(` +resource "aws_appmesh_route" "test" { + name = %[1]q + mesh_name = aws_appmesh_mesh.test.id + virtual_router_name = aws_appmesh_virtual_router.test.name + + spec { + tcp_route { + action { + weighted_target { + virtual_node = aws_appmesh_virtual_node.foo.name + weight = 100 + } + } + + timeout { + idle { + unit = "s" + value = 10 + } + } + } + } +} +`, rName) +} + func testAccAppmeshRouteConfigWithTags(meshName, vrName, vn1Name, vn2Name, rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { return composeConfig(testAccAppmeshRouteConfigBase(meshName, vrName, "http", vn1Name, vn2Name), fmt.Sprintf(` resource "aws_appmesh_route" "test" { diff --git a/aws/resource_aws_appmesh_test.go b/aws/resource_aws_appmesh_test.go index 3d6cf028b4cb..812b9a54ba85 100644 --- a/aws/resource_aws_appmesh_test.go +++ b/aws/resource_aws_appmesh_test.go @@ -20,6 +20,7 @@ func TestAccAWSAppmesh_serial(t *testing.T) { "httpRoute": testAccAwsAppmeshRoute_httpRoute, "routePriority": testAccAwsAppmeshRoute_routePriority, "tcpRoute": testAccAwsAppmeshRoute_tcpRoute, + "tcpRouteTimeout": testAccAwsAppmeshRoute_tcpRoute_timeout, "tags": testAccAwsAppmeshRoute_tags, }, "VirtualNode": { diff --git a/aws/structure.go b/aws/structure.go index 163348fe20fe..f4b2b10749c2 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -5763,6 +5763,29 @@ func expandAppmeshTcpRoute(vTcpRoute []interface{}) *appmesh.TcpRoute { } } + if vTcpTimeout, ok := mTcpRoute["timeout"].([]interface{}); ok && len(vTcpTimeout) > 0 && vTcpTimeout[0] != nil { + tcpTimeout := &appmesh.TcpTimeout{} + + mTcpTimeout := vTcpTimeout[0].(map[string]interface{}) + + if vIdleTimeout, ok := mTcpTimeout["idle"].([]interface{}); ok && len(vIdleTimeout) > 0 && vIdleTimeout[0] != nil { + idleTimeout := &appmesh.Duration{} + + mIdleTimeout := vIdleTimeout[0].(map[string]interface{}) + + if vUnit, ok := mIdleTimeout["unit"].(string); ok && vUnit != "" { + idleTimeout.Unit = aws.String(vUnit) + } + if vValue, ok := mIdleTimeout["value"].(int); ok && vValue > 0 { + idleTimeout.Value = aws.Int64(int64(vValue)) + } + + tcpTimeout.Idle = idleTimeout + } + + tcpRoute.Timeout = tcpTimeout + } + return tcpRoute } @@ -6018,6 +6041,21 @@ func flattenAppmeshTcpRoute(tcpRoute *appmesh.TcpRoute) []interface{} { } } + if tcpTimeout := tcpRoute.Timeout; tcpTimeout != nil { + mTcpTimeout := map[string]interface{}{} + + if idleTimeout := tcpTimeout.Idle; idleTimeout != nil { + mIdleTimeout := map[string]interface{}{ + "unit": aws.StringValue(idleTimeout.Unit), + "value": int(aws.Int64Value(idleTimeout.Value)), + } + + mTcpTimeout["idle"] = []interface{}{mIdleTimeout} + } + + mTcpRoute["timeout"] = []interface{}{mTcpTimeout} + } + return []interface{}{mTcpRoute} } diff --git a/website/docs/r/appmesh_route.html.markdown b/website/docs/r/appmesh_route.html.markdown index 25cab4a8b317..b93a27966378 100644 --- a/website/docs/r/appmesh_route.html.markdown +++ b/website/docs/r/appmesh_route.html.markdown @@ -208,12 +208,22 @@ The `http2_route` and `http_route` objects supports the following: The `tcp_route` object supports the following: * `action` - (Required) The action to take if a match is determined. +* `timeout` - (Optional) The types of timeouts. The `action` object supports the following: * `weighted_target` - (Required) The targets that traffic is routed to when a request matches the route. You can specify one or more targets and their relative weights with which to distribute traffic. +The `timeout` object supports the following: + +* `idle` - (Optional) The idle timeout. An idle timeout bounds the amount of time that a connection may be idle. + +The `idle` object supports the following: + +* `unit` - (Required) The unit of time. Valid values: `ms`, `s`. +* `value` - (Required) The number of time units. Minimum value of `0`. + The `grpc_route`'s `match` object supports the following: * `metadata` - (Optional) The data to match from the gRPC request. From d7f95506d93c3d6dd6593b92b3f2ec4857291008 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 28 Jul 2020 18:12:02 -0400 Subject: [PATCH 08/17] r/aws_appmesh_route: Add HTTP and HTTP2 route timeout configuration support. Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/Route/httpRoute' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/Route/httpRoute -timeout 120m === RUN TestAccAWSAppmesh_serial === RUN TestAccAWSAppmesh_serial/Route === RUN TestAccAWSAppmesh_serial/Route/httpRoute === RUN TestAccAWSAppmesh_serial/Route/httpRouteTimeout === RUN TestAccAWSAppmesh_serial/VirtualRouter --- FAIL: TestAccAWSAppmesh_serial (40.30s) --- FAIL: TestAccAWSAppmesh_serial/Route (40.30s) --- FAIL: TestAccAWSAppmesh_serial/Route/httpRoute (12.26s) testing.go:684: Step 0 error: Check failed: Check 17/23 error: aws_appmesh_route.test: Attribute 'spec.0.http_route.0.timeout.#' expected "0", got "1" --- PASS: TestAccAWSAppmesh_serial/Route/httpRouteTimeout (28.03s) --- PASS: TestAccAWSAppmesh_serial/VirtualRouter (0.00s) FAIL FAIL github.com/terraform-providers/terraform-provider-aws/aws 40.353s FAIL GNUmakefile:26: recipe for target 'testacc' failed make: *** [testacc] Error 1 $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/Route/http2Route' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/Route/http2Route -timeout 120m === RUN TestAccAWSAppmesh_serial === RUN TestAccAWSAppmesh_serial/Route === RUN TestAccAWSAppmesh_serial/Route/http2Route === RUN TestAccAWSAppmesh_serial/Route/http2RouteTimeout === RUN TestAccAWSAppmesh_serial/VirtualRouter --- FAIL: TestAccAWSAppmesh_serial (40.79s) --- FAIL: TestAccAWSAppmesh_serial/Route (40.79s) --- PASS: TestAccAWSAppmesh_serial/Route/http2Route (29.14s) --- FAIL: TestAccAWSAppmesh_serial/Route/http2RouteTimeout (11.65s) testing.go:684: Step 0 error: Check failed: Check 17/27 error: aws_appmesh_route.test: Attribute 'spec.0.http2_route.0.timeout.#' expected "1", got "0" --- PASS: TestAccAWSAppmesh_serial/VirtualRouter (0.00s) FAIL FAIL github.com/terraform-providers/terraform-provider-aws/aws 40.836s FAIL GNUmakefile:26: recipe for target 'testacc' failed make: *** [testacc] Error 1 --- aws/resource_aws_appmesh_route.go | 58 +++++ aws/resource_aws_appmesh_route_test.go | 278 ++++++++++++++++++++- aws/resource_aws_appmesh_test.go | 22 +- aws/structure.go | 62 +++++ website/docs/r/appmesh_route.html.markdown | 11 + 5 files changed, 419 insertions(+), 12 deletions(-) diff --git a/aws/resource_aws_appmesh_route.go b/aws/resource_aws_appmesh_route.go index a0f7c7743bae..e163fabf9d0e 100644 --- a/aws/resource_aws_appmesh_route.go +++ b/aws/resource_aws_appmesh_route.go @@ -707,6 +707,64 @@ func appmeshRouteHttpRouteSchema() *schema.Schema { }, }, }, + + "timeout": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "idle": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unit": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + appmesh.DurationUnitMs, + appmesh.DurationUnitS, + }, false), + }, + + "value": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + + "per_request": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unit": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + appmesh.DurationUnitMs, + appmesh.DurationUnitS, + }, false), + }, + + "value": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + }, + }, + }, }, }, } diff --git a/aws/resource_aws_appmesh_route_test.go b/aws/resource_aws_appmesh_route_test.go index 7be21a4fbe83..a0e26af51b1e 100644 --- a/aws/resource_aws_appmesh_route_test.go +++ b/aws/resource_aws_appmesh_route_test.go @@ -270,7 +270,7 @@ func testAccAwsAppmeshRoute_grpcRoute(t *testing.T) { }) } -func testAccAwsAppmeshRoute_grpcRoute_timeout(t *testing.T) { +func testAccAwsAppmeshRoute_grpcRouteTimeout(t *testing.T) { var r appmesh.RouteData resourceName := "aws_appmesh_route.test" meshName := acctest.RandomWithPrefix("tf-acc-test") @@ -410,6 +410,7 @@ func testAccAwsAppmeshRoute_http2Route(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.retry_policy.0.per_retry_timeout.0.unit", "s"), resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.retry_policy.0.per_retry_timeout.0.value", "15"), resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.retry_policy.0.tcp_retry_events.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.timeout.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), @@ -460,6 +461,105 @@ func testAccAwsAppmeshRoute_http2Route(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.retry_policy.0.per_retry_timeout.0.value", "250000"), resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.retry_policy.0.tcp_retry_events.#", "1"), tfawsresource.TestCheckTypeSetElemAttr(resourceName, "spec.0.http2_route.0.retry_policy.0.tcp_retry_events.*", "connection-error"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.timeout.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), + ), + }, + { + ResourceName: resourceName, + ImportStateIdFunc: testAccAwsAppmeshRouteImportStateIdFunc(resourceName), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAwsAppmeshRoute_http2RouteTimeout(t *testing.T) { + var r appmesh.RouteData + resourceName := "aws_appmesh_route.test" + meshName := acctest.RandomWithPrefix("tf-acc-test") + vrName := acctest.RandomWithPrefix("tf-acc-test") + vn1Name := acctest.RandomWithPrefix("tf-acc-test") + vn2Name := acctest.RandomWithPrefix("tf-acc-test") + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAppmeshRouteDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsAppmeshRouteConfig_http2RouteWithTimeout(meshName, vrName, vn1Name, vn2Name, rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshRouteExists(resourceName, &r), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.action.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.action.0.weighted_target.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.match.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.match.0.header.#", "1"), + tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.http2_route.0.match.0.header.*", map[string]string{ + "invert": "false", + "match.#": "0", + "name": "X-Testing1", + }), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.match.0.method", "POST"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.match.0.prefix", "/"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.match.0.scheme", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.retry_policy.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.timeout.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.timeout.0.idle.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.timeout.0.idle.0.unit", "ms"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.timeout.0.idle.0.value", "250000"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.timeout.0.per_request.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), + ), + }, + { + Config: testAccAwsAppmeshRouteConfig_http2RouteWithTimeoutUpdated(meshName, vrName, vn1Name, vn2Name, rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshRouteExists(resourceName, &r), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.action.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.action.0.weighted_target.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.match.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.match.0.header.#", "1"), + tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.http2_route.0.match.0.header.*", map[string]string{ + "invert": "false", + "match.#": "0", + "name": "X-Testing1", + }), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.match.0.method", "POST"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.match.0.prefix", "/"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.match.0.scheme", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.retry_policy.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.timeout.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.timeout.0.idle.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.timeout.0.idle.0.unit", "s"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.timeout.0.idle.0.value", "10"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.timeout.0.per_request.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.timeout.0.per_request.0.unit", "s"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.0.timeout.0.per_request.0.value", "5"), resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), @@ -513,6 +613,7 @@ func testAccAwsAppmeshRoute_httpRoute(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.prefix", "/"), resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.scheme", ""), resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.retry_policy.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.priority", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), @@ -542,6 +643,7 @@ func testAccAwsAppmeshRoute_httpRoute(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.prefix", "/path"), resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.scheme", ""), resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.retry_policy.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.priority", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), @@ -568,10 +670,101 @@ func testAccAwsAppmeshRoute_httpRoute(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.method", ""), resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.prefix", "/path"), resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.scheme", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.priority", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), + ), + }, + { + ResourceName: resourceName, + ImportStateIdFunc: testAccAwsAppmeshRouteImportStateIdFunc(resourceName), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAwsAppmeshRoute_httpRouteTimeout(t *testing.T) { + var r appmesh.RouteData + resourceName := "aws_appmesh_route.test" + meshName := acctest.RandomWithPrefix("tf-acc-test") + vrName := acctest.RandomWithPrefix("tf-acc-test") + vn1Name := acctest.RandomWithPrefix("tf-acc-test") + vn2Name := acctest.RandomWithPrefix("tf-acc-test") + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAppmeshRouteDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAppmeshRouteConfig_httpRouteWithTimeout(meshName, vrName, vn1Name, vn2Name, rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshRouteExists(resourceName, &r), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.action.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.action.0.weighted_target.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.header.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.method", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.prefix", "/"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.scheme", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.retry_policy.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.0.idle.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.0.idle.0.unit", "ms"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.0.idle.0.value", "250000"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.0.per_request.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.priority", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), + ), + }, + { + Config: testAccAppmeshRouteConfig_httpRouteWithTimeoutUpdated(meshName, vrName, vn1Name, vn2Name, rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshRouteExists(resourceName, &r), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http2_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.action.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.action.0.weighted_target.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.header.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.method", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.prefix", "/"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.match.0.scheme", ""), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.retry_policy.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.0.idle.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.0.idle.0.unit", "s"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.0.idle.0.value", "10"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.0.per_request.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.0.per_request.0.unit", "s"), + resource.TestCheckResourceAttr(resourceName, "spec.0.http_route.0.timeout.0.per_request.0.value", "5"), + resource.TestCheckResourceAttr(resourceName, "spec.0.priority", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), ), @@ -678,7 +871,7 @@ func testAccAwsAppmeshRoute_tcpRoute(t *testing.T) { }) } -func testAccAwsAppmeshRoute_tcpRoute_timeout(t *testing.T) { +func testAccAwsAppmeshRoute_tcpRouteTimeout(t *testing.T) { var r appmesh.RouteData resourceName := "aws_appmesh_route.test" meshName := acctest.RandomWithPrefix("tf-acc-test") @@ -1778,6 +1971,18 @@ resource "aws_appmesh_route" "test" { weight = 100 } } + + timeout { + idle { + unit = "s" + value = 10 + } + + per_request { + unit = "s" + value = 5 + } + } } } } @@ -1844,6 +2049,75 @@ resource "aws_appmesh_route" "test" { `, rName)) } +func testAccAppmeshRouteConfig_httpRouteWithTimeout(meshName, vrName, vn1Name, vn2Name, rName string) string { + return testAccAppmeshRouteConfigBase(meshName, vrName, "http", vn1Name, vn2Name) + fmt.Sprintf(` +resource "aws_appmesh_route" "test" { + name = %[1]q + mesh_name = aws_appmesh_mesh.test.id + virtual_router_name = aws_appmesh_virtual_router.test.name + + spec { + http_route { + match { + prefix = "/" + } + + action { + weighted_target { + virtual_node = aws_appmesh_virtual_node.foo.name + weight = 100 + } + } + + timeout { + idle { + unit = "ms" + value = 250000 + } + } + } + } +} +`, rName) +} + +func testAccAppmeshRouteConfig_httpRouteWithTimeoutUpdated(meshName, vrName, vn1Name, vn2Name, rName string) string { + return testAccAppmeshRouteConfigBase(meshName, vrName, "http", vn1Name, vn2Name) + fmt.Sprintf(` +resource "aws_appmesh_route" "test" { + name = %[1]q + mesh_name = aws_appmesh_mesh.test.id + virtual_router_name = aws_appmesh_virtual_router.test.name + + spec { + http_route { + match { + prefix = "/" + } + + action { + weighted_target { + virtual_node = aws_appmesh_virtual_node.foo.name + weight = 100 + } + } + + timeout { + idle { + unit = "s" + value = 10 + } + + per_request { + unit = "s" + value = 5 + } + } + } + } +} +`, rName) +} + func testAccAppmeshRouteConfig_tcpRoute(meshName, vrName, vn1Name, vn2Name, rName string) string { return composeConfig(testAccAppmeshRouteConfigBase(meshName, vrName, "tcp", vn1Name, vn2Name), fmt.Sprintf(` resource "aws_appmesh_route" "test" { diff --git a/aws/resource_aws_appmesh_test.go b/aws/resource_aws_appmesh_test.go index 812b9a54ba85..aa865abcafe2 100644 --- a/aws/resource_aws_appmesh_test.go +++ b/aws/resource_aws_appmesh_test.go @@ -12,16 +12,18 @@ func TestAccAWSAppmesh_serial(t *testing.T) { "tags": testAccAwsAppmeshMesh_tags, }, "Route": { - "grpcRoute": testAccAwsAppmeshRoute_grpcRoute, - "grpcRouteTimeout": testAccAwsAppmeshRoute_grpcRoute_timeout, - "http2Route": testAccAwsAppmeshRoute_http2Route, - "httpHeader": testAccAwsAppmeshRoute_httpHeader, - "httpRetryPolicy": testAccAwsAppmeshRoute_httpRetryPolicy, - "httpRoute": testAccAwsAppmeshRoute_httpRoute, - "routePriority": testAccAwsAppmeshRoute_routePriority, - "tcpRoute": testAccAwsAppmeshRoute_tcpRoute, - "tcpRouteTimeout": testAccAwsAppmeshRoute_tcpRoute_timeout, - "tags": testAccAwsAppmeshRoute_tags, + "grpcRoute": testAccAwsAppmeshRoute_grpcRoute, + "grpcRouteTimeout": testAccAwsAppmeshRoute_grpcRouteTimeout, + "http2Route": testAccAwsAppmeshRoute_http2Route, + "http2RouteTimeout": testAccAwsAppmeshRoute_http2RouteTimeout, + "httpHeader": testAccAwsAppmeshRoute_httpHeader, + "httpRetryPolicy": testAccAwsAppmeshRoute_httpRetryPolicy, + "httpRoute": testAccAwsAppmeshRoute_httpRoute, + "httpRouteTimeout": testAccAwsAppmeshRoute_httpRouteTimeout, + "routePriority": testAccAwsAppmeshRoute_routePriority, + "tcpRoute": testAccAwsAppmeshRoute_tcpRoute, + "tcpRouteTimeout": testAccAwsAppmeshRoute_tcpRouteTimeout, + "tags": testAccAwsAppmeshRoute_tags, }, "VirtualNode": { "basic": testAccAwsAppmeshVirtualNode_basic, diff --git a/aws/structure.go b/aws/structure.go index f4b2b10749c2..bd834bd1a022 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -5724,6 +5724,44 @@ func expandAppmeshHttpRoute(vHttpRoute []interface{}) *appmesh.HttpRoute { httpRoute.RetryPolicy = httpRetryPolicy } + if vHttpTimeout, ok := mHttpRoute["timeout"].([]interface{}); ok && len(vHttpTimeout) > 0 && vHttpTimeout[0] != nil { + httpTimeout := &appmesh.HttpTimeout{} + + mHttpTimeout := vHttpTimeout[0].(map[string]interface{}) + + if vIdleTimeout, ok := mHttpTimeout["idle"].([]interface{}); ok && len(vIdleTimeout) > 0 && vIdleTimeout[0] != nil { + idleTimeout := &appmesh.Duration{} + + mIdleTimeout := vIdleTimeout[0].(map[string]interface{}) + + if vUnit, ok := mIdleTimeout["unit"].(string); ok && vUnit != "" { + idleTimeout.Unit = aws.String(vUnit) + } + if vValue, ok := mIdleTimeout["value"].(int); ok && vValue > 0 { + idleTimeout.Value = aws.Int64(int64(vValue)) + } + + httpTimeout.Idle = idleTimeout + } + + if vPerRequestTimeout, ok := mHttpTimeout["per_request"].([]interface{}); ok && len(vPerRequestTimeout) > 0 && vPerRequestTimeout[0] != nil { + perRequestTimeout := &appmesh.Duration{} + + mPerRequestTimeout := vPerRequestTimeout[0].(map[string]interface{}) + + if vUnit, ok := mPerRequestTimeout["unit"].(string); ok && vUnit != "" { + perRequestTimeout.Unit = aws.String(vUnit) + } + if vValue, ok := mPerRequestTimeout["value"].(int); ok && vValue > 0 { + perRequestTimeout.Value = aws.Int64(int64(vValue)) + } + + httpTimeout.PerRequest = perRequestTimeout + } + + httpRoute.Timeout = httpTimeout + } + return httpRoute } @@ -6010,6 +6048,30 @@ func flattenAppmeshHttpRoute(httpRoute *appmesh.HttpRoute) []interface{} { mHttpRoute["retry_policy"] = []interface{}{mHttpRetryPolicy} } + if httpTimeout := httpRoute.Timeout; httpTimeout != nil { + mHttpTimeout := map[string]interface{}{} + + if idleTimeout := httpTimeout.Idle; idleTimeout != nil { + mIdleTimeout := map[string]interface{}{ + "unit": aws.StringValue(idleTimeout.Unit), + "value": int(aws.Int64Value(idleTimeout.Value)), + } + + mHttpTimeout["idle"] = []interface{}{mIdleTimeout} + } + + if perRequestTimeout := httpTimeout.PerRequest; perRequestTimeout != nil { + mPerRequestTimeout := map[string]interface{}{ + "unit": aws.StringValue(perRequestTimeout.Unit), + "value": int(aws.Int64Value(perRequestTimeout.Value)), + } + + mHttpTimeout["per_request"] = []interface{}{mPerRequestTimeout} + } + + mHttpRoute["timeout"] = []interface{}{mHttpTimeout} + } + return []interface{}{mHttpRoute} } diff --git a/website/docs/r/appmesh_route.html.markdown b/website/docs/r/appmesh_route.html.markdown index b93a27966378..5f851a8a60bc 100644 --- a/website/docs/r/appmesh_route.html.markdown +++ b/website/docs/r/appmesh_route.html.markdown @@ -204,6 +204,7 @@ The `http2_route` and `http_route` objects supports the following: * `action` - (Required) The action to take if a match is determined. * `match` - (Required) The criteria for determining an HTTP request match. * `retry_policy` - (Optional) The retry policy. +* `timeout` - (Optional) The types of timeouts. The `tcp_route` object supports the following: @@ -282,6 +283,16 @@ Valid values: `client-error` (HTTP status code 409), `gateway-error` (HTTP statu You must specify at least one value for `http_retry_events`, or at least one value for `tcp_retry_events`. +The `http2_route` and `http_route`'s `timeout` object supports the following: + +* `idle` - (Optional) The idle timeout. An idle timeout bounds the amount of time that a connection may be idle. +* `per_request` - (Optional) The per request timeout. + +The `idle` and `per_request` objects support the following: + +* `unit` - (Required) The unit of time. Valid values: `ms`, `s`. +* `value` - (Required) The number of time units. Minimum value of `0`. + The `per_retry_timeout` object supports the following: * `unit` - (Required) Retry unit. Valid values: `ms`, `s`. From 9f3a7c54960935ecac9aa48ccd6258d43601a78a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 29 Jul 2020 17:05:03 -0400 Subject: [PATCH 09/17] r/aws_appmesh_route: Fix HTTP and HTTP2 route timeout acceptance tests. Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/Route/httpRoute' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/Route/httpRoute -timeout 120m === RUN TestAccAWSAppmesh_serial === RUN TestAccAWSAppmesh_serial/Route === RUN TestAccAWSAppmesh_serial/Route/httpRouteTimeout === RUN TestAccAWSAppmesh_serial/Route/httpRoute === RUN TestAccAWSAppmesh_serial/VirtualRouter --- PASS: TestAccAWSAppmesh_serial (66.64s) --- PASS: TestAccAWSAppmesh_serial/Route (66.64s) --- PASS: TestAccAWSAppmesh_serial/Route/httpRouteTimeout (27.84s) --- PASS: TestAccAWSAppmesh_serial/Route/httpRoute (38.80s) --- PASS: TestAccAWSAppmesh_serial/VirtualRouter (0.00s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 66.726s $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/Route/http2Route' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/Route/http2Route -timeout 120m === RUN TestAccAWSAppmesh_serial === RUN TestAccAWSAppmesh_serial/Route === RUN TestAccAWSAppmesh_serial/Route/http2RouteTimeout === RUN TestAccAWSAppmesh_serial/Route/http2Route === RUN TestAccAWSAppmesh_serial/VirtualRouter --- PASS: TestAccAWSAppmesh_serial (56.66s) --- PASS: TestAccAWSAppmesh_serial/Route (56.65s) --- PASS: TestAccAWSAppmesh_serial/Route/http2RouteTimeout (28.57s) --- PASS: TestAccAWSAppmesh_serial/Route/http2Route (28.08s) --- PASS: TestAccAWSAppmesh_serial/VirtualRouter (0.00s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 56.732s --- aws/resource_aws_appmesh_route_test.go | 28 +++++++++++----------- website/docs/r/appmesh_route.html.markdown | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/aws/resource_aws_appmesh_route_test.go b/aws/resource_aws_appmesh_route_test.go index a0e26af51b1e..83baf7270780 100644 --- a/aws/resource_aws_appmesh_route_test.go +++ b/aws/resource_aws_appmesh_route_test.go @@ -1581,8 +1581,13 @@ resource "aws_appmesh_route" "test" { timeout { idle { - unit = "ms" - value = 250000 + unit = "s" + value = 10 + } + + per_request { + unit = "s" + value = 5 } } } @@ -1730,6 +1735,13 @@ resource "aws_appmesh_route" "test" { weight = 100 } } + + timeout { + idle { + unit = "ms" + value = 250000 + } + } } } } @@ -1971,18 +1983,6 @@ resource "aws_appmesh_route" "test" { weight = 100 } } - - timeout { - idle { - unit = "s" - value = 10 - } - - per_request { - unit = "s" - value = 5 - } - } } } } diff --git a/website/docs/r/appmesh_route.html.markdown b/website/docs/r/appmesh_route.html.markdown index 5f851a8a60bc..98613d2c0185 100644 --- a/website/docs/r/appmesh_route.html.markdown +++ b/website/docs/r/appmesh_route.html.markdown @@ -257,8 +257,8 @@ Valid values: `client-error` (HTTP status code 409), `gateway-error` (HTTP statu The `grpc_route`'s `timeout` object supports the following: -* `idle` - (Optional) The idle timeout. An idle timeout bounds the amount of time that a connection may be idle. The default value is none. -* `per_request` - (Optional) The per request timeout. The default value is 15 seconds. +* `idle` - (Optional) The idle timeout. An idle timeout bounds the amount of time that a connection may be idle. +* `per_request` - (Optional) The per request timeout. The `idle` and `per_request` objects support the following: From e0c7d66f1aab34ab8626cc82af27239e44f5c7a4 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 29 Jul 2020 17:30:36 -0400 Subject: [PATCH 10/17] r/aws_appmesh_route: Refactor timeout serde functions. Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/Route' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/Route -timeout 120m === RUN TestAccAWSAppmesh_serial === RUN TestAccAWSAppmesh_serial/Route === RUN TestAccAWSAppmesh_serial/Route/grpcRoute === RUN TestAccAWSAppmesh_serial/Route/grpcRouteTimeout === RUN TestAccAWSAppmesh_serial/Route/http2RouteTimeout === RUN TestAccAWSAppmesh_serial/Route/httpHeader === RUN TestAccAWSAppmesh_serial/Route/httpRoute === RUN TestAccAWSAppmesh_serial/Route/httpRouteTimeout === RUN TestAccAWSAppmesh_serial/Route/tcpRouteTimeout === RUN TestAccAWSAppmesh_serial/Route/tags === RUN TestAccAWSAppmesh_serial/Route/http2Route === RUN TestAccAWSAppmesh_serial/Route/httpRetryPolicy === RUN TestAccAWSAppmesh_serial/Route/routePriority === RUN TestAccAWSAppmesh_serial/Route/tcpRoute === RUN TestAccAWSAppmesh_serial/VirtualRouter === RUN TestAccAWSAppmesh_serial/VirtualRouter/basic === RUN TestAccAWSAppmesh_serial/VirtualRouter/tags --- PASS: TestAccAWSAppmesh_serial (433.25s) --- PASS: TestAccAWSAppmesh_serial/Route (379.45s) --- PASS: TestAccAWSAppmesh_serial/Route/grpcRoute (38.84s) --- PASS: TestAccAWSAppmesh_serial/Route/grpcRouteTimeout (27.86s) --- PASS: TestAccAWSAppmesh_serial/Route/http2RouteTimeout (27.77s) --- PASS: TestAccAWSAppmesh_serial/Route/httpHeader (28.29s) --- PASS: TestAccAWSAppmesh_serial/Route/httpRoute (38.87s) --- PASS: TestAccAWSAppmesh_serial/Route/httpRouteTimeout (28.38s) --- PASS: TestAccAWSAppmesh_serial/Route/tcpRouteTimeout (27.92s) --- PASS: TestAccAWSAppmesh_serial/Route/tags (39.58s) --- PASS: TestAccAWSAppmesh_serial/Route/http2Route (27.67s) --- PASS: TestAccAWSAppmesh_serial/Route/httpRetryPolicy (28.10s) --- PASS: TestAccAWSAppmesh_serial/Route/routePriority (27.74s) --- PASS: TestAccAWSAppmesh_serial/Route/tcpRoute (38.42s) --- PASS: TestAccAWSAppmesh_serial/VirtualRouter (53.80s) --- PASS: TestAccAWSAppmesh_serial/VirtualRouter/basic (22.61s) --- PASS: TestAccAWSAppmesh_serial/VirtualRouter/tags (31.19s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 433.309s --- aws/structure.go | 256 +++++++++++++++++++++++++++-------------------- 1 file changed, 149 insertions(+), 107 deletions(-) diff --git a/aws/structure.go b/aws/structure.go index bd834bd1a022..7454c677ba10 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -5532,45 +5532,53 @@ func expandAppmeshGrpcRoute(vGrpcRoute []interface{}) *appmesh.GrpcRoute { grpcRoute.RetryPolicy = grpcRetryPolicy } - if vGrpcTimeout, ok := mGrpcRoute["timeout"].([]interface{}); ok && len(vGrpcTimeout) > 0 && vGrpcTimeout[0] != nil { - grpcTimeout := &appmesh.GrpcTimeout{} + if vGrpcTimeout, ok := mGrpcRoute["timeout"].([]interface{}); ok { + grpcRoute.Timeout = expandAppmeshGrpcTimeout(vGrpcTimeout) + } - mGrpcTimeout := vGrpcTimeout[0].(map[string]interface{}) + return grpcRoute +} - if vIdleTimeout, ok := mGrpcTimeout["idle"].([]interface{}); ok && len(vIdleTimeout) > 0 && vIdleTimeout[0] != nil { - idleTimeout := &appmesh.Duration{} +func expandAppmeshGrpcTimeout(vGrpcTimeout []interface{}) *appmesh.GrpcTimeout { + if len(vGrpcTimeout) == 0 || vGrpcTimeout[0] == nil { + return nil + } - mIdleTimeout := vIdleTimeout[0].(map[string]interface{}) + grpcTimeout := &appmesh.GrpcTimeout{} - if vUnit, ok := mIdleTimeout["unit"].(string); ok && vUnit != "" { - idleTimeout.Unit = aws.String(vUnit) - } - if vValue, ok := mIdleTimeout["value"].(int); ok && vValue > 0 { - idleTimeout.Value = aws.Int64(int64(vValue)) - } + mGrpcTimeout := vGrpcTimeout[0].(map[string]interface{}) + + if vIdleTimeout, ok := mGrpcTimeout["idle"].([]interface{}); ok && len(vIdleTimeout) > 0 && vIdleTimeout[0] != nil { + idleTimeout := &appmesh.Duration{} + + mIdleTimeout := vIdleTimeout[0].(map[string]interface{}) - grpcTimeout.Idle = idleTimeout + if vUnit, ok := mIdleTimeout["unit"].(string); ok && vUnit != "" { + idleTimeout.Unit = aws.String(vUnit) + } + if vValue, ok := mIdleTimeout["value"].(int); ok && vValue > 0 { + idleTimeout.Value = aws.Int64(int64(vValue)) } - if vPerRequestTimeout, ok := mGrpcTimeout["per_request"].([]interface{}); ok && len(vPerRequestTimeout) > 0 && vPerRequestTimeout[0] != nil { - perRequestTimeout := &appmesh.Duration{} + grpcTimeout.Idle = idleTimeout + } - mPerRequestTimeout := vPerRequestTimeout[0].(map[string]interface{}) + if vPerRequestTimeout, ok := mGrpcTimeout["per_request"].([]interface{}); ok && len(vPerRequestTimeout) > 0 && vPerRequestTimeout[0] != nil { + perRequestTimeout := &appmesh.Duration{} - if vUnit, ok := mPerRequestTimeout["unit"].(string); ok && vUnit != "" { - perRequestTimeout.Unit = aws.String(vUnit) - } - if vValue, ok := mPerRequestTimeout["value"].(int); ok && vValue > 0 { - perRequestTimeout.Value = aws.Int64(int64(vValue)) - } + mPerRequestTimeout := vPerRequestTimeout[0].(map[string]interface{}) - grpcTimeout.PerRequest = perRequestTimeout + if vUnit, ok := mPerRequestTimeout["unit"].(string); ok && vUnit != "" { + perRequestTimeout.Unit = aws.String(vUnit) + } + if vValue, ok := mPerRequestTimeout["value"].(int); ok && vValue > 0 { + perRequestTimeout.Value = aws.Int64(int64(vValue)) } - grpcRoute.Timeout = grpcTimeout + grpcTimeout.PerRequest = perRequestTimeout } - return grpcRoute + return grpcTimeout } func expandAppmeshHttpRoute(vHttpRoute []interface{}) *appmesh.HttpRoute { @@ -5724,45 +5732,53 @@ func expandAppmeshHttpRoute(vHttpRoute []interface{}) *appmesh.HttpRoute { httpRoute.RetryPolicy = httpRetryPolicy } - if vHttpTimeout, ok := mHttpRoute["timeout"].([]interface{}); ok && len(vHttpTimeout) > 0 && vHttpTimeout[0] != nil { - httpTimeout := &appmesh.HttpTimeout{} + if vHttpTimeout, ok := mHttpRoute["timeout"].([]interface{}); ok { + httpRoute.Timeout = expandAppmeshHttpTimeout(vHttpTimeout) + } - mHttpTimeout := vHttpTimeout[0].(map[string]interface{}) + return httpRoute +} - if vIdleTimeout, ok := mHttpTimeout["idle"].([]interface{}); ok && len(vIdleTimeout) > 0 && vIdleTimeout[0] != nil { - idleTimeout := &appmesh.Duration{} +func expandAppmeshHttpTimeout(vHttpTimeout []interface{}) *appmesh.HttpTimeout { + if len(vHttpTimeout) == 0 || vHttpTimeout[0] == nil { + return nil + } - mIdleTimeout := vIdleTimeout[0].(map[string]interface{}) + httpTimeout := &appmesh.HttpTimeout{} - if vUnit, ok := mIdleTimeout["unit"].(string); ok && vUnit != "" { - idleTimeout.Unit = aws.String(vUnit) - } - if vValue, ok := mIdleTimeout["value"].(int); ok && vValue > 0 { - idleTimeout.Value = aws.Int64(int64(vValue)) - } + mHttpTimeout := vHttpTimeout[0].(map[string]interface{}) + + if vIdleTimeout, ok := mHttpTimeout["idle"].([]interface{}); ok && len(vIdleTimeout) > 0 && vIdleTimeout[0] != nil { + idleTimeout := &appmesh.Duration{} - httpTimeout.Idle = idleTimeout + mIdleTimeout := vIdleTimeout[0].(map[string]interface{}) + + if vUnit, ok := mIdleTimeout["unit"].(string); ok && vUnit != "" { + idleTimeout.Unit = aws.String(vUnit) + } + if vValue, ok := mIdleTimeout["value"].(int); ok && vValue > 0 { + idleTimeout.Value = aws.Int64(int64(vValue)) } - if vPerRequestTimeout, ok := mHttpTimeout["per_request"].([]interface{}); ok && len(vPerRequestTimeout) > 0 && vPerRequestTimeout[0] != nil { - perRequestTimeout := &appmesh.Duration{} + httpTimeout.Idle = idleTimeout + } - mPerRequestTimeout := vPerRequestTimeout[0].(map[string]interface{}) + if vPerRequestTimeout, ok := mHttpTimeout["per_request"].([]interface{}); ok && len(vPerRequestTimeout) > 0 && vPerRequestTimeout[0] != nil { + perRequestTimeout := &appmesh.Duration{} - if vUnit, ok := mPerRequestTimeout["unit"].(string); ok && vUnit != "" { - perRequestTimeout.Unit = aws.String(vUnit) - } - if vValue, ok := mPerRequestTimeout["value"].(int); ok && vValue > 0 { - perRequestTimeout.Value = aws.Int64(int64(vValue)) - } + mPerRequestTimeout := vPerRequestTimeout[0].(map[string]interface{}) - httpTimeout.PerRequest = perRequestTimeout + if vUnit, ok := mPerRequestTimeout["unit"].(string); ok && vUnit != "" { + perRequestTimeout.Unit = aws.String(vUnit) + } + if vValue, ok := mPerRequestTimeout["value"].(int); ok && vValue > 0 { + perRequestTimeout.Value = aws.Int64(int64(vValue)) } - httpRoute.Timeout = httpTimeout + httpTimeout.PerRequest = perRequestTimeout } - return httpRoute + return httpTimeout } func expandAppmeshTcpRoute(vTcpRoute []interface{}) *appmesh.TcpRoute { @@ -5801,30 +5817,38 @@ func expandAppmeshTcpRoute(vTcpRoute []interface{}) *appmesh.TcpRoute { } } - if vTcpTimeout, ok := mTcpRoute["timeout"].([]interface{}); ok && len(vTcpTimeout) > 0 && vTcpTimeout[0] != nil { - tcpTimeout := &appmesh.TcpTimeout{} + if vTcpTimeout, ok := mTcpRoute["timeout"].([]interface{}); ok { + tcpRoute.Timeout = expandAppmeshTcpTimeout(vTcpTimeout) + } - mTcpTimeout := vTcpTimeout[0].(map[string]interface{}) + return tcpRoute +} - if vIdleTimeout, ok := mTcpTimeout["idle"].([]interface{}); ok && len(vIdleTimeout) > 0 && vIdleTimeout[0] != nil { - idleTimeout := &appmesh.Duration{} +func expandAppmeshTcpTimeout(vTcpTimeout []interface{}) *appmesh.TcpTimeout { + if len(vTcpTimeout) == 0 || vTcpTimeout[0] == nil { + return nil + } - mIdleTimeout := vIdleTimeout[0].(map[string]interface{}) + tcpTimeout := &appmesh.TcpTimeout{} - if vUnit, ok := mIdleTimeout["unit"].(string); ok && vUnit != "" { - idleTimeout.Unit = aws.String(vUnit) - } - if vValue, ok := mIdleTimeout["value"].(int); ok && vValue > 0 { - idleTimeout.Value = aws.Int64(int64(vValue)) - } + mTcpTimeout := vTcpTimeout[0].(map[string]interface{}) + + if vIdleTimeout, ok := mTcpTimeout["idle"].([]interface{}); ok && len(vIdleTimeout) > 0 && vIdleTimeout[0] != nil { + idleTimeout := &appmesh.Duration{} - tcpTimeout.Idle = idleTimeout + mIdleTimeout := vIdleTimeout[0].(map[string]interface{}) + + if vUnit, ok := mIdleTimeout["unit"].(string); ok && vUnit != "" { + idleTimeout.Unit = aws.String(vUnit) + } + if vValue, ok := mIdleTimeout["value"].(int); ok && vValue > 0 { + idleTimeout.Value = aws.Int64(int64(vValue)) } - tcpRoute.Timeout = tcpTimeout + tcpTimeout.Idle = idleTimeout } - return tcpRoute + return tcpTimeout } func flattenAppmeshRouteSpec(spec *appmesh.RouteSpec) []interface{} { @@ -5932,31 +5956,37 @@ func flattenAppmeshGrpcRoute(grpcRoute *appmesh.GrpcRoute) []interface{} { mGrpcRoute["retry_policy"] = []interface{}{mGrpcRetryPolicy} } - if grpcTimeout := grpcRoute.Timeout; grpcTimeout != nil { - mGrpcTimeout := map[string]interface{}{} + mGrpcRoute["timeout"] = flattenAppmeshGrpcTimeout(grpcRoute.Timeout) - if idleTimeout := grpcTimeout.Idle; idleTimeout != nil { - mIdleTimeout := map[string]interface{}{ - "unit": aws.StringValue(idleTimeout.Unit), - "value": int(aws.Int64Value(idleTimeout.Value)), - } + return []interface{}{mGrpcRoute} +} - mGrpcTimeout["idle"] = []interface{}{mIdleTimeout} +func flattenAppmeshGrpcTimeout(grpcTimeout *appmesh.GrpcTimeout) []interface{} { + if grpcTimeout == nil { + return []interface{}{} + } + + mGrpcTimeout := map[string]interface{}{} + + if idleTimeout := grpcTimeout.Idle; idleTimeout != nil { + mIdleTimeout := map[string]interface{}{ + "unit": aws.StringValue(idleTimeout.Unit), + "value": int(aws.Int64Value(idleTimeout.Value)), } - if perRequestTimeout := grpcTimeout.PerRequest; perRequestTimeout != nil { - mPerRequestTimeout := map[string]interface{}{ - "unit": aws.StringValue(perRequestTimeout.Unit), - "value": int(aws.Int64Value(perRequestTimeout.Value)), - } + mGrpcTimeout["idle"] = []interface{}{mIdleTimeout} + } - mGrpcTimeout["per_request"] = []interface{}{mPerRequestTimeout} + if perRequestTimeout := grpcTimeout.PerRequest; perRequestTimeout != nil { + mPerRequestTimeout := map[string]interface{}{ + "unit": aws.StringValue(perRequestTimeout.Unit), + "value": int(aws.Int64Value(perRequestTimeout.Value)), } - mGrpcRoute["timeout"] = []interface{}{mGrpcTimeout} + mGrpcTimeout["per_request"] = []interface{}{mPerRequestTimeout} } - return []interface{}{mGrpcRoute} + return []interface{}{mGrpcTimeout} } func flattenAppmeshHttpRoute(httpRoute *appmesh.HttpRoute) []interface{} { @@ -6048,31 +6078,37 @@ func flattenAppmeshHttpRoute(httpRoute *appmesh.HttpRoute) []interface{} { mHttpRoute["retry_policy"] = []interface{}{mHttpRetryPolicy} } - if httpTimeout := httpRoute.Timeout; httpTimeout != nil { - mHttpTimeout := map[string]interface{}{} + mHttpRoute["timeout"] = flattenAppmeshHttpTimeout(httpRoute.Timeout) - if idleTimeout := httpTimeout.Idle; idleTimeout != nil { - mIdleTimeout := map[string]interface{}{ - "unit": aws.StringValue(idleTimeout.Unit), - "value": int(aws.Int64Value(idleTimeout.Value)), - } + return []interface{}{mHttpRoute} +} + +func flattenAppmeshHttpTimeout(httpTimeout *appmesh.HttpTimeout) []interface{} { + if httpTimeout == nil { + return []interface{}{} + } - mHttpTimeout["idle"] = []interface{}{mIdleTimeout} + mHttpTimeout := map[string]interface{}{} + + if idleTimeout := httpTimeout.Idle; idleTimeout != nil { + mIdleTimeout := map[string]interface{}{ + "unit": aws.StringValue(idleTimeout.Unit), + "value": int(aws.Int64Value(idleTimeout.Value)), } - if perRequestTimeout := httpTimeout.PerRequest; perRequestTimeout != nil { - mPerRequestTimeout := map[string]interface{}{ - "unit": aws.StringValue(perRequestTimeout.Unit), - "value": int(aws.Int64Value(perRequestTimeout.Value)), - } + mHttpTimeout["idle"] = []interface{}{mIdleTimeout} + } - mHttpTimeout["per_request"] = []interface{}{mPerRequestTimeout} + if perRequestTimeout := httpTimeout.PerRequest; perRequestTimeout != nil { + mPerRequestTimeout := map[string]interface{}{ + "unit": aws.StringValue(perRequestTimeout.Unit), + "value": int(aws.Int64Value(perRequestTimeout.Value)), } - mHttpRoute["timeout"] = []interface{}{mHttpTimeout} + mHttpTimeout["per_request"] = []interface{}{mPerRequestTimeout} } - return []interface{}{mHttpRoute} + return []interface{}{mHttpTimeout} } func flattenAppmeshTcpRoute(tcpRoute *appmesh.TcpRoute) []interface{} { @@ -6103,22 +6139,28 @@ func flattenAppmeshTcpRoute(tcpRoute *appmesh.TcpRoute) []interface{} { } } - if tcpTimeout := tcpRoute.Timeout; tcpTimeout != nil { - mTcpTimeout := map[string]interface{}{} + mTcpRoute["timeout"] = flattenAppmeshTcpTimeout(tcpRoute.Timeout) - if idleTimeout := tcpTimeout.Idle; idleTimeout != nil { - mIdleTimeout := map[string]interface{}{ - "unit": aws.StringValue(idleTimeout.Unit), - "value": int(aws.Int64Value(idleTimeout.Value)), - } + return []interface{}{mTcpRoute} +} + +func flattenAppmeshTcpTimeout(tcpTimeout *appmesh.TcpTimeout) []interface{} { + if tcpTimeout == nil { + return []interface{}{} + } - mTcpTimeout["idle"] = []interface{}{mIdleTimeout} + mTcpTimeout := map[string]interface{}{} + + if idleTimeout := tcpTimeout.Idle; idleTimeout != nil { + mIdleTimeout := map[string]interface{}{ + "unit": aws.StringValue(idleTimeout.Unit), + "value": int(aws.Int64Value(idleTimeout.Value)), } - mTcpRoute["timeout"] = []interface{}{mTcpTimeout} + mTcpTimeout["idle"] = []interface{}{mIdleTimeout} } - return []interface{}{mTcpRoute} + return []interface{}{mTcpTimeout} } func expandRoute53ResolverEndpointIpAddresses(vIpAddresses *schema.Set) []*route53resolver.IpAddressRequest { From b5ee36685b1025cbac368a2f653a689f0b9cf90a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 29 Jul 2020 18:37:05 -0400 Subject: [PATCH 11/17] r/aws_appmesh_virtual_node: Add timeout configuration support. Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/VirtualNode' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/VirtualNode -timeout 120m === RUN TestAccAWSAppmesh_serial === RUN TestAccAWSAppmesh_serial/VirtualNode === RUN TestAccAWSAppmesh_serial/VirtualNode/cloudMapServiceDiscovery === RUN TestAccAWSAppmesh_serial/VirtualNode/listenerHealthChecks === RUN TestAccAWSAppmesh_serial/VirtualNode/logging === RUN TestAccAWSAppmesh_serial/VirtualNode/tags === RUN TestAccAWSAppmesh_serial/VirtualNode/basic --- PASS: TestAccAWSAppmesh_serial (191.43s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode (191.43s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode/cloudMapServiceDiscovery (96.36s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode/listenerHealthChecks (24.56s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode/logging (23.12s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode/tags (32.95s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode/basic (14.41s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 191.496s --- aws/resource_aws_appmesh_virtual_node.go | 197 ++++++++++++++++++ aws/resource_aws_appmesh_virtual_node_test.go | 2 + aws/structure.go | 34 +++ .../docs/r/appmesh_virtual_node.html.markdown | 37 ++++ 4 files changed, 270 insertions(+) diff --git a/aws/resource_aws_appmesh_virtual_node.go b/aws/resource_aws_appmesh_virtual_node.go index 81e3c8ff5561..db86d4a1a5ff 100644 --- a/aws/resource_aws_appmesh_virtual_node.go +++ b/aws/resource_aws_appmesh_virtual_node.go @@ -177,6 +177,203 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource { }, }, + "timeout": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "grpc": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "idle": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unit": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(appmesh.DurationUnit_Values(), false), + }, + + "value": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + + "per_request": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unit": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(appmesh.DurationUnit_Values(), false), + }, + + "value": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + }, + }, + }, + + "http": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "idle": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unit": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(appmesh.DurationUnit_Values(), false), + }, + + "value": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + + "per_request": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unit": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(appmesh.DurationUnit_Values(), false), + }, + + "value": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + }, + }, + }, + + "http2": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "idle": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unit": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(appmesh.DurationUnit_Values(), false), + }, + + "value": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + + "per_request": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unit": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(appmesh.DurationUnit_Values(), false), + }, + + "value": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + }, + }, + }, + + "tcp": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "idle": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unit": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(appmesh.DurationUnit_Values(), false), + }, + + "value": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "tls": { Type: schema.TypeList, Optional: true, diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index 83a1fcc8774f..9a4a40c564f3 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -220,6 +220,7 @@ func testAccAwsAppmeshVirtualNode_listenerHealthChecks(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.port", "8080"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.protocol", "grpc"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), @@ -262,6 +263,7 @@ func testAccAwsAppmeshVirtualNode_listenerHealthChecks(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.port", "8081"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), diff --git a/aws/structure.go b/aws/structure.go index 7454c677ba10..9b2b9cc8f04f 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -4887,6 +4887,30 @@ func expandAppmeshVirtualNodeSpec(vSpec []interface{}) *appmesh.VirtualNodeSpec listener.Tls = tls } + if vTimeout, ok := mListener["timeout"].([]interface{}); ok && len(vTimeout) > 0 && vTimeout[0] != nil { + mTimeout := vTimeout[0].(map[string]interface{}) + + listenerTimeout := &appmesh.ListenerTimeout{} + + if vGrpcTimeout, ok := mTimeout["grpc"].([]interface{}); ok { + listenerTimeout.Grpc = expandAppmeshGrpcTimeout(vGrpcTimeout) + } + + if vHttpTimeout, ok := mTimeout["http"].([]interface{}); ok { + listenerTimeout.Http = expandAppmeshHttpTimeout(vHttpTimeout) + } + + if vHttp2Timeout, ok := mTimeout["http2"].([]interface{}); ok { + listenerTimeout.Http2 = expandAppmeshHttpTimeout(vHttp2Timeout) + } + + if vTcpTimeout, ok := mTimeout["tcp"].([]interface{}); ok { + listenerTimeout.Tcp = expandAppmeshTcpTimeout(vTcpTimeout) + } + + listener.Timeout = listenerTimeout + } + listeners = append(listeners, listener) } @@ -5033,6 +5057,16 @@ func flattenAppmeshVirtualNodeSpec(spec *appmesh.VirtualNodeSpec) []interface{} mListener["port_mapping"] = []interface{}{mPortMapping} } + if listenerTimeout := listener.Timeout; listenerTimeout != nil { + mListenerTimeout := map[string]interface{}{ + "grpc": flattenAppmeshGrpcTimeout(listenerTimeout.Grpc), + "http": flattenAppmeshHttpTimeout(listenerTimeout.Http), + "http2": flattenAppmeshHttpTimeout(listenerTimeout.Http2), + "tcp": flattenAppmeshTcpTimeout(listenerTimeout.Tcp), + } + mListener["timeout"] = []interface{}{mListenerTimeout} + } + if tls := listener.Tls; tls != nil { mTls := map[string]interface{}{ "mode": aws.StringValue(tls.Mode), diff --git a/website/docs/r/appmesh_virtual_node.html.markdown b/website/docs/r/appmesh_virtual_node.html.markdown index 2366dd96db85..232abbc3034c 100644 --- a/website/docs/r/appmesh_virtual_node.html.markdown +++ b/website/docs/r/appmesh_virtual_node.html.markdown @@ -231,6 +231,7 @@ The `listener` object supports the following: * `port_mapping` - (Required) The port mapping information for the listener. * `health_check` - (Optional) The health check information for the listener. +* `timeout` - (Optional) Timeouts for different protocols. * `tls` - (Optional) The Transport Layer Security (TLS) properties for the listener The `logging` object supports the following: @@ -276,6 +277,42 @@ The `health_check` object supports the following: * `path` - (Optional) The destination path for the health check request. This is only required if the specified protocol is `http` or `http2`. * `port` - (Optional) The destination port for the health check request. This port must match the port defined in the `port_mapping` for the listener. +The `timeout` object supports the following: + +* `grpc` - (Optional) Timeouts for gRPC listeners. +* `http` - (Optional) Timeouts for HTTP listeners. +* `http2` - (Optional) Timeouts for HTTP2 listeners. +* `tcp` - (Optional) Timeouts for TCP listeners. + +The `grpc` timeout object supports the following: + +* `idle` - (Optional) The idle timeout. An idle timeout bounds the amount of time that a connection may be idle. +* `per_request` - (Optional) The per request timeout. + +The `idle` and `per_request` objects support the following: + +* `unit` - (Required) The unit of time. Valid values: `ms`, `s`. +* `value` - (Required) The number of time units. Minimum value of `0`. + +The `http` and `http2` timeout objects support the following: + +* `idle` - (Optional) The idle timeout. An idle timeout bounds the amount of time that a connection may be idle. +* `per_request` - (Optional) The per request timeout. + +The `idle` and `per_request` objects support the following: + +* `unit` - (Required) The unit of time. Valid values: `ms`, `s`. +* `value` - (Required) The number of time units. Minimum value of `0`. + +The `tcp` timeout object supports the following: + +* `idle` - (Optional) The idle timeout. An idle timeout bounds the amount of time that a connection may be idle. + +The `idle` object supports the following: + +* `unit` - (Required) The unit of time. Valid values: `ms`, `s`. +* `value` - (Required) The number of time units. Minimum value of `0`. + The `tls` object supports the following: * `certificate` - (Required) The listener's TLS certificate. From dbd6726538171c1dd161ce193527893834609f41 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 30 Jul 2020 17:16:06 -0400 Subject: [PATCH 12/17] r/aws_appmesh_virtual_node: Add 'testAccAwsAppmeshVirtualNode_listenerTimeout'. Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/VirtualNode/listenerTimeout' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/VirtualNode/listenerTimeout -timeout 120m === RUN TestAccAWSAppmesh_serial === RUN TestAccAWSAppmesh_serial/VirtualNode === RUN TestAccAWSAppmesh_serial/VirtualNode/listenerTimeout --- PASS: TestAccAWSAppmesh_serial (23.16s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode (23.16s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode/listenerTimeout (23.16s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 23.237s --- aws/resource_aws_appmesh_test.go | 1 + aws/resource_aws_appmesh_virtual_node_test.go | 173 ++++++++++++++++++ 2 files changed, 174 insertions(+) diff --git a/aws/resource_aws_appmesh_test.go b/aws/resource_aws_appmesh_test.go index aa865abcafe2..5b8c18b44b60 100644 --- a/aws/resource_aws_appmesh_test.go +++ b/aws/resource_aws_appmesh_test.go @@ -32,6 +32,7 @@ func TestAccAWSAppmesh_serial(t *testing.T) { "clientPolicyFile": testAccAwsAppmeshVirtualNode_clientPolicyFile, "cloudMapServiceDiscovery": testAccAwsAppmeshVirtualNode_cloudMapServiceDiscovery, "listenerHealthChecks": testAccAwsAppmeshVirtualNode_listenerHealthChecks, + "listenerTimeout": testAccAwsAppmeshVirtualNode_listenerTimeout, "logging": testAccAwsAppmeshVirtualNode_logging, "tls": testAccAwsAppmeshVirtualNode_tls, "tags": testAccAwsAppmeshVirtualNode_tags, diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index 9a4a40c564f3..24c54d706733 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -285,6 +285,96 @@ func testAccAwsAppmeshVirtualNode_listenerHealthChecks(t *testing.T) { }) } +func testAccAwsAppmeshVirtualNode_listenerTimeout(t *testing.T) { + var vn appmesh.VirtualNodeData + resourceName := "aws_appmesh_virtual_node.test" + meshName := acctest.RandomWithPrefix("tf-acc-test") + vnName := acctest.RandomWithPrefix("tf-acc-test") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAppmeshVirtualNodeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAppmeshVirtualNodeConfig_listenerTimeout(meshName, vnName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), + resource.TestCheckResourceAttr(resourceName, "name", vnName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), + tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ + "virtual_service.#": "1", + "virtual_service.0.virtual_service_name": "servicea.simpleapp.local", + }), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.protocol", "tcp"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.grpc.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.http.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.http2.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.tcp.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.tcp.0.idle.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.tcp.0.idle.0.unit", "ms"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.tcp.0.idle.0.value", "250000"), + resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + ), + }, + { + Config: testAccAppmeshVirtualNodeConfig_listenerTimeoutUpdated(meshName, vnName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), + resource.TestCheckResourceAttr(resourceName, "name", vnName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), + tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ + "virtual_service.#": "1", + "virtual_service.0.virtual_service_name": "servicea.simpleapp.local", + }), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.grpc.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.http.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.http.0.idle.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.http.0.idle.0.unit", "s"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.http.0.idle.0.value", "10"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.http.0.per_request.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.http.0.per_request.0.unit", "s"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.http.0.per_request.0.value", "5"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.http2.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.timeout.0.tcp.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + ), + }, + { + ResourceName: resourceName, + ImportStateId: fmt.Sprintf("%s/%s", meshName, vnName), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccAwsAppmeshVirtualNode_logging(t *testing.T) { var vn appmesh.VirtualNodeData resourceName := "aws_appmesh_virtual_node.test" @@ -1004,6 +1094,89 @@ resource "aws_appmesh_virtual_node" "test" { `, vnName) } +func testAccAppmeshVirtualNodeConfig_listenerTimeout(meshName, vnName string) string { + return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` +resource "aws_appmesh_virtual_node" "test" { + name = %[1]q + mesh_name = aws_appmesh_mesh.test.id + + spec { + backend { + virtual_service { + virtual_service_name = "servicea.simpleapp.local" + } + } + + listener { + port_mapping { + port = 8080 + protocol = "tcp" + } + + timeout { + tcp { + idle { + unit = "ms" + value = 250000 + } + } + } + } + + service_discovery { + dns { + hostname = "serviceb.simpleapp.local" + } + } + } +} +`, vnName) +} + +func testAccAppmeshVirtualNodeConfig_listenerTimeoutUpdated(meshName, vnName string) string { + return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` +resource "aws_appmesh_virtual_node" "test" { + name = %[1]q + mesh_name = aws_appmesh_mesh.test.id + + spec { + backend { + virtual_service { + virtual_service_name = "servicea.simpleapp.local" + } + } + + listener { + port_mapping { + port = 8080 + protocol = "http" + } + + timeout { + http { + idle { + unit = "s" + value = 10 + } + + per_request { + unit = "s" + value = 5 + } + } + } + } + + service_discovery { + dns { + hostname = "serviceb.simpleapp.local" + } + } + } +} +`, vnName) +} + func testAccAppmeshVirtualNodeConfig_logging(meshName, vnName, path string) string { return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { From b790b3be326c6056c29b6c3acd9c75342bc142f5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Sep 2020 16:41:16 -0400 Subject: [PATCH 13/17] Fix compilation errors after rebase. --- aws/resource_aws_appmesh_route.go | 63 -------------------- aws/resource_aws_appmesh_route_test.go | 81 -------------------------- aws/structure.go | 3 - 3 files changed, 147 deletions(-) diff --git a/aws/resource_aws_appmesh_route.go b/aws/resource_aws_appmesh_route.go index e163fabf9d0e..67b3cf490c8a 100644 --- a/aws/resource_aws_appmesh_route.go +++ b/aws/resource_aws_appmesh_route.go @@ -264,69 +264,6 @@ func resourceAwsAppmeshRoute() *schema.Resource { }, }, - "retry_policy": { - Type: schema.TypeList, - Optional: true, - MinItems: 0, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "grpc_retry_events": { - Type: schema.TypeSet, - Optional: true, - MinItems: 0, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, - }, - - "http_retry_events": { - Type: schema.TypeSet, - Optional: true, - MinItems: 0, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, - }, - - "max_retries": { - Type: schema.TypeInt, - Required: true, - }, - - "per_retry_timeout": { - Type: schema.TypeList, - Required: true, - MinItems: 1, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "unit": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - appmesh.DurationUnitMs, - appmesh.DurationUnitS, - }, false), - }, - - "value": { - Type: schema.TypeInt, - Required: true, - }, - }, - }, - }, - - "tcp_retry_events": { - Type: schema.TypeSet, - Optional: true, - MinItems: 0, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, - }, - }, - }, - }, - "timeout": { Type: schema.TypeList, Optional: true, diff --git a/aws/resource_aws_appmesh_route_test.go b/aws/resource_aws_appmesh_route_test.go index 83baf7270780..b58730def486 100644 --- a/aws/resource_aws_appmesh_route_test.go +++ b/aws/resource_aws_appmesh_route_test.go @@ -2459,84 +2459,3 @@ resource "aws_appmesh_route" "test" { } `, rName)) } - -func testAccAwsAppmeshRouteConfig_httpRetryPolicy(meshName, vrName, vn1Name, vn2Name, rName string) string { - return testAccAppmeshRouteConfigBase(meshName, vrName, "http", vn1Name, vn2Name) + fmt.Sprintf(` -resource "aws_appmesh_route" "test" { - name = %[1]q - mesh_name = "${aws_appmesh_mesh.test.id}" - virtual_router_name = "${aws_appmesh_virtual_router.test.name}" - - spec { - http_route { - match { - prefix = "/" - } - - retry_policy { - http_retry_events = [ - "server-error", - ] - - max_retries = 1 - - per_retry_timeout { - unit = "s" - value = 15 - } - } - - action { - weighted_target { - virtual_node = "${aws_appmesh_virtual_node.foo.name}" - weight = 100 - } - } - } - } -} -`, rName) -} - -func testAccAwsAppmeshRouteConfig_httpRetryPolicyUpdated(meshName, vrName, vn1Name, vn2Name, rName string) string { - return testAccAppmeshRouteConfigBase(meshName, vrName, "http", vn1Name, vn2Name) + fmt.Sprintf(` -resource "aws_appmesh_route" "test" { - name = %[1]q - mesh_name = "${aws_appmesh_mesh.test.id}" - virtual_router_name = "${aws_appmesh_virtual_router.test.name}" - - spec { - http_route { - match { - prefix = "/" - } - - retry_policy { - http_retry_events = [ - "client-error", - "gateway-error", - ] - - max_retries = 3 - - per_retry_timeout { - unit = "ms" - value = 250000 - } - - tcp_retry_events = [ - "connection-error", - ] - } - - action { - weighted_target { - virtual_node = "${aws_appmesh_virtual_node.foo.name}" - weight = 100 - } - } - } - } -} -`, rName) -} diff --git a/aws/structure.go b/aws/structure.go index 9b2b9cc8f04f..be0833f71369 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -5705,9 +5705,6 @@ func expandAppmeshHttpRoute(vHttpRoute []interface{}) *appmesh.HttpRoute { httpRouteHeader.Match.Suffix = aws.String(vSuffix) } - if vRange, ok := mMatch["range"].([]interface{}); ok && len(vRange) > 0 && vRange[0] != nil { - httpRouteHeader.Match.Range = &appmesh.MatchRange{} - if vRange, ok := mMatch["range"].([]interface{}); ok && len(vRange) > 0 && vRange[0] != nil { httpRouteHeader.Match.Range = &appmesh.MatchRange{} From 03676051595c7fbdd9fab4b1298e29b1277dcff9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Sep 2020 16:56:59 -0400 Subject: [PATCH 14/17] r/aws_appmesh_virtual_node: Use '_Values()' (#14601). r/aws_appmesh_route: Use '_Values()' (#14601). --- aws/resource_aws_appmesh_route.go | 45 +++++++++++-------------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/aws/resource_aws_appmesh_route.go b/aws/resource_aws_appmesh_route.go index 67b3cf490c8a..a6729676a0d3 100644 --- a/aws/resource_aws_appmesh_route.go +++ b/aws/resource_aws_appmesh_route.go @@ -279,12 +279,9 @@ func resourceAwsAppmeshRoute() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "unit": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - appmesh.DurationUnitMs, - appmesh.DurationUnitS, - }, false), + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(appmesh.DurationUnit_Values(), false), }, "value": { @@ -303,12 +300,9 @@ func resourceAwsAppmeshRoute() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "unit": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - appmesh.DurationUnitMs, - appmesh.DurationUnitS, - }, false), + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(appmesh.DurationUnit_Values(), false), }, "value": { @@ -398,12 +392,9 @@ func resourceAwsAppmeshRoute() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "unit": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - appmesh.DurationUnitMs, - appmesh.DurationUnitS, - }, false), + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(appmesh.DurationUnit_Values(), false), }, "value": { @@ -660,12 +651,9 @@ func appmeshRouteHttpRouteSchema() *schema.Schema { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "unit": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - appmesh.DurationUnitMs, - appmesh.DurationUnitS, - }, false), + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(appmesh.DurationUnit_Values(), false), }, "value": { @@ -684,12 +672,9 @@ func appmeshRouteHttpRouteSchema() *schema.Schema { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "unit": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - appmesh.DurationUnitMs, - appmesh.DurationUnitS, - }, false), + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(appmesh.DurationUnit_Values(), false), }, "value": { From ab056414944e1d9f06bae1212f8c723638e0383c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Sep 2020 17:26:56 -0400 Subject: [PATCH 15/17] r/aws_appmesh_virtual_node: Update resource testing and documentation to 0.12 syntax. r/aws_appmesh_route: Update resource testing and documentation to 0.12 syntax. Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh -timeout 120m === RUN TestAccAWSAppmesh_serial === RUN TestAccAWSAppmesh_serial/Mesh === RUN TestAccAWSAppmesh_serial/Mesh/egressFilter === RUN TestAccAWSAppmesh_serial/Mesh/tags === RUN TestAccAWSAppmesh_serial/Mesh/basic === RUN TestAccAWSAppmesh_serial/Route === RUN TestAccAWSAppmesh_serial/Route/grpcRoute === RUN TestAccAWSAppmesh_serial/Route/http2RouteTimeout === RUN TestAccAWSAppmesh_serial/Route/httpHeader === RUN TestAccAWSAppmesh_serial/Route/tcpRouteTimeout === RUN TestAccAWSAppmesh_serial/Route/tags === RUN TestAccAWSAppmesh_serial/Route/grpcRouteTimeout === RUN TestAccAWSAppmesh_serial/Route/http2Route === RUN TestAccAWSAppmesh_serial/Route/httpRetryPolicy === RUN TestAccAWSAppmesh_serial/Route/httpRoute === RUN TestAccAWSAppmesh_serial/Route/httpRouteTimeout === RUN TestAccAWSAppmesh_serial/Route/routePriority === RUN TestAccAWSAppmesh_serial/Route/tcpRoute === RUN TestAccAWSAppmesh_serial/VirtualNode === RUN TestAccAWSAppmesh_serial/VirtualNode/listenerHealthChecks === RUN TestAccAWSAppmesh_serial/VirtualNode/listenerTimeout === RUN TestAccAWSAppmesh_serial/VirtualNode/logging === RUN TestAccAWSAppmesh_serial/VirtualNode/tags === RUN TestAccAWSAppmesh_serial/VirtualNode/basic === RUN TestAccAWSAppmesh_serial/VirtualNode/cloudMapServiceDiscovery === RUN TestAccAWSAppmesh_serial/VirtualRouter === RUN TestAccAWSAppmesh_serial/VirtualRouter/basic === RUN TestAccAWSAppmesh_serial/VirtualRouter/tags === RUN TestAccAWSAppmesh_serial/VirtualService === RUN TestAccAWSAppmesh_serial/VirtualService/virtualNode === RUN TestAccAWSAppmesh_serial/VirtualService/virtualRouter === RUN TestAccAWSAppmesh_serial/VirtualService/tags --- PASS: TestAccAWSAppmesh_serial (1146.96s) --- PASS: TestAccAWSAppmesh_serial/Mesh (98.83s) --- PASS: TestAccAWSAppmesh_serial/Mesh/egressFilter (39.94s) --- PASS: TestAccAWSAppmesh_serial/Mesh/tags (42.48s) --- PASS: TestAccAWSAppmesh_serial/Mesh/basic (16.41s) --- PASS: TestAccAWSAppmesh_serial/Route (531.21s) --- PASS: TestAccAWSAppmesh_serial/Route/grpcRoute (54.92s) --- PASS: TestAccAWSAppmesh_serial/Route/http2RouteTimeout (39.03s) --- PASS: TestAccAWSAppmesh_serial/Route/httpHeader (38.48s) --- PASS: TestAccAWSAppmesh_serial/Route/tcpRouteTimeout (37.89s) --- PASS: TestAccAWSAppmesh_serial/Route/tags (55.83s) --- PASS: TestAccAWSAppmesh_serial/Route/grpcRouteTimeout (38.00s) --- PASS: TestAccAWSAppmesh_serial/Route/http2Route (38.65s) --- PASS: TestAccAWSAppmesh_serial/Route/httpRetryPolicy (39.38s) --- PASS: TestAccAWSAppmesh_serial/Route/httpRoute (55.40s) --- PASS: TestAccAWSAppmesh_serial/Route/httpRouteTimeout (38.97s) --- PASS: TestAccAWSAppmesh_serial/Route/routePriority (38.38s) --- PASS: TestAccAWSAppmesh_serial/Route/tcpRoute (56.25s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode (278.40s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode/listenerHealthChecks (33.86s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode/listenerTimeout (33.93s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode/logging (35.61s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode/tags (49.14s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode/basic (19.31s) --- PASS: TestAccAWSAppmesh_serial/VirtualNode/cloudMapServiceDiscovery (106.55s) --- PASS: TestAccAWSAppmesh_serial/VirtualRouter (112.07s) --- PASS: TestAccAWSAppmesh_serial/VirtualRouter/basic (33.68s) --- PASS: TestAccAWSAppmesh_serial/VirtualRouter/tags (78.38s) --- PASS: TestAccAWSAppmesh_serial/VirtualService (126.44s) --- PASS: TestAccAWSAppmesh_serial/VirtualService/virtualNode (38.02s) --- PASS: TestAccAWSAppmesh_serial/VirtualService/virtualRouter (34.64s) --- PASS: TestAccAWSAppmesh_serial/VirtualService/tags (53.78s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 1146.999s --- aws/resource_aws_appmesh_route_test.go | 28 ++++++++-------- aws/resource_aws_appmesh_virtual_node_test.go | 32 +++++++++---------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/aws/resource_aws_appmesh_route_test.go b/aws/resource_aws_appmesh_route_test.go index b58730def486..6f7313537268 100644 --- a/aws/resource_aws_appmesh_route_test.go +++ b/aws/resource_aws_appmesh_route_test.go @@ -1558,7 +1558,7 @@ resource "aws_appmesh_route" "test" { } func testAccAwsAppmeshRouteConfig_grpcRouteWithTimeout(meshName, vrName, vn1Name, vn2Name, rName string) string { - return testAccAppmeshRouteConfigBase(meshName, vrName, "grpc", vn1Name, vn2Name) + fmt.Sprintf(` + return composeConfig(testAccAppmeshRouteConfigBase(meshName, vrName, "grpc", vn1Name, vn2Name), fmt.Sprintf(` resource "aws_appmesh_route" "test" { name = %[1]q mesh_name = aws_appmesh_mesh.test.id @@ -1593,11 +1593,11 @@ resource "aws_appmesh_route" "test" { } } } -`, rName) +`, rName)) } func testAccAwsAppmeshRouteConfig_grpcRouteWithTimeoutUpdated(meshName, vrName, vn1Name, vn2Name, rName string) string { - return testAccAppmeshRouteConfigBase(meshName, vrName, "grpc", vn1Name, vn2Name) + fmt.Sprintf(` + return composeConfig(testAccAppmeshRouteConfigBase(meshName, vrName, "grpc", vn1Name, vn2Name), fmt.Sprintf(` resource "aws_appmesh_route" "test" { name = %[1]q mesh_name = aws_appmesh_mesh.test.id @@ -1632,7 +1632,7 @@ resource "aws_appmesh_route" "test" { } } } -`, rName) +`, rName)) } func testAccAwsAppmeshRouteConfig_http2Route(meshName, vrName, vn1Name, vn2Name, rName string) string { @@ -1855,7 +1855,7 @@ resource "aws_appmesh_route" "test" { } } } -`, rName) +`, rName)) } func testAccAwsAppmeshRouteConfig_http2Route(meshName, vrName, vn1Name, vn2Name, rName string) string { @@ -1961,7 +1961,7 @@ resource "aws_appmesh_route" "test" { } } } -`, rName) +`, rName)) } func testAccAppmeshRouteConfig_httpRoute(meshName, vrName, vn1Name, vn2Name, rName string) string { @@ -2050,7 +2050,7 @@ resource "aws_appmesh_route" "test" { } func testAccAppmeshRouteConfig_httpRouteWithTimeout(meshName, vrName, vn1Name, vn2Name, rName string) string { - return testAccAppmeshRouteConfigBase(meshName, vrName, "http", vn1Name, vn2Name) + fmt.Sprintf(` + return composeConfig(testAccAppmeshRouteConfigBase(meshName, vrName, "http", vn1Name, vn2Name), fmt.Sprintf(` resource "aws_appmesh_route" "test" { name = %[1]q mesh_name = aws_appmesh_mesh.test.id @@ -2078,11 +2078,11 @@ resource "aws_appmesh_route" "test" { } } } -`, rName) +`, rName)) } func testAccAppmeshRouteConfig_httpRouteWithTimeoutUpdated(meshName, vrName, vn1Name, vn2Name, rName string) string { - return testAccAppmeshRouteConfigBase(meshName, vrName, "http", vn1Name, vn2Name) + fmt.Sprintf(` + return composeConfig(testAccAppmeshRouteConfigBase(meshName, vrName, "http", vn1Name, vn2Name), fmt.Sprintf(` resource "aws_appmesh_route" "test" { name = %[1]q mesh_name = aws_appmesh_mesh.test.id @@ -2115,7 +2115,7 @@ resource "aws_appmesh_route" "test" { } } } -`, rName) +`, rName)) } func testAccAppmeshRouteConfig_tcpRoute(meshName, vrName, vn1Name, vn2Name, rName string) string { @@ -2192,7 +2192,7 @@ resource "aws_appmesh_route" "test" { } func testAccAppmeshRouteConfig_tcpRouteWithTimeout(meshName, vrName, vn1Name, vn2Name, rName string) string { - return testAccAppmeshRouteConfigBase(meshName, vrName, "tcp", vn1Name, vn2Name) + fmt.Sprintf(` + return composeConfig(testAccAppmeshRouteConfigBase(meshName, vrName, "tcp", vn1Name, vn2Name), fmt.Sprintf(` resource "aws_appmesh_route" "test" { name = %[1]q mesh_name = aws_appmesh_mesh.test.id @@ -2216,11 +2216,11 @@ resource "aws_appmesh_route" "test" { } } } -`, rName) +`, rName)) } func testAccAppmeshRouteConfig_tcpRouteWithTimeoutUpdated(meshName, vrName, vn1Name, vn2Name, rName string) string { - return testAccAppmeshRouteConfigBase(meshName, vrName, "tcp", vn1Name, vn2Name) + fmt.Sprintf(` + return composeConfig(testAccAppmeshRouteConfigBase(meshName, vrName, "tcp", vn1Name, vn2Name), fmt.Sprintf(` resource "aws_appmesh_route" "test" { name = %[1]q mesh_name = aws_appmesh_mesh.test.id @@ -2244,7 +2244,7 @@ resource "aws_appmesh_route" "test" { } } } -`, rName) +`, rName)) } func testAccAppmeshRouteConfigWithTags(meshName, vrName, vn1Name, vn2Name, rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index 24c54d706733..aa1eb7280302 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -961,18 +961,18 @@ resource "aws_acm_certificate" "test" { } func testAccAppmeshVirtualNodeConfig_basic(meshName, vnName string) string { - return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig(testAccAppmeshVirtualNodeConfig_mesh(meshName), fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q mesh_name = aws_appmesh_mesh.test.id spec {} } -`, vnName) +`, vnName)) } func testAccAppmeshVirtualNodeConfig_cloudMapServiceDiscovery(meshName, vnName, rName, attrKey, attrValue string) string { - return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig(testAccAppmeshVirtualNodeConfig_mesh(meshName), fmt.Sprintf(` resource "aws_service_discovery_http_namespace" "test" { name = %[2]q } @@ -1007,11 +1007,11 @@ resource "aws_appmesh_virtual_node" "test" { } } } -`, vnName, rName, attrKey, attrValue) +`, vnName, rName, attrKey, attrValue)) } func testAccAppmeshVirtualNodeConfig_listenerHealthChecks(meshName, vnName string) string { - return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig(testAccAppmeshVirtualNodeConfig_mesh(meshName), fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q mesh_name = aws_appmesh_mesh.test.id @@ -1046,11 +1046,11 @@ resource "aws_appmesh_virtual_node" "test" { } } } -`, vnName) +`, vnName)) } func testAccAppmeshVirtualNodeConfig_listenerHealthChecksUpdated(meshName, vnName string) string { - return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig(testAccAppmeshVirtualNodeConfig_mesh(meshName), fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q mesh_name = aws_appmesh_mesh.test.id @@ -1091,11 +1091,11 @@ resource "aws_appmesh_virtual_node" "test" { } } } -`, vnName) +`, vnName)) } func testAccAppmeshVirtualNodeConfig_listenerTimeout(meshName, vnName string) string { - return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig(testAccAppmeshVirtualNodeConfig_mesh(meshName), fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q mesh_name = aws_appmesh_mesh.test.id @@ -1130,11 +1130,11 @@ resource "aws_appmesh_virtual_node" "test" { } } } -`, vnName) +`, vnName)) } func testAccAppmeshVirtualNodeConfig_listenerTimeoutUpdated(meshName, vnName string) string { - return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig(testAccAppmeshVirtualNodeConfig_mesh(meshName), fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q mesh_name = aws_appmesh_mesh.test.id @@ -1174,11 +1174,11 @@ resource "aws_appmesh_virtual_node" "test" { } } } -`, vnName) +`, vnName)) } func testAccAppmeshVirtualNodeConfig_logging(meshName, vnName, path string) string { - return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig(testAccAppmeshVirtualNodeConfig_mesh(meshName), fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q mesh_name = aws_appmesh_mesh.test.id @@ -1212,11 +1212,11 @@ resource "aws_appmesh_virtual_node" "test" { } } } -`, vnName, path) +`, vnName, path)) } func testAccAppmeshVirtualNodeConfig_tags(meshName, vnName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { - return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig(testAccAppmeshVirtualNodeConfig_mesh(meshName), fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q mesh_name = aws_appmesh_mesh.test.id @@ -1228,7 +1228,7 @@ resource "aws_appmesh_virtual_node" "test" { %[4]s = %[5]q } } -`, vnName, tagKey1, tagValue1, tagKey2, tagValue2) +`, vnName, tagKey1, tagValue1, tagKey2, tagValue2)) } func testAccAppmeshVirtualNodeConfig_tlsFile(meshName, vnName string) string { From d3843772b513657f9a4d7721995ac99a77a50612 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Sep 2020 17:32:54 -0400 Subject: [PATCH 16/17] Remove duplicate example in aws_appmesh_route documentation. --- website/docs/r/appmesh_route.html.markdown | 37 ---------------------- 1 file changed, 37 deletions(-) diff --git a/website/docs/r/appmesh_route.html.markdown b/website/docs/r/appmesh_route.html.markdown index 98613d2c0185..8e321381bab0 100644 --- a/website/docs/r/appmesh_route.html.markdown +++ b/website/docs/r/appmesh_route.html.markdown @@ -114,43 +114,6 @@ resource "aws_appmesh_route" "serviceb" { } ``` -### Retry Policy - -```hcl -resource "aws_appmesh_route" "serviceb" { - name = "serviceB-route" - mesh_name = "${aws_appmesh_mesh.simple.id}" - virtual_router_name = "${aws_appmesh_virtual_router.serviceb.name}" - - spec { - http_route { - match { - prefix = "/" - } - - retry_policy { - http_retry_events = [ - "server-error", - ] - max_retries = 1 - - per_retry_timeout { - unit = "s" - value = 15 - } - } - - action { - weighted_target { - virtual_node = "${aws_appmesh_virtual_node.serviceb.name}" - weight = 100 - } - } - } - } -} -``` - ### TCP Routing ```hcl From c14869d08061407a0225fcc6360adec9ce3b7bf5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 1 Oct 2020 14:04:58 -0400 Subject: [PATCH 17/17] Fixes after rebase. --- aws/resource_aws_appmesh_route.go | 5 +- aws/resource_aws_appmesh_route_test.go | 217 ++++-------------- aws/resource_aws_appmesh_virtual_node_test.go | 6 +- aws/structure.go | 6 - 4 files changed, 49 insertions(+), 185 deletions(-) diff --git a/aws/resource_aws_appmesh_route.go b/aws/resource_aws_appmesh_route.go index a6729676a0d3..5e02abfa7a4c 100644 --- a/aws/resource_aws_appmesh_route.go +++ b/aws/resource_aws_appmesh_route.go @@ -185,9 +185,8 @@ func resourceAwsAppmeshRoute() *schema.Resource { }, "method_name": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice(appmesh.HttpMethod_Values(), false), + Type: schema.TypeString, + Optional: true, }, "prefix": { diff --git a/aws/resource_aws_appmesh_route_test.go b/aws/resource_aws_appmesh_route_test.go index 6f7313537268..2dfad51125e7 100644 --- a/aws/resource_aws_appmesh_route_test.go +++ b/aws/resource_aws_appmesh_route_test.go @@ -257,6 +257,7 @@ func testAccAwsAppmeshRoute_grpcRoute(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), ), }, @@ -290,6 +291,7 @@ func testAccAwsAppmeshRoute_grpcRouteTimeout(t *testing.T) { testAccCheckAppmeshRouteExists(resourceName, &r), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "1"), @@ -315,6 +317,7 @@ func testAccAwsAppmeshRoute_grpcRouteTimeout(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), ), }, @@ -324,6 +327,7 @@ func testAccAwsAppmeshRoute_grpcRouteTimeout(t *testing.T) { testAccCheckAppmeshRouteExists(resourceName, &r), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "1"), @@ -467,6 +471,7 @@ func testAccAwsAppmeshRoute_http2Route(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), ), }, @@ -500,6 +505,7 @@ func testAccAwsAppmeshRoute_http2RouteTimeout(t *testing.T) { testAccCheckAppmeshRouteExists(resourceName, &r), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "0"), @@ -527,6 +533,7 @@ func testAccAwsAppmeshRoute_http2RouteTimeout(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), ), }, @@ -536,6 +543,7 @@ func testAccAwsAppmeshRoute_http2RouteTimeout(t *testing.T) { testAccCheckAppmeshRouteExists(resourceName, &r), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "0"), @@ -675,6 +683,7 @@ func testAccAwsAppmeshRoute_httpRoute(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.#", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), ), }, @@ -708,6 +717,7 @@ func testAccAwsAppmeshRoute_httpRouteTimeout(t *testing.T) { testAccCheckAppmeshRouteExists(resourceName, &r), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "0"), @@ -731,6 +741,7 @@ func testAccAwsAppmeshRoute_httpRouteTimeout(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), ), }, @@ -740,6 +751,7 @@ func testAccAwsAppmeshRoute_httpRouteTimeout(t *testing.T) { testAccCheckAppmeshRouteExists(resourceName, &r), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "0"), @@ -858,6 +870,7 @@ func testAccAwsAppmeshRoute_tcpRoute(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.tcp_route.0.timeout.#", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), ), }, @@ -891,6 +904,7 @@ func testAccAwsAppmeshRoute_tcpRouteTimeout(t *testing.T) { testAccCheckAppmeshRouteExists(resourceName, &r), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "0"), @@ -907,6 +921,7 @@ func testAccAwsAppmeshRoute_tcpRouteTimeout(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualRouter/%s/route/%s", meshName, vrName, rName)), ), }, @@ -916,6 +931,7 @@ func testAccAwsAppmeshRoute_tcpRouteTimeout(t *testing.T) { testAccCheckAppmeshRouteExists(resourceName, &r), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "virtual_router_name", vrName), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.grpc_route.#", "0"), @@ -1581,13 +1597,8 @@ resource "aws_appmesh_route" "test" { timeout { idle { - unit = "s" - value = 10 - } - - per_request { - unit = "s" - value = 5 + unit = "ms" + value = 250000 } } } @@ -1735,122 +1746,43 @@ resource "aws_appmesh_route" "test" { weight = 100 } } - - timeout { - idle { - unit = "ms" - value = 250000 - } - } } } } `, rName)) } -func testAccAwsAppmeshRouteConfig_grpcRoute(meshName, vrName, vn1Name, vn2Name, rName string) string { - return testAccAppmeshRouteConfigBase(meshName, vrName, vn1Name, vn2Name) + fmt.Sprintf(` +func testAccAwsAppmeshRouteConfig_http2RouteWithTimeout(meshName, vrName, vn1Name, vn2Name, rName string) string { + return composeConfig(testAccAppmeshRouteConfigBase(meshName, vrName, "http2", vn1Name, vn2Name), fmt.Sprintf(` resource "aws_appmesh_route" "test" { name = %[1]q - mesh_name = "${aws_appmesh_mesh.test.id}" - virtual_router_name = "${aws_appmesh_virtual_router.test.name}" + mesh_name = aws_appmesh_mesh.test.id + virtual_router_name = aws_appmesh_virtual_router.test.name spec { - grpc_route { + http2_route { match { - metadata { - name = "X-Testing1" - } - } - - retry_policy { - grpc_retry_events = [ - "deadline-exceeded", - "resource-exhausted", - ] - - http_retry_events = [ - "server-error", - ] - - max_retries = 1 + prefix = "/" + method = "POST" + scheme = "http" - per_retry_timeout { - unit = "s" - value = 15 + header { + name = "X-Testing1" } } action { weighted_target { - virtual_node = "${aws_appmesh_virtual_node.foo.name}" + virtual_node = aws_appmesh_virtual_node.foo.name weight = 100 } } - } - } -} -`, rName) -} - -func testAccAwsAppmeshRouteConfig_grpcRouteUpdated(meshName, vrName, vn1Name, vn2Name, rName string) string { - return testAccAppmeshRouteConfigBase(meshName, vrName, vn1Name, vn2Name) + fmt.Sprintf(` -resource "aws_appmesh_route" "test" { - name = %[1]q - mesh_name = "${aws_appmesh_mesh.test.id}" - virtual_router_name = "${aws_appmesh_virtual_router.test.name}" - spec { - grpc_route { - match { - method_name = "test" - service_name = "test.local" - - metadata { - name = "X-Testing1" - invert = true - } - - metadata { - name = "X-Testing2" - invert = false - - match { - range { - start = 2 - end = 7 - } - } - } - } - - retry_policy { - grpc_retry_events = [ - "cancelled", - ] - - http_retry_events = [ - "client-error", - "gateway-error", - ] - - max_retries = 3 - - per_retry_timeout { + timeout { + idle { unit = "ms" value = 250000 } - - tcp_retry_events = [ - "connection-error", - ] - } - - action { - weighted_target { - virtual_node = "${aws_appmesh_virtual_node.foo.name}" - weight = 100 - } } } } @@ -1858,12 +1790,12 @@ resource "aws_appmesh_route" "test" { `, rName)) } -func testAccAwsAppmeshRouteConfig_http2Route(meshName, vrName, vn1Name, vn2Name, rName string) string { - return testAccAppmeshRouteConfigBase(meshName, vrName, vn1Name, vn2Name) + fmt.Sprintf(` +func testAccAwsAppmeshRouteConfig_http2RouteWithTimeoutUpdated(meshName, vrName, vn1Name, vn2Name, rName string) string { + return composeConfig(testAccAppmeshRouteConfigBase(meshName, vrName, "http2", vn1Name, vn2Name), fmt.Sprintf(` resource "aws_appmesh_route" "test" { name = %[1]q - mesh_name = "${aws_appmesh_mesh.test.id}" - virtual_router_name = "${aws_appmesh_virtual_router.test.name}" + mesh_name = aws_appmesh_mesh.test.id + virtual_router_name = aws_appmesh_virtual_router.test.name spec { http2_route { @@ -1877,85 +1809,22 @@ resource "aws_appmesh_route" "test" { } } - retry_policy { - http_retry_events = [ - "server-error", - ] - - max_retries = 1 - - per_retry_timeout { - unit = "s" - value = 15 - } - } - action { weighted_target { - virtual_node = "${aws_appmesh_virtual_node.foo.name}" + virtual_node = aws_appmesh_virtual_node.foo.name weight = 100 } } - } - } -} -`, rName) -} - -func testAccAwsAppmeshRouteConfig_http2RouteUpdated(meshName, vrName, vn1Name, vn2Name, rName string) string { - return testAccAppmeshRouteConfigBase(meshName, vrName, vn1Name, vn2Name) + fmt.Sprintf(` -resource "aws_appmesh_route" "test" { - name = %[1]q - mesh_name = "${aws_appmesh_mesh.test.id}" - virtual_router_name = "${aws_appmesh_virtual_router.test.name}" - - spec { - http2_route { - match { - prefix = "/path" - method = "PUT" - scheme = "https" - - header { - name = "X-Testing1" - invert = true - } - - header { - name = "X-Testing2" - invert = false - - match { - range { - start = 2 - end = 7 - } - } - } - } - retry_policy { - http_retry_events = [ - "client-error", - "gateway-error", - ] - - max_retries = 3 - - per_retry_timeout { - unit = "ms" - value = 250000 + timeout { + idle { + unit = "s" + value = 10 } - tcp_retry_events = [ - "connection-error", - ] - } - - action { - weighted_target { - virtual_node = "${aws_appmesh_virtual_node.foo.name}" - weight = 100 + per_request { + unit = "s" + value = 5 } } } diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index aa1eb7280302..7a1d9ab6ece1 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -146,7 +146,6 @@ func testAccAwsAppmeshVirtualNode_cloudMapServiceDiscovery(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), - testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.aws_cloud_map.#", "1"), @@ -162,7 +161,6 @@ func testAccAwsAppmeshVirtualNode_cloudMapServiceDiscovery(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), - testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.aws_cloud_map.#", "1"), @@ -302,6 +300,7 @@ func testAccAwsAppmeshVirtualNode_listenerTimeout(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ @@ -326,6 +325,7 @@ func testAccAwsAppmeshVirtualNode_listenerTimeout(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, @@ -335,6 +335,7 @@ func testAccAwsAppmeshVirtualNode_listenerTimeout(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ @@ -362,6 +363,7 @@ func testAccAwsAppmeshVirtualNode_listenerTimeout(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, diff --git a/aws/structure.go b/aws/structure.go index be0833f71369..d909c2b7c467 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -5698,12 +5698,6 @@ func expandAppmeshHttpRoute(vHttpRoute []interface{}) *appmesh.HttpRoute { if vSuffix, ok := mMatch["suffix"].(string); ok && vSuffix != "" { httpRouteHeader.Match.Suffix = aws.String(vSuffix) } - if vRegex, ok := mMatch["regex"].(string); ok && vRegex != "" { - httpRouteHeader.Match.Regex = aws.String(vRegex) - } - if vSuffix, ok := mMatch["suffix"].(string); ok && vSuffix != "" { - httpRouteHeader.Match.Suffix = aws.String(vSuffix) - } if vRange, ok := mMatch["range"].([]interface{}); ok && len(vRange) > 0 && vRange[0] != nil { httpRouteHeader.Match.Range = &appmesh.MatchRange{}