Merge pull request #30246 from liggitt/certificates

Automatic merge from submit-queue

Set user info in CertificateSigningRequest.Spec on create

Fixes #30239
This commit is contained in:
Kubernetes Submit Queue 2016-08-12 23:03:18 -07:00 committed by GitHub
commit df1abb40ec
60 changed files with 299 additions and 180 deletions

View File

@ -59,7 +59,7 @@ func MatchCluster(label labels.Selector, field fields.Selector) generic.Matcher
}
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
func (clusterStrategy) PrepareForCreate(obj runtime.Object) {
func (clusterStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
cluster := obj.(*federation.Cluster)
cluster.Status = federation.ClusterStatus{}
}
@ -80,7 +80,7 @@ func (clusterStrategy) AllowCreateOnUpdate() bool {
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (clusterStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (clusterStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
cluster := obj.(*federation.Cluster)
oldCluster := old.(*federation.Cluster)
cluster.Status = oldCluster.Status
@ -100,10 +100,10 @@ type clusterStatusStrategy struct {
var StatusStrategy = clusterStatusStrategy{Strategy}
func (clusterStatusStrategy) PrepareForCreate(obj runtime.Object) {
func (clusterStatusStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
_ = obj.(*federation.Cluster)
}
func (clusterStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (clusterStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
cluster := obj.(*federation.Cluster)
oldCluster := old.(*federation.Cluster)
cluster.Spec = oldCluster.Spec

View File

@ -79,7 +79,7 @@ func TestClusterStrategy(t *testing.T) {
}
cluster := validNewCluster()
Strategy.PrepareForCreate(cluster)
Strategy.PrepareForCreate(ctx, cluster)
if len(cluster.Status.Conditions) != 0 {
t.Errorf("Cluster should not allow setting conditions on create")
}
@ -89,7 +89,7 @@ func TestClusterStrategy(t *testing.T) {
}
invalidCluster := invalidNewCluster()
Strategy.PrepareForUpdate(invalidCluster, cluster)
Strategy.PrepareForUpdate(ctx, invalidCluster, cluster)
if reflect.DeepEqual(invalidCluster.Spec, cluster.Spec) ||
!reflect.DeepEqual(invalidCluster.Status, cluster.Status) {
t.Error("Only spec is expected being changed")
@ -114,7 +114,7 @@ func TestClusterStatusStrategy(t *testing.T) {
cluster := validNewCluster()
invalidCluster := invalidNewCluster()
StatusStrategy.PrepareForUpdate(cluster, invalidCluster)
StatusStrategy.PrepareForUpdate(ctx, cluster, invalidCluster)
if !reflect.DeepEqual(invalidCluster.Spec, cluster.Spec) ||
reflect.DeepEqual(invalidCluster.Status, cluster.Status) {
t.Logf("== cluster.Spec: %v\n", cluster.Spec)

View File

@ -40,7 +40,7 @@ type RESTCreateStrategy interface {
// the object. For example: remove fields that are not to be persisted,
// sort order-insensitive list fields, etc. This should not remove fields
// whose presence would be considered a validation error.
PrepareForCreate(obj runtime.Object)
PrepareForCreate(ctx api.Context, obj runtime.Object)
// Validate is invoked after default fields in the object have been filled in before
// the object is persisted. This method should not mutate the object.
Validate(ctx api.Context, obj runtime.Object) field.ErrorList
@ -67,7 +67,7 @@ func BeforeCreate(strategy RESTCreateStrategy, ctx api.Context, obj runtime.Obje
}
objectMeta.DeletionTimestamp = nil
objectMeta.DeletionGracePeriodSeconds = nil
strategy.PrepareForCreate(obj)
strategy.PrepareForCreate(ctx, obj)
api.FillObjectMetaSystemFields(ctx, objectMeta)
api.GenerateName(strategy, objectMeta)

View File

@ -37,7 +37,7 @@ type RESTDeleteStrategy interface {
type RESTGracefulDeleteStrategy interface {
// CheckGracefulDelete should return true if the object can be gracefully deleted and set
// any default values on the DeleteOptions.
CheckGracefulDelete(obj runtime.Object, options *api.DeleteOptions) bool
CheckGracefulDelete(ctx api.Context, obj runtime.Object, options *api.DeleteOptions) bool
}
// BeforeDelete tests whether the object can be gracefully deleted. If graceful is set the object
@ -87,7 +87,7 @@ func BeforeDelete(strategy RESTDeleteStrategy, ctx api.Context, obj runtime.Obje
return false, true, nil
}
if !gracefulStrategy.CheckGracefulDelete(obj, options) {
if !gracefulStrategy.CheckGracefulDelete(ctx, obj, options) {
return false, false, nil
}
now := unversioned.NewTime(unversioned.Now().Add(time.Second * time.Duration(*options.GracePeriodSeconds)))

View File

@ -17,6 +17,7 @@ limitations under the License.
package rest
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/runtime"
)
@ -24,5 +25,5 @@ import (
type RESTExportStrategy interface {
// Export strips fields that can not be set by the user. If 'exact' is false
// fields specific to the cluster are also stripped
Export(obj runtime.Object, exact bool) error
Export(ctx api.Context, obj runtime.Object, exact bool) error
}

View File

@ -41,7 +41,7 @@ type RESTUpdateStrategy interface {
// the object. For example: remove fields that are not to be persisted,
// sort order-insensitive list fields, etc. This should not remove fields
// whose presence would be considered a validation error.
PrepareForUpdate(obj, old runtime.Object)
PrepareForUpdate(ctx api.Context, obj, old runtime.Object)
// ValidateUpdate is invoked after default fields in the object have been
// filled in before the object is persisted. This method should not mutate
// the object.
@ -93,7 +93,7 @@ func BeforeUpdate(strategy RESTUpdateStrategy, ctx api.Context, obj, old runtime
}
objectMeta.Generation = oldMeta.Generation
strategy.PrepareForUpdate(obj, old)
strategy.PrepareForUpdate(ctx, obj, old)
// Ensure some common fields, like UID, are validated for all resources.
errs, err := validateCommonFields(obj, old)

View File

@ -54,17 +54,6 @@ func (s *storage) ListCSRs(ctx api.Context, options *api.ListOptions) (*certific
}
func (s *storage) CreateCSR(ctx api.Context, csr *certificates.CertificateSigningRequest) error {
// Inject user.Info from request context if available and no
// information was supplied. Don't smash existing user information
// since it should be possible for a broadly-scoped user to request a
// certificate on behalf of a more limited user.
if user, ok := api.UserFrom(ctx); ok {
if csr.Spec.Username == "" {
csr.Spec.Username = user.GetName()
csr.Spec.UID = user.GetUID()
csr.Spec.Groups = user.GetGroups()
}
}
_, err := s.Create(ctx, csr)
return err
}

View File

@ -50,13 +50,21 @@ func (csrStrategy) AllowCreateOnUpdate() bool {
}
// PrepareForCreate clears fields that are not allowed to be set by end users
// on creation. Users cannot create any derived information, but we expect
// information about the requesting user to be injected by the registry
// interface. Clear everything else.
// TODO: check these ordering assumptions. better way to inject user info?
func (csrStrategy) PrepareForCreate(obj runtime.Object) {
// on creation.
func (csrStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
csr := obj.(*certificates.CertificateSigningRequest)
// Clear any user-specified info
csr.Spec.Username = ""
csr.Spec.UID = ""
csr.Spec.Groups = nil
// Inject user.Info from request context
if user, ok := api.UserFrom(ctx); ok {
csr.Spec.Username = user.GetName()
csr.Spec.UID = user.GetUID()
csr.Spec.Groups = user.GetGroups()
}
// Be explicit that users cannot create pre-approved certificate requests.
csr.Status = certificates.CertificateSigningRequestStatus{}
csr.Status.Conditions = []certificates.CertificateSigningRequestCondition{}
@ -64,7 +72,7 @@ func (csrStrategy) PrepareForCreate(obj runtime.Object) {
// PrepareForUpdate clears fields that are not allowed to be set by end users
// on update. Certificate requests are immutable after creation except via subresources.
func (csrStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (csrStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newCSR := obj.(*certificates.CertificateSigningRequest)
oldCSR := old.(*certificates.CertificateSigningRequest)
@ -97,13 +105,13 @@ func (csrStrategy) AllowUnconditionalUpdate() bool {
return true
}
func (s csrStrategy) Export(obj runtime.Object, exact bool) error {
func (s csrStrategy) Export(ctx api.Context, obj runtime.Object, exact bool) error {
csr, ok := obj.(*certificates.CertificateSigningRequest)
if !ok {
// unexpected programmer error
return fmt.Errorf("unexpected object: %v", obj)
}
s.PrepareForCreate(obj)
s.PrepareForCreate(ctx, obj)
if exact {
return nil
}
@ -119,7 +127,7 @@ type csrStatusStrategy struct {
var StatusStrategy = csrStatusStrategy{Strategy}
func (csrStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (csrStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newCSR := obj.(*certificates.CertificateSigningRequest)
oldCSR := old.(*certificates.CertificateSigningRequest)
@ -145,7 +153,7 @@ type csrApprovalStrategy struct {
var ApprovalStrategy = csrApprovalStrategy{Strategy}
func (csrApprovalStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (csrApprovalStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newCSR := obj.(*certificates.CertificateSigningRequest)
oldCSR := old.(*certificates.CertificateSigningRequest)

View File

@ -0,0 +1,121 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package certificates
import (
"reflect"
"testing"
"k8s.io/kubernetes/pkg/api"
certapi "k8s.io/kubernetes/pkg/apis/certificates"
"k8s.io/kubernetes/pkg/auth/user"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/diff"
)
func TestStrategyCreate(t *testing.T) {
tests := map[string]struct {
ctx api.Context
obj runtime.Object
expectedObj runtime.Object
}{
"no user in context, no user in obj": {
ctx: api.NewContext(),
obj: &certapi.CertificateSigningRequest{},
expectedObj: &certapi.CertificateSigningRequest{
Status: certapi.CertificateSigningRequestStatus{Conditions: []certapi.CertificateSigningRequestCondition{}},
},
},
"user in context, no user in obj": {
ctx: api.WithUser(
api.NewContext(),
&user.DefaultInfo{
Name: "bob",
UID: "123",
Groups: []string{"group1"},
Extra: map[string][]string{"foo": {"bar"}},
},
),
obj: &certapi.CertificateSigningRequest{},
expectedObj: &certapi.CertificateSigningRequest{
Spec: certapi.CertificateSigningRequestSpec{
Username: "bob",
UID: "123",
Groups: []string{"group1"},
},
Status: certapi.CertificateSigningRequestStatus{Conditions: []certapi.CertificateSigningRequestCondition{}},
},
},
"no user in context, user in obj": {
ctx: api.NewContext(),
obj: &certapi.CertificateSigningRequest{
Spec: certapi.CertificateSigningRequestSpec{
Username: "bob",
UID: "123",
Groups: []string{"group1"},
},
},
expectedObj: &certapi.CertificateSigningRequest{
Status: certapi.CertificateSigningRequestStatus{Conditions: []certapi.CertificateSigningRequestCondition{}},
},
},
"user in context, user in obj": {
ctx: api.WithUser(
api.NewContext(),
&user.DefaultInfo{
Name: "alice",
UID: "234",
},
),
obj: &certapi.CertificateSigningRequest{
Spec: certapi.CertificateSigningRequestSpec{
Username: "bob",
UID: "123",
Groups: []string{"group1"},
},
},
expectedObj: &certapi.CertificateSigningRequest{
Spec: certapi.CertificateSigningRequestSpec{
Username: "alice",
UID: "234",
Groups: nil,
},
Status: certapi.CertificateSigningRequestStatus{Conditions: []certapi.CertificateSigningRequestCondition{}},
},
},
"pre-approved status": {
ctx: api.NewContext(),
obj: &certapi.CertificateSigningRequest{
Status: certapi.CertificateSigningRequestStatus{
Conditions: []certapi.CertificateSigningRequestCondition{
{Type: certapi.CertificateApproved},
},
},
},
expectedObj: &certapi.CertificateSigningRequest{
Status: certapi.CertificateSigningRequestStatus{Conditions: []certapi.CertificateSigningRequestCondition{}},
}},
}
for k, tc := range tests {
obj := tc.obj
Strategy.PrepareForCreate(tc.ctx, obj)
if !reflect.DeepEqual(obj, tc.expectedObj) {
t.Errorf("%s: object diff: %s", k, diff.ObjectDiff(obj, tc.expectedObj))
}
}
}

View File

@ -58,12 +58,12 @@ func (strategy) AllowCreateOnUpdate() bool {
// PrepareForCreate clears fields that are not allowed to be set by end users
// on creation.
func (strategy) PrepareForCreate(obj runtime.Object) {
func (strategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
_ = obj.(*rbac.ClusterRole)
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (strategy) PrepareForUpdate(obj, old runtime.Object) {
func (strategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newClusterRole := obj.(*rbac.ClusterRole)
oldClusterRole := old.(*rbac.ClusterRole)
@ -97,7 +97,7 @@ func (strategy) AllowUnconditionalUpdate() bool {
return true
}
func (s strategy) Export(obj runtime.Object, exact bool) error {
func (s strategy) Export(ctx api.Context, obj runtime.Object, exact bool) error {
return nil
}

View File

@ -58,12 +58,12 @@ func (strategy) AllowCreateOnUpdate() bool {
// PrepareForCreate clears fields that are not allowed to be set by end users
// on creation.
func (strategy) PrepareForCreate(obj runtime.Object) {
func (strategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
_ = obj.(*rbac.ClusterRoleBinding)
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (strategy) PrepareForUpdate(obj, old runtime.Object) {
func (strategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newClusterRoleBinding := obj.(*rbac.ClusterRoleBinding)
oldClusterRoleBinding := old.(*rbac.ClusterRoleBinding)
@ -97,7 +97,7 @@ func (strategy) AllowUnconditionalUpdate() bool {
return true
}
func (s strategy) Export(obj runtime.Object, exact bool) error {
func (s strategy) Export(ctx api.Context, obj runtime.Object, exact bool) error {
return nil
}

View File

@ -49,7 +49,7 @@ func (strategy) NamespaceScoped() bool {
return true
}
func (strategy) PrepareForCreate(obj runtime.Object) {
func (strategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
_ = obj.(*api.ConfigMap)
}
@ -67,7 +67,7 @@ func (strategy) AllowCreateOnUpdate() bool {
return false
}
func (strategy) PrepareForUpdate(newObj, oldObj runtime.Object) {
func (strategy) PrepareForUpdate(ctx api.Context, newObj, oldObj runtime.Object) {
_ = oldObj.(*api.ConfigMap)
_ = newObj.(*api.ConfigMap)
}

View File

@ -44,7 +44,7 @@ func TestConfigMapStrategy(t *testing.T) {
},
}
Strategy.PrepareForCreate(cfg)
Strategy.PrepareForCreate(ctx, cfg)
errs := Strategy.Validate(ctx, cfg)
if len(errs) != 0 {
@ -62,7 +62,7 @@ func TestConfigMapStrategy(t *testing.T) {
},
}
Strategy.PrepareForUpdate(newCfg, cfg)
Strategy.PrepareForUpdate(ctx, newCfg, cfg)
errs = Strategy.ValidateUpdate(ctx, newCfg, cfg)
if len(errs) == 0 {

View File

@ -47,7 +47,7 @@ func (rcStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears the status of a replication controller before creation.
func (rcStrategy) PrepareForCreate(obj runtime.Object) {
func (rcStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
controller := obj.(*api.ReplicationController)
controller.Status = api.ReplicationControllerStatus{}
@ -55,7 +55,7 @@ func (rcStrategy) PrepareForCreate(obj runtime.Object) {
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (rcStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (rcStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newController := obj.(*api.ReplicationController)
oldController := old.(*api.ReplicationController)
// update is not allowed to set status
@ -133,7 +133,7 @@ type rcStatusStrategy struct {
var StatusStrategy = rcStatusStrategy{Strategy}
func (rcStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (rcStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newRc := obj.(*api.ReplicationController)
oldRc := old.(*api.ReplicationController)
// update is not allowed to set spec

View File

@ -59,7 +59,7 @@ func TestControllerStrategy(t *testing.T) {
},
}
Strategy.PrepareForCreate(rc)
Strategy.PrepareForCreate(ctx, rc)
if rc.Status.Replicas != 0 {
t.Error("ReplicationController should not allow setting status.replicas on create")
}
@ -74,7 +74,7 @@ func TestControllerStrategy(t *testing.T) {
invalidRc := &api.ReplicationController{
ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "4"},
}
Strategy.PrepareForUpdate(invalidRc, rc)
Strategy.PrepareForUpdate(ctx, invalidRc, rc)
errs = Strategy.ValidateUpdate(ctx, invalidRc, rc)
if len(errs) == 0 {
t.Errorf("Expected a validation error")
@ -129,7 +129,7 @@ func TestControllerStatusStrategy(t *testing.T) {
ObservedGeneration: int64(11),
},
}
StatusStrategy.PrepareForUpdate(newController, oldController)
StatusStrategy.PrepareForUpdate(ctx, newController, oldController)
if newController.Status.Replicas != 3 {
t.Errorf("Replication controller status updates should allow change of replicas: %v", newController.Status.Replicas)
}

View File

@ -45,7 +45,7 @@ func (daemonSetStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears the status of a daemon set before creation.
func (daemonSetStrategy) PrepareForCreate(obj runtime.Object) {
func (daemonSetStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
daemonSet := obj.(*extensions.DaemonSet)
daemonSet.Status = extensions.DaemonSetStatus{}
@ -53,7 +53,7 @@ func (daemonSetStrategy) PrepareForCreate(obj runtime.Object) {
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (daemonSetStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (daemonSetStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newDaemonSet := obj.(*extensions.DaemonSet)
oldDaemonSet := old.(*extensions.DaemonSet)
@ -132,7 +132,7 @@ type daemonSetStatusStrategy struct {
var StatusStrategy = daemonSetStatusStrategy{Strategy}
func (daemonSetStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (daemonSetStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newDaemonSet := obj.(*extensions.DaemonSet)
oldDaemonSet := old.(*extensions.DaemonSet)
newDaemonSet.Spec = oldDaemonSet.Spec

View File

@ -46,7 +46,7 @@ func (deploymentStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
func (deploymentStrategy) PrepareForCreate(obj runtime.Object) {
func (deploymentStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
deployment := obj.(*extensions.Deployment)
deployment.Status = extensions.DeploymentStatus{}
deployment.Generation = 1
@ -68,7 +68,7 @@ func (deploymentStrategy) AllowCreateOnUpdate() bool {
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (deploymentStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (deploymentStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newDeployment := obj.(*extensions.Deployment)
oldDeployment := old.(*extensions.Deployment)
newDeployment.Status = oldDeployment.Status
@ -98,7 +98,7 @@ type deploymentStatusStrategy struct {
var StatusStrategy = deploymentStatusStrategy{Strategy}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update of status
func (deploymentStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (deploymentStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newDeployment := obj.(*extensions.Deployment)
oldDeployment := old.(*extensions.Deployment)
newDeployment.Spec = oldDeployment.Spec

View File

@ -56,7 +56,7 @@ func TestStatusUpdates(t *testing.T) {
}
for _, test := range tests {
deploymentStatusStrategy{}.PrepareForUpdate(test.obj, test.old)
deploymentStatusStrategy{}.PrepareForUpdate(api.NewContext(), test.obj, test.old)
if !reflect.DeepEqual(test.expected, test.obj) {
t.Errorf("Unexpected object mismatch! Expected:\n%#v\ngot:\n%#v", test.expected, test.obj)
}

View File

@ -45,11 +45,11 @@ func (endpointsStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
func (endpointsStrategy) PrepareForCreate(obj runtime.Object) {
func (endpointsStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (endpointsStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (endpointsStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
}
// Validate validates a new endpoints.

View File

@ -42,10 +42,10 @@ func (eventStrategy) NamespaceScoped() bool {
return true
}
func (eventStrategy) PrepareForCreate(obj runtime.Object) {
func (eventStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
}
func (eventStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (eventStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
}
func (eventStrategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList {

View File

@ -875,11 +875,11 @@ func (e *Store) Export(ctx api.Context, name string, opts unversioned.ExportOpti
}
if e.ExportStrategy != nil {
if err = e.ExportStrategy.Export(obj, opts.Exact); err != nil {
if err = e.ExportStrategy.Export(ctx, obj, opts.Exact); err != nil {
return nil, err
}
} else {
e.CreateStrategy.PrepareForCreate(obj)
e.CreateStrategy.PrepareForCreate(ctx, obj)
}
return obj, nil
}

View File

@ -57,7 +57,7 @@ func (t *testRESTStrategy) NamespaceScoped() bool { return t.namespaceS
func (t *testRESTStrategy) AllowCreateOnUpdate() bool { return t.allowCreateOnUpdate }
func (t *testRESTStrategy) AllowUnconditionalUpdate() bool { return t.allowUnconditionalUpdate }
func (t *testRESTStrategy) PrepareForCreate(obj runtime.Object) {
func (t *testRESTStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
metaObj, err := meta.Accessor(obj)
if err != nil {
panic(err.Error())
@ -70,7 +70,7 @@ func (t *testRESTStrategy) PrepareForCreate(obj runtime.Object) {
metaObj.SetLabels(labels)
}
func (t *testRESTStrategy) PrepareForUpdate(obj, old runtime.Object) {}
func (t *testRESTStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {}
func (t *testRESTStrategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList {
return nil
}
@ -432,7 +432,7 @@ func TestNoOpUpdates(t *testing.T) {
type testPodExport struct{}
func (t testPodExport) Export(obj runtime.Object, exact bool) error {
func (t testPodExport) Export(ctx api.Context, obj runtime.Object, exact bool) error {
pod := obj.(*api.Pod)
if pod.Labels == nil {
pod.Labels = map[string]string{}

View File

@ -45,7 +45,7 @@ func (autoscalerStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
func (autoscalerStrategy) PrepareForCreate(obj runtime.Object) {
func (autoscalerStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
newHPA := obj.(*autoscaling.HorizontalPodAutoscaler)
// create cannot set status
@ -68,7 +68,7 @@ func (autoscalerStrategy) AllowCreateOnUpdate() bool {
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (autoscalerStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (autoscalerStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newHPA := obj.(*autoscaling.HorizontalPodAutoscaler)
oldHPA := old.(*autoscaling.HorizontalPodAutoscaler)
// Update is not allowed to set status
@ -108,7 +108,7 @@ type autoscalerStatusStrategy struct {
var StatusStrategy = autoscalerStatusStrategy{Strategy}
func (autoscalerStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (autoscalerStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newAutoscaler := obj.(*autoscaling.HorizontalPodAutoscaler)
oldAutoscaler := old.(*autoscaling.HorizontalPodAutoscaler)
// status changes are not allowed to update spec

View File

@ -45,7 +45,7 @@ func (ingressStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears the status of an Ingress before creation.
func (ingressStrategy) PrepareForCreate(obj runtime.Object) {
func (ingressStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
ingress := obj.(*extensions.Ingress)
// create cannot set status
ingress.Status = extensions.IngressStatus{}
@ -54,7 +54,7 @@ func (ingressStrategy) PrepareForCreate(obj runtime.Object) {
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (ingressStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (ingressStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newIngress := obj.(*extensions.Ingress)
oldIngress := old.(*extensions.Ingress)
// Update is not allowed to set status
@ -126,7 +126,7 @@ type ingressStatusStrategy struct {
var StatusStrategy = ingressStatusStrategy{Strategy}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update of status
func (ingressStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (ingressStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newIngress := obj.(*extensions.Ingress)
oldIngress := old.(*extensions.Ingress)
// status changes are not allowed to update spec

View File

@ -78,7 +78,7 @@ func TestIngressStrategy(t *testing.T) {
}
ingress := newIngress()
Strategy.PrepareForCreate(&ingress)
Strategy.PrepareForCreate(ctx, &ingress)
if len(ingress.Status.LoadBalancer.Ingress) != 0 {
t.Error("Ingress should not allow setting status on create")
}
@ -89,7 +89,7 @@ func TestIngressStrategy(t *testing.T) {
invalidIngress := newIngress()
invalidIngress.ResourceVersion = "4"
invalidIngress.Spec = extensions.IngressSpec{}
Strategy.PrepareForUpdate(&invalidIngress, &ingress)
Strategy.PrepareForUpdate(ctx, &invalidIngress, &ingress)
errs = Strategy.ValidateUpdate(ctx, &invalidIngress, &ingress)
if len(errs) == 0 {
t.Errorf("Expected a validation error")
@ -119,7 +119,7 @@ func TestIngressStatusStrategy(t *testing.T) {
},
},
}
StatusStrategy.PrepareForUpdate(&newIngress, &oldIngress)
StatusStrategy.PrepareForUpdate(ctx, &newIngress, &oldIngress)
if newIngress.Status.LoadBalancer.Ingress[0].IP != "127.0.0.2" {
t.Errorf("Ingress status updates should allow change of status fields")
}

View File

@ -46,13 +46,13 @@ func (jobStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears the status of a job before creation.
func (jobStrategy) PrepareForCreate(obj runtime.Object) {
func (jobStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
job := obj.(*batch.Job)
job.Status = batch.JobStatus{}
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (jobStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (jobStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newJob := obj.(*batch.Job)
oldJob := old.(*batch.Job)
newJob.Status = oldJob.Status
@ -144,7 +144,7 @@ type jobStatusStrategy struct {
var StatusStrategy = jobStatusStrategy{Strategy}
func (jobStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (jobStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newJob := obj.(*batch.Job)
oldJob := old.(*batch.Job)
newJob.Spec = oldJob.Spec

View File

@ -72,7 +72,7 @@ func TestJobStrategy(t *testing.T) {
},
}
Strategy.PrepareForCreate(job)
Strategy.PrepareForCreate(ctx, job)
if job.Status.Active != 0 {
t.Errorf("Job does not allow setting status on create")
}
@ -92,7 +92,7 @@ func TestJobStrategy(t *testing.T) {
}
// ensure we do not change status
job.Status.Active = 10
Strategy.PrepareForUpdate(updatedJob, job)
Strategy.PrepareForUpdate(ctx, updatedJob, job)
if updatedJob.Status.Active != 10 {
t.Errorf("PrepareForUpdate should have preserved prior version status")
}
@ -126,7 +126,7 @@ func TestJobStrategyWithGeneration(t *testing.T) {
},
}
Strategy.PrepareForCreate(job)
Strategy.PrepareForCreate(ctx, job)
errs := Strategy.Validate(ctx, job)
if len(errs) != 0 {
t.Errorf("Unexpected error validating %v", errs)
@ -206,7 +206,7 @@ func TestJobStatusStrategy(t *testing.T) {
},
}
StatusStrategy.PrepareForUpdate(newJob, oldJob)
StatusStrategy.PrepareForUpdate(ctx, newJob, oldJob)
if newJob.Status.Active != 12 {
t.Errorf("Job status updates must allow changes to job status")
}

View File

@ -42,14 +42,14 @@ func (limitrangeStrategy) NamespaceScoped() bool {
return true
}
func (limitrangeStrategy) PrepareForCreate(obj runtime.Object) {
func (limitrangeStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
limitRange := obj.(*api.LimitRange)
if len(limitRange.Name) == 0 {
limitRange.Name = string(uuid.NewUUID())
}
}
func (limitrangeStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (limitrangeStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
}
func (limitrangeStrategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList {
@ -78,10 +78,10 @@ func LimitRangeToSelectableFields(limitRange *api.LimitRange) fields.Set {
return fields.Set{}
}
func (limitrangeStrategy) Export(runtime.Object, bool) error {
func (limitrangeStrategy) Export(api.Context, runtime.Object, bool) error {
// Copied from OpenShift exporter
// TODO: this needs to be fixed
// limitrange.Strategy.PrepareForCreate(obj)
// limitrange.Strategy.PrepareForCreate(ctx, obj)
return nil
}

View File

@ -44,7 +44,7 @@ func (namespaceStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
func (namespaceStrategy) PrepareForCreate(obj runtime.Object) {
func (namespaceStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
// on create, status is active
namespace := obj.(*api.Namespace)
namespace.Status = api.NamespaceStatus{
@ -69,7 +69,7 @@ func (namespaceStrategy) PrepareForCreate(obj runtime.Object) {
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (namespaceStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (namespaceStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newNamespace := obj.(*api.Namespace)
oldNamespace := old.(*api.Namespace)
newNamespace.Spec.Finalizers = oldNamespace.Spec.Finalizers
@ -107,7 +107,7 @@ type namespaceStatusStrategy struct {
var StatusStrategy = namespaceStatusStrategy{Strategy}
func (namespaceStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (namespaceStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newNamespace := obj.(*api.Namespace)
oldNamespace := old.(*api.Namespace)
newNamespace.Spec = oldNamespace.Spec
@ -128,7 +128,7 @@ func (namespaceFinalizeStrategy) ValidateUpdate(ctx api.Context, obj, old runtim
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (namespaceFinalizeStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (namespaceFinalizeStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newNamespace := obj.(*api.Namespace)
oldNamespace := old.(*api.Namespace)
newNamespace.Status = oldNamespace.Status

View File

@ -37,7 +37,7 @@ func TestNamespaceStrategy(t *testing.T) {
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"},
Status: api.NamespaceStatus{Phase: api.NamespaceTerminating},
}
Strategy.PrepareForCreate(namespace)
Strategy.PrepareForCreate(ctx, namespace)
if namespace.Status.Phase != api.NamespaceActive {
t.Errorf("Namespaces do not allow setting phase on create")
}
@ -52,7 +52,7 @@ func TestNamespaceStrategy(t *testing.T) {
ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "4"},
}
// ensure we copy spec.finalizers from old to new
Strategy.PrepareForUpdate(invalidNamespace, namespace)
Strategy.PrepareForUpdate(ctx, invalidNamespace, namespace)
if len(invalidNamespace.Spec.Finalizers) != 1 || invalidNamespace.Spec.Finalizers[0] != api.FinalizerKubernetes {
t.Errorf("PrepareForUpdate should have preserved old.spec.finalizers")
}
@ -83,7 +83,7 @@ func TestNamespaceStatusStrategy(t *testing.T) {
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "9", DeletionTimestamp: &now},
Status: api.NamespaceStatus{Phase: api.NamespaceTerminating},
}
StatusStrategy.PrepareForUpdate(namespace, oldNamespace)
StatusStrategy.PrepareForUpdate(ctx, namespace, oldNamespace)
if namespace.Status.Phase != api.NamespaceTerminating {
t.Errorf("Namespace status updates should allow change of phase: %v", namespace.Status.Phase)
}
@ -117,7 +117,7 @@ func TestNamespaceFinalizeStrategy(t *testing.T) {
Spec: api.NamespaceSpec{Finalizers: []api.FinalizerName{"example.com/foo"}},
Status: api.NamespaceStatus{Phase: api.NamespaceTerminating},
}
FinalizeStrategy.PrepareForUpdate(namespace, oldNamespace)
FinalizeStrategy.PrepareForUpdate(ctx, namespace, oldNamespace)
if namespace.Status.Phase != api.NamespaceActive {
t.Errorf("finalize updates should not allow change of phase: %v", namespace.Status.Phase)
}

View File

@ -45,13 +45,13 @@ func (networkPolicyStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears the status of an NetworkPolicy before creation.
func (networkPolicyStrategy) PrepareForCreate(obj runtime.Object) {
func (networkPolicyStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
networkPolicy := obj.(*extensions.NetworkPolicy)
networkPolicy.Generation = 1
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (networkPolicyStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (networkPolicyStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newNetworkPolicy := obj.(*extensions.NetworkPolicy)
oldNetworkPolicy := old.(*extensions.NetworkPolicy)

View File

@ -42,7 +42,7 @@ func TestNetworkPolicyStrategy(t *testing.T) {
},
}
Strategy.PrepareForCreate(np)
Strategy.PrepareForCreate(ctx, np)
errs := Strategy.Validate(ctx, np)
if len(errs) != 0 {
t.Errorf("Unexpected error validating %v", errs)
@ -51,7 +51,7 @@ func TestNetworkPolicyStrategy(t *testing.T) {
invalidNp := &extensions.NetworkPolicy{
ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "4"},
}
Strategy.PrepareForUpdate(invalidNp, np)
Strategy.PrepareForUpdate(ctx, invalidNp, np)
errs = Strategy.ValidateUpdate(ctx, invalidNp, np)
if len(errs) == 0 {
t.Errorf("Expected a validation error")

View File

@ -59,13 +59,13 @@ func (nodeStrategy) AllowCreateOnUpdate() bool {
}
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
func (nodeStrategy) PrepareForCreate(obj runtime.Object) {
func (nodeStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
_ = obj.(*api.Node)
// Nodes allow *all* fields, including status, to be set on create.
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (nodeStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (nodeStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newNode := obj.(*api.Node)
oldNode := old.(*api.Node)
newNode.Status = oldNode.Status
@ -91,13 +91,13 @@ func (nodeStrategy) AllowUnconditionalUpdate() bool {
return true
}
func (ns nodeStrategy) Export(obj runtime.Object, exact bool) error {
func (ns nodeStrategy) Export(ctx api.Context, obj runtime.Object, exact bool) error {
n, ok := obj.(*api.Node)
if !ok {
// unexpected programmer error
return fmt.Errorf("unexpected object: %v", obj)
}
ns.PrepareForCreate(obj)
ns.PrepareForCreate(ctx, obj)
if exact {
return nil
}
@ -113,12 +113,12 @@ type nodeStatusStrategy struct {
var StatusStrategy = nodeStatusStrategy{Strategy}
func (nodeStatusStrategy) PrepareForCreate(obj runtime.Object) {
func (nodeStatusStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
_ = obj.(*api.Node)
// Nodes allow *all* fields, including status, to be set on create.
}
func (nodeStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (nodeStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newNode := obj.(*api.Node)
oldNode := old.(*api.Node)
newNode.Spec = oldNode.Spec

View File

@ -43,7 +43,7 @@ func (persistentvolumeStrategy) NamespaceScoped() bool {
}
// ResetBeforeCreate clears the Status field which is not allowed to be set by end users on creation.
func (persistentvolumeStrategy) PrepareForCreate(obj runtime.Object) {
func (persistentvolumeStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
pv := obj.(*api.PersistentVolume)
pv.Status = api.PersistentVolumeStatus{}
}
@ -62,7 +62,7 @@ func (persistentvolumeStrategy) AllowCreateOnUpdate() bool {
}
// PrepareForUpdate sets the Status fields which is not allowed to be set by an end user updating a PV
func (persistentvolumeStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (persistentvolumeStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newPv := obj.(*api.PersistentVolume)
oldPv := old.(*api.PersistentVolume)
newPv.Status = oldPv.Status
@ -84,7 +84,7 @@ type persistentvolumeStatusStrategy struct {
var StatusStrategy = persistentvolumeStatusStrategy{Strategy}
// PrepareForUpdate sets the Spec field which is not allowed to be changed when updating a PV's Status
func (persistentvolumeStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (persistentvolumeStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newPv := obj.(*api.PersistentVolume)
oldPv := old.(*api.PersistentVolume)
newPv.Spec = oldPv.Spec

View File

@ -43,7 +43,7 @@ func (persistentvolumeclaimStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears the Status field which is not allowed to be set by end users on creation.
func (persistentvolumeclaimStrategy) PrepareForCreate(obj runtime.Object) {
func (persistentvolumeclaimStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
pv := obj.(*api.PersistentVolumeClaim)
pv.Status = api.PersistentVolumeClaimStatus{}
}
@ -62,7 +62,7 @@ func (persistentvolumeclaimStrategy) AllowCreateOnUpdate() bool {
}
// PrepareForUpdate sets the Status field which is not allowed to be set by end users on update
func (persistentvolumeclaimStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (persistentvolumeclaimStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newPvc := obj.(*api.PersistentVolumeClaim)
oldPvc := old.(*api.PersistentVolumeClaim)
newPvc.Status = oldPvc.Status
@ -84,7 +84,7 @@ type persistentvolumeclaimStatusStrategy struct {
var StatusStrategy = persistentvolumeclaimStatusStrategy{Strategy}
// PrepareForUpdate sets the Spec field which is not allowed to be changed when updating a PV's Status
func (persistentvolumeclaimStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (persistentvolumeclaimStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newPv := obj.(*api.PersistentVolumeClaim)
oldPv := old.(*api.PersistentVolumeClaim)
newPv.Spec = oldPv.Spec

View File

@ -45,7 +45,7 @@ func (petSetStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears the status of an PetSet before creation.
func (petSetStrategy) PrepareForCreate(obj runtime.Object) {
func (petSetStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
petSet := obj.(*apps.PetSet)
// create cannot set status
petSet.Status = apps.PetSetStatus{}
@ -54,7 +54,7 @@ func (petSetStrategy) PrepareForCreate(obj runtime.Object) {
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (petSetStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (petSetStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newPetSet := obj.(*apps.PetSet)
oldPetSet := old.(*apps.PetSet)
// Update is not allowed to set status
@ -124,7 +124,7 @@ type petSetStatusStrategy struct {
var StatusStrategy = petSetStatusStrategy{Strategy}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update of status
func (petSetStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (petSetStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newPetSet := obj.(*apps.PetSet)
oldPetSet := old.(*apps.PetSet)
// status changes are not allowed to update spec

View File

@ -55,7 +55,7 @@ func TestPetSetStrategy(t *testing.T) {
Status: apps.PetSetStatus{Replicas: 3},
}
Strategy.PrepareForCreate(ps)
Strategy.PrepareForCreate(ctx, ps)
if ps.Status.Replicas != 0 {
t.Error("PetSet should not allow setting status.pets on create")
}
@ -73,14 +73,14 @@ func TestPetSetStrategy(t *testing.T) {
},
Status: apps.PetSetStatus{Replicas: 4},
}
Strategy.PrepareForUpdate(validPs, ps)
Strategy.PrepareForUpdate(ctx, validPs, ps)
errs = Strategy.ValidateUpdate(ctx, validPs, ps)
if len(errs) != 0 {
t.Errorf("Updating spec.Replicas is allowed on a petset.")
}
validPs.Spec.Selector = &unversioned.LabelSelector{MatchLabels: map[string]string{"a": "bar"}}
Strategy.PrepareForUpdate(validPs, ps)
Strategy.PrepareForUpdate(ctx, validPs, ps)
errs = Strategy.ValidateUpdate(ctx, validPs, ps)
if len(errs) == 0 {
t.Errorf("Expected a validation error since updates are disallowed on petsets.")
@ -130,7 +130,7 @@ func TestPetSetStatusStrategy(t *testing.T) {
Replicas: 2,
},
}
StatusStrategy.PrepareForUpdate(newPS, oldPS)
StatusStrategy.PrepareForUpdate(ctx, newPS, oldPS)
if newPS.Status.Replicas != 2 {
t.Errorf("PetSet status updates should allow change of pets: %v", newPS.Status.Replicas)
}

View File

@ -54,7 +54,7 @@ func (podStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
func (podStrategy) PrepareForCreate(obj runtime.Object) {
func (podStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
pod := obj.(*api.Pod)
pod.Status = api.PodStatus{
Phase: api.PodPending,
@ -62,7 +62,7 @@ func (podStrategy) PrepareForCreate(obj runtime.Object) {
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (podStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (podStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newPod := obj.(*api.Pod)
oldPod := old.(*api.Pod)
newPod.Status = oldPod.Status
@ -96,7 +96,7 @@ func (podStrategy) AllowUnconditionalUpdate() bool {
// CheckGracefulDelete allows a pod to be gracefully deleted. It updates the DeleteOptions to
// reflect the desired grace value.
func (podStrategy) CheckGracefulDelete(obj runtime.Object, options *api.DeleteOptions) bool {
func (podStrategy) CheckGracefulDelete(ctx api.Context, obj runtime.Object, options *api.DeleteOptions) bool {
if options == nil {
return false
}
@ -129,7 +129,7 @@ type podStrategyWithoutGraceful struct {
}
// CheckGracefulDelete prohibits graceful deletion.
func (podStrategyWithoutGraceful) CheckGracefulDelete(obj runtime.Object, options *api.DeleteOptions) bool {
func (podStrategyWithoutGraceful) CheckGracefulDelete(ctx api.Context, obj runtime.Object, options *api.DeleteOptions) bool {
return false
}
@ -142,7 +142,7 @@ type podStatusStrategy struct {
var StatusStrategy = podStatusStrategy{Strategy}
func (podStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (podStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newPod := obj.(*api.Pod)
oldPod := old.(*api.Pod)
newPod.Spec = oldPod.Spec

View File

@ -134,7 +134,7 @@ func TestCheckGracefulDelete(t *testing.T) {
}
for _, tc := range tcs {
out := &api.DeleteOptions{GracePeriodSeconds: &defaultGracePeriod}
Strategy.CheckGracefulDelete(tc.in, out)
Strategy.CheckGracefulDelete(api.NewContext(), tc.in, out)
if out.GracePeriodSeconds == nil {
t.Errorf("out grace period was nil but supposed to be %v", tc.gracePeriod)
}

View File

@ -45,7 +45,7 @@ func (podDisruptionBudgetStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears the status of an PodDisruptionBudget before creation.
func (podDisruptionBudgetStrategy) PrepareForCreate(obj runtime.Object) {
func (podDisruptionBudgetStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
podDisruptionBudget := obj.(*policy.PodDisruptionBudget)
// create cannot set status
podDisruptionBudget.Status = policy.PodDisruptionBudgetStatus{}
@ -54,7 +54,7 @@ func (podDisruptionBudgetStrategy) PrepareForCreate(obj runtime.Object) {
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (podDisruptionBudgetStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (podDisruptionBudgetStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newPodDisruptionBudget := obj.(*policy.PodDisruptionBudget)
oldPodDisruptionBudget := old.(*policy.PodDisruptionBudget)
// Update is not allowed to set status
@ -123,7 +123,7 @@ type podDisruptionBudgetStatusStrategy struct {
var StatusStrategy = podDisruptionBudgetStatusStrategy{Strategy}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update of status
func (podDisruptionBudgetStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (podDisruptionBudgetStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newPodDisruptionBudget := obj.(*policy.PodDisruptionBudget)
oldPodDisruptionBudget := old.(*policy.PodDisruptionBudget)
// status changes are not allowed to update spec

View File

@ -43,7 +43,7 @@ func TestPodDisruptionBudgetStrategy(t *testing.T) {
},
}
Strategy.PrepareForCreate(pdb)
Strategy.PrepareForCreate(ctx, pdb)
errs := Strategy.Validate(ctx, pdb)
if len(errs) != 0 {
t.Errorf("Unexpected error validating %v", errs)
@ -61,7 +61,7 @@ func TestPodDisruptionBudgetStrategy(t *testing.T) {
}
// Nothing in Spec changes: OK
Strategy.PrepareForUpdate(newPdb, pdb)
Strategy.PrepareForUpdate(ctx, newPdb, pdb)
errs = Strategy.ValidateUpdate(ctx, newPdb, pdb)
if len(errs) != 0 {
t.Errorf("Unexpected error updating PodDisruptionBudget.")
@ -69,7 +69,7 @@ func TestPodDisruptionBudgetStrategy(t *testing.T) {
// Changing the selector? No.
newPdb.Spec.Selector = &unversioned.LabelSelector{MatchLabels: map[string]string{"a": "bar"}}
Strategy.PrepareForUpdate(newPdb, pdb)
Strategy.PrepareForUpdate(ctx, newPdb, pdb)
errs = Strategy.ValidateUpdate(ctx, newPdb, pdb)
if len(errs) == 0 {
t.Errorf("Expected a validation error since updates are disallowed on poddisruptionbudgets.")
@ -78,7 +78,7 @@ func TestPodDisruptionBudgetStrategy(t *testing.T) {
// Changing MinAvailable? Also no.
newPdb.Spec.MinAvailable = intstr.FromString("28%")
Strategy.PrepareForUpdate(newPdb, pdb)
Strategy.PrepareForUpdate(ctx, newPdb, pdb)
errs = Strategy.ValidateUpdate(ctx, newPdb, pdb)
if len(errs) == 0 {
t.Errorf("Expected a validation error since updates are disallowed on poddisruptionbudgets.")
@ -120,7 +120,7 @@ func TestPodDisruptionBudgetStatusStrategy(t *testing.T) {
ExpectedPods: 3,
},
}
StatusStrategy.PrepareForUpdate(newPdb, oldPdb)
StatusStrategy.PrepareForUpdate(ctx, newPdb, oldPdb)
if newPdb.Status.CurrentHealthy != 2 {
t.Errorf("PodDisruptionBudget status updates should allow change of CurrentHealthy: %v", newPdb.Status.CurrentHealthy)
}

View File

@ -56,10 +56,10 @@ func (strategy) AllowUnconditionalUpdate() bool {
return true
}
func (strategy) PrepareForCreate(obj runtime.Object) {
func (strategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
}
func (strategy) PrepareForUpdate(obj, old runtime.Object) {
func (strategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
}
func (strategy) Canonicalize(obj runtime.Object) {

View File

@ -44,7 +44,7 @@ func (podTemplateStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
func (podTemplateStrategy) PrepareForCreate(obj runtime.Object) {
func (podTemplateStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
_ = obj.(*api.PodTemplate)
}
@ -64,7 +64,7 @@ func (podTemplateStrategy) AllowCreateOnUpdate() bool {
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (podTemplateStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (podTemplateStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
_ = obj.(*api.PodTemplate)
}
@ -77,7 +77,7 @@ func (podTemplateStrategy) AllowUnconditionalUpdate() bool {
return true
}
func (podTemplateStrategy) Export(obj runtime.Object, exact bool) error {
func (podTemplateStrategy) Export(ctx api.Context, obj runtime.Object, exact bool) error {
// Do nothing
return nil
}

View File

@ -48,7 +48,7 @@ func (rsStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears the status of a ReplicaSet before creation.
func (rsStrategy) PrepareForCreate(obj runtime.Object) {
func (rsStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
rs := obj.(*extensions.ReplicaSet)
rs.Status = extensions.ReplicaSetStatus{}
@ -56,7 +56,7 @@ func (rsStrategy) PrepareForCreate(obj runtime.Object) {
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (rsStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (rsStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newRS := obj.(*extensions.ReplicaSet)
oldRS := old.(*extensions.ReplicaSet)
// update is not allowed to set status
@ -134,7 +134,7 @@ type rsStatusStrategy struct {
var StatusStrategy = rsStatusStrategy{Strategy}
func (rsStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (rsStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newRS := obj.(*extensions.ReplicaSet)
oldRS := old.(*extensions.ReplicaSet)
// update is not allowed to set spec

View File

@ -58,7 +58,7 @@ func TestReplicaSetStrategy(t *testing.T) {
},
}
Strategy.PrepareForCreate(rs)
Strategy.PrepareForCreate(ctx, rs)
if rs.Status.Replicas != 0 {
t.Error("ReplicaSet should not allow setting status.replicas on create")
}
@ -73,7 +73,7 @@ func TestReplicaSetStrategy(t *testing.T) {
invalidRc := &extensions.ReplicaSet{
ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "4"},
}
Strategy.PrepareForUpdate(invalidRc, rs)
Strategy.PrepareForUpdate(ctx, invalidRc, rs)
errs = Strategy.ValidateUpdate(ctx, invalidRc, rs)
if len(errs) == 0 {
t.Errorf("Expected a validation error")
@ -128,7 +128,7 @@ func TestReplicaSetStatusStrategy(t *testing.T) {
ObservedGeneration: int64(11),
},
}
StatusStrategy.PrepareForUpdate(newRS, oldRS)
StatusStrategy.PrepareForUpdate(ctx, newRS, oldRS)
if newRS.Status.Replicas != 3 {
t.Errorf("ReplicaSet status updates should allow change of replicas: %v", newRS.Status.Replicas)
}

View File

@ -44,13 +44,13 @@ func (resourcequotaStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
func (resourcequotaStrategy) PrepareForCreate(obj runtime.Object) {
func (resourcequotaStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
resourcequota := obj.(*api.ResourceQuota)
resourcequota.Status = api.ResourceQuotaStatus{}
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (resourcequotaStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (resourcequotaStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newResourcequota := obj.(*api.ResourceQuota)
oldResourcequota := old.(*api.ResourceQuota)
newResourcequota.Status = oldResourcequota.Status
@ -87,7 +87,7 @@ type resourcequotaStatusStrategy struct {
var StatusStrategy = resourcequotaStatusStrategy{Strategy}
func (resourcequotaStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (resourcequotaStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newResourcequota := obj.(*api.ResourceQuota)
oldResourcequota := old.(*api.ResourceQuota)
newResourcequota.Spec = oldResourcequota.Spec

View File

@ -53,7 +53,7 @@ func TestResourceQuotaStrategy(t *testing.T) {
},
},
}
Strategy.PrepareForCreate(resourceQuota)
Strategy.PrepareForCreate(api.NewContext(), resourceQuota)
if resourceQuota.Status.Used != nil {
t.Errorf("ResourceQuota does not allow setting status on create")
}

View File

@ -58,12 +58,12 @@ func (strategy) AllowCreateOnUpdate() bool {
// PrepareForCreate clears fields that are not allowed to be set by end users
// on creation.
func (strategy) PrepareForCreate(obj runtime.Object) {
func (strategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
_ = obj.(*rbac.Role)
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (strategy) PrepareForUpdate(obj, old runtime.Object) {
func (strategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newRole := obj.(*rbac.Role)
oldRole := old.(*rbac.Role)
@ -97,7 +97,7 @@ func (strategy) AllowUnconditionalUpdate() bool {
return true
}
func (s strategy) Export(obj runtime.Object, exact bool) error {
func (s strategy) Export(ctx api.Context, obj runtime.Object, exact bool) error {
return nil
}

View File

@ -58,12 +58,12 @@ func (strategy) AllowCreateOnUpdate() bool {
// PrepareForCreate clears fields that are not allowed to be set by end users
// on creation.
func (strategy) PrepareForCreate(obj runtime.Object) {
func (strategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
_ = obj.(*rbac.RoleBinding)
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (strategy) PrepareForUpdate(obj, old runtime.Object) {
func (strategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newRoleBinding := obj.(*rbac.RoleBinding)
oldRoleBinding := old.(*rbac.RoleBinding)
@ -97,7 +97,7 @@ func (strategy) AllowUnconditionalUpdate() bool {
return true
}
func (s strategy) Export(obj runtime.Object, exact bool) error {
func (s strategy) Export(ctx api.Context, obj runtime.Object, exact bool) error {
return nil
}

View File

@ -44,13 +44,13 @@ func (scheduledJobStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears the status of a scheduled job before creation.
func (scheduledJobStrategy) PrepareForCreate(obj runtime.Object) {
func (scheduledJobStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
scheduledJob := obj.(*batch.ScheduledJob)
scheduledJob.Status = batch.ScheduledJobStatus{}
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (scheduledJobStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (scheduledJobStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newScheduledJob := obj.(*batch.ScheduledJob)
oldScheduledJob := old.(*batch.ScheduledJob)
newScheduledJob.Status = oldScheduledJob.Status
@ -86,7 +86,7 @@ type scheduledJobStatusStrategy struct {
var StatusStrategy = scheduledJobStatusStrategy{Strategy}
func (scheduledJobStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (scheduledJobStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newJob := obj.(*batch.ScheduledJob)
oldJob := old.(*batch.ScheduledJob)
newJob.Spec = oldJob.Spec

View File

@ -64,7 +64,7 @@ func TestScheduledJobStrategy(t *testing.T) {
},
}
Strategy.PrepareForCreate(scheduledJob)
Strategy.PrepareForCreate(ctx, scheduledJob)
if len(scheduledJob.Status.Active) != 0 {
t.Errorf("ScheduledJob does not allow setting status on create")
}
@ -84,7 +84,7 @@ func TestScheduledJobStrategy(t *testing.T) {
}
// ensure we do not change status
Strategy.PrepareForUpdate(updatedScheduledJob, scheduledJob)
Strategy.PrepareForUpdate(ctx, updatedScheduledJob, scheduledJob)
if updatedScheduledJob.Status.Active != nil {
t.Errorf("PrepareForUpdate should have preserved prior version status")
}
@ -147,7 +147,7 @@ func TestScheduledJobStatusStrategy(t *testing.T) {
},
}
StatusStrategy.PrepareForUpdate(newScheduledJob, oldScheduledJob)
StatusStrategy.PrepareForUpdate(ctx, newScheduledJob, oldScheduledJob)
if newScheduledJob.Status.LastScheduleTime == nil {
t.Errorf("ScheduledJob status updates must allow changes to scheduledJob status")
}

View File

@ -48,7 +48,7 @@ func (strategy) NamespaceScoped() bool {
return true
}
func (strategy) PrepareForCreate(obj runtime.Object) {
func (strategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
}
func (strategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList {
@ -62,7 +62,7 @@ func (strategy) AllowCreateOnUpdate() bool {
return false
}
func (strategy) PrepareForUpdate(obj, old runtime.Object) {
func (strategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
}
func (strategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList {
@ -73,13 +73,13 @@ func (strategy) AllowUnconditionalUpdate() bool {
return true
}
func (s strategy) Export(obj runtime.Object, exact bool) error {
func (s strategy) Export(ctx api.Context, obj runtime.Object, exact bool) error {
t, ok := obj.(*api.Secret)
if !ok {
// unexpected programmer error
return fmt.Errorf("unexpected object: %v", obj)
}
s.PrepareForCreate(obj)
s.PrepareForCreate(ctx, obj)
if exact {
return nil
}

View File

@ -83,7 +83,7 @@ func TestExportSecret(t *testing.T) {
}
for _, test := range tests {
err := Strategy.Export(test.objIn, test.exact)
err := Strategy.Export(api.NewContext(), test.objIn, test.exact)
if err != nil {
if !test.expectErr {
t.Errorf("unexpected error: %v", err)

View File

@ -44,13 +44,13 @@ func (svcStrategy) NamespaceScoped() bool {
}
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
func (svcStrategy) PrepareForCreate(obj runtime.Object) {
func (svcStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
service := obj.(*api.Service)
service.Status = api.ServiceStatus{}
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func (svcStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (svcStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newService := obj.(*api.Service)
oldService := old.(*api.Service)
newService.Status = oldService.Status
@ -78,7 +78,7 @@ func (svcStrategy) AllowUnconditionalUpdate() bool {
return true
}
func (svcStrategy) Export(obj runtime.Object, exact bool) error {
func (svcStrategy) Export(ctx api.Context, obj runtime.Object, exact bool) error {
t, ok := obj.(*api.Service)
if !ok {
// unexpected programmer error
@ -126,7 +126,7 @@ type serviceStatusStrategy struct {
var StatusStrategy = serviceStatusStrategy{Strategy}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update of status
func (serviceStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (serviceStatusStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
newService := obj.(*api.Service)
oldService := old.(*api.Service)
// status changes are not allowed to update spec

View File

@ -93,7 +93,7 @@ func TestExportService(t *testing.T) {
}
for _, test := range tests {
err := Strategy.Export(test.objIn, test.exact)
err := Strategy.Export(api.NewContext(), test.objIn, test.exact)
if err != nil {
if !test.expectErr {
t.Errorf("unexpected error: %v", err)
@ -238,7 +238,7 @@ func TestServiceStatusStrategy(t *testing.T) {
},
},
}
StatusStrategy.PrepareForUpdate(&newService, &oldService)
StatusStrategy.PrepareForUpdate(ctx, &newService, &oldService)
if newService.Status.LoadBalancer.Ingress[0].IP != "127.0.0.2" {
t.Errorf("Service status updates should allow change of status fields")
}

View File

@ -42,7 +42,7 @@ func (strategy) NamespaceScoped() bool {
return true
}
func (strategy) PrepareForCreate(obj runtime.Object) {
func (strategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
cleanSecretReferences(obj.(*api.ServiceAccount))
}
@ -58,7 +58,7 @@ func (strategy) AllowCreateOnUpdate() bool {
return false
}
func (strategy) PrepareForUpdate(obj, old runtime.Object) {
func (strategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
cleanSecretReferences(obj.(*api.ServiceAccount))
}

View File

@ -44,7 +44,7 @@ func (storageClassStrategy) NamespaceScoped() bool {
}
// ResetBeforeCreate clears the Status field which is not allowed to be set by end users on creation.
func (storageClassStrategy) PrepareForCreate(obj runtime.Object) {
func (storageClassStrategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
_ = obj.(*extensions.StorageClass)
}
@ -62,7 +62,7 @@ func (storageClassStrategy) AllowCreateOnUpdate() bool {
}
// PrepareForUpdate sets the Status fields which is not allowed to be set by an end user updating a PV
func (storageClassStrategy) PrepareForUpdate(obj, old runtime.Object) {
func (storageClassStrategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
_ = obj.(*extensions.StorageClass)
_ = old.(*extensions.StorageClass)
}

View File

@ -42,7 +42,7 @@ func TestStorageClassStrategy(t *testing.T) {
},
}
Strategy.PrepareForCreate(storageClass)
Strategy.PrepareForCreate(ctx, storageClass)
errs := Strategy.Validate(ctx, storageClass)
if len(errs) != 0 {
@ -60,7 +60,7 @@ func TestStorageClassStrategy(t *testing.T) {
},
}
Strategy.PrepareForUpdate(newStorageClass, storageClass)
Strategy.PrepareForUpdate(ctx, newStorageClass, storageClass)
errs = Strategy.ValidateUpdate(ctx, newStorageClass, storageClass)
if len(errs) == 0 {

View File

@ -51,7 +51,7 @@ func (strategy) GenerateName(base string) string {
return ""
}
func (strategy) PrepareForCreate(obj runtime.Object) {
func (strategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
}
func (strategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList {
@ -66,7 +66,7 @@ func (strategy) AllowCreateOnUpdate() bool {
return false
}
func (strategy) PrepareForUpdate(obj, old runtime.Object) {
func (strategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
}
func (strategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList {

View File

@ -48,7 +48,7 @@ func (strategy) NamespaceScoped() bool {
return true
}
func (strategy) PrepareForCreate(obj runtime.Object) {
func (strategy) PrepareForCreate(ctx api.Context, obj runtime.Object) {
}
func (strategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList {
@ -63,7 +63,7 @@ func (strategy) AllowCreateOnUpdate() bool {
return false
}
func (strategy) PrepareForUpdate(obj, old runtime.Object) {
func (strategy) PrepareForUpdate(ctx api.Context, obj, old runtime.Object) {
}
func (strategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList {