From 8b8625973c93b772b69513e322d7195ab8848963 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Fri, 17 Mar 2023 12:32:09 -0500 Subject: [PATCH] simplify framework ARN validator --- internal/framework/validators/arn.go | 18 ++++----- internal/verify/validate.go | 59 ++++++++++++---------------- 2 files changed, 33 insertions(+), 44 deletions(-) diff --git a/internal/framework/validators/arn.go b/internal/framework/validators/arn.go index 6dce056a0d8..2910f04f668 100644 --- a/internal/framework/validators/arn.go +++ b/internal/framework/validators/arn.go @@ -3,15 +3,15 @@ package validators import ( "context" + "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-provider-aws/internal/verify" ) type arnValidator struct{} func (validator arnValidator) Description(_ context.Context) string { - return "value must be a valid ARN" + return "An Amazon Resource Name" } func (validator arnValidator) MarkdownDescription(ctx context.Context) string { @@ -23,14 +23,12 @@ func (validator arnValidator) ValidateString(ctx context.Context, request valida return } - if errs := verify.ValidateARN(request.Path.String(), request.ConfigValue.ValueString()); errs != nil { - for _, v := range errs { - response.Diagnostics.Append(diag.NewAttributeErrorDiagnostic( - request.Path, - validator.Description(ctx), - v.Error(), - )) - } + if !arn.IsARN(request.ConfigValue.ValueString()) { + response.Diagnostics.Append(diag.NewAttributeErrorDiagnostic( + request.Path, + validator.Description(ctx), + "value must be a valid ARN", + )) return } } diff --git a/internal/verify/validate.go b/internal/verify/validate.go index 28fac86b442..1839aa00b0a 100644 --- a/internal/verify/validate.go +++ b/internal/verify/validate.go @@ -16,7 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) -var arnAccountIDRegexp = regexp.MustCompile(`^(aws|aws-managed|third-party|\d{12})$`) +var accountIDRegexp = regexp.MustCompile(`^(aws|aws-managed|third-party|\d{12})$`) var partitionRegexp = regexp.MustCompile(`^aws(-[a-z]+)*$`) var regionRegexp = regexp.MustCompile(`^[a-z]{2}(-[a-z]+)+-\d$`) @@ -38,59 +38,50 @@ func Valid4ByteASN(v interface{}, k string) (ws []string, errors []error) { func ValidARN(v interface{}, k string) (ws []string, errors []error) { value := v.(string) - if errs := ValidateARN(k, value); errs != nil { - errors = errs - } - - return -} - -func ValidAccountID(v interface{}, k string) (ws []string, errors []error) { - value := v.(string) - - // http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html - pattern := `^\d{12}$` - if !regexp.MustCompile(pattern).MatchString(value) { - errors = append(errors, fmt.Errorf( - "%q doesn't look like AWS Account ID (exactly 12 digits): %q", - k, value)) - } - - return -} - -// ValidateARN validates that a string is an ARN. -func ValidateARN(attribute, value string) (errors []error) { if value == "" { - return + return ws, errors } parsedARN, err := arn.Parse(value) if err != nil { - errors = append(errors, fmt.Errorf("(%s) is an invalid ARN: %s", value, err)) - return + errors = append(errors, fmt.Errorf("%q (%s) is an invalid ARN: %s", k, value, err)) + return ws, errors } if parsedARN.Partition == "" { - errors = append(errors, fmt.Errorf("%q (%s) is an invalid ARN: missing partition value", attribute, value)) + errors = append(errors, fmt.Errorf("%q (%s) is an invalid ARN: missing partition value", k, value)) } else if !partitionRegexp.MatchString(parsedARN.Partition) { - errors = append(errors, fmt.Errorf("%q (%s) is an invalid ARN: invalid partition value (expecting to match regular expression: %s)", attribute, value, partitionRegexp)) + errors = append(errors, fmt.Errorf("%q (%s) is an invalid ARN: invalid partition value (expecting to match regular expression: %s)", k, value, partitionRegexp)) } if parsedARN.Region != "" && !regionRegexp.MatchString(parsedARN.Region) { - errors = append(errors, fmt.Errorf("%q (%s) is an invalid ARN: invalid region value (expecting to match regular expression: %s)", attribute, value, regionRegexp)) + errors = append(errors, fmt.Errorf("%q (%s) is an invalid ARN: invalid region value (expecting to match regular expression: %s)", k, value, regionRegexp)) } - if parsedARN.AccountID != "" && !arnAccountIDRegexp.MatchString(parsedARN.AccountID) { - errors = append(errors, fmt.Errorf("%q (%s) is an invalid ARN: invalid account ID value (expecting to match regular expression: %s)", attribute, value, arnAccountIDRegexp)) + if parsedARN.AccountID != "" && !accountIDRegexp.MatchString(parsedARN.AccountID) { + errors = append(errors, fmt.Errorf("%q (%s) is an invalid ARN: invalid account ID value (expecting to match regular expression: %s)", k, value, accountIDRegexp)) } if parsedARN.Resource == "" { - errors = append(errors, fmt.Errorf("%q (%s) is an invalid ARN: missing resource value", attribute, value)) + errors = append(errors, fmt.Errorf("%q (%s) is an invalid ARN: missing resource value", k, value)) + } + + return ws, errors +} + +func ValidAccountID(v interface{}, k string) (ws []string, errors []error) { + value := v.(string) + + // http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html + pattern := `^\d{12}$` + if !regexp.MustCompile(pattern).MatchString(value) { + errors = append(errors, fmt.Errorf( + "%q doesn't look like AWS Account ID (exactly 12 digits): %q", + k, value)) } - return errors + return } // ValidateCIDRBlock validates that the specified CIDR block is valid: