diff --git a/pkg/kubectl/cmd/delete.go b/pkg/kubectl/cmd/delete.go index 1bcc01e7d58..b0a0b6ad18d 100644 --- a/pkg/kubectl/cmd/delete.go +++ b/pkg/kubectl/cmd/delete.go @@ -30,6 +30,7 @@ import ( "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" + "k8s.io/kubernetes/pkg/runtime" ) var ( @@ -115,8 +116,11 @@ func RunDelete(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri return err } deleteAll := cmdutil.GetFlagBool(cmd, "all") - mapper, typer := f.Object() - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). + mapper, typer, err := f.UnstructuredObject() + if err != nil { + return err + } + r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). diff --git a/pkg/kubectl/cmd/delete_test.go b/pkg/kubectl/cmd/delete_test.go index 5d1acbb4f36..b4a4b8c4566 100644 --- a/pkg/kubectl/cmd/delete_test.go +++ b/pkg/kubectl/cmd/delete_test.go @@ -30,15 +30,22 @@ import ( "k8s.io/kubernetes/pkg/client/restclient/fake" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" "k8s.io/kubernetes/pkg/kubectl/resource" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/runtime/serializer" ) +var unstructuredSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{ + MediaType: "application/json", + EncodesAsText: true, + Serializer: runtime.UnstructuredJSONScheme}) + func TestDeleteObjectByTuple(t *testing.T) { _, _, rc := testData() - f, tf, codec, ns := cmdtesting.NewAPIFactory() + f, tf, codec, _ := cmdtesting.NewAPIFactory() tf.Printer = &testPrinter{} tf.Client = &fake.RESTClient{ - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master-controller" && m == "DELETE": @@ -67,10 +74,10 @@ func TestDeleteObjectByTuple(t *testing.T) { func TestDeleteNamedObject(t *testing.T) { _, _, rc := testData() - f, tf, codec, ns := cmdtesting.NewAPIFactory() + f, tf, codec, _ := cmdtesting.NewAPIFactory() tf.Printer = &testPrinter{} tf.Client = &fake.RESTClient{ - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master-controller" && m == "DELETE": @@ -99,10 +106,10 @@ func TestDeleteNamedObject(t *testing.T) { func TestDeleteObject(t *testing.T) { _, _, rc := testData() - f, tf, codec, ns := cmdtesting.NewAPIFactory() + f, tf, codec, _ := cmdtesting.NewAPIFactory() tf.Printer = &testPrinter{} tf.Client = &fake.RESTClient{ - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "DELETE": @@ -129,10 +136,10 @@ func TestDeleteObject(t *testing.T) { } func TestDeleteObjectNotFound(t *testing.T) { - f, tf, _, ns := cmdtesting.NewAPIFactory() + f, tf, _, _ := cmdtesting.NewAPIFactory() tf.Printer = &testPrinter{} tf.Client = &fake.RESTClient{ - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "DELETE": @@ -158,10 +165,10 @@ func TestDeleteObjectNotFound(t *testing.T) { } func TestDeleteObjectIgnoreNotFound(t *testing.T) { - f, tf, _, ns := cmdtesting.NewAPIFactory() + f, tf, _, _ := cmdtesting.NewAPIFactory() tf.Printer = &testPrinter{} tf.Client = &fake.RESTClient{ - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "DELETE": @@ -189,16 +196,15 @@ func TestDeleteObjectIgnoreNotFound(t *testing.T) { func TestDeleteAllNotFound(t *testing.T) { _, svc, _ := testData() - - f, tf, codec, ns := cmdtesting.NewAPIFactory() - // Add an item to the list which will result in a 404 on delete svc.Items = append(svc.Items, api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}}) notFoundError := &errors.NewNotFound(api.Resource("services"), "foo").ErrStatus + f, tf, codec, _ := cmdtesting.NewAPIFactory() + tf.Printer = &testPrinter{} tf.Client = &fake.RESTClient{ - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/services" && m == "GET": @@ -232,7 +238,7 @@ func TestDeleteAllNotFound(t *testing.T) { func TestDeleteAllIgnoreNotFound(t *testing.T) { _, svc, _ := testData() - f, tf, codec, ns := cmdtesting.NewAPIFactory() + f, tf, codec, _ := cmdtesting.NewAPIFactory() // Add an item to the list which will result in a 404 on delete svc.Items = append(svc.Items, api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}}) @@ -240,7 +246,7 @@ func TestDeleteAllIgnoreNotFound(t *testing.T) { tf.Printer = &testPrinter{} tf.Client = &fake.RESTClient{ - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/services" && m == "GET": @@ -272,10 +278,10 @@ func TestDeleteAllIgnoreNotFound(t *testing.T) { func TestDeleteMultipleObject(t *testing.T) { _, svc, rc := testData() - f, tf, codec, ns := cmdtesting.NewAPIFactory() + f, tf, codec, _ := cmdtesting.NewAPIFactory() tf.Printer = &testPrinter{} tf.Client = &fake.RESTClient{ - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "DELETE": @@ -306,10 +312,10 @@ func TestDeleteMultipleObject(t *testing.T) { func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) { _, svc, _ := testData() - f, tf, codec, ns := cmdtesting.NewAPIFactory() + f, tf, codec, _ := cmdtesting.NewAPIFactory() tf.Printer = &testPrinter{} tf.Client = &fake.RESTClient{ - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "DELETE": @@ -342,10 +348,10 @@ func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) { func TestDeleteMultipleResourcesWithTheSameName(t *testing.T) { _, svc, rc := testData() - f, tf, codec, ns := cmdtesting.NewAPIFactory() + f, tf, codec, _ := cmdtesting.NewAPIFactory() tf.Printer = &testPrinter{} tf.Client = &fake.RESTClient{ - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/replicationcontrollers/baz" && m == "DELETE": @@ -378,10 +384,10 @@ func TestDeleteMultipleResourcesWithTheSameName(t *testing.T) { func TestDeleteDirectory(t *testing.T) { _, _, rc := testData() - f, tf, codec, ns := cmdtesting.NewAPIFactory() + f, tf, codec, _ := cmdtesting.NewAPIFactory() tf.Printer = &testPrinter{} tf.Client = &fake.RESTClient{ - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case strings.HasPrefix(p, "/namespaces/test/replicationcontrollers/") && m == "DELETE": @@ -409,10 +415,10 @@ func TestDeleteDirectory(t *testing.T) { func TestDeleteMultipleSelector(t *testing.T) { pods, svc, _ := testData() - f, tf, codec, ns := cmdtesting.NewAPIFactory() + f, tf, codec, _ := cmdtesting.NewAPIFactory() tf.Printer = &testPrinter{} tf.Client = &fake.RESTClient{ - NegotiatedSerializer: ns, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { switch p, m := req.URL.Path, req.Method; { case p == "/namespaces/test/pods" && m == "GET": diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index 18181c7b8f0..e5340ec71d0 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -682,11 +682,16 @@ func (f *factory) Scaler(mapping *meta.RESTMapping) (kubectl.Scaler, error) { func (f *factory) Reaper(mapping *meta.RESTMapping) (kubectl.Reaper, error) { mappingVersion := mapping.GroupVersionKind.GroupVersion() - clientset, err := f.clients.ClientSetForVersion(&mappingVersion) - if err != nil { - return nil, err + clientset, clientsetErr := f.clients.ClientSetForVersion(&mappingVersion) + reaper, reaperErr := kubectl.ReaperFor(mapping.GroupVersionKind.GroupKind(), clientset) + + if kubectl.IsNoSuchReaperError(reaperErr) { + return nil, reaperErr } - return kubectl.ReaperFor(mapping.GroupVersionKind.GroupKind(), clientset) + if clientsetErr != nil { + return nil, clientsetErr + } + return reaper, reaperErr } func (f *factory) HistoryViewer(mapping *meta.RESTMapping) (kubectl.HistoryViewer, error) {