@@ -33,6 +33,7 @@ import (
3333 "k8s.io/apimachinery/pkg/runtime"
3434 "k8s.io/apimachinery/pkg/runtime/schema"
3535 "k8s.io/apimachinery/pkg/util/validation/field"
36+ genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
3637 "k8s.io/apiserver/pkg/features"
3738 apiserverstorage "k8s.io/apiserver/pkg/storage"
3839 "k8s.io/apiserver/pkg/storage/names"
@@ -114,6 +115,15 @@ func (a customResourceStrategy) PrepareForCreate(ctx context.Context, obj runtim
114115 }
115116
116117 accessor , _ := meta .Accessor (obj )
118+ if _ , found := accessor .GetAnnotations ()[genericapirequest .AnnotationKey ]; found {
119+ // in general the shard annotation is not attached to objects, instead, it is assigned by the storage layer on the fly
120+ // to avoid an additional UPDATE request (mismatch on the generation field) replicated objects have the shard annotation set
121+ // thus we need to remove the shard annotation and simply return early so that the generation is not reset to 1
122+ annotations := accessor .GetAnnotations ()
123+ delete (annotations , genericapirequest .AnnotationKey )
124+ accessor .SetAnnotations (annotations )
125+ return
126+ }
117127 accessor .SetGeneration (1 )
118128}
119129
@@ -144,6 +154,11 @@ func (a customResourceStrategy) PrepareForUpdate(ctx context.Context, obj, old r
144154 if ! apiequality .Semantic .DeepEqual (newCopyContent , oldCopyContent ) {
145155 oldAccessor , _ := meta .Accessor (oldCustomResourceObject )
146156 newAccessor , _ := meta .Accessor (newCustomResourceObject )
157+ if _ , found := oldAccessor .GetAnnotations ()[genericapirequest .AnnotationKey ]; found {
158+ // the presence of the annotation indicates the object is from the cache server.
159+ // since the objects from the cache should not be modified in any way, just return early.
160+ return
161+ }
147162 newAccessor .SetGeneration (oldAccessor .GetGeneration () + 1 )
148163 }
149164}
0 commit comments