mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 05:27:21 +00:00
Add validation options for PersistentVolumeClaims
These options provide an extensible way of configuring how PVCs are validated
This commit is contained in:
parent
9ba0eed7c5
commit
dba8ee229e
@ -1608,16 +1608,17 @@ func validateEphemeralVolumeSource(ephemeral *core.EphemeralVolumeSource, fldPat
|
|||||||
if ephemeral.VolumeClaimTemplate == nil {
|
if ephemeral.VolumeClaimTemplate == nil {
|
||||||
allErrs = append(allErrs, field.Required(fldPath.Child("volumeClaimTemplate"), ""))
|
allErrs = append(allErrs, field.Required(fldPath.Child("volumeClaimTemplate"), ""))
|
||||||
} else {
|
} else {
|
||||||
allErrs = append(allErrs, ValidatePersistentVolumeClaimTemplate(ephemeral.VolumeClaimTemplate, fldPath.Child("volumeClaimTemplate"))...)
|
opts := ValidationOptionsForPersistentVolumeClaimTemplate(ephemeral.VolumeClaimTemplate, nil)
|
||||||
|
allErrs = append(allErrs, ValidatePersistentVolumeClaimTemplate(ephemeral.VolumeClaimTemplate, fldPath.Child("volumeClaimTemplate"), opts)...)
|
||||||
}
|
}
|
||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidatePersistentVolumeClaimTemplate verifies that the embedded object meta and spec are valid.
|
// ValidatePersistentVolumeClaimTemplate verifies that the embedded object meta and spec are valid.
|
||||||
// Checking of the object data is very minimal because only labels and annotations are used.
|
// Checking of the object data is very minimal because only labels and annotations are used.
|
||||||
func ValidatePersistentVolumeClaimTemplate(claimTemplate *core.PersistentVolumeClaimTemplate, fldPath *field.Path) field.ErrorList {
|
func ValidatePersistentVolumeClaimTemplate(claimTemplate *core.PersistentVolumeClaimTemplate, fldPath *field.Path, opts PersistentVolumeClaimSpecValidationOptions) field.ErrorList {
|
||||||
allErrs := validatePersistentVolumeClaimTemplateObjectMeta(&claimTemplate.ObjectMeta, fldPath.Child("metadata"))
|
allErrs := validatePersistentVolumeClaimTemplateObjectMeta(&claimTemplate.ObjectMeta, fldPath.Child("metadata"))
|
||||||
allErrs = append(allErrs, ValidatePersistentVolumeClaimSpec(&claimTemplate.Spec, fldPath.Child("spec"))...)
|
allErrs = append(allErrs, ValidatePersistentVolumeClaimSpec(&claimTemplate.Spec, fldPath.Child("spec"), opts)...)
|
||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1973,15 +1974,27 @@ func ValidatePersistentVolumeStatusUpdate(newPv, oldPv *core.PersistentVolume) f
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PersistentVolumeClaimSpecValidationOptions contains the different settings for PersistentVolumeClaim validation
|
||||||
|
type PersistentVolumeClaimSpecValidationOptions struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidationOptionsForPersistentVolumeClaim(pvc, oldPvc *core.PersistentVolumeClaim) PersistentVolumeClaimSpecValidationOptions {
|
||||||
|
return PersistentVolumeClaimSpecValidationOptions{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidationOptionsForPersistentVolumeClaimTemplate(claimTemplate, oldClaimTemplate *core.PersistentVolumeClaimTemplate) PersistentVolumeClaimSpecValidationOptions {
|
||||||
|
return PersistentVolumeClaimSpecValidationOptions{}
|
||||||
|
}
|
||||||
|
|
||||||
// ValidatePersistentVolumeClaim validates a PersistentVolumeClaim
|
// ValidatePersistentVolumeClaim validates a PersistentVolumeClaim
|
||||||
func ValidatePersistentVolumeClaim(pvc *core.PersistentVolumeClaim) field.ErrorList {
|
func ValidatePersistentVolumeClaim(pvc *core.PersistentVolumeClaim, opts PersistentVolumeClaimSpecValidationOptions) field.ErrorList {
|
||||||
allErrs := ValidateObjectMeta(&pvc.ObjectMeta, true, ValidatePersistentVolumeName, field.NewPath("metadata"))
|
allErrs := ValidateObjectMeta(&pvc.ObjectMeta, true, ValidatePersistentVolumeName, field.NewPath("metadata"))
|
||||||
allErrs = append(allErrs, ValidatePersistentVolumeClaimSpec(&pvc.Spec, field.NewPath("spec"))...)
|
allErrs = append(allErrs, ValidatePersistentVolumeClaimSpec(&pvc.Spec, field.NewPath("spec"), opts)...)
|
||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidatePersistentVolumeClaimSpec validates a PersistentVolumeClaimSpec
|
// ValidatePersistentVolumeClaimSpec validates a PersistentVolumeClaimSpec
|
||||||
func ValidatePersistentVolumeClaimSpec(spec *core.PersistentVolumeClaimSpec, fldPath *field.Path) field.ErrorList {
|
func ValidatePersistentVolumeClaimSpec(spec *core.PersistentVolumeClaimSpec, fldPath *field.Path, opts PersistentVolumeClaimSpecValidationOptions) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
if len(spec.AccessModes) == 0 {
|
if len(spec.AccessModes) == 0 {
|
||||||
allErrs = append(allErrs, field.Required(fldPath.Child("accessModes"), "at least 1 access mode is required"))
|
allErrs = append(allErrs, field.Required(fldPath.Child("accessModes"), "at least 1 access mode is required"))
|
||||||
@ -2032,9 +2045,9 @@ func ValidatePersistentVolumeClaimSpec(spec *core.PersistentVolumeClaimSpec, fld
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ValidatePersistentVolumeClaimUpdate validates an update to a PersistentVolumeClaim
|
// ValidatePersistentVolumeClaimUpdate validates an update to a PersistentVolumeClaim
|
||||||
func ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc *core.PersistentVolumeClaim) field.ErrorList {
|
func ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc *core.PersistentVolumeClaim, opts PersistentVolumeClaimSpecValidationOptions) field.ErrorList {
|
||||||
allErrs := ValidateObjectMetaUpdate(&newPvc.ObjectMeta, &oldPvc.ObjectMeta, field.NewPath("metadata"))
|
allErrs := ValidateObjectMetaUpdate(&newPvc.ObjectMeta, &oldPvc.ObjectMeta, field.NewPath("metadata"))
|
||||||
allErrs = append(allErrs, ValidatePersistentVolumeClaim(newPvc)...)
|
allErrs = append(allErrs, ValidatePersistentVolumeClaim(newPvc, opts)...)
|
||||||
newPvcClone := newPvc.DeepCopy()
|
newPvcClone := newPvc.DeepCopy()
|
||||||
oldPvcClone := oldPvc.DeepCopy()
|
oldPvcClone := oldPvc.DeepCopy()
|
||||||
|
|
||||||
|
@ -922,12 +922,14 @@ func TestAlphaVolumeSnapshotDataSource(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range successTestCases {
|
for _, tc := range successTestCases {
|
||||||
if errs := ValidatePersistentVolumeClaimSpec(&tc, field.NewPath("spec")); len(errs) != 0 {
|
opts := PersistentVolumeClaimSpecValidationOptions{}
|
||||||
|
if errs := ValidatePersistentVolumeClaimSpec(&tc, field.NewPath("spec"), opts); len(errs) != 0 {
|
||||||
t.Errorf("expected success: %v", errs)
|
t.Errorf("expected success: %v", errs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, tc := range failedTestCases {
|
for _, tc := range failedTestCases {
|
||||||
if errs := ValidatePersistentVolumeClaimSpec(&tc, field.NewPath("spec")); len(errs) == 0 {
|
opts := PersistentVolumeClaimSpecValidationOptions{}
|
||||||
|
if errs := ValidatePersistentVolumeClaimSpec(&tc, field.NewPath("spec"), opts); len(errs) == 0 {
|
||||||
t.Errorf("expected failure: %v", errs)
|
t.Errorf("expected failure: %v", errs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1323,7 +1325,8 @@ func testValidatePVC(t *testing.T, ephemeral bool) {
|
|||||||
opts := PodValidationOptions{}
|
opts := PodValidationOptions{}
|
||||||
_, errs = ValidateVolumes(volumes, nil, field.NewPath(""), opts)
|
_, errs = ValidateVolumes(volumes, nil, field.NewPath(""), opts)
|
||||||
} else {
|
} else {
|
||||||
errs = ValidatePersistentVolumeClaim(scenario.claim)
|
opts := ValidationOptionsForPersistentVolumeClaim(scenario.claim, nil)
|
||||||
|
errs = ValidatePersistentVolumeClaim(scenario.claim, opts)
|
||||||
}
|
}
|
||||||
if len(errs) == 0 && scenario.isExpectedFailure {
|
if len(errs) == 0 && scenario.isExpectedFailure {
|
||||||
t.Error("Unexpected success for scenario")
|
t.Error("Unexpected success for scenario")
|
||||||
@ -1826,7 +1829,8 @@ func TestValidatePersistentVolumeClaimUpdate(t *testing.T) {
|
|||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandPersistentVolumes, scenario.enableResize)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandPersistentVolumes, scenario.enableResize)()
|
||||||
scenario.oldClaim.ResourceVersion = "1"
|
scenario.oldClaim.ResourceVersion = "1"
|
||||||
scenario.newClaim.ResourceVersion = "1"
|
scenario.newClaim.ResourceVersion = "1"
|
||||||
errs := ValidatePersistentVolumeClaimUpdate(scenario.newClaim, scenario.oldClaim)
|
opts := ValidationOptionsForPersistentVolumeClaim(scenario.newClaim, scenario.oldClaim)
|
||||||
|
errs := ValidatePersistentVolumeClaimUpdate(scenario.newClaim, scenario.oldClaim, opts)
|
||||||
if len(errs) == 0 && scenario.isExpectedFailure {
|
if len(errs) == 0 && scenario.isExpectedFailure {
|
||||||
t.Errorf("Unexpected success for scenario: %s", name)
|
t.Errorf("Unexpected success for scenario: %s", name)
|
||||||
}
|
}
|
||||||
@ -1837,6 +1841,22 @@ func TestValidatePersistentVolumeClaimUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidationOptionsForPersistentVolumeClaim(t *testing.T) {
|
||||||
|
expectedValidationOpts := PersistentVolumeClaimSpecValidationOptions{}
|
||||||
|
opts := ValidationOptionsForPersistentVolumeClaim(nil, nil)
|
||||||
|
if opts != expectedValidationOpts {
|
||||||
|
t.Errorf("Expected opts: %+v, received: %+v", opts, expectedValidationOpts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidationOptionsForPersistentVolumeClaimTemplate(t *testing.T) {
|
||||||
|
expectedValidationOpts := PersistentVolumeClaimSpecValidationOptions{}
|
||||||
|
opts := ValidationOptionsForPersistentVolumeClaimTemplate(nil, nil)
|
||||||
|
if opts != expectedValidationOpts {
|
||||||
|
t.Errorf("Expected opts: %+v, received: %+v", opts, expectedValidationOpts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestValidateKeyToPath(t *testing.T) {
|
func TestValidateKeyToPath(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
kp core.KeyToPath
|
kp core.KeyToPath
|
||||||
@ -4321,7 +4341,8 @@ func TestPVCVolumeMode(t *testing.T) {
|
|||||||
"valid nil value": createTestVolModePVC(nil),
|
"valid nil value": createTestVolModePVC(nil),
|
||||||
}
|
}
|
||||||
for k, v := range successCasesPVC {
|
for k, v := range successCasesPVC {
|
||||||
if errs := ValidatePersistentVolumeClaim(v); len(errs) != 0 {
|
opts := ValidationOptionsForPersistentVolumeClaim(v, nil)
|
||||||
|
if errs := ValidatePersistentVolumeClaim(v, opts); len(errs) != 0 {
|
||||||
t.Errorf("expected success for %s", k)
|
t.Errorf("expected success for %s", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4332,7 +4353,8 @@ func TestPVCVolumeMode(t *testing.T) {
|
|||||||
"empty value": createTestVolModePVC(&empty),
|
"empty value": createTestVolModePVC(&empty),
|
||||||
}
|
}
|
||||||
for k, v := range errorCasesPVC {
|
for k, v := range errorCasesPVC {
|
||||||
if errs := ValidatePersistentVolumeClaim(v); len(errs) == 0 {
|
opts := ValidationOptionsForPersistentVolumeClaim(v, nil)
|
||||||
|
if errs := ValidatePersistentVolumeClaim(v, opts); len(errs) == 0 {
|
||||||
t.Errorf("expected failure for %s", k)
|
t.Errorf("expected failure for %s", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -16585,12 +16607,14 @@ func TestAlphaVolumePVCDataSource(t *testing.T) {
|
|||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
if tc.expectedFail {
|
if tc.expectedFail {
|
||||||
if errs := ValidatePersistentVolumeClaimSpec(&tc.claimSpec, field.NewPath("spec")); len(errs) == 0 {
|
opts := PersistentVolumeClaimSpecValidationOptions{}
|
||||||
|
if errs := ValidatePersistentVolumeClaimSpec(&tc.claimSpec, field.NewPath("spec"), opts); len(errs) == 0 {
|
||||||
t.Errorf("expected failure: %v", errs)
|
t.Errorf("expected failure: %v", errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if errs := ValidatePersistentVolumeClaimSpec(&tc.claimSpec, field.NewPath("spec")); len(errs) != 0 {
|
opts := PersistentVolumeClaimSpecValidationOptions{}
|
||||||
|
if errs := ValidatePersistentVolumeClaimSpec(&tc.claimSpec, field.NewPath("spec"), opts); len(errs) != 0 {
|
||||||
t.Errorf("expected success: %v", errs)
|
t.Errorf("expected success: %v", errs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,8 @@ func (persistentvolumeclaimStrategy) PrepareForCreate(ctx context.Context, obj r
|
|||||||
|
|
||||||
func (persistentvolumeclaimStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
func (persistentvolumeclaimStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
||||||
pvc := obj.(*api.PersistentVolumeClaim)
|
pvc := obj.(*api.PersistentVolumeClaim)
|
||||||
return validation.ValidatePersistentVolumeClaim(pvc)
|
opts := validation.ValidationOptionsForPersistentVolumeClaim(pvc, nil)
|
||||||
|
return validation.ValidatePersistentVolumeClaim(pvc, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WarningsOnCreate returns warnings for the creation of the given object.
|
// WarningsOnCreate returns warnings for the creation of the given object.
|
||||||
@ -98,8 +99,11 @@ func (persistentvolumeclaimStrategy) PrepareForUpdate(ctx context.Context, obj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (persistentvolumeclaimStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
func (persistentvolumeclaimStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
||||||
errorList := validation.ValidatePersistentVolumeClaim(obj.(*api.PersistentVolumeClaim))
|
newPvc := obj.(*api.PersistentVolumeClaim)
|
||||||
return append(errorList, validation.ValidatePersistentVolumeClaimUpdate(obj.(*api.PersistentVolumeClaim), old.(*api.PersistentVolumeClaim))...)
|
oldPvc := old.(*api.PersistentVolumeClaim)
|
||||||
|
opts := validation.ValidationOptionsForPersistentVolumeClaim(newPvc, oldPvc)
|
||||||
|
errorList := validation.ValidatePersistentVolumeClaim(newPvc, opts)
|
||||||
|
return append(errorList, validation.ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc, opts)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WarningsOnUpdate returns warnings for the given update.
|
// WarningsOnUpdate returns warnings for the given update.
|
||||||
|
Loading…
Reference in New Issue
Block a user