Merge pull request #74040 from ajatprabha/issue_73648
add ResourceVersion to DeleteOptions.Preconditions Kubernetes-commit: cc8afb25fcfbb2a12ef43300db89d724b284e3e3
This commit is contained in:
commit
91bbfdf08d
File diff suppressed because it is too large
Load Diff
|
|
@ -448,6 +448,7 @@ func (e *Store) Update(ctx context.Context, name string, objInfo rest.UpdatedObj
|
||||||
storagePreconditions := &storage.Preconditions{}
|
storagePreconditions := &storage.Preconditions{}
|
||||||
if preconditions := objInfo.Preconditions(); preconditions != nil {
|
if preconditions := objInfo.Preconditions(); preconditions != nil {
|
||||||
storagePreconditions.UID = preconditions.UID
|
storagePreconditions.UID = preconditions.UID
|
||||||
|
storagePreconditions.ResourceVersion = preconditions.ResourceVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
out := e.NewFunc()
|
out := e.NewFunc()
|
||||||
|
|
@ -879,6 +880,7 @@ func (e *Store) Delete(ctx context.Context, name string, options *metav1.DeleteO
|
||||||
var preconditions storage.Preconditions
|
var preconditions storage.Preconditions
|
||||||
if options.Preconditions != nil {
|
if options.Preconditions != nil {
|
||||||
preconditions.UID = options.Preconditions.UID
|
preconditions.UID = options.Preconditions.UID
|
||||||
|
preconditions.ResourceVersion = options.Preconditions.ResourceVersion
|
||||||
}
|
}
|
||||||
graceful, pendingGraceful, err := rest.BeforeDelete(e.DeleteStrategy, ctx, obj, options)
|
graceful, pendingGraceful, err := rest.BeforeDelete(e.DeleteStrategy, ctx, obj, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -77,9 +77,14 @@ func BeforeDelete(strategy RESTDeleteStrategy, ctx context.Context, obj runtime.
|
||||||
return false, false, errors.NewInvalid(schema.GroupKind{Group: metav1.GroupName, Kind: "DeleteOptions"}, "", errs)
|
return false, false, errors.NewInvalid(schema.GroupKind{Group: metav1.GroupName, Kind: "DeleteOptions"}, "", errs)
|
||||||
}
|
}
|
||||||
// Checking the Preconditions here to fail early. They'll be enforced later on when we actually do the deletion, too.
|
// Checking the Preconditions here to fail early. They'll be enforced later on when we actually do the deletion, too.
|
||||||
if options.Preconditions != nil && options.Preconditions.UID != nil && *options.Preconditions.UID != objectMeta.GetUID() {
|
if options.Preconditions != nil {
|
||||||
|
if options.Preconditions.UID != nil && *options.Preconditions.UID != objectMeta.GetUID() {
|
||||||
return false, false, errors.NewConflict(schema.GroupResource{Group: gvk.Group, Resource: gvk.Kind}, objectMeta.GetName(), fmt.Errorf("the UID in the precondition (%s) does not match the UID in record (%s). The object might have been deleted and then recreated", *options.Preconditions.UID, objectMeta.GetUID()))
|
return false, false, errors.NewConflict(schema.GroupResource{Group: gvk.Group, Resource: gvk.Kind}, objectMeta.GetName(), fmt.Errorf("the UID in the precondition (%s) does not match the UID in record (%s). The object might have been deleted and then recreated", *options.Preconditions.UID, objectMeta.GetUID()))
|
||||||
}
|
}
|
||||||
|
if options.Preconditions.ResourceVersion != nil && *options.Preconditions.ResourceVersion != objectMeta.GetResourceVersion() {
|
||||||
|
return false, false, errors.NewConflict(schema.GroupResource{Group: gvk.Group, Resource: gvk.Kind}, objectMeta.GetName(), fmt.Errorf("the ResourceVersion in the precondition (%s) does not match the ResourceVersion in record (%s). The object might have been modified", *options.Preconditions.ResourceVersion, objectMeta.GetResourceVersion()))
|
||||||
|
}
|
||||||
|
}
|
||||||
gracefulStrategy, ok := strategy.(RESTGracefulDeleteStrategy)
|
gracefulStrategy, ok := strategy.(RESTGracefulDeleteStrategy)
|
||||||
if !ok {
|
if !ok {
|
||||||
// If we're not deleting gracefully there's no point in updating Generation, as we won't update
|
// If we're not deleting gracefully there's no point in updating Generation, as we won't update
|
||||||
|
|
|
||||||
|
|
@ -909,6 +909,45 @@ func (t *Tester) testDeleteWithUID(obj runtime.Object, createFn CreateFunc, getF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test the fast-fail path. We test that the precondition gets verified
|
||||||
|
// again before deleting the object in tests of pkg/storage/etcd.
|
||||||
|
func (t *Tester) testDeleteWithResourceVersion(obj runtime.Object, createFn CreateFunc, getFn GetFunc, isNotFoundFn IsErrorFunc, opts metav1.DeleteOptions) {
|
||||||
|
ctx := t.TestContext()
|
||||||
|
|
||||||
|
foo := obj.DeepCopyObject()
|
||||||
|
t.setObjectMeta(foo, t.namer(1))
|
||||||
|
objectMeta := t.getObjectMetaOrFail(foo)
|
||||||
|
objectMeta.SetResourceVersion("RV0000")
|
||||||
|
if err := createFn(ctx, foo); err != nil {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
opts.Preconditions = metav1.NewRVDeletionPrecondition("RV1111").Preconditions
|
||||||
|
obj, wasDeleted, err := t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.GetName(), &opts)
|
||||||
|
if err == nil || !errors.IsConflict(err) {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if wasDeleted {
|
||||||
|
t.Errorf("unexpected, object %s should not have been deleted immediately", objectMeta.GetName())
|
||||||
|
}
|
||||||
|
obj, _, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.GetName(), metav1.NewRVDeletionPrecondition("RV0000"))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !t.returnDeletedObject {
|
||||||
|
if status, ok := obj.(*metav1.Status); !ok {
|
||||||
|
t.Errorf("expected status of delete, got %v", status)
|
||||||
|
} else if status.Status != metav1.StatusSuccess {
|
||||||
|
t.Errorf("expected success, got: %v", status.Status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = getFn(ctx, foo)
|
||||||
|
if err == nil || !isNotFoundFn(err) {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Graceful Deletion tests.
|
// Graceful Deletion tests.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,9 @@ type Preconditions struct {
|
||||||
// Specifies the target UID.
|
// Specifies the target UID.
|
||||||
// +optional
|
// +optional
|
||||||
UID *types.UID `json:"uid,omitempty"`
|
UID *types.UID `json:"uid,omitempty"`
|
||||||
|
// Specifies the target ResourceVersion
|
||||||
|
// +optional
|
||||||
|
ResourceVersion *string `json:"resourceVersion,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewUIDPreconditions returns a Preconditions with UID set.
|
// NewUIDPreconditions returns a Preconditions with UID set.
|
||||||
|
|
@ -125,8 +128,14 @@ func (p *Preconditions) Check(key string, obj runtime.Object) error {
|
||||||
objMeta.GetUID())
|
objMeta.GetUID())
|
||||||
return NewInvalidObjError(key, err)
|
return NewInvalidObjError(key, err)
|
||||||
}
|
}
|
||||||
|
if p.ResourceVersion != nil && *p.ResourceVersion != objMeta.GetResourceVersion() {
|
||||||
|
err := fmt.Sprintf(
|
||||||
|
"Precondition failed: ResourceVersion in precondition: %v, ResourceVersion in object meta: %v",
|
||||||
|
*p.ResourceVersion,
|
||||||
|
objMeta.GetResourceVersion())
|
||||||
|
return NewInvalidObjError(key, err)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface offers a common interface for object marshaling/unmarshaling operations and
|
// Interface offers a common interface for object marshaling/unmarshaling operations and
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue