add --ignore-not-found option

This commit is contained in:
juanvallejo 2017-02-14 14:48:07 -05:00
parent 436fa5c9d1
commit a76ed0284b
2 changed files with 60 additions and 2 deletions

View File

@ -23,6 +23,7 @@ import (
"github.com/spf13/cobra"
"github.com/golang/glog"
kapierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
@ -42,7 +43,8 @@ import (
type GetOptions struct {
resource.FilenameOptions
Raw string
IgnoreNotFound bool
Raw string
}
var (
@ -121,6 +123,7 @@ func NewCmdGet(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comman
cmd.Flags().Bool("watch-only", false, "Watch for changes to the requested object(s), without listing/getting first.")
cmd.Flags().Bool("show-kind", false, "If present, list the resource type for the requested object(s).")
cmd.Flags().Bool("all-namespaces", false, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")
cmd.Flags().BoolVar(&options.IgnoreNotFound, "ignore-not-found", false, "Treat \"resource not found\" as a successful retrieval.")
cmd.Flags().StringSliceP("label-columns", "L", []string{}, "Accepts a comma separated list of labels that are going to be presented as columns. Names are case-sensitive. You can also use multiple flag options like -L label1 -L label2...")
cmd.Flags().Bool("export", false, "If true, use 'export' for the resources. Exported resources are stripped of cluster-specific information.")
usage := "identifying the resource to get from a server."
@ -305,6 +308,10 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [
return err
}
if options.IgnoreNotFound {
r.IgnoreErrors(kapierrors.IsNotFound)
}
if generic {
// we flattened the data from the builder, so we have individual items, but now we'd like to either:
// 1. if there is more than one item, combine them all into a single list
@ -320,6 +327,10 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [
errs = append(errs, err)
}
if len(infos) == 0 && options.IgnoreNotFound {
return utilerrors.Reduce(utilerrors.Flatten(utilerrors.NewAggregate(errs)))
}
res := ""
if len(infos) > 0 {
res = infos[0].ResourceMapping().Resource
@ -395,7 +406,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [
if err != nil {
allErrs = append(allErrs, err)
}
if len(infos) == 0 && len(allErrs) == 0 {
if len(infos) == 0 && len(allErrs) == 0 && !options.IgnoreNotFound {
outputEmptyListWarning(errOut)
}

View File

@ -210,6 +210,53 @@ func TestGetObjects(t *testing.T) {
}
}
func TestGetObjectIgnoreNotFound(t *testing.T) {
initTestErrorHandler(t)
ns := &api.NamespaceList{
ListMeta: metav1.ListMeta{
ResourceVersion: "1",
},
Items: []api.Namespace{
{
ObjectMeta: metav1.ObjectMeta{Name: "testns", Namespace: "test", ResourceVersion: "11"},
Spec: api.NamespaceSpec{},
},
},
}
f, tf, codec, _ := cmdtesting.NewAPIFactory()
tf.Printer = &testPrinter{}
tf.UnstructuredClient = &fake.RESTClient{
APIRegistry: api.Registry,
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/nonexistentpod" && m == "GET":
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: stringBody("")}, nil
case p == "/api/v1/namespaces/test" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &ns.Items[0])}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdGet(f, buf, errBuf)
cmd.SetOutput(buf)
cmd.Flags().Set("ignore-not-found", "true")
cmd.Flags().Set("output", "yaml")
cmd.Run(cmd, []string{"pods", "nonexistentpod"})
if buf.String() != "" {
t.Errorf("unexpected output: %s", buf.String())
}
}
func TestGetSortedObjects(t *testing.T) {
pods := &api.PodList{
ListMeta: metav1.ListMeta{