Skip to content

Commit

Permalink
r/aws_apigatewayv2_route: Add support for JWT authorizers.
Browse files Browse the repository at this point in the history
  • Loading branch information
ewbankkit committed Apr 9, 2020
1 parent 0231daa commit 4ba6eba
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 10 deletions.
36 changes: 34 additions & 2 deletions aws/resource_aws_apigatewayv2_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ func resourceAwsApiGatewayV2Route() *schema.Resource {
Optional: true,
Default: false,
},
"authorization_scopes": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"authorization_type": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -40,6 +45,7 @@ func resourceAwsApiGatewayV2Route() *schema.Resource {
apigatewayv2.AuthorizationTypeNone,
apigatewayv2.AuthorizationTypeAwsIam,
apigatewayv2.AuthorizationTypeCustom,
apigatewayv2.AuthorizationTypeJwt,
}, false),
},
"authorizer_id": {
Expand Down Expand Up @@ -86,6 +92,9 @@ func resourceAwsApiGatewayV2RouteCreate(d *schema.ResourceData, meta interface{}
AuthorizationType: aws.String(d.Get("authorization_type").(string)),
RouteKey: aws.String(d.Get("route_key").(string)),
}
if v, ok := d.GetOk("authorization_scopes"); ok {
req.AuthorizationScopes = expandStringSet(v.(*schema.Set))
}
if v, ok := d.GetOk("authorizer_id"); ok {
req.AuthorizerId = aws.String(v.(string))
}
Expand Down Expand Up @@ -133,6 +142,9 @@ func resourceAwsApiGatewayV2RouteRead(d *schema.ResourceData, meta interface{})
}

d.Set("api_key_required", resp.ApiKeyRequired)
if err := d.Set("authorization_scopes", flattenStringSet(resp.AuthorizationScopes)); err != nil {
return fmt.Errorf("error setting authorization_scopes: %s", err)
}
d.Set("authorization_type", resp.AuthorizationType)
d.Set("authorizer_id", resp.AuthorizerId)
d.Set("model_selection_expression", resp.ModelSelectionExpression)
Expand All @@ -157,6 +169,9 @@ func resourceAwsApiGatewayV2RouteUpdate(d *schema.ResourceData, meta interface{}
if d.HasChange("api_key_required") {
req.ApiKeyRequired = aws.Bool(d.Get("api_key_required").(bool))
}
if d.HasChange("authorization_scopes") {
req.AuthorizationScopes = expandStringSet(d.Get("authorization_scopes").(*schema.Set))
}
if d.HasChange("authorization_type") {
req.AuthorizationType = aws.String(d.Get("authorization_type").(string))
}
Expand Down Expand Up @@ -212,8 +227,25 @@ func resourceAwsApiGatewayV2RouteImport(d *schema.ResourceData, meta interface{}
return []*schema.ResourceData{}, fmt.Errorf("Wrong format of resource: %s. Please follow 'api-id/route-id'", d.Id())
}

d.SetId(parts[1])
d.Set("api_id", parts[0])
apiId := parts[0]
routeId := parts[1]

conn := meta.(*AWSClient).apigatewayv2conn

resp, err := conn.GetRoute(&apigatewayv2.GetRouteInput{
ApiId: aws.String(apiId),
RouteId: aws.String(routeId),
})
if err != nil {
return nil, err
}

if aws.BoolValue(resp.ApiGatewayManaged) {
return nil, fmt.Errorf("API Gateway v2 route (%s) was created via quick create", routeId)
}

d.SetId(routeId)
d.Set("api_id", apiId)

return []*schema.ResourceData{d}, nil
}
86 changes: 85 additions & 1 deletion aws/resource_aws_apigatewayv2_route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func TestAccAWSAPIGatewayV2Route_disappears(t *testing.T) {
})
}

func TestAccAWSAPIGateway2VRoute_Authorizer(t *testing.T) {
func TestAccAWSAPIGatewayV2Route_Authorizer(t *testing.T) {
var apiId string
var v apigatewayv2.GetRouteOutput
resourceName := "aws_apigatewayv2_route.test"
Expand All @@ -88,6 +88,7 @@ func TestAccAWSAPIGateway2VRoute_Authorizer(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAPIGatewayV2RouteExists(resourceName, &apiId, &v),
resource.TestCheckResourceAttr(resourceName, "api_key_required", "false"),
resource.TestCheckResourceAttr(resourceName, "authorization_scopes.#", "0"),
resource.TestCheckResourceAttr(resourceName, "authorization_type", apigatewayv2.AuthorizationTypeCustom),
resource.TestCheckResourceAttrPair(resourceName, "authorizer_id", authorizerResourceName, "id"),
resource.TestCheckResourceAttr(resourceName, "model_selection_expression", ""),
Expand All @@ -109,6 +110,7 @@ func TestAccAWSAPIGateway2VRoute_Authorizer(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAPIGatewayV2RouteExists(resourceName, &apiId, &v),
resource.TestCheckResourceAttr(resourceName, "api_key_required", "false"),
resource.TestCheckResourceAttr(resourceName, "authorization_scopes.#", "0"),
resource.TestCheckResourceAttr(resourceName, "authorization_type", apigatewayv2.AuthorizationTypeAwsIam),
resource.TestCheckResourceAttr(resourceName, "authorizer_id", ""),
resource.TestCheckResourceAttr(resourceName, "model_selection_expression", ""),
Expand All @@ -123,6 +125,60 @@ func TestAccAWSAPIGateway2VRoute_Authorizer(t *testing.T) {
})
}

func TestAccAWSAPIGatewayV2Route_JwtAuthorization(t *testing.T) {
var apiId string
var v apigatewayv2.GetRouteOutput
resourceName := "aws_apigatewayv2_route.test"
authorizerResourceName := "aws_apigatewayv2_authorizer.test"
rName := acctest.RandomWithPrefix("tf-acc-test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSAPIGatewayV2RouteDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSAPIGatewayV2RouteConfig_jwtAuthorization(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAPIGatewayV2RouteExists(resourceName, &apiId, &v),
resource.TestCheckResourceAttr(resourceName, "api_key_required", "false"),
resource.TestCheckResourceAttr(resourceName, "authorization_scopes.#", "2"),
resource.TestCheckResourceAttr(resourceName, "authorization_type", apigatewayv2.AuthorizationTypeJwt),
resource.TestCheckResourceAttrPair(resourceName, "authorizer_id", authorizerResourceName, "id"),
resource.TestCheckResourceAttr(resourceName, "model_selection_expression", ""),
resource.TestCheckResourceAttr(resourceName, "operation_name", ""),
resource.TestCheckResourceAttr(resourceName, "request_models.%", "0"),
resource.TestCheckResourceAttr(resourceName, "route_key", "$connect"),
resource.TestCheckResourceAttr(resourceName, "route_response_selection_expression", ""),
resource.TestCheckResourceAttr(resourceName, "target", ""),
),
},
{
ResourceName: resourceName,
ImportStateIdFunc: testAccAWSAPIGatewayV2RouteImportStateIdFunc(resourceName),
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccAWSAPIGatewayV2RouteConfig_jwtAuthorizationUpdated(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAPIGatewayV2RouteExists(resourceName, &apiId, &v),
resource.TestCheckResourceAttr(resourceName, "api_key_required", "false"),
resource.TestCheckResourceAttr(resourceName, "authorization_scopes.#", "1"),
resource.TestCheckResourceAttr(resourceName, "authorization_type", apigatewayv2.AuthorizationTypeJwt),
resource.TestCheckResourceAttrPair(resourceName, "authorizer_id", authorizerResourceName, "id"),
resource.TestCheckResourceAttr(resourceName, "model_selection_expression", ""),
resource.TestCheckResourceAttr(resourceName, "operation_name", ""),
resource.TestCheckResourceAttr(resourceName, "request_models.%", "0"),
resource.TestCheckResourceAttr(resourceName, "route_key", "$connect"),
resource.TestCheckResourceAttr(resourceName, "route_response_selection_expression", ""),
resource.TestCheckResourceAttr(resourceName, "target", ""),
),
},
},
})
}

func TestAccAWSAPIGatewayV2Route_Model(t *testing.T) {
var apiId string
var v apigatewayv2.GetRouteOutput
Expand Down Expand Up @@ -397,6 +453,34 @@ resource "aws_apigatewayv2_route" "test" {
`)
}

func testAccAWSAPIGatewayV2RouteConfig_jwtAuthorization(rName string) string {
return testAccAWSAPIGatewayV2AuthorizerConfig_jwt(rName) + fmt.Sprintf(`
resource "aws_apigatewayv2_route" "test" {
api_id = "${aws_apigatewayv2_api.test.id}"
route_key = "$connect"
authorization_type = "JWT"
authorizer_id = "${aws_apigatewayv2_authorizer.test.id}"
authorization_scopes = ["user.id", "user.email"]
}
`)
}

func testAccAWSAPIGatewayV2RouteConfig_jwtAuthorizationUpdated(rName string) string {
return testAccAWSAPIGatewayV2AuthorizerConfig_jwt(rName) + fmt.Sprintf(`
resource "aws_apigatewayv2_route" "test" {
api_id = "${aws_apigatewayv2_api.test.id}"
route_key = "$connect"
authorization_type = "JWT"
authorizer_id = "${aws_apigatewayv2_authorizer.test.id}"
authorization_scopes = ["user.email"]
}
`)
}

func testAccAWSAPIGatewayV2RouteConfig_model(rName string) string {
schema := `
{
Expand Down
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ require (
github.com/golangci/golangci-lint v1.23.8
github.com/hashicorp/aws-sdk-go-base v0.4.0
github.com/hashicorp/go-cleanhttp v0.5.1
github.com/hashicorp/go-getter v1.4.2-0.20200106182914-9813cbd4eb02 // indirect
github.com/hashicorp/go-multierror v1.0.0
github.com/hashicorp/go-version v1.2.0
github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7 // indirect
github.com/hashicorp/terraform-plugin-sdk v1.9.0
github.com/hashicorp/vault v0.10.4
github.com/jen20/awspolicyequivalence v1.1.0
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,6 @@ github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVo
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-getter v1.4.0 h1:ENHNi8494porjD0ZhIrjlAHnveSFhY7hvOJrV/fsKkw=
github.com/hashicorp/go-getter v1.4.0/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY=
github.com/hashicorp/go-getter v1.4.2-0.20200106182914-9813cbd4eb02 h1:l1KB3bHVdvegcIf5upQ5mjcHjs2qsWnKh4Yr9xgIuu8=
github.com/hashicorp/go-getter v1.4.2-0.20200106182914-9813cbd4eb02/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY=
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
Expand Down Expand Up @@ -258,8 +256,6 @@ github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/terraform-config-inspect v0.0.0-20191115094559-17f92b0546e8 h1:+RyjwU+Gnd/aTJBPZVDNm903eXVjjqhbaR4Ypx3xYyY=
github.com/hashicorp/terraform-config-inspect v0.0.0-20191115094559-17f92b0546e8/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A=
github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7 h1:Pc5TCv9mbxFN6UVX0LH6CpQrdTM5YjbVI2w15237Pjk=
github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A=
github.com/hashicorp/terraform-json v0.3.1 h1:vRiOLck4YX4UqzljVhdQKsVLixX4L+Pgnm/q+xu6QvE=
github.com/hashicorp/terraform-json v0.3.1/go.mod h1:MdwQStcJb00ht55L/2YH0ypAO9RNtczJ1MaUlf+gJcg=
github.com/hashicorp/terraform-json v0.4.0 h1:KNh29iNxozP5adfUFBJ4/fWd0Cu3taGgjHB38JYqOF4=
Expand Down
6 changes: 5 additions & 1 deletion website/docs/r/apigatewayv2_route.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ The following arguments are supported:
* `api_id` - (Required) The API identifier.
* `route_key` - (Required) The route key for the route.
* `api_key_required` - (Optional) Boolean whether an API key is required for the route. Defaults to `false`.
* `authorization_type` - (Optional) The authorization type for the route. Valid values: `NONE`, `AWS_IAM`, `CUSTOM`. Defaults to `NONE`.
* `authorization_scopes` - (Optional) The authorization scopes supported by this route. The scopes are used with a JWT authorizer to authorize the method invocation.
* `authorization_type` - (Optional) The authorization type for the route.
For WebSocket APIs, valid values are `NONE` for open access, `AWS_IAM` for using AWS IAM permissions, and `CUSTOM` for using a Lambda authorizer.
For HTTP APIs, valid values are `NONE` for open access, or `JWT` for using JSON Web Tokens.
Defaults to `NONE`.
* `authorizer_id` - (Optional) The identifier of the [`aws_apigatewayv2_authorizer`](/docs/providers/aws/r/apigatewayv2_authorizer.html) resource to be associated with this route, if the authorizationType is `CUSTOM`.
* `model_selection_expression` - (Optional) The [model selection expression](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-selection-expressions.html#apigateway-websocket-api-model-selection-expressions) for the route.
* `operation_name` - (Optional) The operation name for the route.
Expand Down

0 comments on commit 4ba6eba

Please sign in to comment.