Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relocate Valid4ByteAsn function to common lib, add to CloudWAN Network Policy Doc Data Source #27305

Merged
merged 7 commits into from
Nov 3, 2022
3 changes: 3 additions & 0 deletions .changelog/27305.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:note
Add plan-time validation for `aws_networkmanager_core_network_policy_document.core_network_configuration.edge_locations[].asn`
```
2 changes: 1 addition & 1 deletion internal/service/ec2/transitgateway_connect_peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func ResourceTransitGatewayConnectPeer() *schema.Resource {
Optional: true,
Computed: true,
ForceNew: true,
ValidateFunc: valid4ByteASN,
ValidateFunc: verify.Valid4ByteASNString,
},
"inside_cidr_blocks": {
Type: schema.TypeSet,
Expand Down
15 changes: 0 additions & 15 deletions internal/service/ec2/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,3 @@ func validAmazonSideASN(v interface{}, k string) (ws []string, errors []error) {
}
return
}

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

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
}

if asn < 0 || asn > 4294967295 {
errors = append(errors, fmt.Errorf("%q (%q) must be in the range 0 to 4294967295", k, v))
}
return
}
31 changes: 0 additions & 31 deletions internal/service/ec2/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,34 +74,3 @@ func TestValidAmazonSideASN(t *testing.T) {
}
}
}

func TestValid4ByteASN(t *testing.T) {
validAsns := []string{
"0",
"1",
"65534",
"65535",
"4294967294",
"4294967295",
}
for _, v := range validAsns {
_, errors := valid4ByteASN(v, "bgp_asn")
if len(errors) != 0 {
t.Fatalf("%q should be a valid ASN: %q", v, errors)
}
}

invalidAsns := []string{
"-1",
"ABCDEFG",
"",
"4294967296",
"9999999999",
}
for _, v := range invalidAsns {
_, errors := valid4ByteASN(v, "bgp_asn")
if len(errors) == 0 {
t.Fatalf("%q should be an invalid ASN", v)
}
}
}
2 changes: 1 addition & 1 deletion internal/service/ec2/vpnsite_customer_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func ResourceCustomerGateway() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: valid4ByteASN,
ValidateFunc: verify.Valid4ByteASNString,
},
"certificate_arn": {
Type: schema.TypeString,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,9 @@ func DataSourceCoreNetworkPolicyDocument() *schema.Resource {
ValidateFunc: verify.ValidRegionName,
},
"asn": {
Type: schema.TypeInt,
Optional: true,
Type: schema.TypeInt,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be changed to a schema.TypeString, which will be handled internally as an int64. We can take advantage of the Terraform parser which will allow some string values, such as numbers and boolean values to omit the quotes

Optional: true,
ValidateFunc: verify.Valid4ByteASN,
},
"inside_cidr_blocks": {
Type: schema.TypeList,
Expand Down
21 changes: 21 additions & 0 deletions internal/verify/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,27 @@ var accountIDRegexp = regexp.MustCompile(`^(aws|aws-managed|\d{12})$`)
var partitionRegexp = regexp.MustCompile(`^aws(-[a-z]+)*$`)
var regionRegexp = regexp.MustCompile(`^[a-z]{2}(-[a-z]+)+-\d$`)

func Valid4ByteASN(v interface{}, k string) (ws []string, errors []error) {
stringValue := strconv.Itoa(v.(int))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gdavison Can you see any concerns with the 32-bit BSD build on this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ASN numbers are 32-bit unsigned values, so this will fail for any values between 2147483647 and 4294967295. Basically, for any resources using terraform-plugin-sdk (and therefore a TypeInt) we have to accept a TypeString and parse it into an int64. Technically, we could use a uint32, but the AWS API takes an int64


return Valid4ByteASNString(stringValue, k)
}

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

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
}

if asn < 0 || asn > 4294967295 {
errors = append(errors, fmt.Errorf("%q (%q) must be in the range 0 to 4294967295", k, v))
}
return
}

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

Expand Down
60 changes: 60 additions & 0 deletions internal/verify/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,66 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

func TestValid4ByteAsn(t *testing.T) {
validAsns := []int{
0,
1,
65534,
65535,
4294967294,
4294967295,
}
for _, v := range validAsns {
_, errors := Valid4ByteASN(v, "bgp_asn")
if len(errors) != 0 {
t.Fatalf("%q should be a valid ASN: %q", v, errors)
}
}

invalidAsns := []int{
-1,
4294967296,
9999999999,
}
for _, v := range invalidAsns {
_, errors := Valid4ByteASN(v, "bgp_asn")
if len(errors) == 0 {
t.Fatalf("%q should be an invalid ASN", v)
}
}
}

func TestValid4ByteASNString(t *testing.T) {
validAsns := []string{
"0",
"1",
"65534",
"65535",
"4294967294",
"4294967295",
}
for _, v := range validAsns {
_, errors := Valid4ByteASNString(v, "bgp_asn")
if len(errors) != 0 {
t.Fatalf("%q should be a valid ASN: %q", v, errors)
}
}

invalidAsns := []string{
"-1",
"ABCDEFG",
"",
"4294967296",
"9999999999",
}
for _, v := range invalidAsns {
_, errors := Valid4ByteASNString(v, "bgp_asn")
if len(errors) == 0 {
t.Fatalf("%q should be an invalid ASN", v)
}
}
}

func TestValidTypeStringNullableBoolean(t *testing.T) {
testCases := []struct {
val interface{}
Expand Down