diff --git a/.changelog/27305.txt b/.changelog/27305.txt new file mode 100644 index 00000000000..aacb6dd7f1c --- /dev/null +++ b/.changelog/27305.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +data-source/aws_networkmanager_core_network_policy_document: Add plan-time validation for `core_network_configuration.edge_locations.asn` +``` \ No newline at end of file diff --git a/internal/service/ec2/transitgateway_connect_peer.go b/internal/service/ec2/transitgateway_connect_peer.go index a73c5101a35..c752332efe0 100644 --- a/internal/service/ec2/transitgateway_connect_peer.go +++ b/internal/service/ec2/transitgateway_connect_peer.go @@ -50,7 +50,7 @@ func ResourceTransitGatewayConnectPeer() *schema.Resource { Optional: true, Computed: true, ForceNew: true, - ValidateFunc: valid4ByteASN, + ValidateFunc: verify.Valid4ByteASN, }, "inside_cidr_blocks": { Type: schema.TypeSet, diff --git a/internal/service/ec2/validate.go b/internal/service/ec2/validate.go index 1e651c9610b..abe4b81514f 100644 --- a/internal/service/ec2/validate.go +++ b/internal/service/ec2/validate.go @@ -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 -} diff --git a/internal/service/ec2/validate_test.go b/internal/service/ec2/validate_test.go index 8d271ff8ac0..5bf3e49152d 100644 --- a/internal/service/ec2/validate_test.go +++ b/internal/service/ec2/validate_test.go @@ -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) - } - } -} diff --git a/internal/service/ec2/vpnsite_customer_gateway.go b/internal/service/ec2/vpnsite_customer_gateway.go index 9fdd2f2ea57..28680ed5d21 100644 --- a/internal/service/ec2/vpnsite_customer_gateway.go +++ b/internal/service/ec2/vpnsite_customer_gateway.go @@ -37,7 +37,7 @@ func ResourceCustomerGateway() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: valid4ByteASN, + ValidateFunc: verify.Valid4ByteASN, }, "certificate_arn": { Type: schema.TypeString, @@ -76,19 +76,22 @@ func resourceCustomerGatewayCreate(d *schema.ResourceData, meta interface{}) err defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))) - i64BgpAsn, err := strconv.ParseInt(d.Get("bgp_asn").(string), 10, 64) - - if err != nil { - return err - } - input := &ec2.CreateCustomerGatewayInput{ - BgpAsn: aws.Int64(i64BgpAsn), IpAddress: aws.String(d.Get("ip_address").(string)), TagSpecifications: tagSpecificationsFromKeyValueTags(tags, ec2.ResourceTypeCustomerGateway), Type: aws.String(d.Get("type").(string)), } + if v, ok := d.GetOk("bgp_asn"); ok { + v, err := strconv.ParseInt(v.(string), 10, 64) + + if err != nil { + return err + } + + input.BgpAsn = aws.Int64(v) + } + if v, ok := d.GetOk("certificate_arn"); ok { input.CertificateArn = aws.String(v.(string)) } diff --git a/internal/service/networkmanager/core_network_policy_document_data_source.go b/internal/service/networkmanager/core_network_policy_document_data_source.go index 30ce32bc5a6..ccedee089ef 100644 --- a/internal/service/networkmanager/core_network_policy_document_data_source.go +++ b/internal/service/networkmanager/core_network_policy_document_data_source.go @@ -160,8 +160,9 @@ func DataSourceCoreNetworkPolicyDocument() *schema.Resource { ValidateFunc: verify.ValidRegionName, }, "asn": { - Type: schema.TypeInt, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: verify.Valid4ByteASN, }, "inside_cidr_blocks": { Type: schema.TypeList, @@ -625,8 +626,14 @@ func expandDataCoreNetworkPolicyNetworkConfigurationEdgeLocations(tfList []inter locMap[edgeLocation.Location] = struct{}{} } - if v, ok := cfgEdgeLocation["asn"]; ok { - edgeLocation.Asn = v.(int) + if v, ok := cfgEdgeLocation["asn"].(string); ok && v != "" { + v, err := strconv.ParseInt(v, 10, 64) + + if err != nil { + return nil, err + } + + edgeLocation.Asn = v } if cidrs := cfgEdgeLocation["inside_cidr_blocks"].([]interface{}); len(cidrs) > 0 { diff --git a/internal/service/networkmanager/core_network_policy_model.go b/internal/service/networkmanager/core_network_policy_model.go index 9adddac9f4d..a34d165d1f7 100644 --- a/internal/service/networkmanager/core_network_policy_model.go +++ b/internal/service/networkmanager/core_network_policy_model.go @@ -64,7 +64,7 @@ type CoreNetworkPolicyCoreNetworkConfiguration struct { type CoreNetworkEdgeLocation struct { Location string `json:"location"` - Asn int `json:"asn,omitempty"` + Asn int64 `json:"asn,omitempty"` InsideCidrBlocks interface{} `json:"inside-cidr-blocks,omitempty"` } diff --git a/internal/verify/validate.go b/internal/verify/validate.go index a331a08de62..7d4dc49b917 100644 --- a/internal/verify/validate.go +++ b/internal/verify/validate.go @@ -20,6 +20,21 @@ 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) { + 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) diff --git a/internal/verify/validate_test.go b/internal/verify/validate_test.go index 8f1db93a4e9..5b04a40dffe 100644 --- a/internal/verify/validate_test.go +++ b/internal/verify/validate_test.go @@ -9,6 +9,37 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) +func TestValid4ByteASNString(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) + } + } +} + func TestValidTypeStringNullableBoolean(t *testing.T) { testCases := []struct { val interface{}