From 86cd26750f1bd2b7aff023c2c44b884bd6b28fe2 Mon Sep 17 00:00:00 2001 From: Ninir Date: Mon, 17 Jul 2017 14:46:29 +0200 Subject: [PATCH] Added API Gateway Gateway response resource --- aws/provider.go | 1 + ...source_aws_api_gateway_gateway_response.go | 145 +++++++++++++++++ ...e_aws_api_gateway_gateway_response_test.go | 148 ++++++++++++++++++ website/aws.erb | 3 + .../r/api_gateway_gateway_response.markdown | 43 +++++ 5 files changed, 340 insertions(+) create mode 100644 aws/resource_aws_api_gateway_gateway_response.go create mode 100644 aws/resource_aws_api_gateway_gateway_response_test.go create mode 100644 website/docs/r/api_gateway_gateway_response.markdown diff --git a/aws/provider.go b/aws/provider.go index e06823c7b21..e9b79881bfa 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -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(), diff --git a/aws/resource_aws_api_gateway_gateway_response.go b/aws/resource_aws_api_gateway_gateway_response.go new file mode 100644 index 00000000000..105d1227f24 --- /dev/null +++ b/aws/resource_aws_api_gateway_gateway_response.go @@ -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) + }) +} diff --git a/aws/resource_aws_api_gateway_gateway_response_test.go b/aws/resource_aws_api_gateway_gateway_response_test.go new file mode 100644 index 00000000000..c2dc74362f3 --- /dev/null +++ b/aws/resource_aws_api_gateway_gateway_response_test.go @@ -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) +} diff --git a/website/aws.erb b/website/aws.erb index 1b0f0414c1b..828db6e79a7 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -212,6 +212,9 @@ > aws_api_gateway_domain_name + > + aws_api_gateway_gateway_response + > aws_api_gateway_integration diff --git a/website/docs/r/api_gateway_gateway_response.markdown b/website/docs/r/api_gateway_gateway_response.markdown new file mode 100644 index 00000000000..ba9c4e1075b --- /dev/null +++ b/website/docs/r/api_gateway_gateway_response.markdown @@ -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.