diff --git a/pkg/kubectl/resource/builder.go b/pkg/kubectl/resource/builder.go index f7d4d6cf844..6c9919999f3 100644 --- a/pkg/kubectl/resource/builder.go +++ b/pkg/kubectl/resource/builder.go @@ -212,6 +212,10 @@ func (b *Builder) ResourceNames(resource string, names ...string) *Builder { b.resourceTuples = append(b.resourceTuples, tuple) continue } + if len(resource) == 0 { + b.errs = append(b.errs, fmt.Errorf("the argument %q must be RESOURCE/NAME", name)) + continue + } // Use the given default type to create a resource tuple b.resourceTuples = append(b.resourceTuples, resourceTuple{Resource: resource, Name: name}) diff --git a/pkg/kubectl/resource/builder_test.go b/pkg/kubectl/resource/builder_test.go index 42dd3902e4b..ac4ec52aaea 100644 --- a/pkg/kubectl/resource/builder_test.go +++ b/pkg/kubectl/resource/builder_test.go @@ -626,6 +626,28 @@ func TestResourceNames(t *testing.T) { } } +func TestResourceNamesWithoutResource(t *testing.T) { + pods, svc := testData() + b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{ + "/namespaces/test/pods/foo": runtime.EncodeOrDie(testapi.Default.Codec(), &pods.Items[0]), + "/namespaces/test/services/baz": runtime.EncodeOrDie(testapi.Default.Codec(), &svc.Items[0]), + }), testapi.Default.Codec()). + NamespaceParam("test") + + test := &testVisitor{} + + if b.Do().Err() == nil { + t.Errorf("unexpected non-error") + } + + b.ResourceNames("", "foo", "services/baz") + + err := b.Do().Visit(test.Handle) + if err == nil || !strings.Contains(err.Error(), "must be RESOURCE/NAME") { + t.Fatalf("unexpected response: %v", err) + } +} + func TestResourceByNameWithoutRequireObject(t *testing.T) { b := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClientWith("", t, map[string]string{}), testapi.Default.Codec()). NamespaceParam("test")