Files
terraform-provider-unifi/internal/provider/validators/hostname.go
2025-03-21 11:52:55 +01:00

66 lines
1.8 KiB
Go

package validators
import (
"context"
"fmt"
"github.com/filipowm/terraform-provider-unifi/internal/provider/types"
"regexp"
"strings"
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
)
// A regex pattern for validating hostnames without protocol schemes
// This matches hostnames according to RFC 1035 with some limitations
var hostnameRegex = regexp.MustCompile(`^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$`)
// Hostname returns a validator which ensures that the string value is a valid hostname without protocol schemes.
func Hostname() validator.String {
return hostnameValidator{}
}
type hostnameValidator struct{}
func (v hostnameValidator) Description(_ context.Context) string {
return "must be a valid hostname (without protocol scheme)"
}
func (v hostnameValidator) MarkdownDescription(ctx context.Context) string {
return v.Description(ctx)
}
func (v hostnameValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
value := req.ConfigValue
if !types.IsDefined(value) {
return
}
val := value.ValueString()
// Check if the hostname has a scheme (which it shouldn't)
if strings.Contains(val, "://") {
resp.Diagnostics.Append(
validatordiag.InvalidAttributeValueDiagnostic(
req.Path,
v.Description(ctx),
fmt.Sprintf("%q should not include a protocol scheme (e.g., http:// or https://)", val),
),
)
return
}
// Convert to lowercase for validation
hostname := strings.ToLower(val)
if !hostnameRegex.MatchString(hostname) {
resp.Diagnostics.Append(
validatordiag.InvalidAttributeValueDiagnostic(
req.Path,
v.Description(ctx),
fmt.Sprintf("%q is not a valid hostname", val),
),
)
}
}