Skip to content

Commit

Permalink
service/ec2: Add arn attribute and plan-time validations to aws_custo…
Browse files Browse the repository at this point in the history
…mer_gateway resources (#13611)

Output from acceptance testing:

```
--- PASS: TestAccAWSCustomerGateway_basic (33.92s)
--- PASS: TestAccAWSCustomerGateway_disappears (17.29s)
--- PASS: TestAccAWSCustomerGateway_similarAlreadyExists (21.86s)
--- PASS: TestAccAWSCustomerGateway_tags (29.58s)

--- PASS: TestAccAWSCustomerGatewayDataSource_Filter (20.30s)
--- PASS: TestAccAWSCustomerGatewayDataSource_ID (19.81s)
```
  • Loading branch information
DrFaust92 committed Jun 23, 2020
1 parent c8360f7 commit fe5c54f
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 102 deletions.
15 changes: 15 additions & 0 deletions aws/data_source_aws_customer_gateway.go
Expand Up @@ -7,6 +7,7 @@ import (
"strconv"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
Expand Down Expand Up @@ -35,6 +36,10 @@ func dataSourceAwsCustomerGateway() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"arn": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
Expand Down Expand Up @@ -90,5 +95,15 @@ func dataSourceAwsCustomerGatewayRead(d *schema.ResourceData, meta interface{})
return fmt.Errorf("error setting tags for EC2 Customer Gateway %q: %s", aws.StringValue(cg.CustomerGatewayId), err)
}

arn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Service: "ec2",
Region: meta.(*AWSClient).region,
AccountID: meta.(*AWSClient).accountid,
Resource: fmt.Sprintf("customer-gateway/%s", d.Id()),
}.String()

d.Set("arn", arn)

return nil
}
5 changes: 3 additions & 2 deletions aws/data_source_aws_customer_gateway_test.go
Expand Up @@ -12,7 +12,7 @@ func TestAccAWSCustomerGatewayDataSource_Filter(t *testing.T) {
dataSourceName := "data.aws_customer_gateway.test"
resourceName := "aws_customer_gateway.test"

asn := acctest.RandIntRange(64512, 65534)
asn := randIntRange(64512, 65534)
hostOctet := acctest.RandIntRange(1, 254)

resource.ParallelTest(t, resource.TestCase{
Expand All @@ -29,6 +29,7 @@ func TestAccAWSCustomerGatewayDataSource_Filter(t *testing.T) {
resource.TestCheckResourceAttrPair(resourceName, "ip_address", dataSourceName, "ip_address"),
resource.TestCheckResourceAttrPair(resourceName, "tags.%", dataSourceName, "tags.%"),
resource.TestCheckResourceAttrPair(resourceName, "type", dataSourceName, "type"),
resource.TestCheckResourceAttrPair(resourceName, "arn", dataSourceName, "arn"),
),
},
},
Expand All @@ -39,7 +40,7 @@ func TestAccAWSCustomerGatewayDataSource_ID(t *testing.T) {
dataSourceName := "data.aws_customer_gateway.test"
resourceName := "aws_customer_gateway.test"

asn := acctest.RandIntRange(64512, 65534)
asn := randIntRange(64512, 65534)
hostOctet := acctest.RandIntRange(1, 254)

resource.ParallelTest(t, resource.TestCase{
Expand Down
63 changes: 44 additions & 19 deletions aws/resource_aws_customer_gateway.go
Expand Up @@ -7,10 +7,11 @@ import (
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

Expand All @@ -26,24 +27,36 @@ func resourceAwsCustomerGateway() *schema.Resource {

Schema: map[string]*schema.Schema{
"bgp_asn": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
Type: schema.TypeInt,
Required: true,
ForceNew: true,
ValidateFunc: validation.IntBetween(1, 65534),
},

"ip_address": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.Any(
validation.StringIsEmpty,
validation.IsIPv4Address,
),
},

"type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
ec2.GatewayTypeIpsec1,
}, false),
},

"tags": tagsSchema(),
"arn": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
Expand Down Expand Up @@ -79,14 +92,15 @@ func resourceAwsCustomerGatewayCreate(d *schema.ResourceData, meta interface{})

// Store the ID
customerGateway := resp.CustomerGateway
d.SetId(*customerGateway.CustomerGatewayId)
log.Printf("[INFO] Customer gateway ID: %s", *customerGateway.CustomerGatewayId)
cgId := aws.StringValue(customerGateway.CustomerGatewayId)
d.SetId(cgId)
log.Printf("[INFO] Customer gateway ID: %s", cgId)

// Wait for the CustomerGateway to be available.
stateConf := &resource.StateChangeConf{
Pending: []string{"pending"},
Target: []string{"available"},
Refresh: customerGatewayRefreshFunc(conn, *customerGateway.CustomerGatewayId),
Refresh: customerGatewayRefreshFunc(conn, cgId),
Timeout: 10 * time.Minute,
Delay: 10 * time.Second,
MinTimeout: 3 * time.Second,
Expand All @@ -95,8 +109,7 @@ func resourceAwsCustomerGatewayCreate(d *schema.ResourceData, meta interface{})
_, stateErr := stateConf.WaitForState()
if stateErr != nil {
return fmt.Errorf(
"Error waiting for customer gateway (%s) to become ready: %s",
*customerGateway.CustomerGatewayId, err)
"Error waiting for customer gateway (%s) to become ready: %s", cgId, err)
}

if v := d.Get("tags").(map[string]interface{}); len(v) > 0 {
Expand All @@ -105,7 +118,7 @@ func resourceAwsCustomerGatewayCreate(d *schema.ResourceData, meta interface{})
}
}

return nil
return resourceAwsCustomerGatewayRead(d, meta)
}

func customerGatewayRefreshFunc(conn *ec2.EC2, gatewayId string) resource.StateRefreshFunc {
Expand All @@ -119,7 +132,7 @@ func customerGatewayRefreshFunc(conn *ec2.EC2, gatewayId string) resource.StateR
Filters: []*ec2.Filter{gatewayFilter},
})
if err != nil {
if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidCustomerGatewayID.NotFound" {
if isAWSErr(err, "InvalidCustomerGatewayID.NotFound", "") {
resp = nil
} else {
log.Printf("Error on CustomerGatewayRefresh: %s", err)
Expand Down Expand Up @@ -161,7 +174,7 @@ func resourceAwsCustomerGatewayExists(vpnType, ipAddress string, bgpAsn int, con
return false, err
}

if len(resp.CustomerGateways) > 0 && *resp.CustomerGateways[0].State != "deleted" {
if len(resp.CustomerGateways) > 0 && aws.StringValue(resp.CustomerGateways[0].State) != "deleted" {
return true, nil
}

Expand All @@ -181,7 +194,8 @@ func resourceAwsCustomerGatewayRead(d *schema.ResourceData, meta interface{}) er
Filters: []*ec2.Filter{gatewayFilter},
})
if err != nil {
if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidCustomerGatewayID.NotFound" {
if isAWSErr(err, "InvalidCustomerGatewayID.NotFound", "") {
log.Printf("[WARN] Customer Gateway (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
} else {
Expand All @@ -194,7 +208,7 @@ func resourceAwsCustomerGatewayRead(d *schema.ResourceData, meta interface{}) er
return fmt.Errorf("Error finding CustomerGateway: %s", d.Id())
}

if *resp.CustomerGateways[0].State == "deleted" {
if aws.StringValue(resp.CustomerGateways[0].State) == "deleted" {
log.Printf("[INFO] Customer Gateway is in `deleted` state: %s", d.Id())
d.SetId("")
return nil
Expand All @@ -208,15 +222,25 @@ func resourceAwsCustomerGatewayRead(d *schema.ResourceData, meta interface{}) er
return fmt.Errorf("error setting tags: %s", err)
}

if *customerGateway.BgpAsn != "" {
val, err := strconv.ParseInt(*customerGateway.BgpAsn, 0, 0)
if aws.StringValue(customerGateway.BgpAsn) != "" {
val, err := strconv.ParseInt(aws.StringValue(customerGateway.BgpAsn), 0, 0)
if err != nil {
return fmt.Errorf("error parsing bgp_asn: %s", err)
}

d.Set("bgp_asn", int(val))
}

arn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Service: "ec2",
Region: meta.(*AWSClient).region,
AccountID: meta.(*AWSClient).accountid,
Resource: fmt.Sprintf("customer-gateway/%s", d.Id()),
}.String()

d.Set("arn", arn)

return nil
}

Expand All @@ -241,7 +265,7 @@ func resourceAwsCustomerGatewayDelete(d *schema.ResourceData, meta interface{})
CustomerGatewayId: aws.String(d.Id()),
})
if err != nil {
if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidCustomerGatewayID.NotFound" {
if isAWSErr(err, "InvalidCustomerGatewayID.NotFound", "") {
return nil
} else {
return fmt.Errorf("[ERROR] Error deleting CustomerGateway: %s", err)
Expand Down Expand Up @@ -294,9 +318,10 @@ func checkGatewayDeleteResponse(resp *ec2.DescribeCustomerGatewaysOutput, id str
return fmt.Errorf("Error finding CustomerGateway for delete: %s", id)
}

switch *resp.CustomerGateways[0].State {
cgState := aws.StringValue(resp.CustomerGateways[0].State)
switch cgState {
case "pending", "available", "deleting":
return fmt.Errorf("Gateway (%s) in state (%s), retrying", id, *resp.CustomerGateways[0].State)
return fmt.Errorf("Gateway (%s) in state (%s), retrying", id, cgState)
case "deleted":
return nil
default:
Expand Down

0 comments on commit fe5c54f

Please sign in to comment.