apimachineryk8s.io/apimachinery/pkg/api/validate Index | Files | Directories

package validate

import "k8s.io/apimachinery/pkg/api/validate"

Package validate holds API validation functions which are designed for use with the k8s.io/code-generator/cmd/validation-gen tool. Each validation function has a similar fingerprint:

func <Name>(ctx context.Context,
            op operation.Operation,
            fldPath *field.Path,
            value, oldValue <nilable type>,
            <other args...>) field.ErrorList

The value and oldValue arguments will always be a nilable type. If the original value was a string, these will be a *string. If the original value was a slice or map, these will be the same slice or map type.

For a CREATE operation, the oldValue will always be nil. For an UPDATE operation, either value or oldValue may be nil, e.g. when adding or removing a value in a list-map. Validators which care about UPDATE operations should look at the opCtx argument to know which operation is being executed.

Tightened validation (also known as ratcheting validation) is supported by defining a new validation function. For example:

func TightenedMaxLength(ctx context.Context, op operation.Operation, fldPath *field.Path, value, oldValue *string) field.ErrorList {
  if oldValue != nil && len(MaxLength(ctx, op, fldPath, oldValue, nil)) > 0 {
    // old value is not valid, so this value skips the tightened validation
    return nil
  }
  return MaxLength(ctx, op, fldPath, value, nil)
}

In general, we cannot distinguish a non-specified slice or map from one that is specified but empty. Validators should not rely on nil values, but use len() instead.

Index

Functions

func DirectEqual

func DirectEqual[T comparable](a, b T) bool

DirectEqual is a MatchFunc that uses the == operator to compare two values. It can be used by any other function that needs to compare two values directly.

func DiscriminatedUnion

func DiscriminatedUnion[T any, D ~string](_ context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj T, union *UnionMembership, discriminatorExtractor ExtractorFn[T, D], isSetFns ...ExtractorFn[T, bool]) (errs field.ErrorList)

DiscriminatedUnion verifies specified union member matches the discriminator.

UnionMembership must define all the members of the union and the discriminator.

For example:

var UnionMembershipForABC = validate.NewDiscriminatedUnionMembership("type", [2]string{"a", "A"}, [2]string{"b", "B"}, [2]string{"c", "C"})
func ValidateABC(ctx context.Context, op operation.Operation, fldPath *field.Path, in *ABC) (errs field.ErrorList) {
	errs = append(errs, DiscriminatedUnion(ctx, op, fldPath, in, oldIn, UnionMembershipForABC,
		func(in *ABC) string { return string(in.Type) },
		func(in *ABC) bool { return in.A != nil },
		func(in *ABC) bool { return in.B != ""},
		func(in *ABC) bool { return in.C != 0 },
	)...)
	return errs
}

It is not an error for the discriminatorValue to be unknown. That must be validated on its own.

func EachMapKey

func EachMapKey[K ~string, T any](ctx context.Context, op operation.Operation, fldPath *field.Path, newMap, oldMap map[K]T,
	validator ValidateFunc[*K]) field.ErrorList

EachMapKey validates each element of newMap with the specified validation function.

func EachMapVal

func EachMapVal[K ~string, V any](ctx context.Context, op operation.Operation, fldPath *field.Path, newMap, oldMap map[K]V,
	equiv MatchFunc[V], validator ValidateFunc[*V]) field.ErrorList

EachMapVal validates each value in newMap using the specified validation function, passing the corresponding old value from oldMap if the key exists in oldMap. For update operations, it implements validation ratcheting by skipping validation when the old value exists and the equiv function confirms the values are equivalent. The value-type of the map is assumed to not be nilable. If equiv is nil, value-based ratcheting is disabled and all values will be validated.

func EachSliceVal

func EachSliceVal[T any](ctx context.Context, op operation.Operation, fldPath *field.Path, newSlice, oldSlice []T,
	match, equiv MatchFunc[T], validator ValidateFunc[*T]) field.ErrorList

EachSliceVal performs validation on each element of newSlice using the provided validation function.

For update operations, the match function finds corresponding values in oldSlice for each value in newSlice. This comparison can be either full or partial (e.g., matching only specific struct fields that serve as a unique identifier). If match is nil, validation proceeds without considering old values, and the equiv function is not used.

For update operations, the equiv function checks if a new value is equivalent to its corresponding old value, enabling validation ratcheting. If equiv is nil but match is provided, the match function is assumed to perform full value comparison.

Note: The slice element type must be non-nilable.

func Enum

func Enum[T ~string](_ context.Context, op operation.Operation, fldPath *field.Path, value, _ *T, symbols sets.Set[T]) field.ErrorList

Enum verifies that the specified value is one of the valid symbols. This is for string enums only.

func FixedResult

func FixedResult[T any](_ context.Context, op operation.Operation, fldPath *field.Path, value, _ T, result bool, arg string) field.ErrorList

FixedResult asserts a fixed boolean result. This is mostly useful for testing.

func ForbiddenMap

func ForbiddenMap[K comparable, T any](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ map[K]T) field.ErrorList

ForbiddenMap verifies that the specified map is empty.

func ForbiddenPointer

func ForbiddenPointer[T any](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *T) field.ErrorList

ForbiddenPointer verifies that the specified pointer is nil.

func ForbiddenSlice

func ForbiddenSlice[T any](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ []T) field.ErrorList

ForbiddenSlice verifies that the specified slice is empty.

func ForbiddenValue

func ForbiddenValue[T comparable](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *T) field.ErrorList

ForbiddenValue verifies that the specified value is the zero-value for its type.

func ImmutableByCompare

func ImmutableByCompare[T comparable](_ context.Context, op operation.Operation, fldPath *field.Path, value, oldValue *T) field.ErrorList

ImmutableByCompare verifies that the specified value has not changed in the course of an update operation. It does nothing if the old value is not provided. If the caller needs to compare types that are not trivially comparable, they should use ImmutableByReflect instead.

Caution: structs with pointer fields satisfy comparable, but this function will only compare pointer values. It does not compare the pointed-to values.

func ImmutableByReflect

func ImmutableByReflect[T any](_ context.Context, op operation.Operation, fldPath *field.Path, value, oldValue T) field.ErrorList

ImmutableByReflect verifies that the specified value has not changed in the course of an update operation. It does nothing if the old value is not provided. Unlike ImmutableByCompare, this function can be used with types that are not directly comparable, at the cost of performance.

func Minimum

func Minimum[T constraints.Integer](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *T, min T) field.ErrorList

Minimum verifies that the specified value is greater than or equal to min.

func NEQ

func NEQ[T comparable](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *T, disallowed T) field.ErrorList

NEQ validates that the specified comparable value is not equal to the disallowed value.

func OptionalMap

func OptionalMap[K comparable, T any](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ map[K]T) field.ErrorList

OptionalMap verifies that the specified map is not empty. This is identical to RequiredMap, but the caller should treat an error here as an indication that the optional value was not specified.

func OptionalPointer

func OptionalPointer[T any](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *T) field.ErrorList

OptionalPointer verifies that the specified pointer is not nil. This is identical to RequiredPointer, but the caller should treat an error here as an indication that the optional value was not specified.

func OptionalSlice

func OptionalSlice[T any](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ []T) field.ErrorList

OptionalSlice verifies that the specified slice is not empty. This is identical to RequiredSlice, but the caller should treat an error here as an indication that the optional value was not specified.

func OptionalValue

func OptionalValue[T comparable](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *T) field.ErrorList

OptionalValue verifies that the specified value is not the zero-value for its type. This is identical to RequiredValue, but the caller should treat an error here as an indication that the optional value was not specified.

func RequiredMap

func RequiredMap[K comparable, T any](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ map[K]T) field.ErrorList

RequiredMap verifies that the specified map is not empty.

func RequiredPointer

func RequiredPointer[T any](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *T) field.ErrorList

RequiredPointer verifies that the specified pointer is not nil.

func RequiredSlice

func RequiredSlice[T any](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ []T) field.ErrorList

RequiredSlice verifies that the specified slice is not empty.

func RequiredValue

func RequiredValue[T comparable](_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *T) field.ErrorList

RequiredValue verifies that the specified value is not the zero-value for its type.

func SemanticDeepEqual

func SemanticDeepEqual[T any](a, b T) bool

SemanticDeepEqual is a MatchFunc that uses equality.Semantic.DeepEqual to compare two values. This wrapper is needed because MatchFunc requires a function that takes two arguments of specific type T, while equality.Semantic.DeepEqual takes arguments of type interface{}/any. The wrapper satisfies the type constraints of MatchFunc while leveraging the underlying semantic equality logic. It can be used by any other function that needs to call DeepEqual.

func SliceItem

func SliceItem[TList ~[]TItem, TItem any](
	ctx context.Context, op operation.Operation, fldPath *field.Path,
	newList, oldList TList,
	matches MatchItemFn[TItem],
	equiv MatchFunc[TItem],
	itemValidator func(ctx context.Context, op operation.Operation, fldPath *field.Path, newObj, oldObj *TItem) field.ErrorList,
) field.ErrorList

SliceItem finds the first item in newList that satisfies the 'matches' predicate, and if found, also looks for a matching item in oldList. It then invokes 'itemValidator' on these items. The fldPath passed to itemValidator is indexed to the matched item's position in newList. This function processes only the *first* matching item found in newList. It assumes that the 'matches' predicate targets a unique identifier (primary key) and will match at most one element per list. If this assumption is violated, changes in list order can lead this function to have inconsistent behavior. This function does not validate items that were removed (present in oldList but not in newList).

func Subfield

func Subfield[Tstruct any, Tfield any](ctx context.Context, op operation.Operation, fldPath *field.Path, newStruct, oldStruct *Tstruct,
	fldName string, getField GetFieldFunc[Tstruct, Tfield], validator ValidateFunc[Tfield]) field.ErrorList

Subfield validates a subfield of a struct against a validator function.

func Union

func Union[T any](_ context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj T, union *UnionMembership, isSetFns ...ExtractorFn[T, bool]) field.ErrorList

Union verifies that exactly one member of a union is specified.

UnionMembership must define all the members of the union.

For example:

var UnionMembershipForABC := validate.NewUnionMembership([2]string{"a", "A"}, [2]string{"b", "B"}, [2]string{"c", "C"})
func ValidateABC(ctx context.Context, op operation.Operation, fldPath *field.Path, in *ABC) (errs fields.ErrorList) {
	errs = append(errs, Union(ctx, op, fldPath, in, oldIn, UnionMembershipForABC,
		func(in *ABC) bool { return in.A != nil },
		func(in *ABC) bool { return in.B != ""},
		func(in *ABC) bool { return in.C != 0 },
	)...)
	return errs
}

func Unique

func Unique[T any](_ context.Context, _ operation.Operation, fldPath *field.Path, newSlice, _ []T, match MatchFunc[T]) field.ErrorList

Unique verifies that each element of newSlice is unique, according to the match function. It compares every element of the slice with every other element and returns errors for non-unique items.

func ZeroOrOneOfUnion

func ZeroOrOneOfUnion[T any](_ context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj T, union *UnionMembership, isSetFns ...ExtractorFn[T, bool]) field.ErrorList

ZeroOrOneOfUnion verifies that at most one member of a union is specified.

ZeroOrOneOfMembership must define all the members of the union.

For example:

var ZeroOrOneOfMembershipForABC = validate.NewUnionMembership([2]string{"a", "A"}, [2]string{"b", "B"}, [2]string{"c", "C"})
func ValidateABC(ctx context.Context, op operation.Operation, fldPath *field.Path, in *ABC) (errs field.ErrorList) {
	errs = append(errs, ZeroOrOneOfUnion(ctx, op, fldPath, in, oldIn, UnionMembershipForABC,
		func(in *ABC) bool { return in.A != nil },
		func(in *ABC) bool { return in.B != ""},
		func(in *ABC) bool { return in.C != 0 },
	)...)
	return errs
}

Types

type ExtractorFn

type ExtractorFn[T, V any] func(obj T) V

ExtractorFn extracts a value from a parent object. Depending on the context, that could be the value of a field or just whether that field was set or not. Note: obj is not guaranteed to be non-nil, need to handle nil obj in the extractor.

type GetFieldFunc

type GetFieldFunc[Tstruct any, Tfield any] func(*Tstruct) Tfield

GetFieldFunc is a function that extracts a field from a type and returns a nilable value.

type MatchFunc

type MatchFunc[T any] func(T, T) bool

MatchFunc is a function that compares two values of the same type, according to some criteria, and returns true if they match.

type MatchItemFn

type MatchItemFn[T any] func(*T) bool

MatchItemFn takes a pointer to an item and returns true if it matches the criteria.

type UnionMembership

type UnionMembership struct {
	// contains filtered or unexported fields
}

UnionMembership represents an ordered list of field union memberships.

func NewDiscriminatedUnionMembership

func NewDiscriminatedUnionMembership(discriminatorFieldName string, members ...[2]string) *UnionMembership

NewDiscriminatedUnionMembership returns a new UnionMembership for the given discriminator field and list of members. members are provided in the same way as for NewUnionMembership.

func NewUnionMembership

func NewUnionMembership(member ...[2]string) *UnionMembership

NewUnionMembership returns a new UnionMembership for the given list of members.

Each member is a [2]string to provide a fieldName and discriminatorValue pair, where [0] identifies the field name and [1] identifies the union member Name.

Field names must be unique.

type UnionValidationOptions

type UnionValidationOptions struct {
	// ErrorForEmpty returns error when no fields are set (nil means no error)
	ErrorForEmpty func(fldPath *field.Path, allFields []string) *field.Error

	// ErrorForMultiple returns error when multiple fields are set (nil means no error)
	ErrorForMultiple func(fldPath *field.Path, specifiedFields []string, allFields []string) *field.Error
}

UnionValidationOptions configures how union validation behaves

type ValidateFunc

type ValidateFunc[T any] func(ctx context.Context, op operation.Operation, fldPath *field.Path, newValue, oldValue T) field.ErrorList

ValidateFunc is a function that validates a value, possibly considering the old value (if any).

Source Files

common.go doc.go each.go enum.go equality.go immutable.go item.go limits.go required.go subfield.go testing.go union.go zeroorone.go

Directories

PathSynopsis
pkg/api/validate/constraints
pkg/api/validate/content
Version
v0.34.0-rc.0
Published
Jul 25, 2025
Platform
js/wasm
Imports
11 packages
Last checked
28 minutes ago

Tools for package owners.