mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	add validation rule to prevent adding finalizers if the object is being deleted
This commit is contained in:
		@@ -438,6 +438,11 @@ func ValidateObjectMetaUpdate(newMeta, oldMeta *api.ObjectMeta, fldPath *field.P
 | 
				
			|||||||
		allErrs = append(allErrs, field.Invalid(fldPath.Child("deletionTimestamp"), newMeta.DeletionTimestamp, "field is immutable; may only be changed via deletion"))
 | 
							allErrs = append(allErrs, field.Invalid(fldPath.Child("deletionTimestamp"), newMeta.DeletionTimestamp, "field is immutable; may only be changed via deletion"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Finalizers cannot be added if the object is already being deleted.
 | 
				
			||||||
 | 
						if oldMeta.DeletionTimestamp != nil {
 | 
				
			||||||
 | 
							allErrs = append(allErrs, ValidateNoNewFinalizers(newMeta.Finalizers, oldMeta.Finalizers, fldPath.Child("finalizers"))...)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Reject updates that don't specify a resource version
 | 
						// Reject updates that don't specify a resource version
 | 
				
			||||||
	if len(newMeta.ResourceVersion) == 0 {
 | 
						if len(newMeta.ResourceVersion) == 0 {
 | 
				
			||||||
		allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceVersion"), newMeta.ResourceVersion, "must be specified for an update"))
 | 
							allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceVersion"), newMeta.ResourceVersion, "must be specified for an update"))
 | 
				
			||||||
@@ -461,6 +466,16 @@ func ValidateObjectMetaUpdate(newMeta, oldMeta *api.ObjectMeta, fldPath *field.P
 | 
				
			|||||||
	return allErrs
 | 
						return allErrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ValidateNoNewFinalizers(newFinalizers []string, oldFinalizers []string, fldPath *field.Path) field.ErrorList {
 | 
				
			||||||
 | 
						const newFinalizersErrorMsg string = `no new finalizers can be added if the object is being deleted`
 | 
				
			||||||
 | 
						allErrs := field.ErrorList{}
 | 
				
			||||||
 | 
						extra := sets.NewString(newFinalizers...).Difference(sets.NewString(oldFinalizers...))
 | 
				
			||||||
 | 
						if len(extra) != 0 {
 | 
				
			||||||
 | 
							allErrs = append(allErrs, field.Forbidden(fldPath, fmt.Sprintf("no new finalizers can be added if the object is being deleted, found new finalizers %#v", extra.List())))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return allErrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func validateVolumes(volumes []api.Volume, fldPath *field.Path) (sets.String, field.ErrorList) {
 | 
					func validateVolumes(volumes []api.Volume, fldPath *field.Path) (sets.String, field.ErrorList) {
 | 
				
			||||||
	allErrs := field.ErrorList{}
 | 
						allErrs := field.ErrorList{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -248,6 +248,45 @@ func TestValidateObjectMetaUpdateIgnoresCreationTimestamp(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestValidateFinalizersUpdate(t *testing.T) {
 | 
				
			||||||
 | 
						testcases := map[string]struct {
 | 
				
			||||||
 | 
							Old         api.ObjectMeta
 | 
				
			||||||
 | 
							New         api.ObjectMeta
 | 
				
			||||||
 | 
							ExpectedErr string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							"invalid adding finalizers": {
 | 
				
			||||||
 | 
								Old:         api.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &unversioned.Time{}, Finalizers: []string{"x/a"}},
 | 
				
			||||||
 | 
								New:         api.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &unversioned.Time{}, Finalizers: []string{"x/a", "y/b"}},
 | 
				
			||||||
 | 
								ExpectedErr: "y/b",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"invalid changing finalizers": {
 | 
				
			||||||
 | 
								Old:         api.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &unversioned.Time{}, Finalizers: []string{"x/a"}},
 | 
				
			||||||
 | 
								New:         api.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &unversioned.Time{}, Finalizers: []string{"x/b"}},
 | 
				
			||||||
 | 
								ExpectedErr: "x/b",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"valid removing finalizers": {
 | 
				
			||||||
 | 
								Old:         api.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &unversioned.Time{}, Finalizers: []string{"x/a", "y/b"}},
 | 
				
			||||||
 | 
								New:         api.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &unversioned.Time{}, Finalizers: []string{"x/a"}},
 | 
				
			||||||
 | 
								ExpectedErr: "",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"valid adding finalizers for objects not being deleted": {
 | 
				
			||||||
 | 
								Old:         api.ObjectMeta{Name: "test", ResourceVersion: "1", Finalizers: []string{"x/a"}},
 | 
				
			||||||
 | 
								New:         api.ObjectMeta{Name: "test", ResourceVersion: "1", Finalizers: []string{"x/a", "y/b"}},
 | 
				
			||||||
 | 
								ExpectedErr: "",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for name, tc := range testcases {
 | 
				
			||||||
 | 
							errs := ValidateObjectMetaUpdate(&tc.New, &tc.Old, field.NewPath("field"))
 | 
				
			||||||
 | 
							if len(errs) == 0 {
 | 
				
			||||||
 | 
								if len(tc.ExpectedErr) != 0 {
 | 
				
			||||||
 | 
									t.Errorf("case: %q, expected error to contain %q", name, tc.ExpectedErr)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else if e, a := tc.ExpectedErr, errs.ToAggregate().Error(); !strings.Contains(a, e) {
 | 
				
			||||||
 | 
								t.Errorf("case: %q, expected error to contain %q, got error %q", name, e, a)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestValidateObjectMetaUpdatePreventsDeletionFieldMutation(t *testing.T) {
 | 
					func TestValidateObjectMetaUpdatePreventsDeletionFieldMutation(t *testing.T) {
 | 
				
			||||||
	now := unversioned.NewTime(time.Unix(1000, 0).UTC())
 | 
						now := unversioned.NewTime(time.Unix(1000, 0).UTC())
 | 
				
			||||||
	later := unversioned.NewTime(time.Unix(2000, 0).UTC())
 | 
						later := unversioned.NewTime(time.Unix(2000, 0).UTC())
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user