diff --git a/pkg/api/testing/serialization_test.go b/pkg/api/testing/serialization_test.go index 8c24ca09da..d91980aba6 100644 --- a/pkg/api/testing/serialization_test.go +++ b/pkg/api/testing/serialization_test.go @@ -156,11 +156,13 @@ var nonRoundTrippableTypes = sets.NewString( "WatchEvent", // ListOptions is now part of the meta group "ListOptions", - // Delete options is only read in metav1 + // DeleteOptions, CreateOptions and UpdateOptions are only read in metav1 "DeleteOptions", + "CreateOptions", + "UpdateOptions", ) -var commonKinds = []string{"Status", "ListOptions", "DeleteOptions", "ExportOptions"} +var commonKinds = []string{"Status", "ListOptions", "DeleteOptions", "ExportOptions", "GetOptions", "CreateOptions", "UpdateOptions"} // TestCommonKindsRegistered verifies that all group/versions registered with // the testapi package have the common kinds. diff --git a/pkg/master/reconcilers/lease.go b/pkg/master/reconcilers/lease.go index 934ece2900..179f129c5e 100644 --- a/pkg/master/reconcilers/lease.go +++ b/pkg/master/reconcilers/lease.go @@ -221,7 +221,7 @@ func (r *leaseEndpointReconciler) doReconcile(serviceName string, endpointPorts } glog.Warningf("Resetting endpoints for master service %q to %v", serviceName, masterIPs) - return r.endpointRegistry.UpdateEndpoints(ctx, e, rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc) + return r.endpointRegistry.UpdateEndpoints(ctx, e, rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, &metav1.UpdateOptions{}) } // checkEndpointSubsetFormatWithLease determines if the endpoint is in the diff --git a/pkg/registry/apps/daemonset/storage/storage.go b/pkg/registry/apps/daemonset/storage/storage.go index 2b02d9f80e..a896649147 100644 --- a/pkg/registry/apps/daemonset/storage/storage.go +++ b/pkg/registry/apps/daemonset/storage/storage.go @@ -96,8 +96,8 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/pkg/registry/apps/deployment/registry.go b/pkg/registry/apps/deployment/registry.go index 64c0b4380c..6cce8f53e0 100644 --- a/pkg/registry/apps/deployment/registry.go +++ b/pkg/registry/apps/deployment/registry.go @@ -30,8 +30,8 @@ import ( type Registry interface { ListDeployments(ctx context.Context, options *metainternalversion.ListOptions) (*extensions.DeploymentList, error) GetDeployment(ctx context.Context, deploymentID string, options *metav1.GetOptions) (*extensions.Deployment, error) - CreateDeployment(ctx context.Context, deployment *extensions.Deployment, createValidation rest.ValidateObjectFunc) (*extensions.Deployment, error) - UpdateDeployment(ctx context.Context, deployment *extensions.Deployment, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*extensions.Deployment, error) + CreateDeployment(ctx context.Context, deployment *extensions.Deployment, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (*extensions.Deployment, error) + UpdateDeployment(ctx context.Context, deployment *extensions.Deployment, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) (*extensions.Deployment, error) DeleteDeployment(ctx context.Context, deploymentID string) error } @@ -64,16 +64,16 @@ func (s *storage) GetDeployment(ctx context.Context, deploymentID string, option return obj.(*extensions.Deployment), nil } -func (s *storage) CreateDeployment(ctx context.Context, deployment *extensions.Deployment, createValidation rest.ValidateObjectFunc) (*extensions.Deployment, error) { - obj, err := s.Create(ctx, deployment, createValidation, false) +func (s *storage) CreateDeployment(ctx context.Context, deployment *extensions.Deployment, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (*extensions.Deployment, error) { + obj, err := s.Create(ctx, deployment, createValidation, options) if err != nil { return nil, err } return obj.(*extensions.Deployment), nil } -func (s *storage) UpdateDeployment(ctx context.Context, deployment *extensions.Deployment, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*extensions.Deployment, error) { - obj, _, err := s.Update(ctx, deployment.Name, rest.DefaultUpdatedObjectInfo(deployment), createValidation, updateValidation, false) +func (s *storage) UpdateDeployment(ctx context.Context, deployment *extensions.Deployment, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) (*extensions.Deployment, error) { + obj, _, err := s.Update(ctx, deployment.Name, rest.DefaultUpdatedObjectInfo(deployment), createValidation, updateValidation, false, options) if err != nil { return nil, err } diff --git a/pkg/registry/apps/deployment/storage/storage.go b/pkg/registry/apps/deployment/storage/storage.go index 141ff75801..2bedd8a11e 100644 --- a/pkg/registry/apps/deployment/storage/storage.go +++ b/pkg/registry/apps/deployment/storage/storage.go @@ -129,10 +129,10 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } // RollbackREST implements the REST endpoint for initiating the rollback of a deployment @@ -161,7 +161,7 @@ func (r *RollbackREST) New() runtime.Object { var _ = rest.Creater(&RollbackREST{}) -func (r *RollbackREST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (r *RollbackREST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { rollback, ok := obj.(*extensions.DeploymentRollback) if !ok { return nil, errors.NewBadRequest(fmt.Sprintf("not a DeploymentRollback: %#v", obj)) @@ -257,7 +257,7 @@ func (r *ScaleREST) Get(ctx context.Context, name string, options *metav1.GetOpt return scale, nil } -func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { deployment, err := r.registry.GetDeployment(ctx, name, &metav1.GetOptions{}) if err != nil { return nil, false, errors.NewNotFound(extensions.Resource("deployments/scale"), name) @@ -286,7 +286,7 @@ func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.Update deployment.Spec.Replicas = scale.Spec.Replicas deployment.ResourceVersion = scale.ResourceVersion - deployment, err = r.registry.UpdateDeployment(ctx, deployment, createValidation, updateValidation) + deployment, err = r.registry.UpdateDeployment(ctx, deployment, createValidation, updateValidation, options) if err != nil { return nil, false, err } diff --git a/pkg/registry/apps/deployment/storage/storage_test.go b/pkg/registry/apps/deployment/storage/storage_test.go index 72c96f49db..483e470683 100644 --- a/pkg/registry/apps/deployment/storage/storage_test.go +++ b/pkg/registry/apps/deployment/storage/storage_test.go @@ -257,7 +257,7 @@ func TestScaleUpdate(t *testing.T) { }, } - if _, _, err := storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("error updating scale %v: %v", update, err) } obj, err := storage.Scale.Get(ctx, name, &metav1.GetOptions{}) @@ -272,7 +272,7 @@ func TestScaleUpdate(t *testing.T) { update.ResourceVersion = deployment.ResourceVersion update.Spec.Replicas = 15 - if _, _, err = storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil && !errors.IsConflict(err) { + if _, _, err = storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil && !errors.IsConflict(err) { t.Fatalf("unexpected error, expecting an update conflict but got %v", err) } } @@ -296,7 +296,7 @@ func TestStatusUpdate(t *testing.T) { }, } - if _, _, err := storage.Status.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Status.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("unexpected error: %v", err) } obj, err := storage.Deployment.Get(ctx, name, &metav1.GetOptions{}) @@ -347,10 +347,10 @@ func TestEtcdCreateDeploymentRollback(t *testing.T) { storage, server := newStorage(t) rollbackStorage := storage.Rollback - if _, err := storage.Deployment.Create(ctx, validNewDeployment(), rest.ValidateAllObjectFunc, false); err != nil { + if _, err := storage.Deployment.Create(ctx, validNewDeployment(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil { t.Fatalf("%s: unexpected error: %v", k, err) } - rollbackRespStatus, err := rollbackStorage.Create(ctx, &test.rollback, rest.ValidateAllObjectFunc, false) + rollbackRespStatus, err := rollbackStorage.Create(ctx, &test.rollback, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if !test.errOK(err) { t.Errorf("%s: unexpected error: %v", k, err) } else if err == nil { @@ -387,7 +387,7 @@ func TestEtcdCreateDeploymentRollbackNoDeployment(t *testing.T) { Name: name, UpdatedAnnotations: map[string]string{}, RollbackTo: extensions.RollbackConfig{Revision: 1}, - }, rest.ValidateAllObjectFunc, false) + }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err == nil { t.Fatalf("Expected not-found-error but got nothing") } diff --git a/pkg/registry/apps/replicaset/registry.go b/pkg/registry/apps/replicaset/registry.go index fd0f696fda..65b50a8a8e 100644 --- a/pkg/registry/apps/replicaset/registry.go +++ b/pkg/registry/apps/replicaset/registry.go @@ -34,8 +34,8 @@ type Registry interface { ListReplicaSets(ctx context.Context, options *metainternalversion.ListOptions) (*extensions.ReplicaSetList, error) WatchReplicaSets(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) GetReplicaSet(ctx context.Context, replicaSetID string, options *metav1.GetOptions) (*extensions.ReplicaSet, error) - CreateReplicaSet(ctx context.Context, replicaSet *extensions.ReplicaSet, createValidation rest.ValidateObjectFunc) (*extensions.ReplicaSet, error) - UpdateReplicaSet(ctx context.Context, replicaSet *extensions.ReplicaSet, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*extensions.ReplicaSet, error) + CreateReplicaSet(ctx context.Context, replicaSet *extensions.ReplicaSet, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (*extensions.ReplicaSet, error) + UpdateReplicaSet(ctx context.Context, replicaSet *extensions.ReplicaSet, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) (*extensions.ReplicaSet, error) DeleteReplicaSet(ctx context.Context, replicaSetID string) error } @@ -73,16 +73,16 @@ func (s *storage) GetReplicaSet(ctx context.Context, replicaSetID string, option return obj.(*extensions.ReplicaSet), nil } -func (s *storage) CreateReplicaSet(ctx context.Context, replicaSet *extensions.ReplicaSet, createValidation rest.ValidateObjectFunc) (*extensions.ReplicaSet, error) { - obj, err := s.Create(ctx, replicaSet, createValidation, false) +func (s *storage) CreateReplicaSet(ctx context.Context, replicaSet *extensions.ReplicaSet, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (*extensions.ReplicaSet, error) { + obj, err := s.Create(ctx, replicaSet, createValidation, options) if err != nil { return nil, err } return obj.(*extensions.ReplicaSet), nil } -func (s *storage) UpdateReplicaSet(ctx context.Context, replicaSet *extensions.ReplicaSet, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*extensions.ReplicaSet, error) { - obj, _, err := s.Update(ctx, replicaSet.Name, rest.DefaultUpdatedObjectInfo(replicaSet), createValidation, updateValidation, false) +func (s *storage) UpdateReplicaSet(ctx context.Context, replicaSet *extensions.ReplicaSet, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) (*extensions.ReplicaSet, error) { + obj, _, err := s.Update(ctx, replicaSet.Name, rest.DefaultUpdatedObjectInfo(replicaSet), createValidation, updateValidation, false, options) if err != nil { return nil, err } diff --git a/pkg/registry/apps/replicaset/storage/storage.go b/pkg/registry/apps/replicaset/storage/storage.go index 4b4a755c2a..2ffa3f2b79 100644 --- a/pkg/registry/apps/replicaset/storage/storage.go +++ b/pkg/registry/apps/replicaset/storage/storage.go @@ -126,10 +126,10 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } type ScaleREST struct { @@ -170,7 +170,7 @@ func (r *ScaleREST) Get(ctx context.Context, name string, options *metav1.GetOpt return scale, err } -func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { rs, err := r.registry.GetReplicaSet(ctx, name, &metav1.GetOptions{}) if err != nil { return nil, false, errors.NewNotFound(extensions.Resource("replicasets/scale"), name) @@ -200,7 +200,7 @@ func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.Update rs.Spec.Replicas = scale.Spec.Replicas rs.ResourceVersion = scale.ResourceVersion - rs, err = r.registry.UpdateReplicaSet(ctx, rs, createValidation, updateValidation) + rs, err = r.registry.UpdateReplicaSet(ctx, rs, createValidation, updateValidation, options) if err != nil { return nil, false, err } diff --git a/pkg/registry/apps/replicaset/storage/storage_test.go b/pkg/registry/apps/replicaset/storage/storage_test.go index 4c567b893d..c77703f702 100644 --- a/pkg/registry/apps/replicaset/storage/storage_test.go +++ b/pkg/registry/apps/replicaset/storage/storage_test.go @@ -49,7 +49,7 @@ func newStorage(t *testing.T) (*ReplicaSetStorage, *etcdtesting.EtcdTestServer) // createReplicaSet is a helper function that returns a ReplicaSet with the updated resource version. func createReplicaSet(storage *REST, rs extensions.ReplicaSet, t *testing.T) (extensions.ReplicaSet, error) { ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), rs.Namespace) - obj, err := storage.Create(ctx, &rs, rest.ValidateAllObjectFunc, false) + obj, err := storage.Create(ctx, &rs, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("Failed to create ReplicaSet, %v", err) } @@ -174,7 +174,7 @@ func TestGenerationNumber(t *testing.T) { // Updates to spec should increment the generation number storedRS.Spec.Replicas += 1 - if _, _, err := storage.ReplicaSet.Update(ctx, storedRS.Name, rest.DefaultUpdatedObjectInfo(storedRS), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.ReplicaSet.Update(ctx, storedRS.Name, rest.DefaultUpdatedObjectInfo(storedRS), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Errorf("unexpected error: %v", err) } etcdRS, err = storage.ReplicaSet.Get(ctx, rs.Name, &metav1.GetOptions{}) @@ -188,7 +188,7 @@ func TestGenerationNumber(t *testing.T) { // Updates to status should not increment either spec or status generation numbers storedRS.Status.Replicas += 1 - if _, _, err := storage.ReplicaSet.Update(ctx, storedRS.Name, rest.DefaultUpdatedObjectInfo(storedRS), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.ReplicaSet.Update(ctx, storedRS.Name, rest.DefaultUpdatedObjectInfo(storedRS), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Errorf("unexpected error: %v", err) } etcdRS, err = storage.ReplicaSet.Get(ctx, rs.Name, &metav1.GetOptions{}) @@ -319,7 +319,7 @@ func TestScaleUpdate(t *testing.T) { }, } - if _, _, err := storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("error updating scale %v: %v", update, err) } @@ -335,7 +335,7 @@ func TestScaleUpdate(t *testing.T) { update.ResourceVersion = rs.ResourceVersion update.Spec.Replicas = 15 - if _, _, err = storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil && !errors.IsConflict(err) { + if _, _, err = storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil && !errors.IsConflict(err) { t.Fatalf("unexpected error, expecting an update conflict but got %v", err) } } @@ -360,7 +360,7 @@ func TestStatusUpdate(t *testing.T) { }, } - if _, _, err := storage.Status.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Status.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("unexpected error: %v", err) } obj, err := storage.ReplicaSet.Get(ctx, "foo", &metav1.GetOptions{}) diff --git a/pkg/registry/apps/statefulset/registry.go b/pkg/registry/apps/statefulset/registry.go index 666d5760a5..8c707a93b6 100644 --- a/pkg/registry/apps/statefulset/registry.go +++ b/pkg/registry/apps/statefulset/registry.go @@ -33,8 +33,8 @@ type Registry interface { ListStatefulSets(ctx context.Context, options *metainternalversion.ListOptions) (*apps.StatefulSetList, error) WatchStatefulSets(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) GetStatefulSet(ctx context.Context, statefulSetID string, options *metav1.GetOptions) (*apps.StatefulSet, error) - CreateStatefulSet(ctx context.Context, statefulSet *apps.StatefulSet, createValidation rest.ValidateObjectFunc) (*apps.StatefulSet, error) - UpdateStatefulSet(ctx context.Context, statefulSet *apps.StatefulSet, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*apps.StatefulSet, error) + CreateStatefulSet(ctx context.Context, statefulSet *apps.StatefulSet, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (*apps.StatefulSet, error) + UpdateStatefulSet(ctx context.Context, statefulSet *apps.StatefulSet, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) (*apps.StatefulSet, error) DeleteStatefulSet(ctx context.Context, statefulSetID string) error } @@ -72,16 +72,16 @@ func (s *storage) GetStatefulSet(ctx context.Context, statefulSetID string, opti return obj.(*apps.StatefulSet), nil } -func (s *storage) CreateStatefulSet(ctx context.Context, statefulSet *apps.StatefulSet, createValidation rest.ValidateObjectFunc) (*apps.StatefulSet, error) { - obj, err := s.Create(ctx, statefulSet, rest.ValidateAllObjectFunc, false) +func (s *storage) CreateStatefulSet(ctx context.Context, statefulSet *apps.StatefulSet, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (*apps.StatefulSet, error) { + obj, err := s.Create(ctx, statefulSet, rest.ValidateAllObjectFunc, options) if err != nil { return nil, err } return obj.(*apps.StatefulSet), nil } -func (s *storage) UpdateStatefulSet(ctx context.Context, statefulSet *apps.StatefulSet, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*apps.StatefulSet, error) { - obj, _, err := s.Update(ctx, statefulSet.Name, rest.DefaultUpdatedObjectInfo(statefulSet), createValidation, updateValidation, false) +func (s *storage) UpdateStatefulSet(ctx context.Context, statefulSet *apps.StatefulSet, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) (*apps.StatefulSet, error) { + obj, _, err := s.Update(ctx, statefulSet.Name, rest.DefaultUpdatedObjectInfo(statefulSet), createValidation, updateValidation, false, options) if err != nil { return nil, err } diff --git a/pkg/registry/apps/statefulset/storage/storage.go b/pkg/registry/apps/statefulset/storage/storage.go index 904509b3db..670ce41e81 100644 --- a/pkg/registry/apps/statefulset/storage/storage.go +++ b/pkg/registry/apps/statefulset/storage/storage.go @@ -109,10 +109,10 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } // Implement ShortNamesProvider @@ -159,7 +159,7 @@ func (r *ScaleREST) Get(ctx context.Context, name string, options *metav1.GetOpt return scale, err } -func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { ss, err := r.registry.GetStatefulSet(ctx, name, &metav1.GetOptions{}) if err != nil { return nil, false, err @@ -188,7 +188,7 @@ func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.Update ss.Spec.Replicas = scale.Spec.Replicas ss.ResourceVersion = scale.ResourceVersion - ss, err = r.registry.UpdateStatefulSet(ctx, ss, createValidation, updateValidation) + ss, err = r.registry.UpdateStatefulSet(ctx, ss, createValidation, updateValidation, options) if err != nil { return nil, false, err } diff --git a/pkg/registry/apps/statefulset/storage/storage_test.go b/pkg/registry/apps/statefulset/storage/storage_test.go index afaec9bb8f..a23a6cecb7 100644 --- a/pkg/registry/apps/statefulset/storage/storage_test.go +++ b/pkg/registry/apps/statefulset/storage/storage_test.go @@ -115,7 +115,7 @@ func TestStatusUpdate(t *testing.T) { }, } - if _, _, err := storage.Status.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Status.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("unexpected error: %v", err) } obj, err := storage.StatefulSet.Get(ctx, "foo", &metav1.GetOptions{}) @@ -268,7 +268,7 @@ func TestScaleUpdate(t *testing.T) { }, } - if _, _, err := storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("error updating scale %v: %v", update, err) } @@ -284,7 +284,7 @@ func TestScaleUpdate(t *testing.T) { update.ResourceVersion = sts.ResourceVersion update.Spec.Replicas = 15 - if _, _, err = storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil && !errors.IsConflict(err) { + if _, _, err = storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil && !errors.IsConflict(err) { t.Fatalf("unexpected error, expecting an update conflict but got %v", err) } } diff --git a/pkg/registry/authentication/tokenreview/BUILD b/pkg/registry/authentication/tokenreview/BUILD index 9e116fad6f..7ef5901f8f 100644 --- a/pkg/registry/authentication/tokenreview/BUILD +++ b/pkg/registry/authentication/tokenreview/BUILD @@ -12,6 +12,7 @@ go_library( deps = [ "//pkg/apis/authentication:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library", diff --git a/pkg/registry/authentication/tokenreview/storage.go b/pkg/registry/authentication/tokenreview/storage.go index c90a01b68a..cfd7f8ec2c 100644 --- a/pkg/registry/authentication/tokenreview/storage.go +++ b/pkg/registry/authentication/tokenreview/storage.go @@ -22,6 +22,7 @@ import ( "net/http" apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/authentication/authenticator" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" @@ -45,7 +46,7 @@ func (r *REST) New() runtime.Object { return &authentication.TokenReview{} } -func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { tokenReview, ok := obj.(*authentication.TokenReview) if !ok { return nil, apierrors.NewBadRequest(fmt.Sprintf("not a TokenReview: %#v", obj)) diff --git a/pkg/registry/authorization/localsubjectaccessreview/BUILD b/pkg/registry/authorization/localsubjectaccessreview/BUILD index 6a919496fa..a91a80a924 100644 --- a/pkg/registry/authorization/localsubjectaccessreview/BUILD +++ b/pkg/registry/authorization/localsubjectaccessreview/BUILD @@ -14,6 +14,7 @@ go_library( "//pkg/apis/authorization/validation:go_default_library", "//pkg/registry/authorization/util:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library", diff --git a/pkg/registry/authorization/localsubjectaccessreview/rest.go b/pkg/registry/authorization/localsubjectaccessreview/rest.go index c2e6a5dccb..2049adb91c 100644 --- a/pkg/registry/authorization/localsubjectaccessreview/rest.go +++ b/pkg/registry/authorization/localsubjectaccessreview/rest.go @@ -21,6 +21,7 @@ import ( "fmt" kapierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/authorization/authorizer" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" @@ -46,7 +47,7 @@ func (r *REST) New() runtime.Object { return &authorizationapi.LocalSubjectAccessReview{} } -func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { localSubjectAccessReview, ok := obj.(*authorizationapi.LocalSubjectAccessReview) if !ok { return nil, kapierrors.NewBadRequest(fmt.Sprintf("not a LocaLocalSubjectAccessReview: %#v", obj)) diff --git a/pkg/registry/authorization/selfsubjectaccessreview/BUILD b/pkg/registry/authorization/selfsubjectaccessreview/BUILD index 3bb8ff1007..ac53dcfec8 100644 --- a/pkg/registry/authorization/selfsubjectaccessreview/BUILD +++ b/pkg/registry/authorization/selfsubjectaccessreview/BUILD @@ -14,6 +14,7 @@ go_library( "//pkg/apis/authorization/validation:go_default_library", "//pkg/registry/authorization/util:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library", diff --git a/pkg/registry/authorization/selfsubjectaccessreview/rest.go b/pkg/registry/authorization/selfsubjectaccessreview/rest.go index 236034eea4..f8e17d706c 100644 --- a/pkg/registry/authorization/selfsubjectaccessreview/rest.go +++ b/pkg/registry/authorization/selfsubjectaccessreview/rest.go @@ -21,6 +21,7 @@ import ( "fmt" apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/authorization/authorizer" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" @@ -46,7 +47,7 @@ func (r *REST) New() runtime.Object { return &authorizationapi.SelfSubjectAccessReview{} } -func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { selfSAR, ok := obj.(*authorizationapi.SelfSubjectAccessReview) if !ok { return nil, apierrors.NewBadRequest(fmt.Sprintf("not a SelfSubjectAccessReview: %#v", obj)) diff --git a/pkg/registry/authorization/selfsubjectrulesreview/BUILD b/pkg/registry/authorization/selfsubjectrulesreview/BUILD index 49dfbc4a68..46a86fdd13 100644 --- a/pkg/registry/authorization/selfsubjectrulesreview/BUILD +++ b/pkg/registry/authorization/selfsubjectrulesreview/BUILD @@ -8,6 +8,7 @@ go_library( deps = [ "//pkg/apis/authorization:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library", diff --git a/pkg/registry/authorization/selfsubjectrulesreview/rest.go b/pkg/registry/authorization/selfsubjectrulesreview/rest.go index 610d88230c..a9414904b5 100644 --- a/pkg/registry/authorization/selfsubjectrulesreview/rest.go +++ b/pkg/registry/authorization/selfsubjectrulesreview/rest.go @@ -21,6 +21,7 @@ import ( "fmt" apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/authorization/authorizer" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" @@ -49,7 +50,7 @@ func (r *REST) New() runtime.Object { } // Create attempts to get self subject rules in specific namespace. -func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { selfSRR, ok := obj.(*authorizationapi.SelfSubjectRulesReview) if !ok { return nil, apierrors.NewBadRequest(fmt.Sprintf("not a SelfSubjectRulesReview: %#v", obj)) diff --git a/pkg/registry/authorization/subjectaccessreview/BUILD b/pkg/registry/authorization/subjectaccessreview/BUILD index f4294c79c5..7aa80d6852 100644 --- a/pkg/registry/authorization/subjectaccessreview/BUILD +++ b/pkg/registry/authorization/subjectaccessreview/BUILD @@ -15,6 +15,7 @@ go_library( "//pkg/apis/authorization/validation:go_default_library", "//pkg/registry/authorization/util:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library", @@ -40,6 +41,7 @@ go_test( embed = [":go_default_library"], deps = [ "//pkg/apis/authorization:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library", diff --git a/pkg/registry/authorization/subjectaccessreview/rest.go b/pkg/registry/authorization/subjectaccessreview/rest.go index 3fe3da03cb..91180f6af2 100644 --- a/pkg/registry/authorization/subjectaccessreview/rest.go +++ b/pkg/registry/authorization/subjectaccessreview/rest.go @@ -21,6 +21,7 @@ import ( "fmt" kapierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/registry/rest" @@ -45,7 +46,7 @@ func (r *REST) New() runtime.Object { return &authorizationapi.SubjectAccessReview{} } -func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { subjectAccessReview, ok := obj.(*authorizationapi.SubjectAccessReview) if !ok { return nil, kapierrors.NewBadRequest(fmt.Sprintf("not a SubjectAccessReview: %#v", obj)) diff --git a/pkg/registry/authorization/subjectaccessreview/rest_test.go b/pkg/registry/authorization/subjectaccessreview/rest_test.go index ce882a8b4b..cde4aa1881 100644 --- a/pkg/registry/authorization/subjectaccessreview/rest_test.go +++ b/pkg/registry/authorization/subjectaccessreview/rest_test.go @@ -23,6 +23,7 @@ import ( "reflect" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" @@ -195,7 +196,7 @@ func TestCreate(t *testing.T) { } storage := NewREST(auth) - result, err := storage.Create(genericapirequest.NewContext(), &authorizationapi.SubjectAccessReview{Spec: tc.spec}, rest.ValidateAllObjectFunc, false) + result, err := storage.Create(genericapirequest.NewContext(), &authorizationapi.SubjectAccessReview{Spec: tc.spec}, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { if tc.expectedErr != "" { if !strings.Contains(err.Error(), tc.expectedErr) { diff --git a/pkg/registry/autoscaling/horizontalpodautoscaler/storage/storage.go b/pkg/registry/autoscaling/horizontalpodautoscaler/storage/storage.go index 4692396a05..b9e7dcad42 100644 --- a/pkg/registry/autoscaling/horizontalpodautoscaler/storage/storage.go +++ b/pkg/registry/autoscaling/horizontalpodautoscaler/storage/storage.go @@ -89,8 +89,8 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/pkg/registry/autoscaling/horizontalpodautoscaler/storage/storage_test.go b/pkg/registry/autoscaling/horizontalpodautoscaler/storage/storage_test.go index 153d30e012..6a8999893b 100644 --- a/pkg/registry/autoscaling/horizontalpodautoscaler/storage/storage_test.go +++ b/pkg/registry/autoscaling/horizontalpodautoscaler/storage/storage_test.go @@ -194,7 +194,7 @@ func TestUpdateStatus(t *testing.T) { }, } - _, _, err = statusStorage.Update(ctx, autoscalerIn.Name, rest.DefaultUpdatedObjectInfo(autoscalerIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = statusStorage.Update(ctx, autoscalerIn.Name, rest.DefaultUpdatedObjectInfo(autoscalerIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } diff --git a/pkg/registry/batch/cronjob/storage/storage.go b/pkg/registry/batch/cronjob/storage/storage.go index d1932cbf19..c71092db1b 100644 --- a/pkg/registry/batch/cronjob/storage/storage.go +++ b/pkg/registry/batch/cronjob/storage/storage.go @@ -88,8 +88,8 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/pkg/registry/batch/job/storage/storage.go b/pkg/registry/batch/job/storage/storage.go index 8f9da6e24e..77d853deb7 100644 --- a/pkg/registry/batch/job/storage/storage.go +++ b/pkg/registry/batch/job/storage/storage.go @@ -99,8 +99,8 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/pkg/registry/certificates/certificates/registry.go b/pkg/registry/certificates/certificates/registry.go index 188f2ab682..dd93497d87 100644 --- a/pkg/registry/certificates/certificates/registry.go +++ b/pkg/registry/certificates/certificates/registry.go @@ -29,8 +29,8 @@ import ( // Registry is an interface for things that know how to store CSRs. type Registry interface { ListCSRs(ctx context.Context, options *metainternalversion.ListOptions) (*certificates.CertificateSigningRequestList, error) - CreateCSR(ctx context.Context, csr *certificates.CertificateSigningRequest, createValidation rest.ValidateObjectFunc) error - UpdateCSR(ctx context.Context, csr *certificates.CertificateSigningRequest, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error + CreateCSR(ctx context.Context, csr *certificates.CertificateSigningRequest, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) error + UpdateCSR(ctx context.Context, csr *certificates.CertificateSigningRequest, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error GetCSR(ctx context.Context, csrID string, options *metav1.GetOptions) (*certificates.CertificateSigningRequest, error) DeleteCSR(ctx context.Context, csrID string) error WatchCSRs(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) @@ -56,13 +56,13 @@ func (s *storage) ListCSRs(ctx context.Context, options *metainternalversion.Lis return obj.(*certificates.CertificateSigningRequestList), nil } -func (s *storage) CreateCSR(ctx context.Context, csr *certificates.CertificateSigningRequest, createValidation rest.ValidateObjectFunc) error { - _, err := s.Create(ctx, csr, createValidation, false) +func (s *storage) CreateCSR(ctx context.Context, csr *certificates.CertificateSigningRequest, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) error { + _, err := s.Create(ctx, csr, createValidation, options) return err } -func (s *storage) UpdateCSR(ctx context.Context, csr *certificates.CertificateSigningRequest, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error { - _, _, err := s.Update(ctx, csr.Name, rest.DefaultUpdatedObjectInfo(csr), createValidation, updateValidation, false) +func (s *storage) UpdateCSR(ctx context.Context, csr *certificates.CertificateSigningRequest, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error { + _, _, err := s.Update(ctx, csr.Name, rest.DefaultUpdatedObjectInfo(csr), createValidation, updateValidation, false, options) return err } diff --git a/pkg/registry/certificates/certificates/storage/storage.go b/pkg/registry/certificates/certificates/storage/storage.go index deeeb4ac76..0b9fd6ea53 100644 --- a/pkg/registry/certificates/certificates/storage/storage.go +++ b/pkg/registry/certificates/certificates/storage/storage.go @@ -90,10 +90,10 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } var _ = rest.Patcher(&StatusREST{}) @@ -108,8 +108,8 @@ func (r *ApprovalREST) New() runtime.Object { } // Update alters the approval subset of an object. -func (r *ApprovalREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *ApprovalREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/pkg/registry/core/configmap/registry.go b/pkg/registry/core/configmap/registry.go index 81f9c6e858..5161517876 100644 --- a/pkg/registry/core/configmap/registry.go +++ b/pkg/registry/core/configmap/registry.go @@ -31,8 +31,8 @@ type Registry interface { ListConfigMaps(ctx context.Context, options *metainternalversion.ListOptions) (*api.ConfigMapList, error) WatchConfigMaps(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) GetConfigMap(ctx context.Context, name string, options *metav1.GetOptions) (*api.ConfigMap, error) - CreateConfigMap(ctx context.Context, cfg *api.ConfigMap, createValidation rest.ValidateObjectFunc) (*api.ConfigMap, error) - UpdateConfigMap(ctx context.Context, cfg *api.ConfigMap, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*api.ConfigMap, error) + CreateConfigMap(ctx context.Context, cfg *api.ConfigMap, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (*api.ConfigMap, error) + UpdateConfigMap(ctx context.Context, cfg *api.ConfigMap, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) (*api.ConfigMap, error) DeleteConfigMap(ctx context.Context, name string) error } @@ -69,8 +69,8 @@ func (s *storage) GetConfigMap(ctx context.Context, name string, options *metav1 return obj.(*api.ConfigMap), nil } -func (s *storage) CreateConfigMap(ctx context.Context, cfg *api.ConfigMap, createValidation rest.ValidateObjectFunc) (*api.ConfigMap, error) { - obj, err := s.Create(ctx, cfg, createValidation, false) +func (s *storage) CreateConfigMap(ctx context.Context, cfg *api.ConfigMap, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (*api.ConfigMap, error) { + obj, err := s.Create(ctx, cfg, createValidation, options) if err != nil { return nil, err } @@ -78,8 +78,8 @@ func (s *storage) CreateConfigMap(ctx context.Context, cfg *api.ConfigMap, creat return obj.(*api.ConfigMap), nil } -func (s *storage) UpdateConfigMap(ctx context.Context, cfg *api.ConfigMap, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*api.ConfigMap, error) { - obj, _, err := s.Update(ctx, cfg.Name, rest.DefaultUpdatedObjectInfo(cfg), createValidation, updateValidation, false) +func (s *storage) UpdateConfigMap(ctx context.Context, cfg *api.ConfigMap, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) (*api.ConfigMap, error) { + obj, _, err := s.Update(ctx, cfg.Name, rest.DefaultUpdatedObjectInfo(cfg), createValidation, updateValidation, false, options) if err != nil { return nil, err } diff --git a/pkg/registry/core/endpoint/registry.go b/pkg/registry/core/endpoint/registry.go index 1fedeaf0fb..0b4659de5a 100644 --- a/pkg/registry/core/endpoint/registry.go +++ b/pkg/registry/core/endpoint/registry.go @@ -31,7 +31,7 @@ type Registry interface { ListEndpoints(ctx context.Context, options *metainternalversion.ListOptions) (*api.EndpointsList, error) GetEndpoints(ctx context.Context, name string, options *metav1.GetOptions) (*api.Endpoints, error) WatchEndpoints(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) - UpdateEndpoints(ctx context.Context, e *api.Endpoints, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error + UpdateEndpoints(ctx context.Context, e *api.Endpoints, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error DeleteEndpoints(ctx context.Context, name string) error } @@ -66,8 +66,8 @@ func (s *storage) GetEndpoints(ctx context.Context, name string, options *metav1 return obj.(*api.Endpoints), nil } -func (s *storage) UpdateEndpoints(ctx context.Context, endpoints *api.Endpoints, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error { - _, _, err := s.Update(ctx, endpoints.Name, rest.DefaultUpdatedObjectInfo(endpoints), createValidation, updateValidation, false) +func (s *storage) UpdateEndpoints(ctx context.Context, endpoints *api.Endpoints, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error { + _, _, err := s.Update(ctx, endpoints.Name, rest.DefaultUpdatedObjectInfo(endpoints), createValidation, updateValidation, false, options) return err } diff --git a/pkg/registry/core/namespace/registry.go b/pkg/registry/core/namespace/registry.go index 6fc2c8a972..9abe821ca0 100644 --- a/pkg/registry/core/namespace/registry.go +++ b/pkg/registry/core/namespace/registry.go @@ -31,8 +31,8 @@ type Registry interface { ListNamespaces(ctx context.Context, options *metainternalversion.ListOptions) (*api.NamespaceList, error) WatchNamespaces(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) GetNamespace(ctx context.Context, namespaceID string, options *metav1.GetOptions) (*api.Namespace, error) - CreateNamespace(ctx context.Context, namespace *api.Namespace, createValidation rest.ValidateObjectFunc) error - UpdateNamespace(ctx context.Context, namespace *api.Namespace, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error + CreateNamespace(ctx context.Context, namespace *api.Namespace, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) error + UpdateNamespace(ctx context.Context, namespace *api.Namespace, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error DeleteNamespace(ctx context.Context, namespaceID string) error } @@ -67,13 +67,13 @@ func (s *storage) GetNamespace(ctx context.Context, namespaceName string, option return obj.(*api.Namespace), nil } -func (s *storage) CreateNamespace(ctx context.Context, namespace *api.Namespace, createValidation rest.ValidateObjectFunc) error { - _, err := s.Create(ctx, namespace, createValidation, false) +func (s *storage) CreateNamespace(ctx context.Context, namespace *api.Namespace, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) error { + _, err := s.Create(ctx, namespace, createValidation, options) return err } -func (s *storage) UpdateNamespace(ctx context.Context, namespace *api.Namespace, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error { - _, _, err := s.Update(ctx, namespace.Name, rest.DefaultUpdatedObjectInfo(namespace), createValidation, updateValidation, false) +func (s *storage) UpdateNamespace(ctx context.Context, namespace *api.Namespace, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error { + _, _, err := s.Update(ctx, namespace.Name, rest.DefaultUpdatedObjectInfo(namespace), createValidation, updateValidation, false, options) return err } diff --git a/pkg/registry/core/namespace/storage/storage.go b/pkg/registry/core/namespace/storage/storage.go index bdf601bbc0..842edbe3cd 100644 --- a/pkg/registry/core/namespace/storage/storage.go +++ b/pkg/registry/core/namespace/storage/storage.go @@ -100,12 +100,12 @@ func (r *REST) List(ctx context.Context, options *metainternalversion.ListOption return r.store.List(ctx, options) } -func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { - return r.store.Create(ctx, obj, createValidation, includeUninitialized) +func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { + return r.store.Create(ctx, obj, createValidation, options) } -func (r *REST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate) +func (r *REST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) } func (r *REST) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { @@ -234,10 +234,10 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } func (r *FinalizeREST) New() runtime.Object { @@ -245,8 +245,8 @@ func (r *FinalizeREST) New() runtime.Object { } // Update alters the status finalizers subset of an object. -func (r *FinalizeREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *FinalizeREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/pkg/registry/core/namespace/storage/storage_test.go b/pkg/registry/core/namespace/storage/storage_test.go index d18c106abf..6730de112a 100644 --- a/pkg/registry/core/namespace/storage/storage_test.go +++ b/pkg/registry/core/namespace/storage/storage_test.go @@ -69,7 +69,7 @@ func TestCreateSetsFields(t *testing.T) { defer storage.store.DestroyFunc() namespace := validNewNamespace() ctx := genericapirequest.NewContext() - _, err := storage.Create(ctx, namespace, rest.ValidateAllObjectFunc, false) + _, err := storage.Create(ctx, namespace, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/pkg/registry/core/node/registry.go b/pkg/registry/core/node/registry.go index 631243ce66..cfb27bdd72 100644 --- a/pkg/registry/core/node/registry.go +++ b/pkg/registry/core/node/registry.go @@ -29,8 +29,8 @@ import ( // Registry is an interface for things that know how to store node. type Registry interface { ListNodes(ctx context.Context, options *metainternalversion.ListOptions) (*api.NodeList, error) - CreateNode(ctx context.Context, node *api.Node, createValidation rest.ValidateObjectFunc) error - UpdateNode(ctx context.Context, node *api.Node, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error + CreateNode(ctx context.Context, node *api.Node, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) error + UpdateNode(ctx context.Context, node *api.Node, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error GetNode(ctx context.Context, nodeID string, options *metav1.GetOptions) (*api.Node, error) DeleteNode(ctx context.Context, nodeID string) error WatchNodes(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) @@ -56,13 +56,13 @@ func (s *storage) ListNodes(ctx context.Context, options *metainternalversion.Li return obj.(*api.NodeList), nil } -func (s *storage) CreateNode(ctx context.Context, node *api.Node, createValidation rest.ValidateObjectFunc) error { - _, err := s.Create(ctx, node, createValidation, false) +func (s *storage) CreateNode(ctx context.Context, node *api.Node, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) error { + _, err := s.Create(ctx, node, createValidation, options) return err } -func (s *storage) UpdateNode(ctx context.Context, node *api.Node, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error { - _, _, err := s.Update(ctx, node.Name, rest.DefaultUpdatedObjectInfo(node), createValidation, updateValidation, false) +func (s *storage) UpdateNode(ctx context.Context, node *api.Node, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error { + _, _, err := s.Update(ctx, node.Name, rest.DefaultUpdatedObjectInfo(node), createValidation, updateValidation, false, options) return err } diff --git a/pkg/registry/core/node/storage/storage.go b/pkg/registry/core/node/storage/storage.go index 0269ccb30c..2e76aff461 100644 --- a/pkg/registry/core/node/storage/storage.go +++ b/pkg/registry/core/node/storage/storage.go @@ -69,10 +69,10 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } // NewStorage returns a NodeStorage object that will work against nodes. diff --git a/pkg/registry/core/persistentvolume/storage/storage.go b/pkg/registry/core/persistentvolume/storage/storage.go index 17a133afc1..f1339b3dd1 100644 --- a/pkg/registry/core/persistentvolume/storage/storage.go +++ b/pkg/registry/core/persistentvolume/storage/storage.go @@ -84,8 +84,8 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/pkg/registry/core/persistentvolume/storage/storage_test.go b/pkg/registry/core/persistentvolume/storage/storage_test.go index ede192c50d..fa6fd9d66b 100644 --- a/pkg/registry/core/persistentvolume/storage/storage_test.go +++ b/pkg/registry/core/persistentvolume/storage/storage_test.go @@ -183,7 +183,7 @@ func TestUpdateStatus(t *testing.T) { }, } - _, _, err = statusStorage.Update(ctx, pvIn.Name, rest.DefaultUpdatedObjectInfo(pvIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = statusStorage.Update(ctx, pvIn.Name, rest.DefaultUpdatedObjectInfo(pvIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } diff --git a/pkg/registry/core/persistentvolumeclaim/storage/storage.go b/pkg/registry/core/persistentvolumeclaim/storage/storage.go index d4c0b54e29..2eeaa3a365 100644 --- a/pkg/registry/core/persistentvolumeclaim/storage/storage.go +++ b/pkg/registry/core/persistentvolumeclaim/storage/storage.go @@ -84,8 +84,8 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/pkg/registry/core/persistentvolumeclaim/storage/storage_test.go b/pkg/registry/core/persistentvolumeclaim/storage/storage_test.go index 2f4ef94662..14f6a45ee2 100644 --- a/pkg/registry/core/persistentvolumeclaim/storage/storage_test.go +++ b/pkg/registry/core/persistentvolumeclaim/storage/storage_test.go @@ -179,7 +179,7 @@ func TestUpdateStatus(t *testing.T) { }, } - _, _, err = statusStorage.Update(ctx, pvc.Name, rest.DefaultUpdatedObjectInfo(pvc), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = statusStorage.Update(ctx, pvc.Name, rest.DefaultUpdatedObjectInfo(pvc), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } diff --git a/pkg/registry/core/pod/storage/eviction.go b/pkg/registry/core/pod/storage/eviction.go index 5eb66cb6e7..f0f3e37567 100644 --- a/pkg/registry/core/pod/storage/eviction.go +++ b/pkg/registry/core/pod/storage/eviction.go @@ -78,7 +78,7 @@ func (r *EvictionREST) New() runtime.Object { } // Create attempts to create a new eviction. That is, it tries to evict a pod. -func (r *EvictionREST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (r *EvictionREST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { eviction := obj.(*policy.Eviction) obj, err := r.store.Get(ctx, eviction.Name, &metav1.GetOptions{}) diff --git a/pkg/registry/core/pod/storage/storage.go b/pkg/registry/core/pod/storage/storage.go index aecefb6cad..1f0bcc4091 100644 --- a/pkg/registry/core/pod/storage/storage.go +++ b/pkg/registry/core/pod/storage/storage.go @@ -140,7 +140,7 @@ func (r *BindingREST) New() runtime.Object { var _ = rest.Creater(&BindingREST{}) // Create ensures a pod is bound to a specific host. -func (r *BindingREST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (out runtime.Object, err error) { +func (r *BindingREST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (out runtime.Object, err error) { binding := obj.(*api.Binding) // TODO: move me to a binding strategy @@ -217,8 +217,8 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/pkg/registry/core/pod/storage/storage_test.go b/pkg/registry/core/pod/storage/storage_test.go index 4cf40707c7..1d20d14185 100644 --- a/pkg/registry/core/pod/storage/storage_test.go +++ b/pkg/registry/core/pod/storage/storage_test.go @@ -189,7 +189,7 @@ func TestIgnoreDeleteNotFound(t *testing.T) { } // create pod - _, err = registry.Create(testContext, pod, rest.ValidateAllObjectFunc, false) + _, err = registry.Create(testContext, pod, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -226,7 +226,7 @@ func TestCreateSetsFields(t *testing.T) { defer server.Terminate(t) defer storage.Store.DestroyFunc() pod := validNewPod() - _, err := storage.Create(genericapirequest.NewDefaultContext(), pod, rest.ValidateAllObjectFunc, false) + _, err := storage.Create(genericapirequest.NewDefaultContext(), pod, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -490,7 +490,7 @@ func TestEtcdCreate(t *testing.T) { defer server.Terminate(t) defer storage.Store.DestroyFunc() ctx := genericapirequest.NewDefaultContext() - _, err := storage.Create(ctx, validNewPod(), rest.ValidateAllObjectFunc, false) + _, err := storage.Create(ctx, validNewPod(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -499,7 +499,7 @@ func TestEtcdCreate(t *testing.T) { _, err = bindingStorage.Create(ctx, &api.Binding{ ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "foo"}, Target: api.ObjectReference{Name: "machine"}, - }, rest.ValidateAllObjectFunc, false) + }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -525,7 +525,7 @@ func TestEtcdCreateBindingNoPod(t *testing.T) { _, err := bindingStorage.Create(ctx, &api.Binding{ ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "foo"}, Target: api.ObjectReference{Name: "machine"}, - }, rest.ValidateAllObjectFunc, false) + }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err == nil { t.Fatalf("Expected not-found-error but got nothing") } @@ -548,7 +548,7 @@ func TestEtcdCreateFailsWithoutNamespace(t *testing.T) { defer storage.Store.DestroyFunc() pod := validNewPod() pod.Namespace = "" - _, err := storage.Create(genericapirequest.NewContext(), pod, rest.ValidateAllObjectFunc, false) + _, err := storage.Create(genericapirequest.NewContext(), pod, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) // Accept "namespace" or "Namespace". if err == nil || !strings.Contains(err.Error(), "amespace") { t.Fatalf("expected error that namespace was missing from context, got: %v", err) @@ -560,7 +560,7 @@ func TestEtcdCreateWithContainersNotFound(t *testing.T) { defer server.Terminate(t) defer storage.Store.DestroyFunc() ctx := genericapirequest.NewDefaultContext() - _, err := storage.Create(ctx, validNewPod(), rest.ValidateAllObjectFunc, false) + _, err := storage.Create(ctx, validNewPod(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -573,7 +573,7 @@ func TestEtcdCreateWithContainersNotFound(t *testing.T) { Annotations: map[string]string{"label1": "value1"}, }, Target: api.ObjectReference{Name: "machine"}, - }, rest.ValidateAllObjectFunc, false) + }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -595,7 +595,7 @@ func TestEtcdCreateWithConflict(t *testing.T) { defer storage.Store.DestroyFunc() ctx := genericapirequest.NewDefaultContext() - _, err := storage.Create(ctx, validNewPod(), rest.ValidateAllObjectFunc, false) + _, err := storage.Create(ctx, validNewPod(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -609,12 +609,12 @@ func TestEtcdCreateWithConflict(t *testing.T) { }, Target: api.ObjectReference{Name: "machine"}, } - _, err = bindingStorage.Create(ctx, &binding, rest.ValidateAllObjectFunc, false) + _, err = bindingStorage.Create(ctx, &binding, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } - _, err = bindingStorage.Create(ctx, &binding, rest.ValidateAllObjectFunc, false) + _, err = bindingStorage.Create(ctx, &binding, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err == nil || !errors.IsConflict(err) { t.Fatalf("expected resource conflict error, not: %v", err) } @@ -625,7 +625,7 @@ func TestEtcdCreateWithExistingContainers(t *testing.T) { defer server.Terminate(t) defer storage.Store.DestroyFunc() ctx := genericapirequest.NewDefaultContext() - _, err := storage.Create(ctx, validNewPod(), rest.ValidateAllObjectFunc, false) + _, err := storage.Create(ctx, validNewPod(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -634,7 +634,7 @@ func TestEtcdCreateWithExistingContainers(t *testing.T) { _, err = bindingStorage.Create(ctx, &api.Binding{ ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "foo"}, Target: api.ObjectReference{Name: "machine"}, - }, rest.ValidateAllObjectFunc, false) + }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -684,10 +684,10 @@ func TestEtcdCreateBinding(t *testing.T) { for k, test := range testCases { storage, bindingStorage, _, server := newStorage(t) - if _, err := storage.Create(ctx, validNewPod(), rest.ValidateAllObjectFunc, false); err != nil { + if _, err := storage.Create(ctx, validNewPod(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil { t.Fatalf("%s: unexpected error: %v", k, err) } - if _, err := bindingStorage.Create(ctx, &test.binding, rest.ValidateAllObjectFunc, false); !test.errOK(err) { + if _, err := bindingStorage.Create(ctx, &test.binding, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); !test.errOK(err) { t.Errorf("%s: unexpected error: %v", k, err) } else if err == nil { // If bind succeeded, verify Host field in pod's Spec. @@ -713,7 +713,7 @@ func TestEtcdUpdateUninitialized(t *testing.T) { pod := validNewPod() // add pending initializers to the pod pod.ObjectMeta.Initializers = &metav1.Initializers{Pending: []metav1.Initializer{{Name: "init.k8s.io"}}} - if _, err := storage.Create(ctx, pod, rest.ValidateAllObjectFunc, true); err != nil { + if _, err := storage.Create(ctx, pod, rest.ValidateAllObjectFunc, &metav1.CreateOptions{IncludeUninitialized: true}); err != nil { t.Fatalf("unexpected error: %v", err) } podIn := *pod @@ -728,7 +728,7 @@ func TestEtcdUpdateUninitialized(t *testing.T) { }) podIn.ObjectMeta.Initializers = nil - _, _, err := storage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(&podIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err := storage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(&podIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -755,7 +755,7 @@ func TestEtcdStatusUpdateUninitialized(t *testing.T) { pod := validNewPod() // add pending initializers to the pod pod.ObjectMeta.Initializers = &metav1.Initializers{Pending: []metav1.Initializer{{Name: "init.k8s.io"}}} - if _, err := storage.Create(ctx, pod, rest.ValidateAllObjectFunc, true); err != nil { + if _, err := storage.Create(ctx, pod, rest.ValidateAllObjectFunc, &metav1.CreateOptions{IncludeUninitialized: true}); err != nil { t.Fatalf("unexpected error: %v", err) } podIn := *pod @@ -763,7 +763,7 @@ func TestEtcdStatusUpdateUninitialized(t *testing.T) { podIn.Status.Phase = api.PodRunning podIn.ObjectMeta.Initializers = nil - _, _, err := statusStorage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(&podIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err := statusStorage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(&podIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) expected := "Forbidden: must not update status when the object is uninitialized" if err == nil { t.Fatalf("Unexpected no err, expected %q", expected) @@ -779,12 +779,12 @@ func TestEtcdUpdateNotScheduled(t *testing.T) { defer storage.Store.DestroyFunc() ctx := genericapirequest.NewDefaultContext() - if _, err := storage.Create(ctx, validNewPod(), rest.ValidateAllObjectFunc, false); err != nil { + if _, err := storage.Create(ctx, validNewPod(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil { t.Fatalf("unexpected error: %v", err) } podIn := validChangedPod() - _, _, err := storage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(podIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err := storage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(podIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -854,7 +854,7 @@ func TestEtcdUpdateScheduled(t *testing.T) { SchedulerName: api.DefaultSchedulerName, }, } - _, _, err = storage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(&podIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = storage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(&podIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -938,7 +938,7 @@ func TestEtcdUpdateStatus(t *testing.T) { expected.Labels = podIn.Labels expected.Status = podIn.Status - _, _, err = statusStorage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(&podIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = statusStorage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(&podIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } diff --git a/pkg/registry/core/replicationcontroller/registry.go b/pkg/registry/core/replicationcontroller/registry.go index 72d3305956..3edc3d104e 100644 --- a/pkg/registry/core/replicationcontroller/registry.go +++ b/pkg/registry/core/replicationcontroller/registry.go @@ -34,8 +34,8 @@ type Registry interface { ListControllers(ctx context.Context, options *metainternalversion.ListOptions) (*api.ReplicationControllerList, error) WatchControllers(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) GetController(ctx context.Context, controllerID string, options *metav1.GetOptions) (*api.ReplicationController, error) - CreateController(ctx context.Context, controller *api.ReplicationController, createValidation rest.ValidateObjectFunc) (*api.ReplicationController, error) - UpdateController(ctx context.Context, controller *api.ReplicationController, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*api.ReplicationController, error) + CreateController(ctx context.Context, controller *api.ReplicationController, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (*api.ReplicationController, error) + UpdateController(ctx context.Context, controller *api.ReplicationController, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) (*api.ReplicationController, error) DeleteController(ctx context.Context, controllerID string) error } @@ -73,16 +73,16 @@ func (s *storage) GetController(ctx context.Context, controllerID string, option return obj.(*api.ReplicationController), nil } -func (s *storage) CreateController(ctx context.Context, controller *api.ReplicationController, createValidation rest.ValidateObjectFunc) (*api.ReplicationController, error) { - obj, err := s.Create(ctx, controller, createValidation, false) +func (s *storage) CreateController(ctx context.Context, controller *api.ReplicationController, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (*api.ReplicationController, error) { + obj, err := s.Create(ctx, controller, createValidation, options) if err != nil { return nil, err } return obj.(*api.ReplicationController), nil } -func (s *storage) UpdateController(ctx context.Context, controller *api.ReplicationController, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*api.ReplicationController, error) { - obj, _, err := s.Update(ctx, controller.Name, rest.DefaultUpdatedObjectInfo(controller), createValidation, updateValidation, false) +func (s *storage) UpdateController(ctx context.Context, controller *api.ReplicationController, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) (*api.ReplicationController, error) { + obj, _, err := s.Update(ctx, controller.Name, rest.DefaultUpdatedObjectInfo(controller), createValidation, updateValidation, false, options) if err != nil { return nil, err } diff --git a/pkg/registry/core/replicationcontroller/storage/storage.go b/pkg/registry/core/replicationcontroller/storage/storage.go index 016d93a7c9..d193e7b210 100644 --- a/pkg/registry/core/replicationcontroller/storage/storage.go +++ b/pkg/registry/core/replicationcontroller/storage/storage.go @@ -119,10 +119,10 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } type ScaleREST struct { @@ -155,7 +155,7 @@ func (r *ScaleREST) Get(ctx context.Context, name string, options *metav1.GetOpt return scaleFromRC(rc), nil } -func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { rc, err := r.registry.GetController(ctx, name, &metav1.GetOptions{}) if err != nil { return nil, false, errors.NewNotFound(autoscaling.Resource("replicationcontrollers/scale"), name) @@ -182,7 +182,7 @@ func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.Update rc.Spec.Replicas = scale.Spec.Replicas rc.ResourceVersion = scale.ResourceVersion - rc, err = r.registry.UpdateController(ctx, rc, createValidation, updateValidation) + rc, err = r.registry.UpdateController(ctx, rc, createValidation, updateValidation, options) if err != nil { return nil, false, err } diff --git a/pkg/registry/core/replicationcontroller/storage/storage_test.go b/pkg/registry/core/replicationcontroller/storage/storage_test.go index a7b0a0c5b2..c96491374e 100644 --- a/pkg/registry/core/replicationcontroller/storage/storage_test.go +++ b/pkg/registry/core/replicationcontroller/storage/storage_test.go @@ -56,7 +56,7 @@ func newStorage(t *testing.T) (ControllerStorage, *etcdtesting.EtcdTestServer) { // createController is a helper function that returns a controller with the updated resource version. func createController(storage *REST, rc api.ReplicationController, t *testing.T) (api.ReplicationController, error) { ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), rc.Namespace) - obj, err := storage.Create(ctx, &rc, rest.ValidateAllObjectFunc, false) + obj, err := storage.Create(ctx, &rc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("Failed to create controller, %v", err) } @@ -177,7 +177,7 @@ func TestGenerationNumber(t *testing.T) { // Updates to spec should increment the generation number controller.Spec.Replicas += 1 - if _, _, err := storage.Controller.Update(ctx, controller.Name, rest.DefaultUpdatedObjectInfo(controller), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Controller.Update(ctx, controller.Name, rest.DefaultUpdatedObjectInfo(controller), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Errorf("unexpected error: %v", err) } ctrl, err = storage.Controller.Get(ctx, rc.Name, &metav1.GetOptions{}) @@ -191,7 +191,7 @@ func TestGenerationNumber(t *testing.T) { // Updates to status should not increment either spec or status generation numbers controller.Status.Replicas += 1 - if _, _, err := storage.Controller.Update(ctx, controller.Name, rest.DefaultUpdatedObjectInfo(controller), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Controller.Update(ctx, controller.Name, rest.DefaultUpdatedObjectInfo(controller), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Errorf("unexpected error: %v", err) } ctrl, err = storage.Controller.Get(ctx, rc.Name, &metav1.GetOptions{}) @@ -310,7 +310,7 @@ func TestScaleUpdate(t *testing.T) { }, } - if _, _, err := storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("error updating scale %v: %v", update, err) } obj, err := storage.Scale.Get(ctx, name, &metav1.GetOptions{}) @@ -325,7 +325,7 @@ func TestScaleUpdate(t *testing.T) { update.ResourceVersion = rc.ResourceVersion update.Spec.Replicas = 15 - if _, _, err = storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil && !errors.IsConflict(err) { + if _, _, err = storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil && !errors.IsConflict(err) { t.Fatalf("unexpected error, expecting an update conflict but got %v", err) } } diff --git a/pkg/registry/core/resourcequota/storage/storage.go b/pkg/registry/core/resourcequota/storage/storage.go index 39821022d8..7e4cf2b1a8 100644 --- a/pkg/registry/core/resourcequota/storage/storage.go +++ b/pkg/registry/core/resourcequota/storage/storage.go @@ -78,8 +78,8 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/pkg/registry/core/resourcequota/storage/storage_test.go b/pkg/registry/core/resourcequota/storage/storage_test.go index bf11aa5e80..744eb16a56 100644 --- a/pkg/registry/core/resourcequota/storage/storage_test.go +++ b/pkg/registry/core/resourcequota/storage/storage_test.go @@ -88,7 +88,7 @@ func TestCreateSetsFields(t *testing.T) { defer storage.Store.DestroyFunc() ctx := genericapirequest.NewDefaultContext() resourcequota := validNewResourceQuota() - _, err := storage.Create(genericapirequest.NewDefaultContext(), resourcequota, rest.ValidateAllObjectFunc, false) + _, err := storage.Create(genericapirequest.NewDefaultContext(), resourcequota, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -192,7 +192,7 @@ func TestUpdateStatus(t *testing.T) { }, } - _, _, err = status.Update(ctx, resourcequotaIn.Name, rest.DefaultUpdatedObjectInfo(resourcequotaIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = status.Update(ctx, resourcequotaIn.Name, rest.DefaultUpdatedObjectInfo(resourcequotaIn), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } diff --git a/pkg/registry/core/service/registry.go b/pkg/registry/core/service/registry.go index c7431c26f2..cc7773199d 100644 --- a/pkg/registry/core/service/registry.go +++ b/pkg/registry/core/service/registry.go @@ -30,10 +30,10 @@ import ( // Registry is an interface for things that know how to store services. type Registry interface { ListServices(ctx context.Context, options *metainternalversion.ListOptions) (*api.ServiceList, error) - CreateService(ctx context.Context, svc *api.Service, createValidation rest.ValidateObjectFunc) (*api.Service, error) + CreateService(ctx context.Context, svc *api.Service, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (*api.Service, error) GetService(ctx context.Context, name string, options *metav1.GetOptions) (*api.Service, error) DeleteService(ctx context.Context, name string) error - UpdateService(ctx context.Context, svc *api.Service, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*api.Service, error) + UpdateService(ctx context.Context, svc *api.Service, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) (*api.Service, error) WatchServices(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) ExportService(ctx context.Context, name string, options metav1.ExportOptions) (*api.Service, error) } @@ -57,8 +57,8 @@ func (s *storage) ListServices(ctx context.Context, options *metainternalversion return obj.(*api.ServiceList), nil } -func (s *storage) CreateService(ctx context.Context, svc *api.Service, createValidation rest.ValidateObjectFunc) (*api.Service, error) { - obj, err := s.Create(ctx, svc, createValidation, false) +func (s *storage) CreateService(ctx context.Context, svc *api.Service, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (*api.Service, error) { + obj, err := s.Create(ctx, svc, createValidation, options) if err != nil { return nil, err } @@ -78,8 +78,8 @@ func (s *storage) DeleteService(ctx context.Context, name string) error { return err } -func (s *storage) UpdateService(ctx context.Context, svc *api.Service, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*api.Service, error) { - obj, _, err := s.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(svc), createValidation, updateValidation, false) +func (s *storage) UpdateService(ctx context.Context, svc *api.Service, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) (*api.Service, error) { + obj, _, err := s.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(svc), createValidation, updateValidation, false, options) if err != nil { return nil, err } diff --git a/pkg/registry/core/service/storage/rest.go b/pkg/registry/core/service/storage/rest.go index efb59c5a83..7e56daf449 100644 --- a/pkg/registry/core/service/storage/rest.go +++ b/pkg/registry/core/service/storage/rest.go @@ -152,7 +152,7 @@ func (rs *REST) Export(ctx context.Context, name string, opts metav1.ExportOptio return rs.services.Export(ctx, name, opts) } -func (rs *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (rs *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { service := obj.(*api.Service) if err := rest.BeforeCreate(registry.Strategy, ctx, obj); err != nil { @@ -195,7 +195,7 @@ func (rs *REST) Create(ctx context.Context, obj runtime.Object, createValidation return nil, errors.NewInvalid(api.Kind("Service"), service.Name, errs) } - out, err := rs.services.Create(ctx, service, createValidation, includeUninitialized) + out, err := rs.services.Create(ctx, service, createValidation, options) if err != nil { err = rest.CheckGeneratedNameError(registry.Strategy, err, service) } @@ -326,7 +326,7 @@ func (rs *REST) healthCheckNodePortUpdate(oldService, service *api.Service, node return true, nil } -func (rs *REST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (rs *REST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { oldObj, err := rs.services.Get(ctx, name, &metav1.GetOptions{}) if err != nil { return nil, false, err @@ -400,7 +400,7 @@ func (rs *REST) Update(ctx context.Context, name string, objInfo rest.UpdatedObj return nil, false, errors.NewInvalid(api.Kind("Service"), service.Name, errs) } - out, created, err := rs.services.Update(ctx, service.Name, rest.DefaultUpdatedObjectInfo(service), createValidation, updateValidation, forceAllowCreate) + out, created, err := rs.services.Update(ctx, service.Name, rest.DefaultUpdatedObjectInfo(service), createValidation, updateValidation, forceAllowCreate, options) if err == nil { el := nodePortOp.Commit() if el != nil { diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index 2bfd85798e..eb3b7e8cb0 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -107,7 +107,7 @@ func (s *serviceStorage) New() runtime.Object { panic("not implemented") } -func (s *serviceStorage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (s *serviceStorage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { svc := obj.(*api.Service) s.CreatedID = obj.(metav1.Object).GetName() s.Service = svc.DeepCopy() @@ -120,7 +120,7 @@ func (s *serviceStorage) Create(ctx context.Context, obj runtime.Object, createV return svc, s.Err } -func (s *serviceStorage) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (s *serviceStorage) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { s.UpdatedID = name obj, err := objInfo.UpdatedObject(ctx, s.OldService) if err != nil { @@ -249,7 +249,7 @@ func TestServiceRegistryCreate(t *testing.T) { }, } ctx := genericapirequest.NewDefaultContext() - created_svc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, false) + created_svc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -375,7 +375,7 @@ func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() for _, test := range testCases { - created_svc, err := storage.Create(ctx, test.svc, rest.ValidateAllObjectFunc, false) + created_svc, err := storage.Create(ctx, test.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -452,7 +452,7 @@ func TestServiceStorageValidatesCreate(t *testing.T) { } ctx := genericapirequest.NewDefaultContext() for _, failureCase := range failureCases { - c, err := storage.Create(ctx, &failureCase, rest.ValidateAllObjectFunc, false) + c, err := storage.Create(ctx, &failureCase, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if c != nil { t.Errorf("Expected nil object") } @@ -477,7 +477,7 @@ func TestServiceRegistryUpdate(t *testing.T) { TargetPort: intstr.FromInt(6502), }}, }, - }, rest.ValidateAllObjectFunc, false) + }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) svc := obj.(*api.Service) if err != nil { t.Fatalf("Expected no error: %v", err) @@ -496,7 +496,7 @@ func TestServiceRegistryUpdate(t *testing.T) { TargetPort: intstr.FromInt(6502), }}, }, - }), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + }), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Fatalf("Expected no error: %v", err) } @@ -528,7 +528,7 @@ func TestServiceStorageValidatesUpdate(t *testing.T) { Protocol: api.ProtocolTCP, }}, }, - }, rest.ValidateAllObjectFunc, false) + }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) failureCases := map[string]api.Service{ "empty ID": { ObjectMeta: metav1.ObjectMeta{Name: ""}, @@ -558,7 +558,7 @@ func TestServiceStorageValidatesUpdate(t *testing.T) { }, } for _, failureCase := range failureCases { - c, created, err := storage.Update(ctx, failureCase.Name, rest.DefaultUpdatedObjectInfo(&failureCase), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + c, created, err := storage.Update(ctx, failureCase.Name, rest.DefaultUpdatedObjectInfo(&failureCase), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if c != nil || created { t.Errorf("Expected nil object or created false") } @@ -585,7 +585,7 @@ func TestServiceRegistryExternalService(t *testing.T) { }}, }, } - _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, false) + _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("Failed to create service: %#v", err) } @@ -623,7 +623,7 @@ func TestServiceRegistryDelete(t *testing.T) { }}, }, } - registry.Create(ctx, svc, rest.ValidateAllObjectFunc, false) + registry.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) storage.Delete(ctx, svc.Name, &metav1.DeleteOptions{}) if e, a := "foo", registry.DeletedID; e != a { t.Errorf("Expected %v, but got %v", e, a) @@ -646,7 +646,7 @@ func TestServiceRegistryDeleteExternal(t *testing.T) { }}, }, } - registry.Create(ctx, svc, rest.ValidateAllObjectFunc, false) + registry.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) storage.Delete(ctx, svc.Name, &metav1.DeleteOptions{}) if e, a := "foo", registry.DeletedID; e != a { t.Errorf("Expected %v, but got %v", e, a) @@ -672,14 +672,14 @@ func TestServiceRegistryUpdateExternalService(t *testing.T) { }}, }, } - if _, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, false); err != nil { + if _, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil { t.Fatalf("Unexpected error: %v", err) } // Modify load balancer to be external. svc2 := svc1.DeepCopy() svc2.Spec.Type = api.ServiceTypeLoadBalancer - if _, _, err := storage.Update(ctx, svc2.Name, rest.DefaultUpdatedObjectInfo(svc2), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Update(ctx, svc2.Name, rest.DefaultUpdatedObjectInfo(svc2), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("Unexpected error: %v", err) } defer releaseServiceNodePorts(t, ctx, svc2.Name, storage, registry) @@ -687,7 +687,7 @@ func TestServiceRegistryUpdateExternalService(t *testing.T) { // Change port. svc3 := svc2.DeepCopy() svc3.Spec.Ports[0].Port = 6504 - if _, _, err := storage.Update(ctx, svc3.Name, rest.DefaultUpdatedObjectInfo(svc3), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Update(ctx, svc3.Name, rest.DefaultUpdatedObjectInfo(svc3), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("Unexpected error: %v", err) } } @@ -717,7 +717,7 @@ func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { }}, }, } - if _, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, false); err != nil { + if _, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil { t.Fatalf("Unexpected error: %v", err) } defer releaseServiceNodePorts(t, ctx, svc1.Name, storage, registry) @@ -725,7 +725,7 @@ func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { // Modify ports svc2 := svc1.DeepCopy() svc2.Spec.Ports[1].Port = 8088 - if _, _, err := storage.Update(ctx, svc2.Name, rest.DefaultUpdatedObjectInfo(svc2), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Update(ctx, svc2.Name, rest.DefaultUpdatedObjectInfo(svc2), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("Unexpected error: %v", err) } } @@ -739,7 +739,7 @@ func TestServiceRegistryGet(t *testing.T) { Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, }, - }, rest.ValidateAllObjectFunc, false) + }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) storage.Get(ctx, "foo", &metav1.GetOptions{}) if e, a := "foo", registry.GottenID; e != a { t.Errorf("Expected %v, but got %v", e, a) @@ -824,7 +824,7 @@ func TestServiceRegistryResourceLocation(t *testing.T) { {Name: "", Port: 93, TargetPort: intstr.FromInt(80)}, }, }, - }, rest.ValidateAllObjectFunc, false) + }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) } redirector := rest.Redirector(storage) @@ -915,13 +915,13 @@ func TestServiceRegistryList(t *testing.T) { Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, }, - }, rest.ValidateAllObjectFunc, false) + }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) registry.Create(ctx, &api.Service{ ObjectMeta: metav1.ObjectMeta{Name: "foo2", Namespace: metav1.NamespaceDefault}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar2": "baz2"}, }, - }, rest.ValidateAllObjectFunc, false) + }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) registry.ServiceList.ResourceVersion = "1" s, _ := storage.List(ctx, nil) sl := s.(*api.ServiceList) @@ -957,7 +957,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) { }, } ctx := genericapirequest.NewDefaultContext() - created_svc1, _ := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, false) + created_svc1, _ := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) created_service_1 := created_svc1.(*api.Service) if created_service_1.Name != "foo" { t.Errorf("Expected foo, but got %v", created_service_1.Name) @@ -979,7 +979,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) { }}, }} ctx = genericapirequest.NewDefaultContext() - created_svc2, _ := storage.Create(ctx, svc2, rest.ValidateAllObjectFunc, false) + created_svc2, _ := storage.Create(ctx, svc2, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) created_service_2 := created_svc2.(*api.Service) if created_service_2.Name != "bar" { t.Errorf("Expected bar, but got %v", created_service_2.Name) @@ -1012,7 +1012,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) { }, } ctx = genericapirequest.NewDefaultContext() - created_svc3, err := storage.Create(ctx, svc3, rest.ValidateAllObjectFunc, false) + created_svc3, err := storage.Create(ctx, svc3, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatal(err) } @@ -1040,7 +1040,7 @@ func TestServiceRegistryIPReallocation(t *testing.T) { }, } ctx := genericapirequest.NewDefaultContext() - created_svc1, _ := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, false) + created_svc1, _ := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) created_service_1 := created_svc1.(*api.Service) if created_service_1.Name != "foo" { t.Errorf("Expected foo, but got %v", created_service_1.Name) @@ -1068,7 +1068,7 @@ func TestServiceRegistryIPReallocation(t *testing.T) { }, } ctx = genericapirequest.NewDefaultContext() - created_svc2, _ := storage.Create(ctx, svc2, rest.ValidateAllObjectFunc, false) + created_svc2, _ := storage.Create(ctx, svc2, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) created_service_2 := created_svc2.(*api.Service) if created_service_2.Name != "bar" { t.Errorf("Expected bar, but got %v", created_service_2.Name) @@ -1096,7 +1096,7 @@ func TestServiceRegistryIPUpdate(t *testing.T) { }, } ctx := genericapirequest.NewDefaultContext() - created_svc, _ := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, false) + created_svc, _ := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) created_service := created_svc.(*api.Service) if created_service.Spec.Ports[0].Port != 6502 { t.Errorf("Expected port 6502, but got %v", created_service.Spec.Ports[0].Port) @@ -1108,7 +1108,7 @@ func TestServiceRegistryIPUpdate(t *testing.T) { update := created_service.DeepCopy() update.Spec.Ports[0].Port = 6503 - updated_svc, _, _ := storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + updated_svc, _, _ := storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) updated_service := updated_svc.(*api.Service) if updated_service.Spec.Ports[0].Port != 6503 { t.Errorf("Expected port 6503, but got %v", updated_service.Spec.Ports[0].Port) @@ -1127,7 +1127,7 @@ func TestServiceRegistryIPUpdate(t *testing.T) { update.Spec.Ports[0].Port = 6503 update.Spec.ClusterIP = testIP // Error: Cluster IP is immutable - _, _, err := storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err := storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err == nil || !errors.IsInvalid(err) { t.Errorf("Unexpected error type: %v", err) } @@ -1151,7 +1151,7 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) { }, } ctx := genericapirequest.NewDefaultContext() - created_svc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, false) + created_svc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if created_svc == nil || err != nil { t.Errorf("Unexpected failure creating service %v", err) } @@ -1167,7 +1167,7 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) { update := created_service.DeepCopy() - _, _, err = storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Errorf("Unexpected error %v", err) } @@ -1181,7 +1181,7 @@ func TestUpdateServiceWithConflictingNamespace(t *testing.T) { } ctx := genericapirequest.NewDefaultContext() - obj, created, err := storage.Update(ctx, service.Name, rest.DefaultUpdatedObjectInfo(service), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + obj, created, err := storage.Update(ctx, service.Name, rest.DefaultUpdatedObjectInfo(service), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if obj != nil || created { t.Error("Expected a nil object, but we got a value or created was true") } @@ -1212,7 +1212,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing. ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeLocal, }, } - created_svc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, false) + created_svc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if created_svc == nil || err != nil { t.Errorf("Unexpected failure creating service %v", err) } @@ -1253,7 +1253,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *test HealthCheckNodePort: randomNodePort, }, } - created_svc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, false) + created_svc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if created_svc == nil || err != nil { t.Fatalf("Unexpected failure creating service :%v", err) } @@ -1296,7 +1296,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T) HealthCheckNodePort: int32(-1), }, } - created_svc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, false) + created_svc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if created_svc == nil || err != nil { return } @@ -1322,7 +1322,7 @@ func TestServiceRegistryExternalTrafficGlobal(t *testing.T) { ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeCluster, }, } - created_svc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, false) + created_svc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if created_svc == nil || err != nil { t.Errorf("Unexpected failure creating service %v", err) } diff --git a/pkg/registry/core/service/storage/storage.go b/pkg/registry/core/service/storage/storage.go index 2a2c8558fc..7ebe95c15b 100644 --- a/pkg/registry/core/service/storage/storage.go +++ b/pkg/registry/core/service/storage/storage.go @@ -90,8 +90,8 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/pkg/registry/core/serviceaccount/storage/token.go b/pkg/registry/core/serviceaccount/storage/token.go index 23cc43f156..4dd4b86db0 100644 --- a/pkg/registry/core/serviceaccount/storage/token.go +++ b/pkg/registry/core/serviceaccount/storage/token.go @@ -56,7 +56,7 @@ var gvk = schema.GroupVersionKind{ Kind: "TokenRequest", } -func (r *TokenREST) Create(ctx context.Context, name string, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (r *TokenREST) Create(ctx context.Context, name string, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { if err := createValidation(obj); err != nil { return nil, err } diff --git a/pkg/registry/extensions/controller/storage/storage.go b/pkg/registry/extensions/controller/storage/storage.go index b824c71caf..011427fdd1 100644 --- a/pkg/registry/extensions/controller/storage/storage.go +++ b/pkg/registry/extensions/controller/storage/storage.go @@ -71,7 +71,7 @@ func (r *ScaleREST) Get(ctx context.Context, name string, options *metav1.GetOpt return scaleFromRC(rc), nil } -func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { rc, err := (*r.registry).GetController(ctx, name, &metav1.GetOptions{}) if err != nil { return nil, false, errors.NewNotFound(extensions.Resource("replicationcontrollers/scale"), name) @@ -94,7 +94,7 @@ func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.Update rc.Spec.Replicas = scale.Spec.Replicas rc.ResourceVersion = scale.ResourceVersion - rc, err = (*r.registry).UpdateController(ctx, rc, createValidation, updateValidation) + rc, err = (*r.registry).UpdateController(ctx, rc, createValidation, updateValidation, options) if err != nil { return nil, false, errors.NewConflict(extensions.Resource("replicationcontrollers/scale"), scale.Name, err) } diff --git a/pkg/registry/extensions/controller/storage/storage_test.go b/pkg/registry/extensions/controller/storage/storage_test.go index 2695efe6d4..1dda754023 100644 --- a/pkg/registry/extensions/controller/storage/storage_test.go +++ b/pkg/registry/extensions/controller/storage/storage_test.go @@ -110,7 +110,7 @@ func TestUpdate(t *testing.T) { }, } - if _, _, err := storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("unexpected error: %v", err) } obj, err := storage.Get(ctx, "foo", &metav1.GetOptions{}) diff --git a/pkg/registry/extensions/ingress/storage/storage.go b/pkg/registry/extensions/ingress/storage/storage.go index d64d2cd588..da7da8574a 100644 --- a/pkg/registry/extensions/ingress/storage/storage.go +++ b/pkg/registry/extensions/ingress/storage/storage.go @@ -82,8 +82,8 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/pkg/registry/networking/networkpolicy/registry.go b/pkg/registry/networking/networkpolicy/registry.go index 8db95facf4..796515f4c9 100644 --- a/pkg/registry/networking/networkpolicy/registry.go +++ b/pkg/registry/networking/networkpolicy/registry.go @@ -30,7 +30,7 @@ import ( type Registry interface { ListNetworkPolicies(ctx context.Context, options *metainternalversion.ListOptions) (*networking.NetworkPolicyList, error) CreateNetworkPolicy(ctx context.Context, np *networking.NetworkPolicy, createValidation rest.ValidateObjectFunc) error - UpdateNetworkPolicy(ctx context.Context, np *networking.NetworkPolicy, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error + UpdateNetworkPolicy(ctx context.Context, np *networking.NetworkPolicy, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error GetNetworkPolicy(ctx context.Context, name string, options *metav1.GetOptions) (*networking.NetworkPolicy, error) DeleteNetworkPolicy(ctx context.Context, name string) error WatchNetworkPolicies(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) @@ -57,12 +57,12 @@ func (s *storage) ListNetworkPolicies(ctx context.Context, options *metainternal } func (s *storage) CreateNetworkPolicy(ctx context.Context, np *networking.NetworkPolicy, createValidation rest.ValidateObjectFunc) error { - _, err := s.Create(ctx, np, createValidation, false) + _, err := s.Create(ctx, np, createValidation, &metav1.CreateOptions{}) return err } -func (s *storage) UpdateNetworkPolicy(ctx context.Context, np *networking.NetworkPolicy, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error { - _, _, err := s.Update(ctx, np.Name, rest.DefaultUpdatedObjectInfo(np), createValidation, updateValidation, false) +func (s *storage) UpdateNetworkPolicy(ctx context.Context, np *networking.NetworkPolicy, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error { + _, _, err := s.Update(ctx, np.Name, rest.DefaultUpdatedObjectInfo(np), createValidation, updateValidation, false, options) return err } diff --git a/pkg/registry/policy/poddisruptionbudget/storage/storage.go b/pkg/registry/policy/poddisruptionbudget/storage/storage.go index 19cb9b3d2f..68bfc32714 100644 --- a/pkg/registry/policy/poddisruptionbudget/storage/storage.go +++ b/pkg/registry/policy/poddisruptionbudget/storage/storage.go @@ -79,8 +79,8 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/pkg/registry/policy/poddisruptionbudget/storage/storage_test.go b/pkg/registry/policy/poddisruptionbudget/storage/storage_test.go index c2e9953dc2..225c9a0195 100644 --- a/pkg/registry/policy/poddisruptionbudget/storage/storage_test.go +++ b/pkg/registry/policy/poddisruptionbudget/storage/storage_test.go @@ -99,7 +99,7 @@ func TestStatusUpdate(t *testing.T) { }, } - if _, _, err := statusStorage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := statusStorage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("unexpected error: %v", err) } obj, err = storage.Get(ctx, "foo", &metav1.GetOptions{}) diff --git a/pkg/registry/rbac/clusterrole/policybased/BUILD b/pkg/registry/rbac/clusterrole/policybased/BUILD index bce3586e37..cf85355c0f 100644 --- a/pkg/registry/rbac/clusterrole/policybased/BUILD +++ b/pkg/registry/rbac/clusterrole/policybased/BUILD @@ -16,6 +16,7 @@ go_library( "//pkg/registry/rbac:go_default_library", "//pkg/registry/rbac/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library", diff --git a/pkg/registry/rbac/clusterrole/policybased/storage.go b/pkg/registry/rbac/clusterrole/policybased/storage.go index d6fbcc8298..4505d9aba6 100644 --- a/pkg/registry/rbac/clusterrole/policybased/storage.go +++ b/pkg/registry/rbac/clusterrole/policybased/storage.go @@ -22,6 +22,7 @@ import ( "errors" apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/registry/rest" @@ -54,9 +55,9 @@ var fullAuthority = []rbac.PolicyRule{ rbac.NewRule("*").URLs("*").RuleOrDie(), } -func (s *Storage) Create(ctx context.Context, obj runtime.Object, createValidatingAdmission rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (s *Storage) Create(ctx context.Context, obj runtime.Object, createValidatingAdmission rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { if rbacregistry.EscalationAllowed(ctx) || rbacregistry.RoleEscalationAuthorized(ctx, s.authorizer) { - return s.StandardStorage.Create(ctx, obj, createValidatingAdmission, includeUninitialized) + return s.StandardStorage.Create(ctx, obj, createValidatingAdmission, options) } clusterRole := obj.(*rbac.ClusterRole) @@ -71,12 +72,12 @@ func (s *Storage) Create(ctx context.Context, obj runtime.Object, createValidati } } - return s.StandardStorage.Create(ctx, obj, createValidatingAdmission, includeUninitialized) + return s.StandardStorage.Create(ctx, obj, createValidatingAdmission, options) } -func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { if rbacregistry.EscalationAllowed(ctx) || rbacregistry.RoleEscalationAuthorized(ctx, s.authorizer) { - return s.StandardStorage.Update(ctx, name, obj, createValidation, updateValidation, forceAllowCreate) + return s.StandardStorage.Update(ctx, name, obj, createValidation, updateValidation, forceAllowCreate, options) } nonEscalatingInfo := rest.WrapUpdatedObjectInfo(obj, func(ctx context.Context, obj runtime.Object, oldObj runtime.Object) (runtime.Object, error) { @@ -102,7 +103,7 @@ func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjec return obj, nil }) - return s.StandardStorage.Update(ctx, name, nonEscalatingInfo, createValidation, updateValidation, forceAllowCreate) + return s.StandardStorage.Update(ctx, name, nonEscalatingInfo, createValidation, updateValidation, forceAllowCreate, options) } func hasAggregationRule(clusterRole *rbac.ClusterRole) bool { diff --git a/pkg/registry/rbac/clusterrole/policybased/storage_test.go b/pkg/registry/rbac/clusterrole/policybased/storage_test.go index 769fbbc489..a7f80a7109 100644 --- a/pkg/registry/rbac/clusterrole/policybased/storage_test.go +++ b/pkg/registry/rbac/clusterrole/policybased/storage_test.go @@ -118,7 +118,7 @@ func TestEscalation(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { authzCalled, fakeStorage.created, fakeStorage.updated = 0, 0, 0 - _, err := s.Create(request.WithUser(createContext, tc.user), role, nil, false) + _, err := s.Create(request.WithUser(createContext, tc.user), role, nil, nil) if tc.expectAllowed { if err != nil { @@ -145,7 +145,7 @@ func TestEscalation(t *testing.T) { } authzCalled, fakeStorage.created, fakeStorage.updated = 0, 0, 0 - _, _, err = s.Update(request.WithUser(updateContext, tc.user), role.Name, rest.DefaultUpdatedObjectInfo(role), nil, nil, false) + _, _, err = s.Update(request.WithUser(updateContext, tc.user), role.Name, rest.DefaultUpdatedObjectInfo(role), nil, nil, false, nil) if tc.expectAllowed { if err != nil { @@ -180,12 +180,12 @@ type fakeStorage struct { rest.StandardStorage } -func (f *fakeStorage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (f *fakeStorage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { f.created++ return nil, nil } -func (f *fakeStorage) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (f *fakeStorage) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { obj, err := objInfo.UpdatedObject(ctx, &rbac.ClusterRole{}) if err != nil { return obj, false, err diff --git a/pkg/registry/rbac/clusterrolebinding/policybased/storage.go b/pkg/registry/rbac/clusterrolebinding/policybased/storage.go index a57118d63f..2267394aaa 100644 --- a/pkg/registry/rbac/clusterrolebinding/policybased/storage.go +++ b/pkg/registry/rbac/clusterrolebinding/policybased/storage.go @@ -51,14 +51,14 @@ func (r *Storage) NamespaceScoped() bool { return false } -func (s *Storage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (s *Storage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { if rbacregistry.EscalationAllowed(ctx) { - return s.StandardStorage.Create(ctx, obj, createValidation, includeUninitialized) + return s.StandardStorage.Create(ctx, obj, createValidation, options) } clusterRoleBinding := obj.(*rbac.ClusterRoleBinding) if rbacregistry.BindingAuthorized(ctx, clusterRoleBinding.RoleRef, metav1.NamespaceNone, s.authorizer) { - return s.StandardStorage.Create(ctx, obj, createValidation, includeUninitialized) + return s.StandardStorage.Create(ctx, obj, createValidation, options) } v1RoleRef := rbacv1.RoleRef{} @@ -73,12 +73,12 @@ func (s *Storage) Create(ctx context.Context, obj runtime.Object, createValidati if err := rbacregistryvalidation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { return nil, errors.NewForbidden(groupResource, clusterRoleBinding.Name, err) } - return s.StandardStorage.Create(ctx, obj, createValidation, includeUninitialized) + return s.StandardStorage.Create(ctx, obj, createValidation, options) } -func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { if rbacregistry.EscalationAllowed(ctx) { - return s.StandardStorage.Update(ctx, name, obj, createValidation, updateValidation, forceAllowCreate) + return s.StandardStorage.Update(ctx, name, obj, createValidation, updateValidation, forceAllowCreate, options) } nonEscalatingInfo := rest.WrapUpdatedObjectInfo(obj, func(ctx context.Context, obj runtime.Object, oldObj runtime.Object) (runtime.Object, error) { @@ -110,5 +110,5 @@ func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjec return obj, nil }) - return s.StandardStorage.Update(ctx, name, nonEscalatingInfo, createValidation, updateValidation, forceAllowCreate) + return s.StandardStorage.Update(ctx, name, nonEscalatingInfo, createValidation, updateValidation, forceAllowCreate, options) } diff --git a/pkg/registry/rbac/role/policybased/BUILD b/pkg/registry/rbac/role/policybased/BUILD index 8ed764f40a..02a24d90eb 100644 --- a/pkg/registry/rbac/role/policybased/BUILD +++ b/pkg/registry/rbac/role/policybased/BUILD @@ -16,6 +16,7 @@ go_library( "//pkg/registry/rbac:go_default_library", "//pkg/registry/rbac/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library", diff --git a/pkg/registry/rbac/role/policybased/storage.go b/pkg/registry/rbac/role/policybased/storage.go index 76ee6ecd57..25a622fe07 100644 --- a/pkg/registry/rbac/role/policybased/storage.go +++ b/pkg/registry/rbac/role/policybased/storage.go @@ -21,6 +21,7 @@ import ( "context" "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/registry/rest" @@ -48,9 +49,9 @@ func (r *Storage) NamespaceScoped() bool { return true } -func (s *Storage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (s *Storage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { if rbacregistry.EscalationAllowed(ctx) || rbacregistry.RoleEscalationAuthorized(ctx, s.authorizer) { - return s.StandardStorage.Create(ctx, obj, createValidation, includeUninitialized) + return s.StandardStorage.Create(ctx, obj, createValidation, options) } role := obj.(*rbac.Role) @@ -58,12 +59,12 @@ func (s *Storage) Create(ctx context.Context, obj runtime.Object, createValidati if err := rbacregistryvalidation.ConfirmNoEscalationInternal(ctx, s.ruleResolver, rules); err != nil { return nil, errors.NewForbidden(groupResource, role.Name, err) } - return s.StandardStorage.Create(ctx, obj, createValidation, includeUninitialized) + return s.StandardStorage.Create(ctx, obj, createValidation, options) } -func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { if rbacregistry.EscalationAllowed(ctx) || rbacregistry.RoleEscalationAuthorized(ctx, s.authorizer) { - return s.StandardStorage.Update(ctx, name, obj, createValidation, updateValidation, forceAllowCreate) + return s.StandardStorage.Update(ctx, name, obj, createValidation, updateValidation, forceAllowCreate, options) } nonEscalatingInfo := rest.WrapUpdatedObjectInfo(obj, func(ctx context.Context, obj runtime.Object, oldObj runtime.Object) (runtime.Object, error) { @@ -81,5 +82,5 @@ func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjec return obj, nil }) - return s.StandardStorage.Update(ctx, name, nonEscalatingInfo, createValidation, updateValidation, forceAllowCreate) + return s.StandardStorage.Update(ctx, name, nonEscalatingInfo, createValidation, updateValidation, forceAllowCreate, options) } diff --git a/pkg/registry/rbac/role/policybased/storage_test.go b/pkg/registry/rbac/role/policybased/storage_test.go index 47666b70a0..33959f2705 100644 --- a/pkg/registry/rbac/role/policybased/storage_test.go +++ b/pkg/registry/rbac/role/policybased/storage_test.go @@ -120,7 +120,7 @@ func TestEscalation(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { authzCalled, fakeStorage.created, fakeStorage.updated = 0, 0, 0 - _, err := s.Create(request.WithUser(createContext, tc.user), role, nil, false) + _, err := s.Create(request.WithUser(createContext, tc.user), role, nil, nil) if tc.expectAllowed { if err != nil { @@ -147,7 +147,7 @@ func TestEscalation(t *testing.T) { } authzCalled, fakeStorage.created, fakeStorage.updated = 0, 0, 0 - _, _, err = s.Update(request.WithUser(updateContext, tc.user), role.Name, rest.DefaultUpdatedObjectInfo(role), nil, nil, false) + _, _, err = s.Update(request.WithUser(updateContext, tc.user), role.Name, rest.DefaultUpdatedObjectInfo(role), nil, nil, false, nil) if tc.expectAllowed { if err != nil { @@ -182,12 +182,12 @@ type fakeStorage struct { rest.StandardStorage } -func (f *fakeStorage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (f *fakeStorage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { f.created++ return nil, nil } -func (f *fakeStorage) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (f *fakeStorage) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { obj, err := objInfo.UpdatedObject(ctx, &rbac.Role{}) if err != nil { return obj, false, err diff --git a/pkg/registry/rbac/rolebinding/policybased/BUILD b/pkg/registry/rbac/rolebinding/policybased/BUILD index 8891cb382d..ef109e1d11 100644 --- a/pkg/registry/rbac/rolebinding/policybased/BUILD +++ b/pkg/registry/rbac/rolebinding/policybased/BUILD @@ -17,6 +17,7 @@ go_library( "//pkg/registry/rbac/validation:go_default_library", "//staging/src/k8s.io/api/rbac/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library", diff --git a/pkg/registry/rbac/rolebinding/policybased/storage.go b/pkg/registry/rbac/rolebinding/policybased/storage.go index 2cfbc2e5f8..2a0603e740 100644 --- a/pkg/registry/rbac/rolebinding/policybased/storage.go +++ b/pkg/registry/rbac/rolebinding/policybased/storage.go @@ -22,6 +22,7 @@ import ( rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/authorization/authorizer" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" @@ -51,9 +52,9 @@ func (r *Storage) NamespaceScoped() bool { return true } -func (s *Storage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (s *Storage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { if rbacregistry.EscalationAllowed(ctx) { - return s.StandardStorage.Create(ctx, obj, createValidation, includeUninitialized) + return s.StandardStorage.Create(ctx, obj, createValidation, options) } // Get the namespace from the context (populated from the URL). @@ -65,7 +66,7 @@ func (s *Storage) Create(ctx context.Context, obj runtime.Object, createValidati roleBinding := obj.(*rbac.RoleBinding) if rbacregistry.BindingAuthorized(ctx, roleBinding.RoleRef, namespace, s.authorizer) { - return s.StandardStorage.Create(ctx, obj, createValidation, includeUninitialized) + return s.StandardStorage.Create(ctx, obj, createValidation, options) } v1RoleRef := rbacv1.RoleRef{} @@ -80,12 +81,12 @@ func (s *Storage) Create(ctx context.Context, obj runtime.Object, createValidati if err := rbacregistryvalidation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { return nil, errors.NewForbidden(groupResource, roleBinding.Name, err) } - return s.StandardStorage.Create(ctx, obj, createValidation, includeUninitialized) + return s.StandardStorage.Create(ctx, obj, createValidation, options) } -func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { if rbacregistry.EscalationAllowed(ctx) { - return s.StandardStorage.Update(ctx, name, obj, createValidation, updateValidation, forceAllowCreate) + return s.StandardStorage.Update(ctx, name, obj, createValidation, updateValidation, forceAllowCreate, options) } nonEscalatingInfo := rest.WrapUpdatedObjectInfo(obj, func(ctx context.Context, obj runtime.Object, oldObj runtime.Object) (runtime.Object, error) { @@ -124,5 +125,5 @@ func (s *Storage) Update(ctx context.Context, name string, obj rest.UpdatedObjec return obj, nil }) - return s.StandardStorage.Update(ctx, name, nonEscalatingInfo, createValidation, updateValidation, forceAllowCreate) + return s.StandardStorage.Update(ctx, name, nonEscalatingInfo, createValidation, updateValidation, forceAllowCreate, options) } diff --git a/pkg/registry/registrytest/endpoint.go b/pkg/registry/registrytest/endpoint.go index cc22b478e1..f2c49d6b1a 100644 --- a/pkg/registry/registrytest/endpoint.go +++ b/pkg/registry/registrytest/endpoint.go @@ -67,7 +67,7 @@ func (e *EndpointRegistry) WatchEndpoints(ctx context.Context, options *metainte return nil, fmt.Errorf("unimplemented!") } -func (e *EndpointRegistry) UpdateEndpoints(ctx context.Context, endpoints *api.Endpoints, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error { +func (e *EndpointRegistry) UpdateEndpoints(ctx context.Context, endpoints *api.Endpoints, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error { // TODO: support namespaces in this mock e.lock.Lock() defer e.lock.Unlock() diff --git a/pkg/registry/scheduling/priorityclass/registry.go b/pkg/registry/scheduling/priorityclass/registry.go index acc0012165..2c7072d0c2 100644 --- a/pkg/registry/scheduling/priorityclass/registry.go +++ b/pkg/registry/scheduling/priorityclass/registry.go @@ -29,8 +29,8 @@ import ( // Registry is an interface for things that know how to store PriorityClass. type Registry interface { ListPriorityClasses(ctx context.Context, options *metainternalversion.ListOptions) (*scheduling.PriorityClassList, error) - CreatePriorityClass(ctx context.Context, pc *scheduling.PriorityClass, createValidation rest.ValidateObjectFunc) error - UpdatePriorityClass(ctx context.Context, pc *scheduling.PriorityClass, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error + CreatePriorityClass(ctx context.Context, pc *scheduling.PriorityClass, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) error + UpdatePriorityClass(ctx context.Context, pc *scheduling.PriorityClass, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error GetPriorityClass(ctx context.Context, name string, options *metav1.GetOptions) (*scheduling.PriorityClass, error) DeletePriorityClass(ctx context.Context, name string) error WatchPriorityClasses(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) @@ -56,13 +56,13 @@ func (s *storage) ListPriorityClasses(ctx context.Context, options *metainternal return obj.(*scheduling.PriorityClassList), nil } -func (s *storage) CreatePriorityClass(ctx context.Context, pc *scheduling.PriorityClass, createValidation rest.ValidateObjectFunc) error { - _, err := s.Create(ctx, pc, createValidation, false) +func (s *storage) CreatePriorityClass(ctx context.Context, pc *scheduling.PriorityClass, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) error { + _, err := s.Create(ctx, pc, createValidation, options) return err } -func (s *storage) UpdatePriorityClass(ctx context.Context, pc *scheduling.PriorityClass, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error { - _, _, err := s.Update(ctx, pc.Name, rest.DefaultUpdatedObjectInfo(pc), createValidation, updateValidation, false) +func (s *storage) UpdatePriorityClass(ctx context.Context, pc *scheduling.PriorityClass, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error { + _, _, err := s.Update(ctx, pc.Name, rest.DefaultUpdatedObjectInfo(pc), createValidation, updateValidation, false, options) return err } diff --git a/pkg/registry/settings/podpreset/registry.go b/pkg/registry/settings/podpreset/registry.go index daf910c90f..39fc6a78ce 100644 --- a/pkg/registry/settings/podpreset/registry.go +++ b/pkg/registry/settings/podpreset/registry.go @@ -29,8 +29,8 @@ import ( // Registry is an interface for things that know how to store PodPresets. type Registry interface { ListPodPresets(ctx context.Context, options *metainternalversion.ListOptions) (*settings.PodPresetList, error) - CreatePodPreset(ctx context.Context, pp *settings.PodPreset, createValidation rest.ValidateObjectFunc) error - UpdatePodPreset(ctx context.Context, pp *settings.PodPreset, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error + CreatePodPreset(ctx context.Context, pp *settings.PodPreset, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) error + UpdatePodPreset(ctx context.Context, pp *settings.PodPreset, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error GetPodPreset(ctx context.Context, ppID string, options *metav1.GetOptions) (*settings.PodPreset, error) DeletePodPreset(ctx context.Context, ppID string) error WatchPodPresets(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) @@ -56,13 +56,13 @@ func (s *storage) ListPodPresets(ctx context.Context, options *metainternalversi return obj.(*settings.PodPresetList), nil } -func (s *storage) CreatePodPreset(ctx context.Context, pp *settings.PodPreset, createValidation rest.ValidateObjectFunc) error { - _, err := s.Create(ctx, pp, createValidation, false) +func (s *storage) CreatePodPreset(ctx context.Context, pp *settings.PodPreset, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) error { + _, err := s.Create(ctx, pp, createValidation, options) return err } -func (s *storage) UpdatePodPreset(ctx context.Context, pp *settings.PodPreset, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) error { - _, _, err := s.Update(ctx, pp.Name, rest.DefaultUpdatedObjectInfo(pp), createValidation, updateValidation, false) +func (s *storage) UpdatePodPreset(ctx context.Context, pp *settings.PodPreset, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) error { + _, _, err := s.Update(ctx, pp.Name, rest.DefaultUpdatedObjectInfo(pp), createValidation, updateValidation, false, options) return err } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go index 4c0dd4da57..3e0552f132 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go @@ -182,10 +182,10 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } type ScaleREST struct { @@ -224,7 +224,7 @@ func (r *ScaleREST) Get(ctx context.Context, name string, options *metav1.GetOpt return scaleObject, err } -func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { cr, err := r.registry.GetCustomResource(ctx, name, &metav1.GetOptions{}) if err != nil { return nil, false, err @@ -262,7 +262,7 @@ func (r *ScaleREST) Update(ctx context.Context, name string, objInfo rest.Update } cr.SetResourceVersion(scale.ResourceVersion) - cr, err = r.registry.UpdateCustomResource(ctx, cr, createValidation, updateValidation) + cr, err = r.registry.UpdateCustomResource(ctx, cr, createValidation, updateValidation, options) if err != nil { return nil, false, err } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd_test.go index 86351582db..6bb0e749ea 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd_test.go @@ -112,7 +112,7 @@ func newStorage(t *testing.T) (customresource.CustomResourceStorage, *etcdtestin // createCustomResource is a helper function that returns a CustomResource with the updated resource version. func createCustomResource(storage *customresource.REST, cr unstructured.Unstructured, t *testing.T) (unstructured.Unstructured, error) { ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), cr.GetNamespace()) - obj, err := storage.Create(ctx, &cr, rest.ValidateAllObjectFunc, false) + obj, err := storage.Create(ctx, &cr, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("Failed to create CustomResource, %v", err) } @@ -205,7 +205,7 @@ func TestGenerationNumber(t *testing.T) { // Updates to spec should increment the generation number setSpecReplicas(storedCR, getSpecReplicas(storedCR)+1) - if _, _, err := storage.CustomResource.Update(ctx, storedCR.GetName(), rest.DefaultUpdatedObjectInfo(storedCR), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.CustomResource.Update(ctx, storedCR.GetName(), rest.DefaultUpdatedObjectInfo(storedCR), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Errorf("unexpected error: %v", err) } etcdCR, err = storage.CustomResource.Get(ctx, cr.GetName(), &metav1.GetOptions{}) @@ -219,7 +219,7 @@ func TestGenerationNumber(t *testing.T) { // Updates to status should not increment the generation number setStatusReplicas(storedCR, getStatusReplicas(storedCR)+1) - if _, _, err := storage.CustomResource.Update(ctx, storedCR.GetName(), rest.DefaultUpdatedObjectInfo(storedCR), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.CustomResource.Update(ctx, storedCR.GetName(), rest.DefaultUpdatedObjectInfo(storedCR), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Errorf("unexpected error: %v", err) } etcdCR, err = storage.CustomResource.Get(ctx, cr.GetName(), &metav1.GetOptions{}) @@ -339,7 +339,7 @@ func TestStatusUpdate(t *testing.T) { "replicas": int64(7), } - if _, _, err := storage.Status.Update(ctx, update.GetName(), rest.DefaultUpdatedObjectInfo(update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Status.Update(ctx, update.GetName(), rest.DefaultUpdatedObjectInfo(update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("unexpected error: %v", err) } @@ -459,7 +459,7 @@ func TestScaleUpdate(t *testing.T) { }, } - if _, _, err := storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("error updating scale %v: %v", update, err) } @@ -475,7 +475,7 @@ func TestScaleUpdate(t *testing.T) { update.ResourceVersion = scale.ResourceVersion update.Spec.Replicas = 15 - if _, _, err = storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil && !errors.IsConflict(err) { + if _, _, err = storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil && !errors.IsConflict(err) { t.Fatalf("unexpected error, expecting an update conflict but got %v", err) } } @@ -507,7 +507,7 @@ func TestScaleUpdateWithoutSpecReplicas(t *testing.T) { }, } - if _, _, err := storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if _, _, err := storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("error updating scale %v: %v", update, err) } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/registry.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/registry.go index b377ae3cda..f722058f32 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/registry.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/registry.go @@ -36,7 +36,7 @@ type Registry interface { WatchCustomResources(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) GetCustomResource(ctx context.Context, customResourceID string, options *metav1.GetOptions) (*unstructured.Unstructured, error) CreateCustomResource(ctx context.Context, customResource *unstructured.Unstructured, createValidation rest.ValidateObjectFunc) (*unstructured.Unstructured, error) - UpdateCustomResource(ctx context.Context, customResource *unstructured.Unstructured, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*unstructured.Unstructured, error) + UpdateCustomResource(ctx context.Context, customResource *unstructured.Unstructured, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) (*unstructured.Unstructured, error) DeleteCustomResource(ctx context.Context, customResourceID string) error } @@ -83,15 +83,15 @@ func (s *storage) GetCustomResource(ctx context.Context, customResourceID string } func (s *storage) CreateCustomResource(ctx context.Context, customResource *unstructured.Unstructured, createValidation rest.ValidateObjectFunc) (*unstructured.Unstructured, error) { - obj, err := s.Create(ctx, customResource, rest.ValidateAllObjectFunc, false) + obj, err := s.Create(ctx, customResource, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { return nil, err } return obj.(*unstructured.Unstructured), nil } -func (s *storage) UpdateCustomResource(ctx context.Context, customResource *unstructured.Unstructured, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*unstructured.Unstructured, error) { - obj, _, err := s.Update(ctx, customResource.GetName(), rest.DefaultUpdatedObjectInfo(customResource), createValidation, updateValidation, false) +func (s *storage) UpdateCustomResource(ctx context.Context, customResource *unstructured.Unstructured, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, options *metav1.UpdateOptions) (*unstructured.Unstructured, error) { + obj, _, err := s.Update(ctx, customResource.GetName(), rest.DefaultUpdatedObjectInfo(customResource), createValidation, updateValidation, false, options) if err != nil { return nil, err } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/etcd.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/etcd.go index 194647e23d..e152e8a507 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/etcd.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/etcd.go @@ -172,8 +172,8 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/register.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/register.go index 78b8a83faf..1d8878b784 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/register.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/register.go @@ -80,6 +80,8 @@ func addToGroupVersion(scheme *runtime.Scheme, groupVersion schema.GroupVersion) &metav1.GetOptions{}, &metav1.ExportOptions{}, &metav1.DeleteOptions{}, + &metav1.CreateOptions{}, + &metav1.UpdateOptions{}, ) scheme.AddKnownTypes(SchemeGroupVersion, &metav1beta1.Table{}, @@ -94,7 +96,10 @@ func addToGroupVersion(scheme *runtime.Scheme, groupVersion schema.GroupVersion) &metav1beta1.PartialObjectMetadataList{}, ) // Allow delete options to be decoded across all version in this scheme (we may want to be more clever than this) - scheme.AddUnversionedTypes(SchemeGroupVersion, &metav1.DeleteOptions{}) + scheme.AddUnversionedTypes(SchemeGroupVersion, + &metav1.DeleteOptions{}, + &metav1.CreateOptions{}, + &metav1.UpdateOptions{}) metav1.AddToGroupVersion(scheme, metav1.SchemeGroupVersion) return nil } diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/register.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/register.go index 9b8cc97741..e80bc93b04 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/register.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/register.go @@ -53,6 +53,8 @@ func AddToGroupVersion(scheme *runtime.Scheme, groupVersion schema.GroupVersion) &ExportOptions{}, &GetOptions{}, &DeleteOptions{}, + &CreateOptions{}, + &UpdateOptions{}, ) utilruntime.Must(scheme.AddConversionFuncs( Convert_versioned_Event_to_watch_Event, @@ -86,6 +88,8 @@ func init() { &ExportOptions{}, &GetOptions{}, &DeleteOptions{}, + &CreateOptions{}, + &UpdateOptions{}, ) // register manually. This usually goes through the SchemeBuilder, which we cannot use here. diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go index e93df18461..91a7c8bb43 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go @@ -453,6 +453,45 @@ type DeleteOptions struct { // foreground. // +optional PropagationPolicy *DeletionPropagation `json:"propagationPolicy,omitempty" protobuf:"varint,4,opt,name=propagationPolicy"` + + // When present, indicates that modifications should not be + // persisted. An invalid or unrecognized dryRun directive will + // result in a BadRequest response and no further processing of + // the request. + // +optional + DryRun []string `json:"dryRun,omitempty" protobuf:"bytes,5,rep,name=dryRun"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CreateOptions may be provided when creating an API object. +type CreateOptions struct { + TypeMeta `json:",inline"` + + // When present, indicates that modifications should not be + // persisted. An invalid or unrecognized dryRun directive will + // result in a BadRequest response and no further processing of + // the request. + // +optional + DryRun []string `json:"dryRun,omitempty" protobuf:"bytes,1,rep,name=dryRun"` + + // If IncludeUninitialized is specified, the object may be + // returned without completing initialization. + IncludeUninitialized bool `json:"includeUninitialized,omitempty" protobuf:"varint,2,opt,name=includeUninitialized"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// UpdateOptions may be provided when updating an API object. +type UpdateOptions struct { + TypeMeta `json:",inline"` + + // When present, indicates that modifications should not be + // persisted. An invalid or unrecognized dryRun directive will + // result in a BadRequest response and no further processing of + // the request. + // +optional + DryRun []string `json:"dryRun,omitempty" protobuf:"bytes,1,rep,name=dryRun"` } // Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out. diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go index 2b3f56d13f..30b55eb929 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go @@ -461,7 +461,7 @@ func (storage *SimpleRESTStorage) NewList() runtime.Object { return &genericapitesting.SimpleList{} } -func (storage *SimpleRESTStorage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (storage *SimpleRESTStorage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { storage.checkContext(ctx) storage.created = obj.(*genericapitesting.Simple) if err := storage.errors["create"]; err != nil { @@ -477,7 +477,7 @@ func (storage *SimpleRESTStorage) Create(ctx context.Context, obj runtime.Object return obj, err } -func (storage *SimpleRESTStorage) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (storage *SimpleRESTStorage) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { storage.checkContext(ctx) obj, err := objInfo.UpdatedObject(ctx, &storage.item) if err != nil { @@ -646,7 +646,7 @@ type NamedCreaterRESTStorage struct { createdName string } -func (storage *NamedCreaterRESTStorage) Create(ctx context.Context, name string, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (storage *NamedCreaterRESTStorage) Create(ctx context.Context, name string, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { storage.checkContext(ctx) storage.created = obj.(*genericapitesting.Simple) storage.createdName = name @@ -3616,6 +3616,7 @@ func TestCreateInvokeAdmissionControl(t *testing.T) { } func expectApiStatus(t *testing.T, method, url string, data []byte, code int) *metav1.Status { + t.Helper() client := http.Client{} request, err := http.NewRequest(method, url, bytes.NewBuffer(data)) if err != nil { @@ -3628,12 +3629,13 @@ func expectApiStatus(t *testing.T, method, url string, data []byte, code int) *m return nil } var status metav1.Status - if body, err := extractBody(response, &status); err != nil { + body, err := extractBody(response, &status) + if err != nil { t.Fatalf("unexpected error on %s %s: %v\nbody:\n%s", method, url, err, body) return nil } if code != response.StatusCode { - t.Fatalf("Expected %s %s to return %d, Got %d", method, url, code, response.StatusCode) + t.Fatalf("Expected %s %s to return %d, Got %d: %v", method, url, code, response.StatusCode, body) } return &status } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go index 5427600782..9ce7392cf6 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go @@ -24,6 +24,7 @@ import ( "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" + metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -80,6 +81,15 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte return } + options := &metav1.CreateOptions{} + values := req.URL.Query() + // TODO: replace with content type negotiation? + if err := metainternalversion.ParameterCodec.DecodeParameters(values, scope.MetaGroupVersion, options); err != nil { + err = errors.NewBadRequest(err.Error()) + scope.err(err, w, req) + return + } + defaultGVK := scope.Kind original := r.New() trace.Step("About to convert to expected version") @@ -110,9 +120,6 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte } } - // TODO: replace with content type negotiation? - includeUninitialized := req.URL.Query().Get("includeUninitialized") == "1" - trace.Step("About to store object in database") result, err := finishRequest(timeout, func() (runtime.Object, error) { return r.Create( @@ -120,7 +127,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte name, obj, rest.AdmissionToValidateObjectFunc(admit, admissionAttributes), - includeUninitialized, + options, ) }) if err != nil { @@ -170,6 +177,6 @@ type namedCreaterAdapter struct { rest.Creater } -func (c *namedCreaterAdapter) Create(ctx context.Context, name string, obj runtime.Object, createValidatingAdmission rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { - return c.Creater.Create(ctx, obj, createValidatingAdmission, includeUninitialized) +func (c *namedCreaterAdapter) Create(ctx context.Context, name string, obj runtime.Object, createValidatingAdmission rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { + return c.Creater.Create(ctx, obj, createValidatingAdmission, options) } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go index b7f7341d6c..6afba30366 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go @@ -90,12 +90,10 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco audit.LogRequestObject(ae, obj, scope.Resource, scope.Subresource, scope.Serializer) trace.Step("Recorded the audit event") } else { - if values := req.URL.Query(); len(values) > 0 { - if err := metainternalversion.ParameterCodec.DecodeParameters(values, scope.MetaGroupVersion, options); err != nil { - err = errors.NewBadRequest(err.Error()) - scope.err(err, w, req) - return - } + if err := metainternalversion.ParameterCodec.DecodeParameters(req.URL.Query(), scope.MetaGroupVersion, options); err != nil { + err = errors.NewBadRequest(err.Error()) + scope.err(err, w, req) + return } } } @@ -260,6 +258,12 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco ae := request.AuditEventFrom(ctx) audit.LogRequestObject(ae, obj, scope.Resource, scope.Subresource, scope.Serializer) + } else { + if err := metainternalversion.ParameterCodec.DecodeParameters(req.URL.Query(), scope.MetaGroupVersion, options); err != nil { + err = errors.NewBadRequest(err.Error()) + scope.err(err, w, req) + return + } } } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go index ed58449d59..c68c9fcb93 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go @@ -26,6 +26,8 @@ import ( "github.com/evanphx/json-patch" "k8s.io/apimachinery/pkg/api/errors" + metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" @@ -88,6 +90,13 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface return } + options := &metav1.UpdateOptions{} + if err := metainternalversion.ParameterCodec.DecodeParameters(req.URL.Query(), scope.MetaGroupVersion, options); err != nil { + err = errors.NewBadRequest(err.Error()) + scope.err(err, w, req) + return + } + ae := request.AuditEventFrom(ctx) admit = admission.WithAudit(admit, ae) @@ -106,10 +115,30 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface ) userInfo, _ := request.UserFrom(ctx) - staticAdmissionAttributes := admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, userInfo) + staticAdmissionAttributes := admission.NewAttributesRecord( + nil, + nil, + scope.Kind, + namespace, + name, + scope.Resource, + scope.Subresource, + admission.Update, + userInfo, + ) admissionCheck := func(updatedObject runtime.Object, currentObject runtime.Object) error { if mutatingAdmission, ok := admit.(admission.MutationInterface); ok && admit.Handles(admission.Update) { - return mutatingAdmission.Admit(admission.NewAttributesRecord(updatedObject, currentObject, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, userInfo)) + return mutatingAdmission.Admit(admission.NewAttributesRecord( + updatedObject, + currentObject, + scope.Kind, + namespace, + name, + scope.Resource, + scope.Subresource, + admission.Update, + userInfo, + )) } return nil } @@ -129,6 +158,7 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface codec: codec, timeout: timeout, + options: options, restPatcher: r, name: name, @@ -184,6 +214,7 @@ type patcher struct { codec runtime.Codec timeout time.Duration + options *metav1.UpdateOptions // Operation information restPatcher rest.Patcher @@ -356,7 +387,7 @@ func (p *patcher) patchResource(ctx context.Context) (runtime.Object, error) { } p.updatedObjectInfo = rest.DefaultUpdatedObjectInfo(nil, p.applyPatch, p.applyAdmission) return finishRequest(p.timeout, func() (runtime.Object, error) { - updateObject, _, updateErr := p.restPatcher.Update(ctx, p.name, p.updatedObjectInfo, p.createValidation, p.updateValidation, false) + updateObject, _, updateErr := p.restPatcher.Update(ctx, p.name, p.updatedObjectInfo, p.createValidation, p.updateValidation, false, p.options) return updateObject, updateErr }) } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go index 6af1392389..cd4c0b6810 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go @@ -173,7 +173,7 @@ func (p *testPatcher) New() runtime.Object { return &example.Pod{} } -func (p *testPatcher) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (p *testPatcher) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // Simulate GuaranteedUpdate behavior (retries internally on etcd changes if the incoming resource doesn't pin resourceVersion) for { currentPod := p.startingPod diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go index ac318f2764..1b4037e6d0 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go @@ -24,6 +24,8 @@ import ( "time" "k8s.io/apimachinery/pkg/api/errors" + metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/admission" @@ -64,6 +66,13 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac return } + options := &metav1.UpdateOptions{} + if err := metainternalversion.ParameterCodec.DecodeParameters(req.URL.Query(), scope.MetaGroupVersion, options); err != nil { + err = errors.NewBadRequest(err.Error()) + scope.err(err, w, req) + return + } + s, err := negotiation.NegotiateInputSerializer(req, false, scope.Serializer) if err != nil { scope.err(err, w, req) @@ -127,6 +136,7 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac withAuthorization(rest.AdmissionToValidateObjectFunc(admit, staticAdmissionAttributes), scope.Authorizer, createAuthorizerAttributes), rest.AdmissionToValidateObjectUpdateFunc(admit, staticAdmissionAttributes), false, + options, ) wasCreated = created return obj, err diff --git a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go index e609f974c8..358da7de5c 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go @@ -322,7 +322,7 @@ func (e *Store) ListPredicate(ctx context.Context, p storage.SelectionPredicate, } // Create inserts a new item according to the unique key from the object. -func (e *Store) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) { +func (e *Store) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { if err := rest.BeforeCreate(e.CreateStrategy, ctx, obj); err != nil { return nil, err } @@ -377,7 +377,7 @@ func (e *Store) Create(ctx context.Context, obj runtime.Object, createValidation return nil, err } } - if !includeUninitialized { + if !options.IncludeUninitialized { return e.WaitForInitialized(ctx, out) } return out, nil @@ -522,7 +522,7 @@ func (e *Store) deleteWithoutFinalizers(ctx context.Context, name, key string, o // Update performs an atomic update and set of the object. Returns the result of the update // or an error. If the registry allows create-on-update, the create flow will be executed. // A bool is returned along with the object and any errors, to indicate object creation. -func (e *Store) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (e *Store) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { key, err := e.KeyFunc(ctx, name) if err != nil { return nil, false, err diff --git a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store_test.go b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store_test.go index b6119149c8..76310225a3 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store_test.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store_test.go @@ -248,7 +248,7 @@ func TestStoreListResourceVersion(t *testing.T) { destroyFunc, registry := newTestGenericStoreRegistry(t, scheme, true) defer destroyFunc() - obj, err := registry.Create(ctx, fooPod, rest.ValidateAllObjectFunc, false) + obj, err := registry.Create(ctx, fooPod, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatal(err) } @@ -278,7 +278,7 @@ func TestStoreListResourceVersion(t *testing.T) { t.Fatalf("expected waiting, but get %#v", l) } - if _, err := registry.Create(ctx, barPod, rest.ValidateAllObjectFunc, false); err != nil { + if _, err := registry.Create(ctx, barPod, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil { t.Fatal(err) } @@ -320,13 +320,13 @@ func TestStoreCreate(t *testing.T) { } // create the object with denying admission - objA, err := registry.Create(testContext, podA, denyCreateValidation, false) + objA, err := registry.Create(testContext, podA, denyCreateValidation, &metav1.CreateOptions{}) if err == nil { t.Errorf("Expected admission error: %v", err) } // create the object - objA, err = registry.Create(testContext, podA, rest.ValidateAllObjectFunc, false) + objA, err = registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -348,7 +348,7 @@ func TestStoreCreate(t *testing.T) { } // now try to create the second pod - _, err = registry.Create(testContext, podB, rest.ValidateAllObjectFunc, false) + _, err = registry.Create(testContext, podB, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if !errors.IsAlreadyExists(err) { t.Errorf("Unexpected error: %v", err) } @@ -367,7 +367,7 @@ func TestStoreCreate(t *testing.T) { } // try to create before graceful deletion period is over - _, err = registry.Create(testContext, podA, rest.ValidateAllObjectFunc, false) + _, err = registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err == nil || !errors.IsAlreadyExists(err) { t.Fatalf("Expected 'already exists' error from storage, but got %v", err) } @@ -459,7 +459,7 @@ func TestStoreCreateInitialized(t *testing.T) { } pod.Initializers = nil - updated, _, err := registry.Update(ctx, podA.Name, rest.DefaultUpdatedObjectInfo(pod), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + updated, _, err := registry.Update(ctx, podA.Name, rest.DefaultUpdatedObjectInfo(pod), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Fatal(err) } @@ -495,7 +495,7 @@ func TestStoreCreateInitialized(t *testing.T) { }() // create the object - objA, err := registry.Create(ctx, podA, rest.ValidateAllObjectFunc, false) + objA, err := registry.Create(ctx, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -552,7 +552,7 @@ func TestStoreCreateInitializedFailed(t *testing.T) { } pod.Initializers.Pending = nil pod.Initializers.Result = &metav1.Status{Status: metav1.StatusFailure, Code: 403, Reason: metav1.StatusReasonForbidden, Message: "induced failure"} - updated, _, err := registry.Update(ctx, podA.Name, rest.DefaultUpdatedObjectInfo(pod), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + updated, _, err := registry.Update(ctx, podA.Name, rest.DefaultUpdatedObjectInfo(pod), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Fatal(err) } @@ -575,7 +575,7 @@ func TestStoreCreateInitializedFailed(t *testing.T) { }() // create the object - _, err := registry.Create(ctx, podA, rest.ValidateAllObjectFunc, false) + _, err := registry.Create(ctx, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if !errors.IsForbidden(err) { t.Fatalf("unexpected error: %#v", err.(errors.APIStatus).Status()) } @@ -593,7 +593,7 @@ func TestStoreCreateInitializedFailed(t *testing.T) { } func updateAndVerify(t *testing.T, ctx context.Context, registry *Store, pod *example.Pod) bool { - obj, _, err := registry.Update(ctx, pod.Name, rest.DefaultUpdatedObjectInfo(pod), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + obj, _, err := registry.Update(ctx, pod.Name, rest.DefaultUpdatedObjectInfo(pod), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) return false @@ -629,13 +629,13 @@ func TestStoreUpdate(t *testing.T) { defer destroyFunc() // try to update a non-existing node with denying admission, should still return NotFound - _, _, err := registry.Update(testContext, podA.Name, rest.DefaultUpdatedObjectInfo(podA), denyCreateValidation, denyUpdateValidation, false) + _, _, err := registry.Update(testContext, podA.Name, rest.DefaultUpdatedObjectInfo(podA), denyCreateValidation, denyUpdateValidation, false, &metav1.UpdateOptions{}) if !errors.IsNotFound(err) { t.Errorf("Unexpected error: %v", err) } // try to update a non-existing node - _, _, err = registry.Update(testContext, podA.Name, rest.DefaultUpdatedObjectInfo(podA), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = registry.Update(testContext, podA.Name, rest.DefaultUpdatedObjectInfo(podA), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if !errors.IsNotFound(err) { t.Errorf("Unexpected error: %v", err) } @@ -644,7 +644,7 @@ func TestStoreUpdate(t *testing.T) { registry.UpdateStrategy.(*testRESTStrategy).allowCreateOnUpdate = true // createIfNotFound with denying create admission - _, _, err = registry.Update(testContext, podA.Name, rest.DefaultUpdatedObjectInfo(podA), denyCreateValidation, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = registry.Update(testContext, podA.Name, rest.DefaultUpdatedObjectInfo(podA), denyCreateValidation, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err == nil { t.Errorf("expected admission error on create") } @@ -658,13 +658,13 @@ func TestStoreUpdate(t *testing.T) { registry.UpdateStrategy.(*testRESTStrategy).allowCreateOnUpdate = false // outofDate - _, _, err = registry.Update(testContext, podAWithResourceVersion.Name, rest.DefaultUpdatedObjectInfo(podAWithResourceVersion), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = registry.Update(testContext, podAWithResourceVersion.Name, rest.DefaultUpdatedObjectInfo(podAWithResourceVersion), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if !errors.IsConflict(err) { t.Errorf("Unexpected error updating podAWithResourceVersion: %v", err) } // try to update with denying admission - _, _, err = registry.Update(testContext, podA.Name, rest.DefaultUpdatedObjectInfo(podA), rest.ValidateAllObjectFunc, denyUpdateValidation, false) + _, _, err = registry.Update(testContext, podA.Name, rest.DefaultUpdatedObjectInfo(podA), rest.ValidateAllObjectFunc, denyUpdateValidation, false, &metav1.UpdateOptions{}) if err == nil { t.Errorf("expected admission error on update") } @@ -701,7 +701,7 @@ func TestNoOpUpdates(t *testing.T) { var err error var createResult runtime.Object - if createResult, err = registry.Create(genericapirequest.NewDefaultContext(), newPod(), rest.ValidateAllObjectFunc, false); err != nil { + if createResult, err = registry.Create(genericapirequest.NewDefaultContext(), newPod(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -712,7 +712,7 @@ func TestNoOpUpdates(t *testing.T) { var updateResult runtime.Object p := newPod() - if updateResult, _, err = registry.Update(genericapirequest.NewDefaultContext(), p.Name, rest.DefaultUpdatedObjectInfo(p), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false); err != nil { + if updateResult, _, err = registry.Update(genericapirequest.NewDefaultContext(), p.Name, rest.DefaultUpdatedObjectInfo(p), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -876,7 +876,7 @@ func TestStoreDelete(t *testing.T) { } // create pod - _, err = registry.Create(testContext, podA, rest.ValidateAllObjectFunc, false) + _, err = registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -914,7 +914,7 @@ func TestStoreDeleteUninitialized(t *testing.T) { } // create pod - _, err = registry.Create(testContext, podA, rest.ValidateAllObjectFunc, true) + _, err = registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{IncludeUninitialized: true}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -991,7 +991,7 @@ func TestGracefulStoreHandleFinalizers(t *testing.T) { registry.EnableGarbageCollection = gcEnabled // create pod - _, err := registry.Create(testContext, podWithFinalizer, rest.ValidateAllObjectFunc, false) + _, err := registry.Create(testContext, podWithFinalizer, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -1013,7 +1013,7 @@ func TestGracefulStoreHandleFinalizers(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "foo", Finalizers: []string{"foo.com/x"}, ResourceVersion: podWithFinalizer.ObjectMeta.ResourceVersion}, Spec: example.PodSpec{NodeName: "machine"}, } - _, _, err = registry.Update(testContext, updatedPodWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(updatedPodWithFinalizer), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = registry.Update(testContext, updatedPodWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(updatedPodWithFinalizer), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -1028,7 +1028,7 @@ func TestGracefulStoreHandleFinalizers(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: podWithFinalizer.ObjectMeta.ResourceVersion}, Spec: example.PodSpec{NodeName: "anothermachine"}, } - _, _, err = registry.Update(testContext, podWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(podWithNoFinalizer), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = registry.Update(testContext, podWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(podWithNoFinalizer), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -1057,7 +1057,7 @@ func TestFailedInitializationStoreUpdate(t *testing.T) { defer destroyFunc() // create pod, view initializing - obj, err := registry.Create(testContext, podInitializing, rest.ValidateAllObjectFunc, true) + obj, err := registry.Create(testContext, podInitializing, rest.ValidateAllObjectFunc, &metav1.CreateOptions{IncludeUninitialized: true}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -1065,7 +1065,7 @@ func TestFailedInitializationStoreUpdate(t *testing.T) { // update the pod with initialization failure, the pod should be deleted pod.Initializers.Result = &metav1.Status{Status: metav1.StatusFailure} - result, _, err := registry.Update(testContext, podInitializing.Name, rest.DefaultUpdatedObjectInfo(pod), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + result, _, err := registry.Update(testContext, podInitializing.Name, rest.DefaultUpdatedObjectInfo(pod), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -1096,7 +1096,7 @@ func TestNonGracefulStoreHandleFinalizers(t *testing.T) { registry.EnableGarbageCollection = gcEnabled // create pod - _, err := registry.Create(testContext, podWithFinalizer, rest.ValidateAllObjectFunc, false) + _, err := registry.Create(testContext, podWithFinalizer, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -1133,7 +1133,7 @@ func TestNonGracefulStoreHandleFinalizers(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "foo", Finalizers: []string{"foo.com/x"}, ResourceVersion: podWithFinalizer.ObjectMeta.ResourceVersion}, Spec: example.PodSpec{NodeName: "machine"}, } - _, _, err = registry.Update(testContext, updatedPodWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(updatedPodWithFinalizer), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = registry.Update(testContext, updatedPodWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(updatedPodWithFinalizer), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -1152,7 +1152,7 @@ func TestNonGracefulStoreHandleFinalizers(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: podWithFinalizer.ObjectMeta.ResourceVersion}, Spec: example.PodSpec{NodeName: "anothermachine"}, } - _, _, err = registry.Update(testContext, podWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(podWithNoFinalizer), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = registry.Update(testContext, podWithFinalizer.ObjectMeta.Name, rest.DefaultUpdatedObjectInfo(podWithNoFinalizer), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -1398,7 +1398,7 @@ func TestStoreDeleteWithOrphanDependents(t *testing.T) { for _, tc := range testcases { registry.DeleteStrategy = tc.strategy // create pod - _, err := registry.Create(testContext, tc.pod, rest.ValidateAllObjectFunc, false) + _, err := registry.Create(testContext, tc.pod, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -1617,7 +1617,7 @@ func TestStoreDeletionPropagation(t *testing.T) { i++ pod := createPod(i, tc.existingFinalizers) // create pod - _, err := registry.Create(testContext, pod, rest.ValidateAllObjectFunc, false) + _, err := registry.Create(testContext, pod, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -1669,13 +1669,13 @@ func TestStoreDeleteCollection(t *testing.T) { destroyFunc, registry := NewTestGenericStoreRegistry(t) defer destroyFunc() - if _, err := registry.Create(testContext, podA, rest.ValidateAllObjectFunc, false); err != nil { + if _, err := registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil { t.Errorf("Unexpected error: %v", err) } - if _, err := registry.Create(testContext, podB, rest.ValidateAllObjectFunc, false); err != nil { + if _, err := registry.Create(testContext, podB, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil { t.Errorf("Unexpected error: %v", err) } - if _, err := registry.Create(testContext, podC, rest.ValidateAllObjectFunc, true); err != nil { + if _, err := registry.Create(testContext, podC, rest.ValidateAllObjectFunc, &metav1.CreateOptions{IncludeUninitialized: true}); err != nil { t.Errorf("Unexpected error: %v", err) } @@ -1711,10 +1711,10 @@ func TestStoreDeleteCollectionNotFound(t *testing.T) { for i := 0; i < 10; i++ { // Setup - if _, err := registry.Create(testContext, podA, rest.ValidateAllObjectFunc, false); err != nil { + if _, err := registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil { t.Errorf("Unexpected error: %v", err) } - if _, err := registry.Create(testContext, podB, rest.ValidateAllObjectFunc, false); err != nil { + if _, err := registry.Create(testContext, podB, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil { t.Errorf("Unexpected error: %v", err) } @@ -1750,7 +1750,7 @@ func TestStoreDeleteCollectionWithWatch(t *testing.T) { destroyFunc, registry := NewTestGenericStoreRegistry(t) defer destroyFunc() - objCreated, err := registry.Create(testContext, podA, rest.ValidateAllObjectFunc, false) + objCreated, err := registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -1819,7 +1819,7 @@ func TestStoreWatch(t *testing.T) { if err != nil { t.Errorf("%v: unexpected error: %v", name, err) } else { - obj, err := registry.Create(testContext, podA, rest.ValidateAllObjectFunc, false) + obj, err := registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { got, open := <-wi.ResultChan() if !open { @@ -1963,7 +1963,7 @@ func TestQualifiedResource(t *testing.T) { defer destroyFunc() // update a non-exist object - _, _, err := registry.Update(testContext, podA.Name, rest.DefaultUpdatedObjectInfo(podA), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err := registry.Update(testContext, podA.Name, rest.DefaultUpdatedObjectInfo(podA), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if !errors.IsNotFound(err) { t.Fatalf("Unexpected error: %v", err) } @@ -1995,13 +1995,13 @@ func TestQualifiedResource(t *testing.T) { } // create a non-exist object - _, err = registry.Create(testContext, podA, rest.ValidateAllObjectFunc, false) + _, err = registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatal(err) } // create a exist object will fail - _, err = registry.Create(testContext, podA, rest.ValidateAllObjectFunc, false) + _, err = registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if !errors.IsAlreadyExists(err) { t.Fatalf("Unexpected error: %v", err) } diff --git a/staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go b/staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go index cbfe07b280..d3d1b2f8bc 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go @@ -178,7 +178,7 @@ type Creater interface { // Create creates a new version of a resource. If includeUninitialized is set, the object may be returned // without completing initialization. - Create(ctx context.Context, obj runtime.Object, createValidation ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) + Create(ctx context.Context, obj runtime.Object, createValidation ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) } // NamedCreater is an object that can create an instance of a RESTful object using a name parameter. @@ -191,7 +191,7 @@ type NamedCreater interface { // This is needed for create operations on subresources which include the name of the parent // resource in the path. If includeUninitialized is set, the object may be returned without // completing initialization. - Create(ctx context.Context, name string, obj runtime.Object, createValidation ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) + Create(ctx context.Context, name string, obj runtime.Object, createValidation ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) } // UpdatedObjectInfo provides information about an updated object to an Updater. @@ -236,14 +236,14 @@ type Updater interface { // Update finds a resource in the storage and updates it. Some implementations // may allow updates creates the object - they should set the created boolean // to true. - Update(ctx context.Context, name string, objInfo UpdatedObjectInfo, createValidation ValidateObjectFunc, updateValidation ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) + Update(ctx context.Context, name string, objInfo UpdatedObjectInfo, createValidation ValidateObjectFunc, updateValidation ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) } // CreaterUpdater is a storage object that must support both create and update. // Go prevents embedded interfaces that implement the same method. type CreaterUpdater interface { Creater - Update(ctx context.Context, name string, objInfo UpdatedObjectInfo, createValidation ValidateObjectFunc, updateValidation ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) + Update(ctx context.Context, name string, objInfo UpdatedObjectInfo, createValidation ValidateObjectFunc, updateValidation ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) } // CreaterUpdater must satisfy the Updater interface. diff --git a/staging/src/k8s.io/apiserver/pkg/registry/rest/resttest/resttest.go b/staging/src/k8s.io/apiserver/pkg/registry/rest/resttest/resttest.go index e222abd829..778123fb62 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/rest/resttest/resttest.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/rest/resttest/resttest.go @@ -243,7 +243,7 @@ func (t *Tester) testCreateAlreadyExisting(obj runtime.Object, createFn CreateFu } defer t.delete(ctx, foo) - _, err := t.storage.(rest.Creater).Create(ctx, foo, rest.ValidateAllObjectFunc, false) + _, err := t.storage.(rest.Creater).Create(ctx, foo, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if !errors.IsAlreadyExists(err) { t.Errorf("expected already exists err, got %v", err) } @@ -255,7 +255,7 @@ func (t *Tester) testCreateEquals(obj runtime.Object, getFn GetFunc) { foo := obj.DeepCopyObject() t.setObjectMeta(foo, t.namer(2)) - created, err := t.storage.(rest.Creater).Create(ctx, foo, rest.ValidateAllObjectFunc, false) + created, err := t.storage.(rest.Creater).Create(ctx, foo, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -283,7 +283,7 @@ func (t *Tester) testCreateDiscardsObjectNamespace(valid runtime.Object) { objectMeta.SetNamespace("not-default") // Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted - created, err := t.storage.(rest.Creater).Create(t.TestContext(), valid.DeepCopyObject(), rest.ValidateAllObjectFunc, false) + created, err := t.storage.(rest.Creater).Create(t.TestContext(), valid.DeepCopyObject(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -299,7 +299,7 @@ func (t *Tester) testCreateGeneratesName(valid runtime.Object) { objectMeta.SetName("") objectMeta.SetGenerateName("test-") - created, err := t.storage.(rest.Creater).Create(t.TestContext(), valid, rest.ValidateAllObjectFunc, false) + created, err := t.storage.(rest.Creater).Create(t.TestContext(), valid, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -314,7 +314,7 @@ func (t *Tester) testCreateHasMetadata(valid runtime.Object) { objectMeta.SetName(t.namer(1)) objectMeta.SetNamespace(t.TestNamespace()) - obj, err := t.storage.(rest.Creater).Create(t.TestContext(), valid, rest.ValidateAllObjectFunc, false) + obj, err := t.storage.(rest.Creater).Create(t.TestContext(), valid, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -332,7 +332,7 @@ func (t *Tester) testCreateIgnoresContextNamespace(valid runtime.Object) { ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), "not-default2") // Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted - created, err := t.storage.(rest.Creater).Create(ctx, valid.DeepCopyObject(), rest.ValidateAllObjectFunc, false) + created, err := t.storage.(rest.Creater).Create(ctx, valid.DeepCopyObject(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -351,7 +351,7 @@ func (t *Tester) testCreateIgnoresMismatchedNamespace(valid runtime.Object) { ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), "not-default2") // Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted - created, err := t.storage.(rest.Creater).Create(ctx, valid.DeepCopyObject(), rest.ValidateAllObjectFunc, false) + created, err := t.storage.(rest.Creater).Create(ctx, valid.DeepCopyObject(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -369,7 +369,7 @@ func (t *Tester) testCreateValidatesNames(valid runtime.Object) { objCopyMeta.SetName(invalidName) ctx := t.TestContext() - _, err := t.storage.(rest.Creater).Create(ctx, objCopy, rest.ValidateAllObjectFunc, false) + _, err := t.storage.(rest.Creater).Create(ctx, objCopy, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if !errors.IsInvalid(err) { t.Errorf("%s: Expected to get an invalid resource error, got '%v'", invalidName, err) } @@ -381,7 +381,7 @@ func (t *Tester) testCreateValidatesNames(valid runtime.Object) { objCopyMeta.SetName(objCopyMeta.GetName() + invalidSuffix) ctx := t.TestContext() - _, err := t.storage.(rest.Creater).Create(ctx, objCopy, rest.ValidateAllObjectFunc, false) + _, err := t.storage.(rest.Creater).Create(ctx, objCopy, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if !errors.IsInvalid(err) { t.Errorf("%s: Expected to get an invalid resource error, got '%v'", invalidSuffix, err) } @@ -391,7 +391,7 @@ func (t *Tester) testCreateValidatesNames(valid runtime.Object) { func (t *Tester) testCreateInvokesValidation(invalid ...runtime.Object) { for i, obj := range invalid { ctx := t.TestContext() - _, err := t.storage.(rest.Creater).Create(ctx, obj, rest.ValidateAllObjectFunc, false) + _, err := t.storage.(rest.Creater).Create(ctx, obj, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if !errors.IsInvalid(err) { t.Errorf("%d: Expected to get an invalid resource error, got %v", i, err) } @@ -402,7 +402,7 @@ func (t *Tester) testCreateRejectsMismatchedNamespace(valid runtime.Object) { objectMeta := t.getObjectMetaOrFail(valid) objectMeta.SetNamespace("not-default") - _, err := t.storage.(rest.Creater).Create(t.TestContext(), valid, rest.ValidateAllObjectFunc, false) + _, err := t.storage.(rest.Creater).Create(t.TestContext(), valid, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err == nil { t.Errorf("Expected an error, but we didn't get one") } else if !strings.Contains(err.Error(), "does not match the namespace sent on the request") { @@ -416,7 +416,7 @@ func (t *Tester) testCreateResetsUserData(valid runtime.Object) { objectMeta.SetUID("bad-uid") objectMeta.SetCreationTimestamp(now) - obj, err := t.storage.(rest.Creater).Create(t.TestContext(), valid, rest.ValidateAllObjectFunc, false) + obj, err := t.storage.(rest.Creater).Create(t.TestContext(), valid, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -434,7 +434,7 @@ func (t *Tester) testCreateIgnoreClusterName(valid runtime.Object) { objectMeta.SetName(t.namer(3)) objectMeta.SetClusterName("clustername-to-ignore") - obj, err := t.storage.(rest.Creater).Create(t.TestContext(), valid.DeepCopyObject(), rest.ValidateAllObjectFunc, false) + obj, err := t.storage.(rest.Creater).Create(t.TestContext(), valid.DeepCopyObject(), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -463,7 +463,7 @@ func (t *Tester) testUpdateEquals(obj runtime.Object, createFn CreateFunc, getFn } toUpdate = updateFn(toUpdate) toUpdateMeta := t.getObjectMetaOrFail(toUpdate) - updated, created, err := t.storage.(rest.Updater).Update(ctx, toUpdateMeta.GetName(), rest.DefaultUpdatedObjectInfo(toUpdate), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + updated, created, err := t.storage.(rest.Updater).Update(ctx, toUpdateMeta.GetName(), rest.DefaultUpdatedObjectInfo(toUpdate), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -503,7 +503,7 @@ func (t *Tester) testUpdateFailsOnVersionTooOld(obj runtime.Object, createFn Cre olderMeta := t.getObjectMetaOrFail(older) olderMeta.SetResourceVersion("1") - _, _, err = t.storage.(rest.Updater).Update(t.TestContext(), olderMeta.GetName(), rest.DefaultUpdatedObjectInfo(older), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = t.storage.(rest.Updater).Update(t.TestContext(), olderMeta.GetName(), rest.DefaultUpdatedObjectInfo(older), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err == nil { t.Errorf("Expected an error, but we didn't get one") } else if !errors.IsConflict(err) { @@ -523,7 +523,7 @@ func (t *Tester) testUpdateInvokesValidation(obj runtime.Object, createFn Create for _, update := range invalidUpdateFn { toUpdate := update(foo.DeepCopyObject()) toUpdateMeta := t.getObjectMetaOrFail(toUpdate) - got, created, err := t.storage.(rest.Updater).Update(t.TestContext(), toUpdateMeta.GetName(), rest.DefaultUpdatedObjectInfo(toUpdate), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + got, created, err := t.storage.(rest.Updater).Update(t.TestContext(), toUpdateMeta.GetName(), rest.DefaultUpdatedObjectInfo(toUpdate), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if got != nil || created { t.Errorf("expected nil object and no creation for object: %v", toUpdate) } @@ -544,7 +544,7 @@ func (t *Tester) testUpdateWithWrongUID(obj runtime.Object, createFn CreateFunc, } objectMeta.SetUID(types.UID("UID1111")) - obj, created, err := t.storage.(rest.Updater).Update(ctx, objectMeta.GetName(), rest.DefaultUpdatedObjectInfo(foo), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + obj, created, err := t.storage.(rest.Updater).Update(ctx, objectMeta.GetName(), rest.DefaultUpdatedObjectInfo(foo), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if created || obj != nil { t.Errorf("expected nil object and no creation for object: %v", foo) } @@ -588,7 +588,7 @@ func (t *Tester) testUpdateRetrievesOldObject(obj runtime.Object, createFn Creat return updatedObject, nil } - updatedObj, created, err := t.storage.(rest.Updater).Update(ctx, objectMeta.GetName(), rest.DefaultUpdatedObjectInfo(storedFooWithUpdates, noopTransform), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + updatedObj, created, err := t.storage.(rest.Updater).Update(ctx, objectMeta.GetName(), rest.DefaultUpdatedObjectInfo(storedFooWithUpdates, noopTransform), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) return @@ -623,7 +623,7 @@ func (t *Tester) testUpdatePropagatesUpdatedObjectError(obj runtime.Object, crea return nil, propagateErr } - _, _, err := t.storage.(rest.Updater).Update(ctx, name, rest.DefaultUpdatedObjectInfo(foo, noopTransform), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err := t.storage.(rest.Updater).Update(ctx, name, rest.DefaultUpdatedObjectInfo(foo, noopTransform), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != propagateErr { t.Errorf("expected propagated error, got %#v", err) } @@ -649,7 +649,7 @@ func (t *Tester) testUpdateIgnoreGenerationUpdates(obj runtime.Object, createFn olderMeta := t.getObjectMetaOrFail(older) olderMeta.SetGeneration(2) - _, _, err = t.storage.(rest.Updater).Update(t.TestContext(), olderMeta.GetName(), rest.DefaultUpdatedObjectInfo(older), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = t.storage.(rest.Updater).Update(t.TestContext(), olderMeta.GetName(), rest.DefaultUpdatedObjectInfo(older), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -665,7 +665,7 @@ func (t *Tester) testUpdateIgnoreGenerationUpdates(obj runtime.Object, createFn func (t *Tester) testUpdateOnNotFound(obj runtime.Object) { t.setObjectMeta(obj, t.namer(0)) - _, created, err := t.storage.(rest.Updater).Update(t.TestContext(), t.namer(0), rest.DefaultUpdatedObjectInfo(obj), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, created, err := t.storage.(rest.Updater).Update(t.TestContext(), t.namer(0), rest.DefaultUpdatedObjectInfo(obj), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if t.createOnUpdate { if err != nil { t.Errorf("creation allowed on updated, but got an error: %v", err) @@ -700,7 +700,7 @@ func (t *Tester) testUpdateRejectsMismatchedNamespace(obj runtime.Object, create objectMeta.SetName(t.namer(1)) objectMeta.SetNamespace("not-default") - obj, updated, err := t.storage.(rest.Updater).Update(t.TestContext(), "foo1", rest.DefaultUpdatedObjectInfo(storedFoo), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + obj, updated, err := t.storage.(rest.Updater).Update(t.TestContext(), "foo1", rest.DefaultUpdatedObjectInfo(storedFoo), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if obj != nil || updated { t.Errorf("expected nil object and not updated") } @@ -731,7 +731,7 @@ func (t *Tester) testUpdateIgnoreClusterName(obj runtime.Object, createFn Create olderMeta := t.getObjectMetaOrFail(older) olderMeta.SetClusterName("clustername-to-ignore") - _, _, err = t.storage.(rest.Updater).Update(t.TestContext(), olderMeta.GetName(), rest.DefaultUpdatedObjectInfo(older), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false) + _, _, err = t.storage.(rest.Updater).Update(t.TestContext(), olderMeta.GetName(), rest.DefaultUpdatedObjectInfo(older), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -1063,14 +1063,14 @@ func (t *Tester) testGetDifferentNamespace(obj runtime.Object) { ctx1 := genericapirequest.WithNamespace(genericapirequest.NewContext(), "bar3") objMeta.SetNamespace(genericapirequest.NamespaceValue(ctx1)) - _, err := t.storage.(rest.Creater).Create(ctx1, obj, rest.ValidateAllObjectFunc, false) + _, err := t.storage.(rest.Creater).Create(ctx1, obj, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } ctx2 := genericapirequest.WithNamespace(genericapirequest.NewContext(), "bar4") objMeta.SetNamespace(genericapirequest.NamespaceValue(ctx2)) - _, err = t.storage.(rest.Creater).Create(ctx2, obj, rest.ValidateAllObjectFunc, false) + _, err = t.storage.(rest.Creater).Create(ctx2, obj, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -1104,7 +1104,7 @@ func (t *Tester) testGetFound(obj runtime.Object) { ctx := t.TestContext() t.setObjectMeta(obj, t.namer(1)) - existing, err := t.storage.(rest.Creater).Create(ctx, obj, rest.ValidateAllObjectFunc, false) + existing, err := t.storage.(rest.Creater).Create(ctx, obj, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -1127,7 +1127,7 @@ func (t *Tester) testGetMimatchedNamespace(obj runtime.Object) { objMeta := t.getObjectMetaOrFail(obj) objMeta.SetName(t.namer(4)) objMeta.SetNamespace(genericapirequest.NamespaceValue(ctx1)) - _, err := t.storage.(rest.Creater).Create(ctx1, obj, rest.ValidateAllObjectFunc, false) + _, err := t.storage.(rest.Creater).Create(ctx1, obj, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -1146,7 +1146,7 @@ func (t *Tester) testGetMimatchedNamespace(obj runtime.Object) { func (t *Tester) testGetNotFound(obj runtime.Object) { ctx := t.TestContext() t.setObjectMeta(obj, t.namer(2)) - _, err := t.storage.(rest.Creater).Create(ctx, obj, rest.ValidateAllObjectFunc, false) + _, err := t.storage.(rest.Creater).Create(ctx, obj, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } diff --git a/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/etcd.go b/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/etcd.go index 98afe4e1e6..f94bbf91f6 100644 --- a/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/etcd.go +++ b/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/etcd.go @@ -79,8 +79,8 @@ func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOp } // Update alters the status subset of an object. -func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool) (runtime.Object, bool, error) { +func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { // We are explicitly setting forceAllowCreate to false in the call to the underlying storage because // subresources should never allow create on update. - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false) + return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options) } diff --git a/test/integration/apiserver/print_test.go b/test/integration/apiserver/print_test.go index 65e5dde0d4..04971d3781 100644 --- a/test/integration/apiserver/print_test.go +++ b/test/integration/apiserver/print_test.go @@ -55,6 +55,8 @@ var kindWhiteList = sets.NewString( "ExportOptions", "GetOptions", "ListOptions", + "CreateOptions", + "UpdateOptions", "NodeProxyOptions", "PodAttachOptions", "PodExecOptions", diff --git a/test/integration/etcd/etcd_storage_path_test.go b/test/integration/etcd/etcd_storage_path_test.go index 579b26fe8c..965bf2d3c1 100644 --- a/test/integration/etcd/etcd_storage_path_test.go +++ b/test/integration/etcd/etcd_storage_path_test.go @@ -534,6 +534,8 @@ var kindWhiteList = sets.NewString( "DeleteOptions", "ExportOptions", "ListOptions", + "CreateOptions", + "UpdateOptions", "NodeProxyOptions", "PodAttachOptions", "PodExecOptions",