diff --git a/pkg/kubectl/cmd/label.go b/pkg/kubectl/cmd/label.go index 8a3d795185b..681b06ec37f 100644 --- a/pkg/kubectl/cmd/label.go +++ b/pkg/kubectl/cmd/label.go @@ -17,21 +17,24 @@ limitations under the License. package cmd import ( - "encoding/json" "fmt" "io" "reflect" "strings" + jsonpatch "github.com/evanphx/json-patch" "github.com/golang/glog" "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" - "k8s.io/apimachinery/pkg/util/strategicpatch" + "k8s.io/apimachinery/pkg/util/json" "k8s.io/apimachinery/pkg/util/validation" + "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -175,8 +178,12 @@ func (o *LabelOptions) RunLabel(f cmdutil.Factory, cmd *cobra.Command) error { } changeCause := f.Command() - mapper, typer := f.Object() - b := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + + mapper, typer, err := f.UnstructuredObject() + if err != nil { + return err + } + b := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). @@ -213,10 +220,7 @@ func (o *LabelOptions) RunLabel(f cmdutil.Factory, cmd *cobra.Command) error { } outputObj = info.Object } else { - obj, err := cmdutil.MaybeConvertObject(info.Object, info.Mapping.GroupVersionKind.GroupVersion(), info.Mapping) - if err != nil { - return err - } + obj := info.Object name, namespace := info.Name, info.Namespace oldData, err := json.Marshal(obj) if err != nil { @@ -247,21 +251,21 @@ func (o *LabelOptions) RunLabel(f cmdutil.Factory, cmd *cobra.Command) error { if !reflect.DeepEqual(oldData, newData) { dataChangeMsg = "labeled" } - patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, obj) + patchBytes, err := jsonpatch.CreateMergePatch(oldData, newData) createdPatch := err == nil if err != nil { glog.V(2).Infof("couldn't compute patch: %v", err) } mapping := info.ResourceMapping() - client, err := f.ClientForMapping(mapping) + client, err := f.UnstructuredClientForMapping(mapping) if err != nil { return err } helper := resource.NewHelper(client, mapping) if createdPatch { - outputObj, err = helper.Patch(namespace, name, types.StrategicMergePatchType, patchBytes) + outputObj, err = helper.Patch(namespace, name, types.MergePatchType, patchBytes) } else { outputObj, err = helper.Replace(namespace, name, false, obj) } diff --git a/pkg/kubectl/cmd/label_test.go b/pkg/kubectl/cmd/label_test.go index 8d051f3add2..40590cf72e3 100644 --- a/pkg/kubectl/cmd/label_test.go +++ b/pkg/kubectl/cmd/label_test.go @@ -347,10 +347,10 @@ func TestLabelErrors(t *testing.T) { func TestLabelForResourceFromFile(t *testing.T) { pods, _, _ := testData() - f, tf, codec, ns := cmdtesting.NewAPIFactory() - tf.Client = &fake.RESTClient{ + f, tf, codec, _ := cmdtesting.NewAPIFactory() + tf.UnstructuredClient = &fake.RESTClient{ APIRegistry: api.Registry, - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { switch req.Method { case "GET": @@ -398,10 +398,10 @@ func TestLabelForResourceFromFile(t *testing.T) { } func TestLabelLocal(t *testing.T) { - f, tf, _, ns := cmdtesting.NewAPIFactory() - tf.Client = &fake.RESTClient{ + f, tf, _, _ := cmdtesting.NewAPIFactory() + tf.UnstructuredClient = &fake.RESTClient{ APIRegistry: api.Registry, - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req) return nil, nil @@ -432,10 +432,10 @@ func TestLabelLocal(t *testing.T) { func TestLabelMultipleObjects(t *testing.T) { pods, _, _ := testData() - f, tf, codec, ns := cmdtesting.NewAPIFactory() - tf.Client = &fake.RESTClient{ + f, tf, codec, _ := cmdtesting.NewAPIFactory() + tf.UnstructuredClient = &fake.RESTClient{ APIRegistry: api.Registry, - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { switch req.Method { case "GET":