Skip to content

Commit

Permalink
Merge pull request #30375 from posquit0/dx-gateway-name
Browse files Browse the repository at this point in the history
Allow to rename the dx gateway name
  • Loading branch information
ewbankkit authored Apr 12, 2023
2 parents 347c6cf + baf4ccc commit cfca091
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 153 deletions.
7 changes: 7 additions & 0 deletions .changelog/30375.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/aws_dx_gateway: Add plan time validation to `name` argument
```

```release-note:enhancement
resource/aws_dx_gateway: Allow updates to `name` without forcing resource replacement
```
48 changes: 34 additions & 14 deletions internal/service/directconnect/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package directconnect
import (
"context"
"log"
"regexp"
"strconv"
"time"

Expand All @@ -11,16 +12,19 @@ import (
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
)

// @SDKResource("aws_dx_gateway")
func ResourceGateway() *schema.Resource {
return &schema.Resource{
CreateWithoutTimeout: resourceGatewayCreate,
ReadWithoutTimeout: resourceGatewayRead,
UpdateWithoutTimeout: resourceGatewayUpdate,
DeleteWithoutTimeout: resourceGatewayDelete,

Importer: &schema.ResourceImporter{
Expand All @@ -32,15 +36,13 @@ func ResourceGateway() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validAmazonSideASN,
ValidateFunc: verify.ValidAmazonSideASN,
},

"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[a-z0-9-]{1,100}$`), "Name must contain no more than 100 characters. Valid characters are a-z, 0-9, and hyphens (–)."),
},

"owner_account_id": {
Type: schema.TypeString,
Computed: true,
Expand All @@ -64,22 +66,20 @@ func resourceGatewayCreate(ctx context.Context, d *schema.ResourceData, meta int
}

if v, ok := d.Get("amazon_side_asn").(string); ok && v != "" {
if v, err := strconv.ParseInt(v, 10, 64); err == nil {
input.AmazonSideAsn = aws.Int64(v)
}
v, _ := strconv.ParseInt(v, 10, 64)
input.AmazonSideAsn = aws.Int64(v)
}

log.Printf("[DEBUG] Creating Direct Connect Gateway: %s", input)
resp, err := conn.CreateDirectConnectGatewayWithContext(ctx, input)
output, err := conn.CreateDirectConnectGatewayWithContext(ctx, input)

if err != nil {
return sdkdiag.AppendErrorf(diags, "creating Direct Connect Gateway (%s): %s", name, err)
}

d.SetId(aws.StringValue(resp.DirectConnectGateway.DirectConnectGatewayId))
d.SetId(aws.StringValue(output.DirectConnectGateway.DirectConnectGatewayId))

if _, err := waitGatewayCreated(ctx, conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting for Direct Connect Gateway (%s) to create: %s", d.Id(), err)
return sdkdiag.AppendErrorf(diags, "waiting for Direct Connect Gateway (%s) create: %s", d.Id(), err)
}

return append(diags, resourceGatewayRead(ctx, d, meta)...)
Expand Down Expand Up @@ -108,6 +108,26 @@ func resourceGatewayRead(ctx context.Context, d *schema.ResourceData, meta inter
return diags
}

func resourceGatewayUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).DirectConnectConn()

if d.HasChange("name") {
input := &directconnect.UpdateDirectConnectGatewayInput{
DirectConnectGatewayId: aws.String(d.Id()),
NewDirectConnectGatewayName: aws.String(d.Get("name").(string)),
}

_, err := conn.UpdateDirectConnectGatewayWithContext(ctx, input)

if err != nil {
return sdkdiag.AppendErrorf(diags, "updating Direct Connect Gateway (%s): %s", d.Id(), err)
}
}

return append(diags, resourceGatewayRead(ctx, d, meta)...)
}

func resourceGatewayDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).DirectConnectConn()
Expand All @@ -126,7 +146,7 @@ func resourceGatewayDelete(ctx context.Context, d *schema.ResourceData, meta int
}

if _, err := waitGatewayDeleted(ctx, conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting for Direct Connect Gateway (%s) to delete: %s", d.Id(), err)
return sdkdiag.AppendErrorf(diags, "waiting for Direct Connect Gateway (%s) delete: %s", d.Id(), err)
}

return diags
Expand Down
32 changes: 32 additions & 0 deletions internal/service/directconnect/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,38 @@ func TestAccDirectConnectGateway_complex(t *testing.T) {
})
}

func TestAccDirectConnectGateway_update(t *testing.T) {
ctx := acctest.Context(t)
var v directconnect.Gateway
rName1 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
rName2 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
rBgpAsn := sdkacctest.RandIntRange(64512, 65534)
resourceName := "aws_dx_gateway.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, directconnect.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckGatewayDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccGatewayConfig_basic(rName1, rBgpAsn),
Check: resource.ComposeTestCheckFunc(
testAccCheckGatewayExists(ctx, resourceName, &v),
resource.TestCheckResourceAttr(resourceName, "name", rName1),
),
},
{
Config: testAccGatewayConfig_basic(rName2, rBgpAsn),
Check: resource.ComposeTestCheckFunc(
testAccCheckGatewayExists(ctx, resourceName, &v),
resource.TestCheckResourceAttr(resourceName, "name", rName2),
),
},
},
})
}

func testAccCheckGatewayDestroy(ctx context.Context) resource.TestCheckFunc {
return func(s *terraform.State) error {
conn := acctest.Provider.Meta().(*conns.AWSClient).DirectConnectConn()
Expand Down
24 changes: 0 additions & 24 deletions internal/service/directconnect/validate.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package directconnect

import (
"fmt"
"strconv"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)
Expand All @@ -22,24 +19,3 @@ func validConnectionBandWidth() schema.SchemaValidateFunc {
"400Mbps",
"500Mbps"}, false)
}

func validAmazonSideASN(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)

// http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateVpnGateway.html
asn, err := strconv.ParseInt(value, 10, 64)
if err != nil {
errors = append(errors, fmt.Errorf("%q (%q) must be a 64-bit integer", k, v))
return
}

// https://github.com/hashicorp/terraform-provider-aws/issues/5263
isLegacyAsn := func(a int64) bool {
return a == 7224 || a == 9059 || a == 10124 || a == 17493
}

if !isLegacyAsn(asn) && ((asn < 64512) || (asn > 65534 && asn < 4200000000) || (asn > 4294967294)) {
errors = append(errors, fmt.Errorf("%q (%q) must be 7224, 9059, 10124 or 17493 or in the range 64512 to 65534 or 4200000000 to 4294967294", k, v))
}
return
}
46 changes: 0 additions & 46 deletions internal/service/directconnect/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,49 +42,3 @@ func TestValidConnectionBandWidth(t *testing.T) {
}
}
}

func TestValidAmazonSideASN(t *testing.T) {
t.Parallel()

validAsns := []string{
"7224",
"9059",
"10124",
"17493",
"64512",
"64513",
"65533",
"65534",
"4200000000",
"4200000001",
"4294967293",
"4294967294",
}
for _, v := range validAsns {
_, errors := validAmazonSideASN(v, "amazon_side_asn")
if len(errors) != 0 {
t.Fatalf("%q should be a valid ASN: %q", v, errors)
}
}

invalidAsns := []string{
"1",
"ABCDEFG",
"",
"7225",
"9058",
"10125",
"17492",
"64511",
"65535",
"4199999999",
"4294967295",
"9999999999",
}
for _, v := range invalidAsns {
_, errors := validAmazonSideASN(v, "amazon_side_asn")
if len(errors) == 0 {
t.Fatalf("%q should be an invalid ASN", v)
}
}
}
22 changes: 0 additions & 22 deletions internal/service/ec2/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package ec2
import (
"fmt"
"regexp"
"strconv"
"strings"
)

Expand Down Expand Up @@ -43,24 +42,3 @@ func validNestedExactlyOneOf(m map[string]interface{}, valid []string) error {
}
return nil
}

func validAmazonSideASN(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)

// http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateVpnGateway.html
asn, err := strconv.ParseInt(value, 10, 64)
if err != nil {
errors = append(errors, fmt.Errorf("%q (%q) must be a 64-bit integer", k, v))
return
}

// https://github.com/hashicorp/terraform-provider-aws/issues/5263
isLegacyAsn := func(a int64) bool {
return a == 7224 || a == 9059 || a == 10124 || a == 17493
}

if !isLegacyAsn(asn) && ((asn < 64512) || (asn > 65534 && asn < 4200000000) || (asn > 4294967294)) {
errors = append(errors, fmt.Errorf("%q (%q) must be 7224, 9059, 10124 or 17493 or in the range 64512 to 65534 or 4200000000 to 4294967294", k, v))
}
return
}
46 changes: 0 additions & 46 deletions internal/service/ec2/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,49 +32,3 @@ func TestValidSecurityGroupRuleDescription(t *testing.T) {
}
}
}

func TestValidAmazonSideASN(t *testing.T) {
t.Parallel()

validAsns := []string{
"7224",
"9059",
"10124",
"17493",
"64512",
"64513",
"65533",
"65534",
"4200000000",
"4200000001",
"4294967293",
"4294967294",
}
for _, v := range validAsns {
_, errors := validAmazonSideASN(v, "amazon_side_asn")
if len(errors) != 0 {
t.Fatalf("%q should be a valid ASN: %q", v, errors)
}
}

invalidAsns := []string{
"1",
"ABCDEFG",
"",
"7225",
"9058",
"10125",
"17492",
"64511",
"65535",
"4199999999",
"4294967295",
"9999999999",
}
for _, v := range invalidAsns {
_, errors := validAmazonSideASN(v, "amazon_side_asn")
if len(errors) == 0 {
t.Fatalf("%q should be an invalid ASN", v)
}
}
}
2 changes: 1 addition & 1 deletion internal/service/ec2/vpnsite_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func ResourceVPNGateway() *schema.Resource {
Optional: true,
ForceNew: true,
Computed: true,
ValidateFunc: validAmazonSideASN,
ValidateFunc: verify.ValidAmazonSideASN,
},
"arn": {
Type: schema.TypeString,
Expand Down
21 changes: 21 additions & 0 deletions internal/verify/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,27 @@ func Valid4ByteASN(v interface{}, k string) (ws []string, errors []error) {
return
}

func ValidAmazonSideASN(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)

// http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateVpnGateway.html
asn, err := strconv.ParseInt(value, 10, 64)
if err != nil {
errors = append(errors, fmt.Errorf("%q (%q) must be a 64-bit integer", k, v))
return
}

// https://github.com/hashicorp/terraform-provider-aws/issues/5263
isLegacyAsn := func(a int64) bool {
return a == 7224 || a == 9059 || a == 10124 || a == 17493
}

if !isLegacyAsn(asn) && ((asn < 64512) || (asn > 65534 && asn < 4200000000) || (asn > 4294967294)) {
errors = append(errors, fmt.Errorf("%q (%q) must be 7224, 9059, 10124 or 17493 or in the range 64512 to 65534 or 4200000000 to 4294967294", k, v))
}
return
}

// ValidARN validates that a string value matches a generic ARN format
var ValidARN = ValidARNCheck()

Expand Down
Loading

0 comments on commit cfca091

Please sign in to comment.