Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var DictContraintCheckers map[string]ConstraintDefinition = map[string]ConstraintDefinition{}
View Source
var DocumentContraintCheckers map[string]ConstraintDefinition = map[string]ConstraintDefinition{}
View Source
var ListContraintCheckers map[string]ConstraintDefinition = map[string]ConstraintDefinition{ "not_empty": { Name: "not_empty", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { if val.Kind() != box.ValueList { return fmt.Errorf("expected list, got %s", val.Kind()) } if lst, ok := val.ListValue(); ok && len(lst) == 0 { return fmt.Errorf("list is empty - expected non-empty list") } return nil }, }, }
View Source
var NumberContraintCheckers map[string]ConstraintDefinition = map[string]ConstraintDefinition{ "min": { Name: "min", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { if len(args) != 1 { return fmt.Errorf("min constraint requires 1 argument") } arg, ok := args[0].NumberValue() if !ok { return fmt.Errorf("expected number, got %s", args[0].Kind()) } valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if valNum < arg { return fmt.Errorf("value %v is not >= %v", val, arg) } return nil }, }, "max": { Name: "max", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { if len(args) != 1 { return fmt.Errorf("max constraint requires 1 argument") } arg, ok := args[0].NumberValue() if !ok { return fmt.Errorf("expected number, got %s", args[0].Kind()) } valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if valNum > arg { return fmt.Errorf("value %v is not <= %v", val, arg) } return nil }, }, "eq": { Name: "eq", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { if len(args) != 1 { return fmt.Errorf("eq constraint requires 1 argument") } arg, ok := args[0].NumberValue() if !ok { return fmt.Errorf("expected number, got %s", args[0].Kind()) } valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if valNum != arg { return fmt.Errorf("value %v is not equal to %v", val, arg) } return nil }, }, "neq": { Name: "neq", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { if len(args) != 1 { return fmt.Errorf("neq constraint requires 1 argument") } arg, ok := args[0].NumberValue() if !ok { return fmt.Errorf("expected number, got %s", args[0].Kind()) } valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if valNum == arg { return fmt.Errorf("value %v is equal to %v", val, arg) } return nil }, }, "gt": { Name: "gt", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { if len(args) != 1 { return fmt.Errorf("gt constraint requires 1 argument") } arg, ok := args[0].NumberValue() if !ok { return fmt.Errorf("expected number, got %s", args[0].Kind()) } valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if valNum <= arg { return fmt.Errorf("value %v is not > %v", val, arg) } return nil }, }, "lt": { Name: "lt", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { if len(args) != 1 { return fmt.Errorf("lt constraint requires 1 argument") } arg, ok := args[0].NumberValue() if !ok { return fmt.Errorf("expected number, got %s", args[0].Kind()) } valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if valNum >= arg { return fmt.Errorf("value %v is not < %v", val, arg) } return nil }, }, "in": { Name: "in", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { if len(args) != 1 { return fmt.Errorf("in constraint requires 1 argument") } valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } set, err := numberConstraintSet(args[0]) if err != nil { return err } if !slices.Contains(set, valNum) { return fmt.Errorf("value %v is not in the set", val) } return nil }, }, "not_in": { Name: "not_in", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { if len(args) != 1 { return fmt.Errorf("not_in constraint requires 1 argument") } valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } set, err := numberConstraintSet(args[0]) if err != nil { return err } if slices.Contains(set, valNum) { return fmt.Errorf("value %v is in the set", val) } return nil }, }, "range": { Name: "range", NumArgs: 2, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { if len(args) != 2 { return fmt.Errorf("range constraint requires 2 arguments") } valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } min, ok0 := args[0].NumberValue() max, ok1 := args[1].NumberValue() if !ok0 { return fmt.Errorf("expected number, got %s", args[0].Kind()) } if !ok1 { return fmt.Errorf("expected number, got %s", args[1].Kind()) } if valNum < min || valNum > max { return fmt.Errorf("value %v is not in range [%v, %v]", val, min, max) } return nil }, }, "even": { Name: "even", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if math.Mod(valNum, 2) != 0 { return fmt.Errorf("value %v is not even", val) } return nil }, }, "odd": { Name: "odd", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if math.Mod(valNum, 2) == 0 { return fmt.Errorf("value %v is not odd", val) } return nil }, }, "multiple_of": { Name: "multiple_of", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { if len(args) != 1 { return fmt.Errorf("multiple_of constraint requires 1 argument") } valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } divisor, ok := args[0].NumberValue() if !ok { return fmt.Errorf("expected number, got %s", args[0].Kind()) } if divisor == 0 { return fmt.Errorf("divisor cannot be zero") } epsilon := 1e-10 remainder := math.Mod(valNum, divisor) if remainder > epsilon && remainder < divisor-epsilon { return fmt.Errorf("value %v is not a multiple of %v", val, divisor) } return nil }, }, "positive": { Name: "positive", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if valNum <= 0 { return fmt.Errorf("value %v is not positive", val) } return nil }, }, "negative": { Name: "negative", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if valNum >= 0 { return fmt.Errorf("value %v is not negative", val) } return nil }, }, "non_negative": { Name: "non_negative", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if valNum < 0 { return fmt.Errorf("value %v is negative", val) } return nil }, }, "non_positive": { Name: "non_positive", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if valNum > 0 { return fmt.Errorf("value %v is positive", val) } return nil }, }, "finite": { Name: "finite", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if math.IsInf(valNum, 0) || math.IsNaN(valNum) { return fmt.Errorf("value %v is not finite", val) } return nil }, }, "infinite": { Name: "infinite", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if !math.IsInf(valNum, 0) { return fmt.Errorf("value %v is not infinite", val) } return nil }, }, "nan": { Name: "nan", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { valNum, ok := val.NumberValue() if !ok { return fmt.Errorf("expected number, got %s", val.Kind()) } if !math.IsNaN(valNum) { return fmt.Errorf("value %v is not NaN", val) } return nil }, }, }
View Source
var RecordContraintCheckers map[string]ConstraintDefinition = map[string]ConstraintDefinition{}
View Source
var ShapeContraintCheckers map[string]ConstraintDefinition = map[string]ConstraintDefinition{}
View Source
var StringContraintCheckers map[string]ConstraintDefinition = map[string]ConstraintDefinition{ "length": { Name: "length", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if len(args) != 1 { return fmt.Errorf("length constraint requires 1 argument") } expectedLen, okn := args[0].NumberValue() if !okn { return fmt.Errorf("expected number, got %s", args[0].Kind()) } if len(s) != int(expectedLen) { return fmt.Errorf("string length %d is not equal to %g", len(s), expectedLen) } return nil }, }, "minlength": { Name: "minlength", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if len(args) != 1 { return fmt.Errorf("minlength constraint requires 1 argument") } expectedLen, okn := args[0].NumberValue() if !okn { return fmt.Errorf("expected number, got %s", args[0].Kind()) } if len(s) < int(expectedLen) { return fmt.Errorf("string length %d is not greater than or equal to %g", len(s), expectedLen) } return nil }, }, "maxlength": { Name: "maxlength", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if len(args) != 1 { return fmt.Errorf("maxlength constraint requires 1 argument") } expectedLen, okn := args[0].NumberValue() if !okn { return fmt.Errorf("expected number, got %s", args[0].Kind()) } if len(s) > int(expectedLen) { return fmt.Errorf("string length %d is not less than or equal to %g", len(s), expectedLen) } return nil }, }, "regexp": { Name: "regexp", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if len(args) != 1 { return fmt.Errorf("regexp constraint requires 1 argument") } pattern, okp := args[0].StringValue() if !okp { return fmt.Errorf("expected string, got %s", args[0].Kind()) } matched, err := regexp.MatchString(pattern, s) if err != nil { return fmt.Errorf("invalid regexp pattern: %v", err) } if !matched { return fmt.Errorf("string %q does not match pattern %q", s, pattern) } return nil }, }, "starts_with": { Name: "starts_with", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if len(args) != 1 { return fmt.Errorf("starts_with constraint requires 1 argument") } prefix, okp := args[0].StringValue() if !okp { return fmt.Errorf("expected string, got %s", args[0].Kind()) } if !strings.HasPrefix(s, prefix) { return fmt.Errorf("string %q does not start with %q", s, prefix) } return nil }, }, "ends_with": { Name: "ends_with", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if len(args) != 1 { return fmt.Errorf("ends_with constraint requires 1 argument") } suffix, okp := args[0].StringValue() if !okp { return fmt.Errorf("expected string, got %s", args[0].Kind()) } if !strings.HasSuffix(s, suffix) { return fmt.Errorf("string %q does not end with %q", s, suffix) } return nil }, }, "has_substring": { Name: "has_substring", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if len(args) != 1 { return fmt.Errorf("has_substring constraint requires 1 argument") } substring, okp := args[0].StringValue() if !okp { return fmt.Errorf("expected string, got %s", args[0].Kind()) } if !strings.Contains(s, substring) { return fmt.Errorf("string %q does not contain %q", s, substring) } return nil }, }, "not_has_substring": { Name: "not_has_substring", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if len(args) != 1 { return fmt.Errorf("not_has_substring constraint requires 1 argument") } substring, okp := args[0].StringValue() if !okp { return fmt.Errorf("expected string, got %s", args[0].Kind()) } if strings.Contains(s, substring) { return fmt.Errorf("string %q contains %q", s, substring) } return nil }, }, "email": { Name: "email", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } emailRegex := regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`) if !emailRegex.MatchString(s) { return fmt.Errorf("string %q is not a valid email", s) } return nil }, }, "url": { Name: "url", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } urlRegex := regexp.MustCompile(`^https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(/.*)?$`) if !urlRegex.MatchString(s) { return fmt.Errorf("string %q is not a valid URL", s) } return nil }, }, "uuid": { Name: "uuid", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } err := uuid.Validate(s) if err != nil { return fmt.Errorf("string %q is not a valid UUID: %v", s, err) } return nil }, }, "alphanumeric": { Name: "alphanumeric", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } for _, r := range s { if !unicode.IsLetter(r) && !unicode.IsDigit(r) { return fmt.Errorf("string %q contains non-alphanumeric characters", s) } } return nil }, }, "alpha": { Name: "alpha", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } for _, r := range s { if !unicode.IsLetter(r) { return fmt.Errorf("string %q contains non-letter characters", s) } } return nil }, }, "numeric": { Name: "numeric", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if _, err := strconv.ParseFloat(s, 64); err != nil { return fmt.Errorf("string %q is not a valid numeric value", s) } return nil }, }, "lowercase": { Name: "lowercase", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if s != strings.ToLower(s) { return fmt.Errorf("string %q is not lowercase", s) } return nil }, }, "uppercase": { Name: "uppercase", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if s != strings.ToUpper(s) { return fmt.Errorf("string %q is not uppercase", s) } return nil }, }, "trimmed": { Name: "trimmed", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if s != strings.TrimSpace(s) { return fmt.Errorf("string %q has leading or trailing whitespace", s) } return nil }, }, "not_empty": { Name: "not_empty", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if s == "" { return fmt.Errorf("string is empty") } return nil }, }, "one_of": { Name: "one_of", NumArgs: -1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if len(args) < 1 { return fmt.Errorf("one_of constraint requires at least 1 argument") } for _, arg := range args { argString, oka := arg.StringValue() if !oka { return fmt.Errorf("expected string, got %s", arg.Kind()) } if s == argString { return nil } } return fmt.Errorf("string %q is not one of the allowed values", s) }, }, "not_one_of": { Name: "not_one_of", NumArgs: -1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { s, ok := val.StringValue() if !ok { return fmt.Errorf("expected string, got %s", val.Kind()) } if len(args) < 1 { return fmt.Errorf("not_one_of constraint requires at least 1 argument") } for _, arg := range args { argString, oka := arg.StringValue() if !oka { return fmt.Errorf("expected string, got %s", arg.Kind()) } if s == argString { return fmt.Errorf("string %q is one of the allowed values", s) } } return nil }, }, }
View Source
var TrinaryConstraintCheckers map[string]ConstraintDefinition = map[string]ConstraintDefinition{ "not_unknown": { Name: "not_unknown", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { tv, ok := val.TrinaryValue() if !ok { return fmt.Errorf("expected trinary, got %s", val.Kind()) } if tv == trinary.Unknown { return fmt.Errorf("value is unknown") } return nil }, }, "eq": { Name: "eq", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { tv, ok := val.TrinaryValue() if !ok { return fmt.Errorf("expected trinary, got %s", val.Kind()) } if len(args) != 1 { return fmt.Errorf("eq constraint requires 1 argument") } expected, oka := args[0].TrinaryValue() if !oka { return fmt.Errorf("eq constraint expects a boolean argument") } if tv != expected { return fmt.Errorf("value %v is not equal to %v", tv, expected) } return nil }, }, "neq": { Name: "neq", NumArgs: 1, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { tv, ok := val.TrinaryValue() if !ok { return fmt.Errorf("expected trinary, got %s", val.Kind()) } if len(args) != 1 { return fmt.Errorf("neq constraint requires 1 argument") } expected, oka := args[0].TrinaryValue() if !oka { return fmt.Errorf("neq constraint expects a boolean argument") } if tv == expected { return fmt.Errorf("value %v is equal to %v - expected not equal", tv, expected) } return nil }, }, "is_true": { Name: "is_true", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { tv, ok := val.TrinaryValue() if !ok { return fmt.Errorf("expected trinary, got %s", val.Kind()) } if tv != trinary.True { return fmt.Errorf("value %v is not true", tv) } return nil }, }, "is_false": { Name: "is_false", NumArgs: 0, Checker: func(ctx context.Context, p *index.Policy, val box.Value, args []box.Value) error { tv, ok := val.TrinaryValue() if !ok { return fmt.Errorf("expected trinary, got %s", val.Kind()) } if tv != trinary.False { return fmt.Errorf("value %v is not false", tv) } return nil }, }, }
TrinaryConstraintCheckers contains supported boolean constraint validators. For trinaries, common constraints include eq/neq (compare to true/false/unknown), and truthiness helpers like is_true/is_false.
Functions ¶
This section is empty.
Types ¶
type ConstraintChecker ¶
type ConstraintDefinition ¶
type ConstraintDefinition struct {
Name string
NumArgs int
Checker ConstraintChecker
}
Click to show internal directories.
Click to hide internal directories.