Skip to content

Commit

Permalink
Add 'aws_api_gateway2_route_response' resource.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kit Ewbank authored and ewbankkit committed Apr 15, 2020
1 parent e307efc commit 7ecef9c
Show file tree
Hide file tree
Showing 5 changed files with 375 additions and 0 deletions.
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ func Provider() terraform.ResourceProvider {
"aws_apigatewayv2_integration_response": resourceAwsApiGatewayV2IntegrationResponse(),
"aws_apigatewayv2_model": resourceAwsApiGatewayV2Model(),
"aws_apigatewayv2_route": resourceAwsApiGatewayV2Route(),
"aws_api_gateway_v2_route_response": resourceAwsApiGateway2RouteResponse(),
"aws_app_cookie_stickiness_policy": resourceAwsAppCookieStickinessPolicy(),
"aws_appautoscaling_target": resourceAwsAppautoscalingTarget(),
"aws_appautoscaling_policy": resourceAwsAppautoscalingPolicy(),
Expand Down
160 changes: 160 additions & 0 deletions aws/resource_aws_api_gateway2_route_response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package aws

import (
"fmt"
"log"
"strings"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/apigatewayv2"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func resourceAwsApiGateway2RouteResponse() *schema.Resource {
return &schema.Resource{
Create: resourceAwsApiGateway2RouteResponseCreate,
Read: resourceAwsApiGateway2RouteResponseRead,
Update: resourceAwsApiGateway2RouteResponseUpdate,
Delete: resourceAwsApiGateway2RouteResponseDelete,
Importer: &schema.ResourceImporter{
State: resourceAwsApiGateway2RouteResponseImport,
},

Schema: map[string]*schema.Schema{
"api_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"model_selection_expression": {
Type: schema.TypeString,
Optional: true,
},
"response_models": {
Type: schema.TypeMap,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"route_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"route_response_key": {
Type: schema.TypeString,
Required: true,
},
},
}
}

func resourceAwsApiGateway2RouteResponseCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigatewayv2conn

req := &apigatewayv2.CreateRouteResponseInput{
ApiId: aws.String(d.Get("api_id").(string)),
RouteId: aws.String(d.Get("route_id").(string)),
RouteResponseKey: aws.String(d.Get("route_response_key").(string)),
}
if v, ok := d.GetOk("model_selection_expression"); ok {
req.ModelSelectionExpression = aws.String(v.(string))
}
if v, ok := d.GetOk("response_models"); ok {
req.ResponseModels = stringMapToPointers(v.(map[string]interface{}))
}

log.Printf("[DEBUG] Creating API Gateway v2 route response: %s", req)
resp, err := conn.CreateRouteResponse(req)
if err != nil {
return fmt.Errorf("error creating API Gateway v2 route response: %s", err)
}

d.SetId(aws.StringValue(resp.RouteResponseId))

return resourceAwsApiGateway2RouteResponseRead(d, meta)
}

func resourceAwsApiGateway2RouteResponseRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigatewayv2conn

resp, err := conn.GetRouteResponse(&apigatewayv2.GetRouteResponseInput{
ApiId: aws.String(d.Get("api_id").(string)),
RouteId: aws.String(d.Get("route_id").(string)),
RouteResponseId: aws.String(d.Id()),
})
if isAWSErr(err, apigatewayv2.ErrCodeNotFoundException, "") {
log.Printf("[WARN] API Gateway v2 route response (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}
if err != nil {
return fmt.Errorf("error reading API Gateway v2 route response: %s", err)
}

d.Set("model_selection_expression", resp.ModelSelectionExpression)
if err := d.Set("response_models", pointersMapToStringList(resp.ResponseModels)); err != nil {
return fmt.Errorf("error setting response_models: %s", err)
}
d.Set("route_response_key", resp.RouteResponseKey)

return nil
}

func resourceAwsApiGateway2RouteResponseUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigatewayv2conn

req := &apigatewayv2.UpdateRouteResponseInput{
ApiId: aws.String(d.Get("api_id").(string)),
RouteId: aws.String(d.Get("route_id").(string)),
RouteResponseId: aws.String(d.Id()),
}
if d.HasChange("model_selection_expression") {
req.ModelSelectionExpression = aws.String(d.Get("model_selection_expression").(string))
}
if d.HasChange("response_models") {
req.ResponseModels = stringMapToPointers(d.Get("response_models").(map[string]interface{}))
}
if d.HasChange("route_response_key") {
req.RouteResponseKey = aws.String(d.Get("route_response_key").(string))
}

log.Printf("[DEBUG] Updating API Gateway v2 route response: %s", req)
_, err := conn.UpdateRouteResponse(req)
if err != nil {
return fmt.Errorf("error updating API Gateway v2 route response: %s", err)
}

return resourceAwsApiGateway2RouteResponseRead(d, meta)
}

func resourceAwsApiGateway2RouteResponseDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigatewayv2conn

log.Printf("[DEBUG] Deleting API Gateway v2 route response (%s)", d.Id())
_, err := conn.DeleteRouteResponse(&apigatewayv2.DeleteRouteResponseInput{
ApiId: aws.String(d.Get("api_id").(string)),
RouteId: aws.String(d.Get("route_id").(string)),
RouteResponseId: aws.String(d.Id()),
})
if isAWSErr(err, apigatewayv2.ErrCodeNotFoundException, "") {
return nil
}
if err != nil {
return fmt.Errorf("error deleting API Gateway v2 route response: %s", err)
}

return nil
}

func resourceAwsApiGateway2RouteResponseImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
parts := strings.Split(d.Id(), "/")
if len(parts) != 3 {
return []*schema.ResourceData{}, fmt.Errorf("Wrong format of resource: %s. Please follow 'api-id/route-id/route-response-id'", d.Id())
}

d.SetId(parts[2])
d.Set("api_id", parts[0])
d.Set("route_id", parts[1])

return []*schema.ResourceData{d}, nil
}
163 changes: 163 additions & 0 deletions aws/resource_aws_api_gateway2_route_response_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package aws

import (
"fmt"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/apigatewayv2"
"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
)

func TestAccAWSAPIGateway2RouteResponse_basic(t *testing.T) {
resourceName := "aws_api_gateway_v2_route_response.test"
routeResourceName := "aws_api_gateway_v2_route.test"
rName := fmt.Sprintf("tf-testacc-apigwv2-%s", acctest.RandStringFromCharSet(13, acctest.CharSetAlphaNum))

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSAPIGateway2RouteResponseDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSAPIGateway2RouteResponseConfig_basic(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAPIGateway2RouteResponseExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "model_selection_expression", ""),
resource.TestCheckResourceAttr(resourceName, "response_models.%", "0"),
resource.TestCheckResourceAttrPair(resourceName, "route_id", routeResourceName, "id"),
resource.TestCheckResourceAttr(resourceName, "route_response_key", "$default"),
),
},
{
ResourceName: resourceName,
ImportStateIdFunc: testAccAWSAPIGateway2RouteResponseImportStateIdFunc(resourceName),
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAWSAPIGateway2RouteResponse_Model(t *testing.T) {
resourceName := "aws_api_gateway_v2_route_response.test"
modelResourceName := "aws_api_gateway_v2_model.test"
routeResourceName := "aws_api_gateway_v2_route.test"
rName := fmt.Sprintf("tftestaccapigwv2%s", acctest.RandStringFromCharSet(16, acctest.CharSetAlphaNum))

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSAPIGateway2RouteResponseDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSAPIGateway2RouteResponseConfig_model(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAPIGateway2RouteResponseExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "model_selection_expression", "action"),
resource.TestCheckResourceAttr(resourceName, "response_models.%", "1"),
resource.TestCheckResourceAttrPair(resourceName, "response_models.test", modelResourceName, "name"),
resource.TestCheckResourceAttrPair(resourceName, "route_id", routeResourceName, "id"),
resource.TestCheckResourceAttr(resourceName, "route_response_key", "$default"),
),
},
{
ResourceName: resourceName,
ImportStateIdFunc: testAccAWSAPIGateway2RouteResponseImportStateIdFunc(resourceName),
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccCheckAWSAPIGateway2RouteResponseDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).apigatewayv2conn

for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_api_gateway_v2_route_response" {
continue
}

_, err := conn.GetRouteResponse(&apigatewayv2.GetRouteResponseInput{
ApiId: aws.String(rs.Primary.Attributes["api_id"]),
RouteId: aws.String(rs.Primary.Attributes["route_id"]),
RouteResponseId: aws.String(rs.Primary.ID),
})
if isAWSErr(err, apigatewayv2.ErrCodeNotFoundException, "") {
continue
}
if err != nil {
return err
}

return fmt.Errorf("API Gateway v2 route response %s still exists", rs.Primary.ID)
}

return nil
}

func testAccCheckAWSAPIGateway2RouteResponseExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("No API Gateway v2 route response ID is set")
}

conn := testAccProvider.Meta().(*AWSClient).apigatewayv2conn

_, err := conn.GetRouteResponse(&apigatewayv2.GetRouteResponseInput{
ApiId: aws.String(rs.Primary.Attributes["api_id"]),
RouteId: aws.String(rs.Primary.Attributes["route_id"]),
RouteResponseId: aws.String(rs.Primary.ID),
})
if err != nil {
return err
}

return nil
}
}

func testAccAWSAPIGateway2RouteResponseImportStateIdFunc(resourceName string) resource.ImportStateIdFunc {
return func(s *terraform.State) (string, error) {
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return "", fmt.Errorf("Not Found: %s", resourceName)
}

return fmt.Sprintf("%s/%s/%s", rs.Primary.Attributes["api_id"], rs.Primary.Attributes["route_id"], rs.Primary.ID), nil
}
}

func testAccAWSAPIGateway2RouteResponseConfig_basic(rName string) string {
return testAccAWSAPIGatewayV2RouteConfig_basic(rName) + fmt.Sprintf(`
resource "aws_api_gateway_v2_route_response" "test" {
api_id = "${aws_api_gateway_v2_api.test.id}"
route_id = "${aws_api_gateway_v2_route.test.id}"
route_response_key = "$default"
}
`)
}

func testAccAWSAPIGateway2RouteResponseConfig_model(rName string) string {
return testAccAWSAPIGatewayV2RouteConfig_model(rName) + fmt.Sprintf(`
resource "aws_api_gateway_v2_route_response" "test" {
api_id = "${aws_api_gateway_v2_api.test.id}"
route_id = "${aws_api_gateway_v2_route.test.id}"
route_response_key = "$default"
model_selection_expression = "action"
response_models = {
"test" = "${aws_api_gateway_v2_model.test.name}"
}
}
`)
}
3 changes: 3 additions & 0 deletions website/aws.erb
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@
<li>
<a href="/docs/providers/aws/r/apigatewayv2_route.html">aws_apigatewayv2_route</a>
</li>
<li>
<a href="/docs/providers/aws/r/api_gateway_v2_route_response.html">aws_api_gateway_v2_route_response</a>
</li>
</ul>
</li>
</ul>
Expand Down
48 changes: 48 additions & 0 deletions website/docs/r/api_gateway_v2_route_response.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
layout: "aws"
page_title: "AWS: aws_api_gateway_v2_route_response"
sidebar_current: "docs-aws-resource-api-gateway-v2-route-response"
description: |-
Manages an Amazon API Gateway Version 2 route response.
---

# Resource: aws_api_gateway_v2_route_response

Manages an Amazon API Gateway Version 2 route response.
More information can be found in the [Amazon API Gateway Developer Guide](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api.html).

## Example Usage

### Basic

```hcl
resource "aws_api_gateway_v2_route_response" "example" {
api_id = "${aws_api_gateway_v2_api.example.id}"
route_id = "${aws_api_gateway_v2_route.example.id}"
route_response_key = "$default"
}
```

## Argument Reference

The following arguments are supported:

* `api_id` - (Required) The API identifier.
* `route_id` - (Required) The identifier of the [`aws_api_gateway_v2_route`](/docs/providers/aws/r/api_gateway_v2_route.html).
* `route_response_key` - (Required) The route response key.
* `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 response.
* `response_models` - (Optional) The response models for the route response.

## Attribute Reference

In addition to all arguments above, the following attributes are exported:

* `id` - The route response identifier.

## Import

`aws_api_gateway_v2_route_response` can be imported by using the API identifier, route identifier and route response identifier, e.g.

```
$ terraform import aws_api_gateway_v2_route.example aabbccddee/1122334/998877
```

0 comments on commit 7ecef9c

Please sign in to comment.