Skip to content

Commit

Permalink
Merge pull request #1168 from Ninir/f-apigw-gateway-responses
Browse files Browse the repository at this point in the history
Added API Gateway Gateway response resource
  • Loading branch information
Ninir authored Jul 18, 2017
2 parents 8a74511 + 86cd267 commit ee59d89
Show file tree
Hide file tree
Showing 5 changed files with 340 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 @@ -235,6 +235,7 @@ func Provider() terraform.ResourceProvider {
"aws_api_gateway_client_certificate": resourceAwsApiGatewayClientCertificate(),
"aws_api_gateway_deployment": resourceAwsApiGatewayDeployment(),
"aws_api_gateway_domain_name": resourceAwsApiGatewayDomainName(),
"aws_api_gateway_gateway_response": resourceAwsApiGatewayGatewayResponse(),
"aws_api_gateway_integration": resourceAwsApiGatewayIntegration(),
"aws_api_gateway_integration_response": resourceAwsApiGatewayIntegrationResponse(),
"aws_api_gateway_method": resourceAwsApiGatewayMethod(),
Expand Down
145 changes: 145 additions & 0 deletions aws/resource_aws_api_gateway_gateway_response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package aws

import (
"fmt"
"log"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/apigateway"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsApiGatewayGatewayResponse() *schema.Resource {
return &schema.Resource{
Create: resourceAwsApiGatewayGatewayResponsePut,
Read: resourceAwsApiGatewayGatewayResponseRead,
Update: resourceAwsApiGatewayGatewayResponsePut,
Delete: resourceAwsApiGatewayGatewayResponseDelete,

Schema: map[string]*schema.Schema{
"rest_api_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"response_type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"status_code": {
Type: schema.TypeString,
Optional: true,
},

"response_templates": {
Type: schema.TypeMap,
Elem: schema.TypeString,
Optional: true,
},

"response_parameters": {
Type: schema.TypeMap,
Elem: schema.TypeString,
Optional: true,
},
},
}
}

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

templates := make(map[string]string)
if kv, ok := d.GetOk("response_templates"); ok {
for k, v := range kv.(map[string]interface{}) {
templates[k] = v.(string)
}
}

parameters := make(map[string]string)
if kv, ok := d.GetOk("response_parameters"); ok {
for k, v := range kv.(map[string]interface{}) {
parameters[k] = v.(string)
}
}

input := apigateway.PutGatewayResponseInput{
RestApiId: aws.String(d.Get("rest_api_id").(string)),
ResponseType: aws.String(d.Get("response_type").(string)),
ResponseTemplates: aws.StringMap(templates),
ResponseParameters: aws.StringMap(parameters),
}

if v, ok := d.GetOk("status_code"); ok {
input.StatusCode = aws.String(v.(string))
}

log.Printf("[DEBUG] Putting API Gateway Gateway Response: %s", input)

_, err := conn.PutGatewayResponse(&input)
if err != nil {
return fmt.Errorf("Error putting API Gateway Gateway Response: %s", err)
}

d.SetId(fmt.Sprintf("aggr-%s-%s", d.Get("rest_api_id").(string), d.Get("response_type").(string)))
log.Printf("[DEBUG] API Gateway Gateway Response put (%q)", d.Id())

return resourceAwsApiGatewayGatewayResponseRead(d, meta)
}

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

log.Printf("[DEBUG] Reading API Gateway Gateway Response %s", d.Id())
gatewayResponse, err := conn.GetGatewayResponse(&apigateway.GetGatewayResponseInput{
RestApiId: aws.String(d.Get("rest_api_id").(string)),
ResponseType: aws.String(d.Get("response_type").(string)),
})
if err != nil {
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NotFoundException" {
log.Printf("[WARN] API Gateway Gateway Response (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}
return err
}

log.Printf("[DEBUG] Received API Gateway Gateway Response: %s", gatewayResponse)

d.Set("response_type", gatewayResponse.ResponseType)
d.Set("status_code", gatewayResponse.StatusCode)
d.Set("response_templates", aws.StringValueMap(gatewayResponse.ResponseTemplates))
d.Set("response_parameters", aws.StringValueMap(gatewayResponse.ResponseParameters))

return nil
}

func resourceAwsApiGatewayGatewayResponseDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigateway
log.Printf("[DEBUG] Deleting API Gateway Gateway Response: %s", d.Id())

return resource.Retry(1*time.Minute, func() *resource.RetryError {
_, err := conn.DeleteGatewayResponse(&apigateway.DeleteGatewayResponseInput{
RestApiId: aws.String(d.Get("rest_api_id").(string)),
ResponseType: aws.String(d.Get("response_type").(string)),
})

if err == nil {
return nil
}

apigatewayErr, ok := err.(awserr.Error)

if ok && apigatewayErr.Code() == "NotFoundException" {
return nil
}

return resource.NonRetryableError(err)
})
}
148 changes: 148 additions & 0 deletions aws/resource_aws_api_gateway_gateway_response_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package aws

import (
"fmt"
"testing"

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

func TestAccAWSAPIGatewayGatewayResponse_basic(t *testing.T) {
var conf apigateway.UpdateGatewayResponseOutput

rName := acctest.RandString(10)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSAPIGatewayGatewayResponseDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSAPIGatewayGatewayResponseConfig(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAPIGatewayGatewayResponseExists("aws_api_gateway_gateway_response.test", &conf),
resource.TestCheckResourceAttr("aws_api_gateway_gateway_response.test", "status_code", "401"),
resource.TestCheckResourceAttr("aws_api_gateway_gateway_response.test", "response_parameters.gatewayresponse.header.Authorization", "'Basic'"),
resource.TestCheckResourceAttr("aws_api_gateway_gateway_response.test", "response_templates.application/xml", "#set($inputRoot = $input.path('$'))\n{ }"),
resource.TestCheckNoResourceAttr("aws_api_gateway_gateway_response.test", "response_templates.application/json"),
),
},

{
Config: testAccAWSAPIGatewayGatewayResponseConfigUpdate(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAPIGatewayGatewayResponseExists("aws_api_gateway_gateway_response.test", &conf),
resource.TestCheckResourceAttr("aws_api_gateway_gateway_response.test", "status_code", "477"),
resource.TestCheckResourceAttr("aws_api_gateway_gateway_response.test", "response_templates.application/json", "{'message':$context.error.messageString}"),
resource.TestCheckNoResourceAttr("aws_api_gateway_gateway_response.test", "response_templates.application/xml"),
resource.TestCheckNoResourceAttr("aws_api_gateway_gateway_response.test", "response_parameters.gatewayresponse.header.Authorization"),
),
},
},
})
}

func testAccCheckAWSAPIGatewayGatewayResponseExists(n string, res *apigateway.UpdateGatewayResponseOutput) 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 Gateway Response ID is set")
}

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

req := &apigateway.GetGatewayResponseInput{
RestApiId: aws.String(s.RootModule().Resources["aws_api_gateway_rest_api.main"].Primary.ID),
ResponseType: aws.String(rs.Primary.Attributes["response_type"]),
}
describe, err := conn.GetGatewayResponse(req)
if err != nil {
return err
}

*res = *describe

return nil
}
}

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

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

req := &apigateway.GetGatewayResponseInput{
RestApiId: aws.String(s.RootModule().Resources["aws_api_gateway_rest_api.main"].Primary.ID),
ResponseType: aws.String(rs.Primary.Attributes["response_type"]),
}
_, err := conn.GetGatewayResponse(req)

if err == nil {
return fmt.Errorf("API Gateway Gateway Response still exists")
}

aws2err, ok := err.(awserr.Error)
if !ok {
return err
}
if aws2err.Code() != "NotFoundException" {
return err
}

return nil
}

return nil
}

func testAccAWSAPIGatewayGatewayResponseConfig(rName string) string {
return fmt.Sprintf(`
resource "aws_api_gateway_rest_api" "main" {
name = "%s"
}
resource "aws_api_gateway_gateway_response" "test" {
rest_api_id = "${aws_api_gateway_rest_api.main.id}"
status_code = "401"
response_type = "UNAUTHORIZED"
response_templates = {
"application/xml" = "#set($inputRoot = $input.path('$'))\n{ }"
}
response_parameters = {
"gatewayresponse.header.Authorization" = "'Basic'"
}
}
`, rName)
}

func testAccAWSAPIGatewayGatewayResponseConfigUpdate(rName string) string {
return fmt.Sprintf(`
resource "aws_api_gateway_rest_api" "main" {
name = "%s"
}
resource "aws_api_gateway_gateway_response" "test" {
rest_api_id = "${aws_api_gateway_rest_api.main.id}"
status_code = "477"
response_type = "UNAUTHORIZED"
response_templates = {
"application/json" = "{'message':$context.error.messageString}"
}
}
`, rName)
}
3 changes: 3 additions & 0 deletions website/aws.erb
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@
<li<%= sidebar_current("docs-aws-resource-api-gateway-domain-name") %>>
<a href="/docs/providers/aws/r/api_gateway_domain_name.html">aws_api_gateway_domain_name</a>
</li>
<li<%= sidebar_current("docs-aws-resource-api-gateway-gateway-response") %>>
<a href="/docs/providers/aws/r/api_gateway_gateway_response.html">aws_api_gateway_gateway_response</a>
</li>
<li<%= sidebar_current("docs-aws-resource-api-gateway-integration") %>>
<a href="/docs/providers/aws/r/api_gateway_integration.html">aws_api_gateway_integration</a>
</li>
Expand Down
43 changes: 43 additions & 0 deletions website/docs/r/api_gateway_gateway_response.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
layout: "aws"
page_title: "AWS: aws_api_gateway_gateway_response"
sidebar_current: "docs-aws-resource-api-gateway-gateway-response"
description: |-
Provides an API Gateway Gateway Response for a REST API Gateway.
---

# aws\_api\_gateway\_gateway\_response

Provides an API Gateway Gateway Response for a REST API Gateway.

## Example Usage

```hcl
resource "aws_api_gateway_rest_api" "main" {
name = "MyDemoAPI"
}
resource "aws_api_gateway_gateway_response" "test" {
rest_api_id = "${aws_api_gateway_rest_api.main.id}"
status_code = "401"
response_type = "UNAUTHORIZED"
response_templates = {
"application/json" = "{'message':$context.error.messageString}"
}
response_parameters = {
"gatewayresponse.header.Authorization" = "'Basic'"
}
}
```

## Argument Reference

The following arguments are supported:

* `rest_api_id` - (Required) The string identifier of the associated REST API.
* `response_type` - (Required) The response type of the associated GatewayResponse.
* `status_code` - (Optional) The HTTP status code of the Gateway Response.
* `response_parameters` - (Optional) A map specifying the templates used to transform the response body.
* `response_templates` - (Optional) A map specifying the parameters (paths, query strings and headers) of the Gateway Response.

0 comments on commit ee59d89

Please sign in to comment.