Repository: kubernetes/kubernetes
File: pkg/apis/storage/validation/validation.go (Go)

Code before:

func validateVolumeError(e *storage.VolumeError, fldPath *field.Path) field.ErrorList {
	allErrs := field.ErrorList{}

	if e == nil {
		return allErrs
	}
	if len(e.Message) > maxVolumeErrorMessageSize {
		allErrs = append(allErrs, field.TooLong(fldPath.Child("message"), "" /*unused*/, maxAttachedVolumeMetadataSize))
	}

	if e.ErrorCode != nil {
		value := *e.ErrorCode
		if value < 0 {
			allErrs = append(allErrs, field.Invalid(fldPath.Child("errorCode"), value, validation.InclusiveRangeError(0, math.MaxInt32)))
		}
	}
	return allErrs
}

// ValidateVolumeAttachmentUpdate validates a VolumeAttachment.
func ValidateVolumeAttachmentUpdate(new, old *storage.VolumeAttachment) field.ErrorList {
	allErrs := ValidateVolumeAttachment(new)
	// Spec is read-only
	// If this ever relaxes in the future, make sure to increment the Generation number in PrepareForUpdate
	if !apiequality.Semantic.DeepEqual(old.Spec, new.Spec) {
		err := field.Invalid(
			field.NewPath("spec"),
			new.Spec,
			"field is immutable",
		).MarkCoveredByDeclarative().WithOrigin("immutable")
		allErrs = append(allErrs, err)
	}

	return allErrs
}

var supportedVolumeBindingModes = sets.NewString(string(storage.VolumeBindingImmediate), string(storage.VolumeBindingWaitForFirstConsumer))

// validateVolumeBindingMode tests that VolumeBindingMode specifies valid values.
func validateVolumeBindingMode(mode *storage.VolumeBindingMode, fldPath *field.Path) field.ErrorList {
	allErrs := field.ErrorList{}
	if mode == nil {
		allErrs = append(allErrs, field.Required(fldPath, ""))
	} else if !supportedVolumeBindingModes.Has(string(*mode)) {
		allErrs = append(allErrs, field.NotSupported(fldPath, mode, supportedVolumeBindingModes.List()))
	}

	return allErrs
}


Review comment (suggestion):
Could be `apimachineryvalidation.ValidateImmutableField()`

Code after:

func validateVolumeError(e *storage.VolumeError, fldPath *field.Path) field.ErrorList {
	allErrs := field.ErrorList{}

	if e == nil {
		return allErrs
	}
	if len(e.Message) > maxVolumeErrorMessageSize {
		allErrs = append(allErrs, field.TooLong(fldPath.Child("message"), "" /*unused*/, maxAttachedVolumeMetadataSize))
	}

	if e.ErrorCode != nil {
		value := *e.ErrorCode
		if value < 0 {
			allErrs = append(allErrs, field.Invalid(fldPath.Child("errorCode"), value, validation.InclusiveRangeError(0, math.MaxInt32)))
		}
	}
	return allErrs
}

// ValidateVolumeAttachmentUpdate validates a VolumeAttachment.
func ValidateVolumeAttachmentUpdate(new, old *storage.VolumeAttachment) field.ErrorList {
	allErrs := ValidateVolumeAttachment(new)
	allErrs = append(allErrs, apimachineryvalidation.ValidateImmutableField(new.Spec, old.Spec, field.NewPath("spec")).WithOrigin("immutable").MarkCoveredByDeclarative()...)
	return allErrs
}

var supportedVolumeBindingModes = sets.NewString(string(storage.VolumeBindingImmediate), string(storage.VolumeBindingWaitForFirstConsumer))

// validateVolumeBindingMode tests that VolumeBindingMode specifies valid values.
func validateVolumeBindingMode(mode *storage.VolumeBindingMode, fldPath *field.Path) field.ErrorList {
	allErrs := field.ErrorList{}
	if mode == nil {
		allErrs = append(allErrs, field.Required(fldPath, ""))
	} else if !supportedVolumeBindingModes.Has(string(*mode)) {
		allErrs = append(allErrs, field.NotSupported(fldPath, mode, supportedVolumeBindingModes.List()))
	}

	return allErrs
}

// validateAllowedTopology tests that AllowedTopologies specifies valid values.
func validateAllowedTopologies(topologies []api.TopologySelectorTerm, fldPath *field.Path) field.ErrorList {
	allErrs := field.ErrorList{}

	if len(topologies) == 0 {
		return allErrs
	}

	rawTopologies := make([]map[string]sets.Set[string], len(topologies))
	for i, term := range topologies {