refactor: reorganize code to make it more readable (#71)
This commit is contained in:
committed by
GitHub
parent
86fdc0b27a
commit
cdc0254289
@@ -30,15 +30,15 @@ type cidrValidator struct {
|
||||
allowEmpty bool
|
||||
}
|
||||
|
||||
func (v cidrValidator) Description(ctx context.Context) string {
|
||||
func (v cidrValidator) Description(_ context.Context) string {
|
||||
return "value must be a valid CIDR notation (e.g., '192.168.1.0/24')"
|
||||
}
|
||||
|
||||
func (v cidrValidator) MarkdownDescription(ctx context.Context) string {
|
||||
func (v cidrValidator) MarkdownDescription(_ context.Context) string {
|
||||
return "value must be a valid CIDR notation (e.g., `192.168.1.0/24`)"
|
||||
}
|
||||
|
||||
func (v cidrValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||
func (v cidrValidator) ValidateString(_ context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package validators
|
||||
import (
|
||||
"context"
|
||||
"github.com/biter777/countries"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/base"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/types"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
)
|
||||
@@ -24,7 +24,7 @@ func (c countryCodeAlpha2Validator) MarkdownDescription(ctx context.Context) str
|
||||
|
||||
func (c countryCodeAlpha2Validator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||
code := req.ConfigValue
|
||||
if base.IsEmptyString(code) {
|
||||
if types.IsEmptyString(code) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
package validators
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/base"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
)
|
||||
|
||||
// A common regex pattern for validating email addresses
|
||||
// This is a simplified version and may not catch all edge cases
|
||||
var emailRegex = regexp.MustCompile(`^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$`)
|
||||
|
||||
// Email returns a validator which ensures that the string value is a valid email address.
|
||||
func Email() validator.String {
|
||||
return emailValidator{}
|
||||
}
|
||||
|
||||
type emailValidator struct{}
|
||||
|
||||
func (v emailValidator) Description(_ context.Context) string {
|
||||
return "must be a valid email address"
|
||||
}
|
||||
|
||||
func (v emailValidator) MarkdownDescription(ctx context.Context) string {
|
||||
return v.Description(ctx)
|
||||
}
|
||||
|
||||
func (v emailValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||
value := req.ConfigValue
|
||||
if !base.IsDefined(value) {
|
||||
return
|
||||
}
|
||||
|
||||
val := value.ValueString()
|
||||
if !emailRegex.MatchString(val) {
|
||||
resp.Diagnostics.Append(
|
||||
validatordiag.InvalidAttributeValueDiagnostic(
|
||||
req.Path,
|
||||
v.Description(ctx),
|
||||
fmt.Sprintf("%q is not a valid email address", val),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
package validators_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/validators"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
)
|
||||
|
||||
func TestEmailValidator(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type testCase struct {
|
||||
val types.String
|
||||
expectError bool
|
||||
}
|
||||
tests := map[string]testCase{
|
||||
"unknown": {
|
||||
val: types.StringUnknown(),
|
||||
},
|
||||
"null": {
|
||||
val: types.StringNull(),
|
||||
},
|
||||
"valid-simple": {
|
||||
val: types.StringValue("test@example.com"),
|
||||
},
|
||||
"valid-with-dots": {
|
||||
val: types.StringValue("john.doe@example.com"),
|
||||
},
|
||||
"valid-with-plus": {
|
||||
val: types.StringValue("john+test@example.com"),
|
||||
},
|
||||
"valid-with-subdomain": {
|
||||
val: types.StringValue("john@sub.example.com"),
|
||||
},
|
||||
"valid-with-numbers": {
|
||||
val: types.StringValue("user123@example.com"),
|
||||
},
|
||||
"invalid-no-at": {
|
||||
val: types.StringValue("testexample.com"),
|
||||
expectError: true,
|
||||
},
|
||||
"invalid-no-domain": {
|
||||
val: types.StringValue("test@"),
|
||||
expectError: true,
|
||||
},
|
||||
"invalid-no-tld": {
|
||||
val: types.StringValue("test@example"),
|
||||
expectError: true,
|
||||
},
|
||||
"invalid-space": {
|
||||
val: types.StringValue("test user@example.com"),
|
||||
expectError: true,
|
||||
},
|
||||
"invalid-special-chars": {
|
||||
val: types.StringValue("test*user@example.com"),
|
||||
expectError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
name, test := name, test
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
request := validator.StringRequest{
|
||||
ConfigValue: test.val,
|
||||
}
|
||||
response := validator.StringResponse{}
|
||||
validators.Email().ValidateString(context.Background(), request, &response)
|
||||
|
||||
if !response.Diagnostics.HasError() && test.expectError {
|
||||
t.Fatal("expected error, got no error")
|
||||
}
|
||||
|
||||
if response.Diagnostics.HasError() && !test.expectError {
|
||||
t.Fatalf("got unexpected error: %s", response.Diagnostics)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package validators
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/base"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
)
|
||||
|
||||
var hexColorRegex = regexp.MustCompile("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$")
|
||||
|
||||
// HexColor returns a validator which ensures that the string value is a valid hex color code.
|
||||
// Valid formats are: #RGB or #RRGGBB
|
||||
func HexColor() validator.String {
|
||||
return hexColorValidator{}
|
||||
}
|
||||
|
||||
type hexColorValidator struct{}
|
||||
|
||||
func (v hexColorValidator) Description(_ context.Context) string {
|
||||
return "must be a valid hex color code (e.g., #FFF or #FFFFFF)"
|
||||
}
|
||||
|
||||
func (v hexColorValidator) MarkdownDescription(ctx context.Context) string {
|
||||
return v.Description(ctx)
|
||||
}
|
||||
|
||||
func (v hexColorValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||
value := req.ConfigValue
|
||||
if !base.IsDefined(value) {
|
||||
return
|
||||
}
|
||||
|
||||
val := value.ValueString()
|
||||
if !hexColorRegex.MatchString(val) {
|
||||
resp.Diagnostics.Append(
|
||||
validatordiag.InvalidAttributeValueDiagnostic(
|
||||
req.Path,
|
||||
v.Description(ctx),
|
||||
fmt.Sprintf("%q is not a valid hex color code", val),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
package validators_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/validators"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
)
|
||||
|
||||
func TestHexColorValidator(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type testCase struct {
|
||||
val types.String
|
||||
expectError bool
|
||||
}
|
||||
tests := map[string]testCase{
|
||||
"unknown": {
|
||||
val: types.StringUnknown(),
|
||||
},
|
||||
"null": {
|
||||
val: types.StringNull(),
|
||||
},
|
||||
"valid-6-digits": {
|
||||
val: types.StringValue("#123456"),
|
||||
},
|
||||
"valid-3-digits": {
|
||||
val: types.StringValue("#123"),
|
||||
},
|
||||
"valid-uppercase": {
|
||||
val: types.StringValue("#ABCDEF"),
|
||||
},
|
||||
"valid-mixed-case": {
|
||||
val: types.StringValue("#aBcDeF"),
|
||||
},
|
||||
"invalid-missing-hash": {
|
||||
val: types.StringValue("123456"),
|
||||
expectError: true,
|
||||
},
|
||||
"invalid-too-short": {
|
||||
val: types.StringValue("#12"),
|
||||
expectError: true,
|
||||
},
|
||||
"invalid-too-long": {
|
||||
val: types.StringValue("#1234567"),
|
||||
expectError: true,
|
||||
},
|
||||
"invalid-wrong-chars": {
|
||||
val: types.StringValue("#12345G"),
|
||||
expectError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
name, test := name, test
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
request := validator.StringRequest{
|
||||
ConfigValue: test.val,
|
||||
}
|
||||
response := validator.StringResponse{}
|
||||
validators.HexColor().ValidateString(context.Background(), request, &response)
|
||||
|
||||
if !response.Diagnostics.HasError() && test.expectError {
|
||||
t.Fatal("expected error, got no error")
|
||||
}
|
||||
|
||||
if response.Diagnostics.HasError() && !test.expectError {
|
||||
t.Fatalf("got unexpected error: %s", response.Diagnostics)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,10 @@ package validators
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/types"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/base"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
)
|
||||
@@ -32,7 +32,7 @@ func (v hostnameValidator) MarkdownDescription(ctx context.Context) string {
|
||||
|
||||
func (v hostnameValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||
value := req.ConfigValue
|
||||
if !base.IsDefined(value) {
|
||||
if !types.IsDefined(value) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package validators
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/utils"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package validators
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/utils"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/utils"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
)
|
||||
|
||||
|
||||
1
internal/provider/validators/port_range.go
Normal file
1
internal/provider/validators/port_range.go
Normal file
@@ -0,0 +1 @@
|
||||
package validators
|
||||
27
internal/provider/validators/regex.go
Normal file
27
internal/provider/validators/regex.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package validators
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var (
|
||||
TimeFormatRegex = regexp.MustCompile(`^[0-9][0-9]:[0-9][0-9]$`)
|
||||
TimeFormat = stringvalidator.RegexMatches(TimeFormatRegex, "must be a valid time in 24-hour format (HH:MM)")
|
||||
|
||||
DateFormatRegex = regexp.MustCompile(`^(20[0-9]{2})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$`)
|
||||
DateFormat = stringvalidator.RegexMatches(DateFormatRegex, "must be a valid date in the format YYYY-MM-DD")
|
||||
|
||||
PortRangeRegexp = regexp.MustCompile("(([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])|([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])-([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5]))+(,([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])|,([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])-([1-9][0-9]{0,3}|[1-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-4][0-9]{2}|[6][5][5][0-2][0-9]|[6][5][5][3][0-5])){0,14}")
|
||||
PortRangeV2 = validation.StringMatch(PortRangeRegexp, "invalid port range")
|
||||
|
||||
MacRegex = regexp.MustCompile(`^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$`)
|
||||
Mac = stringvalidator.RegexMatches(MacRegex, "invalid MAC address")
|
||||
|
||||
HexColorRegex = regexp.MustCompile("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$")
|
||||
HexColor = stringvalidator.RegexMatches(HexColorRegex, "invalid hex color code")
|
||||
|
||||
EmailRegex = regexp.MustCompile(`^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$`)
|
||||
Email = stringvalidator.RegexMatches(EmailRegex, "invalid email address")
|
||||
)
|
||||
@@ -3,6 +3,7 @@ package validators
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||
@@ -182,6 +183,33 @@ func RequiredTogetherIf(conditionPath path.Expression, conditionValue attr.Value
|
||||
}
|
||||
}
|
||||
|
||||
func mapPathToExpression(p string) path.Expression {
|
||||
parts := strings.Split(p, ".")
|
||||
root := parts[0]
|
||||
exp := path.MatchRoot(root)
|
||||
for _, part := range parts[1:] {
|
||||
exp = exp.AtName(part)
|
||||
}
|
||||
return exp
|
||||
}
|
||||
|
||||
func mapPathsToExpressions(paths ...string) []path.Expression {
|
||||
var expressions []path.Expression
|
||||
for _, p := range paths {
|
||||
expressions = append(expressions, mapPathToExpression(p))
|
||||
}
|
||||
return expressions
|
||||
}
|
||||
|
||||
func RequiredSimpleTogetherIf(conditionPath string, conditionValue attr.Value, targetExpressions ...string) RequiredTogetherIfValidator {
|
||||
return RequiredTogetherIfValidator{
|
||||
ConditionPath: mapPathToExpression(conditionPath),
|
||||
ConditionValue: conditionValue,
|
||||
TargetExpressions: mapPathsToExpressions(targetExpressions...),
|
||||
CheckOnlyIfSet: false,
|
||||
}
|
||||
}
|
||||
|
||||
// RequiredTogetherIfSet creates a validator that ensures a set of target attributes
|
||||
// are configured together if a condition attribute is set (not null), regardless of its value.
|
||||
func RequiredTogetherIfSet(conditionPath path.Expression, targetExpressions ...path.Expression) RequiredTogetherIfValidator {
|
||||
|
||||
@@ -3,7 +3,7 @@ package validators
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/base"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/types"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
)
|
||||
@@ -41,7 +41,7 @@ func (v stringLengthExactlyValidator) ValidateString(ctx context.Context, req va
|
||||
}
|
||||
|
||||
value := req.ConfigValue
|
||||
if !base.IsDefined(value) {
|
||||
if !types.IsDefined(value) {
|
||||
return
|
||||
}
|
||||
val := value.ValueString()
|
||||
|
||||
@@ -3,10 +3,10 @@ package validators
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/types"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/base"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
)
|
||||
@@ -29,7 +29,7 @@ func (v timezoneValidator) MarkdownDescription(ctx context.Context) string {
|
||||
|
||||
func (v timezoneValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||
value := req.ConfigValue
|
||||
if !base.IsDefined(value) {
|
||||
if !types.IsDefined(value) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ package validators
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/types"
|
||||
"net/url"
|
||||
|
||||
"github.com/filipowm/terraform-provider-unifi/internal/provider/base"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
)
|
||||
@@ -37,7 +37,7 @@ func (v urlValidator) MarkdownDescription(ctx context.Context) string {
|
||||
|
||||
func (v urlValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||
value := req.ConfigValue
|
||||
if !base.IsDefined(value) {
|
||||
if !types.IsDefined(value) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user