Skip to content

Commit

Permalink
New Resource: aws_api_gateway_vpc_link (#2512)
Browse files Browse the repository at this point in the history
* WIP

* Add acctest, docs

* Reflect reviews except one

* wip

* wip

* Modify

* updates

* reflect reviews
  • Loading branch information
atsushi-ishibashi authored and radeksimko committed Feb 16, 2018
1 parent 14cb471 commit 564e006
Show file tree
Hide file tree
Showing 5 changed files with 386 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 @@ -268,6 +268,7 @@ func Provider() terraform.ResourceProvider {
"aws_api_gateway_stage": resourceAwsApiGatewayStage(),
"aws_api_gateway_usage_plan": resourceAwsApiGatewayUsagePlan(),
"aws_api_gateway_usage_plan_key": resourceAwsApiGatewayUsagePlanKey(),
"aws_api_gateway_vpc_link": resourceAwsApiGatewayVpcLink(),
"aws_app_cookie_stickiness_policy": resourceAwsAppCookieStickinessPolicy(),
"aws_appautoscaling_target": resourceAwsAppautoscalingTarget(),
"aws_appautoscaling_policy": resourceAwsAppautoscalingPolicy(),
Expand Down
205 changes: 205 additions & 0 deletions aws/resource_aws_api_gateway_vpc_link.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
package aws

import (
"fmt"
"log"
"time"

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

func resourceAwsApiGatewayVpcLink() *schema.Resource {
return &schema.Resource{
Create: resourceAwsApiGatewayVpcLinkCreate,
Read: resourceAwsApiGatewayVpcLinkRead,
Update: resourceAwsApiGatewayVpcLinkUpdate,
Delete: resourceAwsApiGatewayVpcLinkDelete,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"target_arns": {
Type: schema.TypeSet,
MaxItems: 1,
Required: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
}
}

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

input := &apigateway.CreateVpcLinkInput{
Name: aws.String(d.Get("name").(string)),
TargetArns: expandStringList(d.Get("target_arns").(*schema.Set).List()),
}
if v, ok := d.GetOk("description"); ok {
input.Description = aws.String(v.(string))
}

resp, err := conn.CreateVpcLink(input)
if err != nil {
return err
}

d.SetId(*resp.Id)

stateConf := &resource.StateChangeConf{
Pending: []string{apigateway.VpcLinkStatusPending},
Target: []string{apigateway.VpcLinkStatusAvailable},
Refresh: apigatewayVpcLinkRefreshStatusFunc(conn, *resp.Id),
Timeout: 8 * time.Minute,
MinTimeout: 3 * time.Second,
}

_, err = stateConf.WaitForState()
if err != nil {
d.SetId("")
return fmt.Errorf("[WARN] Error waiting for APIGateway Vpc Link status to be \"%s\": %s", apigateway.VpcLinkStatusAvailable, err)
}

return nil
}

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

input := &apigateway.GetVpcLinkInput{
VpcLinkId: aws.String(d.Id()),
}

resp, err := conn.GetVpcLink(input)
if err != nil {
if isAWSErr(err, apigateway.ErrCodeNotFoundException, "") {
log.Printf("[WARN] VPC Link %s not found, removing from state", d.Id())
d.SetId("")
return nil
}
return err
}

d.Set("name", resp.Name)
d.Set("description", resp.Description)
d.Set("target_arn", flattenStringList(resp.TargetArns))
return nil
}

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

operations := make([]*apigateway.PatchOperation, 0)

if d.HasChange("name") {
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String("replace"),
Path: aws.String("/name"),
Value: aws.String(d.Get("name").(string)),
})
}

if d.HasChange("description") {
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String("replace"),
Path: aws.String("/description"),
Value: aws.String(d.Get("description").(string)),
})
}

input := &apigateway.UpdateVpcLinkInput{
VpcLinkId: aws.String(d.Id()),
PatchOperations: operations,
}

_, err := conn.UpdateVpcLink(input)
if err != nil {
if isAWSErr(err, apigateway.ErrCodeNotFoundException, "") {
log.Printf("[WARN] VPC Link %s not found, removing from state", d.Id())
d.SetId("")
return nil
}
return err
}

stateConf := &resource.StateChangeConf{
Pending: []string{apigateway.VpcLinkStatusPending},
Target: []string{apigateway.VpcLinkStatusAvailable},
Refresh: apigatewayVpcLinkRefreshStatusFunc(conn, d.Id()),
Timeout: 8 * time.Minute,
MinTimeout: 3 * time.Second,
}

_, err = stateConf.WaitForState()
if err != nil {
return fmt.Errorf("[WARN] Error waiting for APIGateway Vpc Link status to be \"%s\": %s", apigateway.VpcLinkStatusAvailable, err)
}

return nil
}

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

input := &apigateway.DeleteVpcLinkInput{
VpcLinkId: aws.String(d.Id()),
}

_, err := conn.DeleteVpcLink(input)
if err != nil {
if isAWSErr(err, apigateway.ErrCodeNotFoundException, "") {
return nil
}
return err
}

stateConf := resource.StateChangeConf{
Pending: []string{apigateway.VpcLinkStatusPending,
apigateway.VpcLinkStatusAvailable,
apigateway.VpcLinkStatusDeleting},
Target: []string{""},
Timeout: 5 * time.Minute,
MinTimeout: 1 * time.Second,
Refresh: func() (interface{}, string, error) {
resp, err := conn.GetVpcLink(&apigateway.GetVpcLinkInput{
VpcLinkId: aws.String(d.Id()),
})
if err != nil {
if isAWSErr(err, apigateway.ErrCodeNotFoundException, "") {
return 1, "", nil
}
return nil, "failed", err
}
return resp, *resp.Status, nil
},
}

if _, err := stateConf.WaitForState(); err != nil {
return err
}

return nil
}

func apigatewayVpcLinkRefreshStatusFunc(conn *apigateway.APIGateway, vl string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
input := &apigateway.GetVpcLinkInput{
VpcLinkId: aws.String(vl),
}
resp, err := conn.GetVpcLink(input)
if err != nil {
return nil, "failed", err
}
return resp, *resp.Status, nil
}
}
132 changes: 132 additions & 0 deletions aws/resource_aws_api_gateway_vpc_link_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package aws

import (
"fmt"
"testing"

"github.com/aws/aws-sdk-go/aws"
"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 TestAccAwsAPIGatewayVpcLink_basic(t *testing.T) {
rName := acctest.RandString(5)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsAPIGatewayVpcLinkDestroy,
Steps: []resource.TestStep{
{
Config: testAccAPIGatewayVpcLinkConfig(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsAPIGatewayVpcLinkExists("aws_api_gateway_vpc_link.test"),
resource.TestCheckResourceAttr("aws_api_gateway_vpc_link.test", "name", fmt.Sprintf("tf-apigateway-%s", rName)),
resource.TestCheckResourceAttr("aws_api_gateway_vpc_link.test", "description", "test"),
resource.TestCheckResourceAttr("aws_api_gateway_vpc_link.test", "target_arns.#", "1"),
),
},
{
Config: testAccAPIGatewayVpcLinkConfig_Update(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsAPIGatewayVpcLinkExists("aws_api_gateway_vpc_link.test"),
resource.TestCheckResourceAttr("aws_api_gateway_vpc_link.test", "name", fmt.Sprintf("tf-apigateway-update-%s", rName)),
resource.TestCheckResourceAttr("aws_api_gateway_vpc_link.test", "description", "test update"),
resource.TestCheckResourceAttr("aws_api_gateway_vpc_link.test", "target_arns.#", "1"),
),
},
},
})
}

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

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

input := &apigateway.GetVpcLinkInput{
VpcLinkId: aws.String(rs.Primary.ID),
}

_, err := conn.GetVpcLink(input)
if err != nil {
if isAWSErr(err, apigateway.ErrCodeNotFoundException, "") {
return nil
}
return err
}

return fmt.Errorf("Expected VPC Link to be destroyed, %s found", rs.Primary.ID)
}

return nil
}

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

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

input := &apigateway.GetVpcLinkInput{
VpcLinkId: aws.String(rs.Primary.ID),
}

_, err := conn.GetVpcLink(input)
if err != nil {
return err
}

return nil
}
}

func testAccAPIGatewayVpcLinkConfig_basis(rName string) string {
return fmt.Sprintf(`
resource "aws_lb" "test_a" {
name = "tf-lb-%s"
internal = true
load_balancer_type = "network"
subnets = ["${aws_subnet.test.id}"]
}
resource "aws_vpc" "test" {
cidr_block = "10.10.0.0/16"
}
data "aws_availability_zones" "test" {}
resource "aws_subnet" "test" {
vpc_id = "${aws_vpc.test.id}"
cidr_block = "10.10.0.0/21"
availability_zone = "${data.aws_availability_zones.test.names[0]}"
}
`, rName)
}

func testAccAPIGatewayVpcLinkConfig(rName string) string {
return testAccAPIGatewayVpcLinkConfig_basis(rName) + fmt.Sprintf(`
resource "aws_api_gateway_vpc_link" "test" {
name = "tf-apigateway-%s"
description = "test"
target_arns = ["${aws_lb.test_a.arn}"]
}
`, rName)
}

func testAccAPIGatewayVpcLinkConfig_Update(rName string) string {
return testAccAPIGatewayVpcLinkConfig_basis(rName) + fmt.Sprintf(`
resource "aws_api_gateway_vpc_link" "test" {
name = "tf-apigateway-update-%s"
description = "test update"
target_arns = ["${aws_lb.test_a.arn}"]
}
`, rName)
}
3 changes: 3 additions & 0 deletions website/aws.erb
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,9 @@
<li<%= sidebar_current("docs-aws-resource-api-gateway-usage-plan-key") %>>
<a href="/docs/providers/aws/r/api_gateway_usage_plan_key.html">aws_api_gateway_usage_plan_key</a>
</li>
<li<%= sidebar_current("docs-aws-resource-api-gateway-vpc-link") %>>
<a href="/docs/providers/aws/r/api_gateway_vpc_link.html">aws_api_gateway_vpc_link</a>
</li>
</ul>
</li>

Expand Down
Loading

0 comments on commit 564e006

Please sign in to comment.