Skip to content

Commit

Permalink
simplify framework ARN validator
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsonaj committed Mar 17, 2023
1 parent a4062c1 commit 8b86259
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 44 deletions.
18 changes: 8 additions & 10 deletions internal/framework/validators/arn.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
}
}
Expand Down
59 changes: 25 additions & 34 deletions internal/verify/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -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$`)

Expand All @@ -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:
Expand Down

0 comments on commit 8b86259

Please sign in to comment.