Skip to content

Commit

Permalink
Merge pull request #16867 from ewbankkit/b-aws_appmesh_route-empty-gr…
Browse files Browse the repository at this point in the history
…pc_route

r/aws_appmesh_route: Allow empty 'match' for 'grpc_route'
  • Loading branch information
breathingdust authored Jan 13, 2021
2 parents 44eb67e + f8ba388 commit ff67ef0
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 60 deletions.
9 changes: 5 additions & 4 deletions aws/resource_aws_appmesh_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ func resourceAwsAppmeshRoute() *schema.Resource {

"match": {
Type: schema.TypeList,
Required: true,
MinItems: 1,
Optional: true,
MinItems: 0,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -196,8 +196,9 @@ func resourceAwsAppmeshRoute() *schema.Resource {
},

"service_name": {
Type: schema.TypeString,
Optional: true,
Type: schema.TypeString,
Optional: true,
RequiredWith: []string{"spec.0.grpc_route.0.match.0.method_name"},
},
},
},
Expand Down
75 changes: 75 additions & 0 deletions aws/resource_aws_appmesh_route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,58 @@ func testAccAwsAppmeshRoute_grpcRouteTimeout(t *testing.T) {
})
}

func testAccAwsAppmeshRoute_grpcRouteEmptyMatch(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); testAccPartitionHasServicePreCheck(appmesh.EndpointsID, t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAppmeshRouteDestroy,
Steps: []resource.TestStep{
{
Config: testAccAwsAppmeshRouteConfig_grpcRouteWithEmptyMatch(meshName, vrName, vn1Name, vn2Name, rName),
Check: resource.ComposeTestCheckFunc(
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"),
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.#", "0"),
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.retry_policy.#", "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"),
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)),
),
},
{
ResourceName: resourceName,
ImportStateIdFunc: testAccAwsAppmeshRouteImportStateIdFunc(resourceName),
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccAwsAppmeshRoute_http2Route(t *testing.T) {
var r appmesh.RouteData
resourceName := "aws_appmesh_route.test"
Expand Down Expand Up @@ -1645,6 +1697,29 @@ resource "aws_appmesh_route" "test" {
`, rName))
}

func testAccAwsAppmeshRouteConfig_grpcRouteWithEmptyMatch(meshName, vrName, vn1Name, vn2Name, rName string) string {
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
virtual_router_name = aws_appmesh_virtual_router.test.name
spec {
grpc_route {
match {}
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 composeConfig(testAccAppmeshRouteConfigBase(meshName, vrName, "http2", vn1Name, vn2Name), fmt.Sprintf(`
resource "aws_appmesh_route" "test" {
Expand Down
25 changes: 13 additions & 12 deletions aws/resource_aws_appmesh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,19 @@ func TestAccAWSAppmesh_serial(t *testing.T) {
"tags": testAccAwsAppmeshMesh_tags,
},
"Route": {
"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,
"grpcRoute": testAccAwsAppmeshRoute_grpcRoute,
"grpcRouteEmptyMatch": testAccAwsAppmeshRoute_grpcRouteEmptyMatch,
"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,
},
"VirtualGateway": {
"basic": testAccAwsAppmeshVirtualGateway_basic,
Expand Down
93 changes: 49 additions & 44 deletions aws/structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -5512,69 +5512,74 @@ func expandAppmeshGrpcRoute(vGrpcRoute []interface{}) *appmesh.GrpcRoute {
}
}

if vGrpcRouteMatch, ok := mGrpcRoute["match"].([]interface{}); ok && len(vGrpcRouteMatch) > 0 && vGrpcRouteMatch[0] != nil {
if vGrpcRouteMatch, ok := mGrpcRoute["match"].([]interface{}); ok {
grpcRouteMatch := &appmesh.GrpcRouteMatch{}

mGrpcRouteMatch := vGrpcRouteMatch[0].(map[string]interface{})
// Empty match is allowed.
// https://github.com/hashicorp/terraform-provider-aws/issues/16816.

if vMethodName, ok := mGrpcRouteMatch["method_name"].(string); ok && vMethodName != "" {
grpcRouteMatch.MethodName = aws.String(vMethodName)
}
if vServiceName, ok := mGrpcRouteMatch["service_name"].(string); ok && vServiceName != "" {
grpcRouteMatch.ServiceName = aws.String(vServiceName)
}

if vGrpcRouteMetadatas, ok := mGrpcRouteMatch["metadata"].(*schema.Set); ok && vGrpcRouteMetadatas.Len() > 0 {
grpcRouteMetadatas := []*appmesh.GrpcRouteMetadata{}

for _, vGrpcRouteMetadata := range vGrpcRouteMetadatas.List() {
grpcRouteMetadata := &appmesh.GrpcRouteMetadata{}
if len(vGrpcRouteMatch) > 0 && vGrpcRouteMatch[0] != nil {
mGrpcRouteMatch := vGrpcRouteMatch[0].(map[string]interface{})

mGrpcRouteMetadata := vGrpcRouteMetadata.(map[string]interface{})
if vMethodName, ok := mGrpcRouteMatch["method_name"].(string); ok && vMethodName != "" {
grpcRouteMatch.MethodName = aws.String(vMethodName)
}
if vServiceName, ok := mGrpcRouteMatch["service_name"].(string); ok && vServiceName != "" {
grpcRouteMatch.ServiceName = aws.String(vServiceName)
}

if vInvert, ok := mGrpcRouteMetadata["invert"].(bool); ok {
grpcRouteMetadata.Invert = aws.Bool(vInvert)
}
if vName, ok := mGrpcRouteMetadata["name"].(string); ok && vName != "" {
grpcRouteMetadata.Name = aws.String(vName)
}
if vGrpcRouteMetadatas, ok := mGrpcRouteMatch["metadata"].(*schema.Set); ok && vGrpcRouteMetadatas.Len() > 0 {
grpcRouteMetadatas := []*appmesh.GrpcRouteMetadata{}

if vMatch, ok := mGrpcRouteMetadata["match"].([]interface{}); ok && len(vMatch) > 0 && vMatch[0] != nil {
grpcRouteMetadata.Match = &appmesh.GrpcRouteMetadataMatchMethod{}
for _, vGrpcRouteMetadata := range vGrpcRouteMetadatas.List() {
grpcRouteMetadata := &appmesh.GrpcRouteMetadata{}

mMatch := vMatch[0].(map[string]interface{})
mGrpcRouteMetadata := vGrpcRouteMetadata.(map[string]interface{})

if vExact, ok := mMatch["exact"].(string); ok && vExact != "" {
grpcRouteMetadata.Match.Exact = aws.String(vExact)
if vInvert, ok := mGrpcRouteMetadata["invert"].(bool); ok {
grpcRouteMetadata.Invert = aws.Bool(vInvert)
}
if vPrefix, ok := mMatch["prefix"].(string); ok && vPrefix != "" {
grpcRouteMetadata.Match.Prefix = aws.String(vPrefix)
}
if vRegex, ok := mMatch["regex"].(string); ok && vRegex != "" {
grpcRouteMetadata.Match.Regex = aws.String(vRegex)
}
if vSuffix, ok := mMatch["suffix"].(string); ok && vSuffix != "" {
grpcRouteMetadata.Match.Suffix = aws.String(vSuffix)
if vName, ok := mGrpcRouteMetadata["name"].(string); ok && vName != "" {
grpcRouteMetadata.Name = aws.String(vName)
}

if vRange, ok := mMatch["range"].([]interface{}); ok && len(vRange) > 0 && vRange[0] != nil {
grpcRouteMetadata.Match.Range = &appmesh.MatchRange{}
if vMatch, ok := mGrpcRouteMetadata["match"].([]interface{}); ok && len(vMatch) > 0 && vMatch[0] != nil {
grpcRouteMetadata.Match = &appmesh.GrpcRouteMetadataMatchMethod{}

mRange := vRange[0].(map[string]interface{})
mMatch := vMatch[0].(map[string]interface{})

if vEnd, ok := mRange["end"].(int); ok && vEnd > 0 {
grpcRouteMetadata.Match.Range.End = aws.Int64(int64(vEnd))
if vExact, ok := mMatch["exact"].(string); ok && vExact != "" {
grpcRouteMetadata.Match.Exact = aws.String(vExact)
}
if vStart, ok := mRange["start"].(int); ok && vStart > 0 {
grpcRouteMetadata.Match.Range.Start = aws.Int64(int64(vStart))
if vPrefix, ok := mMatch["prefix"].(string); ok && vPrefix != "" {
grpcRouteMetadata.Match.Prefix = aws.String(vPrefix)
}
if vRegex, ok := mMatch["regex"].(string); ok && vRegex != "" {
grpcRouteMetadata.Match.Regex = aws.String(vRegex)
}
if vSuffix, ok := mMatch["suffix"].(string); ok && vSuffix != "" {
grpcRouteMetadata.Match.Suffix = aws.String(vSuffix)
}

if vRange, ok := mMatch["range"].([]interface{}); ok && len(vRange) > 0 && vRange[0] != nil {
grpcRouteMetadata.Match.Range = &appmesh.MatchRange{}

mRange := vRange[0].(map[string]interface{})

if vEnd, ok := mRange["end"].(int); ok && vEnd > 0 {
grpcRouteMetadata.Match.Range.End = aws.Int64(int64(vEnd))
}
if vStart, ok := mRange["start"].(int); ok && vStart > 0 {
grpcRouteMetadata.Match.Range.Start = aws.Int64(int64(vStart))
}
}
}

grpcRouteMetadatas = append(grpcRouteMetadatas, grpcRouteMetadata)
}

grpcRouteMetadatas = append(grpcRouteMetadatas, grpcRouteMetadata)
grpcRouteMatch.Metadata = grpcRouteMetadatas
}

grpcRouteMatch.Metadata = grpcRouteMetadatas
}

grpcRoute.Match = grpcRouteMatch
Expand Down

0 comments on commit ff67ef0

Please sign in to comment.