provider/aws: Added API Gateway integration update (#13249)

This commit is contained in:
Gauthier Wallet 2017-03-31 18:45:06 +02:00 committed by Paul Stack
parent 6ed873b72d
commit 42557dae12
3 changed files with 251 additions and 93 deletions

View File

@ -11,87 +11,94 @@ import (
"github.com/aws/aws-sdk-go/service/apigateway"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"strings"
)
func resourceAwsApiGatewayIntegration() *schema.Resource {
return &schema.Resource{
Create: resourceAwsApiGatewayIntegrationCreate,
Read: resourceAwsApiGatewayIntegrationRead,
Update: resourceAwsApiGatewayIntegrationCreate,
Update: resourceAwsApiGatewayIntegrationUpdate,
Delete: resourceAwsApiGatewayIntegrationDelete,
Schema: map[string]*schema.Schema{
"rest_api_id": &schema.Schema{
"rest_api_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"resource_id": &schema.Schema{
"resource_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"http_method": &schema.Schema{
"http_method": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateHTTPMethod,
},
"type": &schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateApiGatewayIntegrationType,
},
"uri": &schema.Schema{
"uri": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"credentials": &schema.Schema{
"credentials": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"integration_http_method": &schema.Schema{
"integration_http_method": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validateHTTPMethod,
},
"request_templates": &schema.Schema{
"request_templates": {
Type: schema.TypeMap,
Optional: true,
Elem: schema.TypeString,
},
"request_parameters": &schema.Schema{
"request_parameters": {
Type: schema.TypeMap,
Elem: schema.TypeString,
Optional: true,
ConflictsWith: []string{"request_parameters_in_json"},
},
"request_parameters_in_json": &schema.Schema{
"request_parameters_in_json": {
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"request_parameters"},
Deprecated: "Use field request_parameters instead",
},
"content_handling": &schema.Schema{
"content_handling": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validateApiGatewayIntegrationContentHandling,
},
"passthrough_behavior": &schema.Schema{
"passthrough_behavior": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ValidateFunc: validateApiGatewayIntegrationPassthroughBehavior,
},
},
@ -101,6 +108,7 @@ func resourceAwsApiGatewayIntegration() *schema.Resource {
func resourceAwsApiGatewayIntegrationCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigateway
log.Print("[DEBUG] Creating API Gateway Integration")
var integrationHttpMethod *string
if v, ok := d.GetOk("integration_http_method"); ok {
integrationHttpMethod = aws.String(v.(string))
@ -163,13 +171,13 @@ func resourceAwsApiGatewayIntegrationCreate(d *schema.ResourceData, meta interfa
d.SetId(fmt.Sprintf("agi-%s-%s-%s", d.Get("rest_api_id").(string), d.Get("resource_id").(string), d.Get("http_method").(string)))
return nil
return resourceAwsApiGatewayIntegrationRead(d, meta)
}
func resourceAwsApiGatewayIntegrationRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigateway
log.Printf("[DEBUG] Reading API Gateway Integration %s", d.Id())
log.Printf("[DEBUG] Reading API Gateway Integration: %s", d.Id())
integration, err := conn.GetIntegration(&apigateway.GetIntegrationInput{
HttpMethod: aws.String(d.Get("http_method").(string)),
ResourceId: aws.String(d.Get("resource_id").(string)),
@ -191,17 +199,127 @@ func resourceAwsApiGatewayIntegrationRead(d *schema.ResourceData, meta interface
}
d.Set("request_templates", aws.StringValueMap(integration.RequestTemplates))
d.Set("credentials", integration.Credentials)
d.Set("type", integration.Type)
d.Set("uri", integration.Uri)
d.Set("request_parameters", aws.StringValueMap(integration.RequestParameters))
d.Set("request_parameters_in_json", aws.StringValueMap(integration.RequestParameters))
d.Set("passthrough_behavior", integration.PassthroughBehavior)
d.Set("content_handling", integration.ContentHandling)
if integration.Uri != nil {
d.Set("uri", integration.Uri)
}
if integration.Credentials != nil {
d.Set("credentials", integration.Credentials)
}
if integration.ContentHandling != nil {
d.Set("content_handling", integration.ContentHandling)
}
return nil
}
func resourceAwsApiGatewayIntegrationUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigateway
log.Printf("[DEBUG] Updating API Gateway Integration: %s", d.Id())
operations := make([]*apigateway.PatchOperation, 0)
// https://docs.aws.amazon.com/apigateway/api-reference/link-relation/integration-update/#remarks
// According to the above documentation, only a few parts are addable / removable.
if d.HasChange("request_templates") {
o, n := d.GetChange("request_templates")
prefix := "requestTemplates"
os := o.(map[string]interface{})
ns := n.(map[string]interface{})
// Handle Removal
for k := range os {
if _, ok := ns[k]; !ok {
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String("remove"),
Path: aws.String(fmt.Sprintf("/%s/%s", prefix, strings.Replace(k, "/", "~1", -1))),
})
}
}
for k, v := range ns {
// Handle replaces
if _, ok := os[k]; ok {
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String("replace"),
Path: aws.String(fmt.Sprintf("/%s/%s", prefix, strings.Replace(k, "/", "~1", -1))),
Value: aws.String(v.(string)),
})
}
// Handle additions
if _, ok := os[k]; !ok {
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String("add"),
Path: aws.String(fmt.Sprintf("/%s/%s", prefix, strings.Replace(k, "/", "~1", -1))),
Value: aws.String(v.(string)),
})
}
}
}
if d.HasChange("request_parameters") {
o, n := d.GetChange("request_parameters")
prefix := "requestParameters"
os := o.(map[string]interface{})
ns := n.(map[string]interface{})
// Handle Removal
for k := range os {
if _, ok := ns[k]; !ok {
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String("remove"),
Path: aws.String(fmt.Sprintf("/%s/%s", prefix, strings.Replace(k, "/", "~1", -1))),
})
}
}
for k, v := range ns {
// Handle replaces
if _, ok := os[k]; ok {
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String("replace"),
Path: aws.String(fmt.Sprintf("/%s/%s", prefix, strings.Replace(k, "/", "~1", -1))),
Value: aws.String(v.(string)),
})
}
// Handle additions
if _, ok := os[k]; !ok {
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String("add"),
Path: aws.String(fmt.Sprintf("/%s/%s", prefix, strings.Replace(k, "/", "~1", -1))),
Value: aws.String(v.(string)),
})
}
}
}
params := &apigateway.UpdateIntegrationInput{
HttpMethod: aws.String(d.Get("http_method").(string)),
ResourceId: aws.String(d.Get("resource_id").(string)),
RestApiId: aws.String(d.Get("rest_api_id").(string)),
PatchOperations: operations,
}
_, err := conn.UpdateIntegration(params)
if err != nil {
return fmt.Errorf("Error updating API Gateway Integration: %s", err)
}
d.SetId(fmt.Sprintf("agi-%s-%s-%s", d.Get("rest_api_id").(string), d.Get("resource_id").(string), d.Get("http_method").(string)))
return resourceAwsApiGatewayIntegrationRead(d, meta)
}
func resourceAwsApiGatewayIntegrationDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigateway
log.Printf("[DEBUG] Deleting API Gateway Integration: %s", d.Id())

View File

@ -19,88 +19,80 @@ func TestAccAWSAPIGatewayIntegration_basic(t *testing.T) {
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSAPIGatewayIntegrationDestroy,
Steps: []resource.TestStep{
resource.TestStep{
{
Config: testAccAWSAPIGatewayIntegrationConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAPIGatewayIntegrationExists("aws_api_gateway_integration.test", &conf),
testAccCheckAWSAPIGatewayIntegrationAttributes(&conf),
resource.TestCheckResourceAttr(
"aws_api_gateway_integration.test", "type", "HTTP"),
resource.TestCheckResourceAttr(
"aws_api_gateway_integration.test", "integration_http_method", "GET"),
resource.TestCheckResourceAttr(
"aws_api_gateway_integration.test", "uri", "https://www.google.de"),
resource.TestCheckResourceAttr(
"aws_api_gateway_integration.test", "request_templates.application/json", ""),
resource.TestCheckResourceAttr(
"aws_api_gateway_integration.test", "request_templates.application/xml", "#set($inputRoot = $input.path('$'))\n{ }"),
resource.TestCheckResourceAttr(
"aws_api_gateway_integration.test", "passthrough_behavior", "WHEN_NO_MATCH"),
resource.TestCheckNoResourceAttr(
"aws_api_gateway_integration.test", "content_handling"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "type", "HTTP"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "integration_http_method", "GET"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "uri", "https://www.google.de"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "passthrough_behavior", "WHEN_NO_MATCH"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "content_handling", "CONVERT_TO_TEXT"),
resource.TestCheckNoResourceAttr("aws_api_gateway_integration.test", "credentials"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_parameters.%", "2"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_parameters.integration.request.header.X-Authorization", "'static'"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_parameters.integration.request.header.X-Foo", "'Bar'"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_templates.%", "2"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_templates.application/json", ""),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_templates.application/xml", "#set($inputRoot = $input.path('$'))\n{ }"),
),
},
resource.TestStep{
{
Config: testAccAWSAPIGatewayIntegrationConfigUpdate,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAPIGatewayIntegrationExists("aws_api_gateway_integration.test", &conf),
testAccCheckAWSAPIGatewayMockIntegrationAttributes(&conf),
resource.TestCheckResourceAttr(
"aws_api_gateway_integration.test", "type", "MOCK"),
resource.TestCheckResourceAttr(
"aws_api_gateway_integration.test", "integration_http_method", ""),
resource.TestCheckResourceAttr(
"aws_api_gateway_integration.test", "uri", ""),
resource.TestCheckResourceAttr(
"aws_api_gateway_integration.test", "passthrough_behavior", "NEVER"),
resource.TestCheckResourceAttr(
"aws_api_gateway_integration.test", "content_handling", "CONVERT_TO_BINARY"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "type", "HTTP"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "integration_http_method", "GET"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "uri", "https://www.google.de"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "passthrough_behavior", "WHEN_NO_MATCH"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "content_handling", "CONVERT_TO_TEXT"),
resource.TestCheckNoResourceAttr("aws_api_gateway_integration.test", "credentials"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_parameters.%", "2"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_parameters.integration.request.header.X-Authorization", "'updated'"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_parameters.integration.request.header.X-FooBar", "'Baz'"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_templates.%", "2"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_templates.application/json", "{'foobar': 'bar}"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_templates.text/html", "<html>Foo</html>"),
),
},
{
Config: testAccAWSAPIGatewayIntegrationConfigUpdateNoTemplates,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAPIGatewayIntegrationExists("aws_api_gateway_integration.test", &conf),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "type", "HTTP"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "integration_http_method", "GET"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "uri", "https://www.google.de"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "passthrough_behavior", "WHEN_NO_MATCH"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "content_handling", "CONVERT_TO_TEXT"),
resource.TestCheckNoResourceAttr("aws_api_gateway_integration.test", "credentials"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_parameters.%", "0"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_templates.%", "0"),
),
},
{
Config: testAccAWSAPIGatewayIntegrationConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAPIGatewayIntegrationExists("aws_api_gateway_integration.test", &conf),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "type", "HTTP"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "integration_http_method", "GET"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "uri", "https://www.google.de"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "passthrough_behavior", "WHEN_NO_MATCH"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "content_handling", "CONVERT_TO_TEXT"),
resource.TestCheckNoResourceAttr("aws_api_gateway_integration.test", "credentials"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_parameters.%", "2"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_parameters.integration.request.header.X-Authorization", "'static'"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_templates.%", "2"),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_templates.application/json", ""),
resource.TestCheckResourceAttr("aws_api_gateway_integration.test", "request_templates.application/xml", "#set($inputRoot = $input.path('$'))\n{ }"),
),
},
},
})
}
func testAccCheckAWSAPIGatewayMockIntegrationAttributes(conf *apigateway.Integration) resource.TestCheckFunc {
return func(s *terraform.State) error {
if *conf.Type != "MOCK" {
return fmt.Errorf("Wrong Type: %q", *conf.Type)
}
if *conf.RequestParameters["integration.request.header.X-Authorization"] != "'updated'" {
return fmt.Errorf("wrong updated RequestParameters for header.X-Authorization")
}
if *conf.ContentHandling != "CONVERT_TO_BINARY" {
return fmt.Errorf("wrong ContentHandling: %q", *conf.ContentHandling)
}
return nil
}
}
func testAccCheckAWSAPIGatewayIntegrationAttributes(conf *apigateway.Integration) resource.TestCheckFunc {
return func(s *terraform.State) error {
if *conf.HttpMethod == "" {
return fmt.Errorf("empty HttpMethod")
}
if *conf.Uri != "https://www.google.de" {
return fmt.Errorf("wrong Uri")
}
if *conf.Type != "HTTP" {
return fmt.Errorf("wrong Type")
}
if conf.RequestTemplates["application/json"] != nil {
return fmt.Errorf("wrong RequestTemplate for application/json")
}
if *conf.RequestTemplates["application/xml"] != "#set($inputRoot = $input.path('$'))\n{ }" {
return fmt.Errorf("wrong RequestTemplate for application/xml")
}
if *conf.RequestParameters["integration.request.header.X-Authorization"] != "'static'" {
return fmt.Errorf("wrong RequestParameters for header.X-Authorization")
}
return nil
}
}
func testAccCheckAWSAPIGatewayIntegrationExists(n string, res *apigateway.Integration) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
@ -196,13 +188,15 @@ resource "aws_api_gateway_integration" "test" {
}
request_parameters = {
"integration.request.header.X-Authorization" = "'static'"
"integration.request.header.X-Authorization" = "'static'"
"integration.request.header.X-Foo" = "'Bar'"
}
type = "HTTP"
uri = "https://www.google.de"
integration_http_method = "GET"
passthrough_behavior = "WHEN_NO_MATCH"
content_handling = "CONVERT_TO_TEXT"
}
`
@ -233,13 +227,55 @@ resource "aws_api_gateway_integration" "test" {
resource_id = "${aws_api_gateway_resource.test.id}"
http_method = "${aws_api_gateway_method.test.http_method}"
request_parameters = {
"integration.request.header.X-Authorization" = "'updated'"
request_templates = {
"application/json" = "{'foobar': 'bar}"
"text/html" = "<html>Foo</html>"
}
type = "MOCK"
passthrough_behavior = "NEVER"
content_handling = "CONVERT_TO_BINARY"
request_parameters = {
"integration.request.header.X-Authorization" = "'updated'"
"integration.request.header.X-FooBar" = "'Baz'"
}
type = "HTTP"
uri = "https://www.google.de"
integration_http_method = "GET"
passthrough_behavior = "WHEN_NO_MATCH"
content_handling = "CONVERT_TO_TEXT"
}
`
const testAccAWSAPIGatewayIntegrationConfigUpdateNoTemplates = `
resource "aws_api_gateway_rest_api" "test" {
name = "test"
}
resource "aws_api_gateway_resource" "test" {
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
parent_id = "${aws_api_gateway_rest_api.test.root_resource_id}"
path_part = "test"
}
resource "aws_api_gateway_method" "test" {
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
resource_id = "${aws_api_gateway_resource.test.id}"
http_method = "GET"
authorization = "NONE"
request_models = {
"application/json" = "Error"
}
}
resource "aws_api_gateway_integration" "test" {
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
resource_id = "${aws_api_gateway_resource.test.id}"
http_method = "${aws_api_gateway_method.test.http_method}"
type = "HTTP"
uri = "https://www.google.de"
integration_http_method = "GET"
passthrough_behavior = "WHEN_NO_MATCH"
content_handling = "CONVERT_TO_TEXT"
}
`

View File

@ -3,12 +3,12 @@ layout: "aws"
page_title: "AWS: aws_api_gateway_integration"
sidebar_current: "docs-aws-resource-api-gateway-integration"
description: |-
Provides an HTTP Method Integration for an API Gateway Resource.
Provides an HTTP Method Integration for an API Gateway Integration.
---
# aws\_api\_gateway\_integration
Provides an HTTP Method Integration for an API Gateway Resource.
Provides an HTTP Method Integration for an API Gateway Integration.
## Example Usage
@ -37,6 +37,10 @@ resource "aws_api_gateway_integration" "MyDemoIntegration" {
http_method = "${aws_api_gateway_method.MyDemoMethod.http_method}"
type = "MOCK"
request_parameters = {
"integration.request.header.X-Authorization" = "'static'"
}
# Transforms the incoming XML request to JSON
request_templates {
"application/xml" = <<EOF