156 lines
4.6 KiB
Go
156 lines
4.6 KiB
Go
package provider
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
|
)
|
|
|
|
// stringOneOfValidator validates that a string value is one of the allowed values.
|
|
type stringOneOfValidator struct {
|
|
values []string
|
|
}
|
|
|
|
func (v stringOneOfValidator) Description(ctx context.Context) string {
|
|
return fmt.Sprintf("value must be one of: %v", v.values)
|
|
}
|
|
|
|
func (v stringOneOfValidator) MarkdownDescription(ctx context.Context) string {
|
|
return fmt.Sprintf("value must be one of: %v", v.values)
|
|
}
|
|
|
|
func (v stringOneOfValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
|
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
|
return
|
|
}
|
|
|
|
value := req.ConfigValue.ValueString()
|
|
for _, allowed := range v.values {
|
|
if value == allowed {
|
|
return
|
|
}
|
|
}
|
|
|
|
resp.Diagnostics.AddAttributeError(
|
|
req.Path,
|
|
"Invalid value",
|
|
fmt.Sprintf("Value must be one of %v, got: %s", v.values, value),
|
|
)
|
|
}
|
|
|
|
func StringOneOf(values ...string) validator.String {
|
|
return stringOneOfValidator{
|
|
values: values,
|
|
}
|
|
}
|
|
|
|
// validJSONArrayValidator проверяет, что строка является валидным JSON массивом
|
|
type validJSONArrayValidator struct{}
|
|
|
|
func (v validJSONArrayValidator) Description(ctx context.Context) string {
|
|
return "value must be a valid JSON array (e.g., [\"item1\", \"item2\"])"
|
|
}
|
|
|
|
func (v validJSONArrayValidator) MarkdownDescription(ctx context.Context) string {
|
|
return "value must be a valid JSON array (e.g., `[\"item1\", \"item2\"]`)"
|
|
}
|
|
|
|
func (v validJSONArrayValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
|
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
|
return
|
|
}
|
|
|
|
value := req.ConfigValue.ValueString()
|
|
if value == "" {
|
|
// Пустая строка не валидна - должен быть либо null, либо JSON массив
|
|
resp.Diagnostics.AddAttributeError(
|
|
req.Path,
|
|
"Invalid JSON Array",
|
|
"Empty string is not a valid JSON array. Use jsonencode([...]) or omit the attribute.",
|
|
)
|
|
return
|
|
}
|
|
|
|
var arr []interface{}
|
|
if err := json.Unmarshal([]byte(value), &arr); err != nil {
|
|
resp.Diagnostics.AddAttributeError(
|
|
req.Path,
|
|
"Invalid JSON Array",
|
|
fmt.Sprintf("Value must be a valid JSON array: %s", err),
|
|
)
|
|
}
|
|
}
|
|
|
|
func ValidJSONArray() validator.String {
|
|
return validJSONArrayValidator{}
|
|
}
|
|
|
|
// validJSONArrayOrEmptyValidator проверяет JSON массив или разрешает пустую строку
|
|
// Используется для accessIpList где "" означает "доступ отовсюду"
|
|
type validJSONArrayOrEmptyValidator struct{}
|
|
|
|
func (v validJSONArrayOrEmptyValidator) Description(ctx context.Context) string {
|
|
return "value must be a valid JSON array or empty string (empty = access from anywhere)"
|
|
}
|
|
|
|
func (v validJSONArrayOrEmptyValidator) MarkdownDescription(ctx context.Context) string {
|
|
return "value must be a valid JSON array or empty string (empty = access from anywhere)"
|
|
}
|
|
|
|
func (v validJSONArrayOrEmptyValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
|
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
|
return
|
|
}
|
|
|
|
value := req.ConfigValue.ValueString()
|
|
if value == "" {
|
|
// Пустая строка разрешена - означает доступ отовсюду
|
|
return
|
|
}
|
|
|
|
var arr []interface{}
|
|
if err := json.Unmarshal([]byte(value), &arr); err != nil {
|
|
resp.Diagnostics.AddAttributeError(
|
|
req.Path,
|
|
"Invalid JSON Array",
|
|
fmt.Sprintf("Value must be a valid JSON array or empty string: %s", err),
|
|
)
|
|
}
|
|
}
|
|
|
|
func ValidJSONArrayOrEmpty() validator.String {
|
|
return validJSONArrayOrEmptyValidator{}
|
|
}
|
|
|
|
type uuidLikeValidator struct{}
|
|
|
|
func (v uuidLikeValidator) Description(ctx context.Context) string {
|
|
return "value must be a UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)"
|
|
}
|
|
|
|
func (v uuidLikeValidator) MarkdownDescription(ctx context.Context) string {
|
|
return "value must be a UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)"
|
|
}
|
|
|
|
func (v uuidLikeValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
|
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
|
return
|
|
}
|
|
|
|
value := strings.TrimSpace(req.ConfigValue.ValueString())
|
|
if value == "" || !uuidLikeRegex.MatchString(value) {
|
|
resp.Diagnostics.AddAttributeError(
|
|
req.Path,
|
|
"Invalid UUID",
|
|
fmt.Sprintf("Value must be a UUID, got: %q", req.ConfigValue.ValueString()),
|
|
)
|
|
}
|
|
}
|
|
|
|
func UUIDLike() validator.String {
|
|
return uuidLikeValidator{}
|
|
}
|