mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 05:03:09 +00:00
Don't print non-error (blank lines in this case) to stdout, and don't print blank lines for empty resources
This commit is contained in:
parent
676417ec7b
commit
75b18e20d5
@ -522,6 +522,9 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
|
|||||||
// track if we write any output
|
// track if we write any output
|
||||||
trackingWriter := &trackingWriterWrapper{Delegate: o.Out}
|
trackingWriter := &trackingWriterWrapper{Delegate: o.Out}
|
||||||
|
|
||||||
|
// remember how much we've written
|
||||||
|
written := 0
|
||||||
|
|
||||||
w := utilprinters.GetNewTabWriter(trackingWriter)
|
w := utilprinters.GetNewTabWriter(trackingWriter)
|
||||||
for ix := range objs {
|
for ix := range objs {
|
||||||
var mapping *meta.RESTMapping
|
var mapping *meta.RESTMapping
|
||||||
@ -544,11 +547,14 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
|
|||||||
w.Flush()
|
w.Flush()
|
||||||
w.SetRememberedWidths(nil)
|
w.SetRememberedWidths(nil)
|
||||||
|
|
||||||
// TODO: this doesn't belong here
|
|
||||||
// add linebreak between resource groups (if there is more than one)
|
// add linebreak between resource groups (if there is more than one)
|
||||||
// skip linebreak above first resource group
|
// skip linebreak above first resource group
|
||||||
if lastMapping != nil && !o.NoHeaders {
|
if lastMapping != nil && !o.NoHeaders {
|
||||||
fmt.Fprintln(o.ErrOut)
|
// If we've written output since the last time we started a new set of headers, write an empty line to separate object types
|
||||||
|
if written != trackingWriter.Written {
|
||||||
|
fmt.Fprintln(w)
|
||||||
|
written = trackingWriter.Written
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printer, err = o.ToPrinter(mapping, nil, printWithNamespace, printWithKind)
|
printer, err = o.ToPrinter(mapping, nil, printWithNamespace, printWithKind)
|
||||||
|
@ -359,7 +359,7 @@ func TestGetMultipleResourceTypesShowKinds(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
streams, _, buf, bufErr := genericclioptions.NewTestIOStreams()
|
||||||
cmd := NewCmdGet("kubectl", tf, streams)
|
cmd := NewCmdGet("kubectl", tf, streams)
|
||||||
cmd.SetOutput(buf)
|
cmd.SetOutput(buf)
|
||||||
cmd.Run(cmd, []string{"all"})
|
cmd.Run(cmd, []string{"all"})
|
||||||
@ -367,12 +367,18 @@ func TestGetMultipleResourceTypesShowKinds(t *testing.T) {
|
|||||||
expected := `NAME AGE
|
expected := `NAME AGE
|
||||||
pod/foo <unknown>
|
pod/foo <unknown>
|
||||||
pod/bar <unknown>
|
pod/bar <unknown>
|
||||||
|
|
||||||
NAME AGE
|
NAME AGE
|
||||||
service/baz <unknown>
|
service/baz <unknown>
|
||||||
`
|
`
|
||||||
if e, a := expected, buf.String(); e != a {
|
if e, a := expected, buf.String(); e != a {
|
||||||
t.Errorf("expected\n%v\ngot\n%v", e, a)
|
t.Errorf("expected\n%v\ngot\n%v", e, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The error out should be empty
|
||||||
|
if e, a := "", bufErr.String(); e != a {
|
||||||
|
t.Errorf("expected\n%v\ngot\n%v", e, a)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetMultipleTableResourceTypesShowKinds(t *testing.T) {
|
func TestGetMultipleTableResourceTypesShowKinds(t *testing.T) {
|
||||||
@ -414,7 +420,7 @@ func TestGetMultipleTableResourceTypesShowKinds(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
streams, _, buf, bufErr := genericclioptions.NewTestIOStreams()
|
||||||
cmd := NewCmdGet("kubectl", tf, streams)
|
cmd := NewCmdGet("kubectl", tf, streams)
|
||||||
cmd.SetOutput(buf)
|
cmd.SetOutput(buf)
|
||||||
cmd.Run(cmd, []string{"all"})
|
cmd.Run(cmd, []string{"all"})
|
||||||
@ -422,12 +428,71 @@ func TestGetMultipleTableResourceTypesShowKinds(t *testing.T) {
|
|||||||
expected := `NAME READY STATUS RESTARTS AGE
|
expected := `NAME READY STATUS RESTARTS AGE
|
||||||
pod/foo 0/0 0 <unknown>
|
pod/foo 0/0 0 <unknown>
|
||||||
pod/bar 0/0 0 <unknown>
|
pod/bar 0/0 0 <unknown>
|
||||||
|
|
||||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||||
service/baz ClusterIP <none> <none> <none> <unknown>
|
service/baz ClusterIP <none> <none> <none> <unknown>
|
||||||
`
|
`
|
||||||
if e, a := expected, buf.String(); e != a {
|
if e, a := expected, buf.String(); e != a {
|
||||||
t.Errorf("expected\n%v\ngot\n%v", e, a)
|
t.Errorf("expected\n%v\ngot\n%v", e, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The error out should be empty
|
||||||
|
if e, a := "", bufErr.String(); e != a {
|
||||||
|
t.Errorf("expected\n%v\ngot\n%v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNoBlankLinesForGetAll(t *testing.T) {
|
||||||
|
tf := cmdtesting.NewTestFactory().WithNamespace("test")
|
||||||
|
defer tf.Cleanup()
|
||||||
|
|
||||||
|
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
|
||||||
|
tf.UnstructuredClient = &fake.RESTClient{
|
||||||
|
NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer,
|
||||||
|
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":
|
||||||
|
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: emptyTableObjBody(codec)}, nil
|
||||||
|
case p == "/namespaces/test/replicationcontrollers" && m == "GET":
|
||||||
|
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: emptyTableObjBody(codec)}, nil
|
||||||
|
case p == "/namespaces/test/services" && m == "GET":
|
||||||
|
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: emptyTableObjBody(codec)}, nil
|
||||||
|
case p == "/namespaces/test/statefulsets" && m == "GET":
|
||||||
|
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: emptyTableObjBody(codec)}, nil
|
||||||
|
case p == "/namespaces/test/horizontalpodautoscalers" && m == "GET":
|
||||||
|
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: emptyTableObjBody(codec)}, nil
|
||||||
|
case p == "/namespaces/test/jobs" && m == "GET":
|
||||||
|
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: emptyTableObjBody(codec)}, nil
|
||||||
|
case p == "/namespaces/test/cronjobs" && m == "GET":
|
||||||
|
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: emptyTableObjBody(codec)}, nil
|
||||||
|
case p == "/namespaces/test/daemonsets" && m == "GET":
|
||||||
|
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: emptyTableObjBody(codec)}, nil
|
||||||
|
case p == "/namespaces/test/deployments" && m == "GET":
|
||||||
|
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: emptyTableObjBody(codec)}, nil
|
||||||
|
case p == "/namespaces/test/replicasets" && m == "GET":
|
||||||
|
return &http.Response{StatusCode: 200, Header: cmdtesting.DefaultHeader(), Body: emptyTableObjBody(codec)}, nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
t.Fatalf("request url: %#v,and request: %#v", req.URL, req)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
streams, _, buf, errbuf := genericclioptions.NewTestIOStreams()
|
||||||
|
cmd := NewCmdGet("kubectl", tf, streams)
|
||||||
|
cmd.SetOutput(buf)
|
||||||
|
cmd.Run(cmd, []string{"all"})
|
||||||
|
|
||||||
|
expected := ``
|
||||||
|
if e, a := expected, buf.String(); e != a {
|
||||||
|
t.Errorf("expected\n%v\ngot\n%v", e, a)
|
||||||
|
}
|
||||||
|
expectedErr := `No resources found in test namespace.
|
||||||
|
`
|
||||||
|
if e, a := expectedErr, errbuf.String(); e != a {
|
||||||
|
t.Errorf("expectedErr\n%v\ngot\n%v", e, a)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetObjectsShowLabels(t *testing.T) {
|
func TestGetObjectsShowLabels(t *testing.T) {
|
||||||
@ -1097,6 +1162,7 @@ func TestGetMultipleTypeObjects(t *testing.T) {
|
|||||||
expected := `NAME AGE
|
expected := `NAME AGE
|
||||||
pod/foo <unknown>
|
pod/foo <unknown>
|
||||||
pod/bar <unknown>
|
pod/bar <unknown>
|
||||||
|
|
||||||
NAME AGE
|
NAME AGE
|
||||||
service/baz <unknown>
|
service/baz <unknown>
|
||||||
`
|
`
|
||||||
@ -1135,6 +1201,7 @@ func TestGetMultipleTypeTableObjects(t *testing.T) {
|
|||||||
expected := `NAME READY STATUS RESTARTS AGE
|
expected := `NAME READY STATUS RESTARTS AGE
|
||||||
pod/foo 0/0 0 <unknown>
|
pod/foo 0/0 0 <unknown>
|
||||||
pod/bar 0/0 0 <unknown>
|
pod/bar 0/0 0 <unknown>
|
||||||
|
|
||||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||||
service/baz ClusterIP <none> <none> <none> <unknown>
|
service/baz ClusterIP <none> <none> <none> <unknown>
|
||||||
`
|
`
|
||||||
@ -1279,6 +1346,7 @@ func TestGetMultipleTypeObjectsWithLabelSelector(t *testing.T) {
|
|||||||
expected := `NAME AGE
|
expected := `NAME AGE
|
||||||
pod/foo <unknown>
|
pod/foo <unknown>
|
||||||
pod/bar <unknown>
|
pod/bar <unknown>
|
||||||
|
|
||||||
NAME AGE
|
NAME AGE
|
||||||
service/baz <unknown>
|
service/baz <unknown>
|
||||||
`
|
`
|
||||||
@ -1322,6 +1390,7 @@ func TestGetMultipleTypeTableObjectsWithLabelSelector(t *testing.T) {
|
|||||||
expected := `NAME READY STATUS RESTARTS AGE
|
expected := `NAME READY STATUS RESTARTS AGE
|
||||||
pod/foo 0/0 0 <unknown>
|
pod/foo 0/0 0 <unknown>
|
||||||
pod/bar 0/0 0 <unknown>
|
pod/bar 0/0 0 <unknown>
|
||||||
|
|
||||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||||
service/baz ClusterIP <none> <none> <none> <unknown>
|
service/baz ClusterIP <none> <none> <none> <unknown>
|
||||||
`
|
`
|
||||||
@ -1365,6 +1434,7 @@ func TestGetMultipleTypeObjectsWithFieldSelector(t *testing.T) {
|
|||||||
expected := `NAME AGE
|
expected := `NAME AGE
|
||||||
pod/foo <unknown>
|
pod/foo <unknown>
|
||||||
pod/bar <unknown>
|
pod/bar <unknown>
|
||||||
|
|
||||||
NAME AGE
|
NAME AGE
|
||||||
service/baz <unknown>
|
service/baz <unknown>
|
||||||
`
|
`
|
||||||
@ -1408,6 +1478,7 @@ func TestGetMultipleTypeTableObjectsWithFieldSelector(t *testing.T) {
|
|||||||
expected := `NAME READY STATUS RESTARTS AGE
|
expected := `NAME READY STATUS RESTARTS AGE
|
||||||
pod/foo 0/0 0 <unknown>
|
pod/foo 0/0 0 <unknown>
|
||||||
pod/bar 0/0 0 <unknown>
|
pod/bar 0/0 0 <unknown>
|
||||||
|
|
||||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||||
service/baz ClusterIP <none> <none> <none> <unknown>
|
service/baz ClusterIP <none> <none> <none> <unknown>
|
||||||
`
|
`
|
||||||
@ -1451,6 +1522,7 @@ func TestGetMultipleTypeObjectsWithDirectReference(t *testing.T) {
|
|||||||
|
|
||||||
expected := `NAME AGE
|
expected := `NAME AGE
|
||||||
service/baz <unknown>
|
service/baz <unknown>
|
||||||
|
|
||||||
NAME AGE
|
NAME AGE
|
||||||
node/foo <unknown>
|
node/foo <unknown>
|
||||||
`
|
`
|
||||||
@ -1494,6 +1566,7 @@ func TestGetMultipleTypeTableObjectsWithDirectReference(t *testing.T) {
|
|||||||
|
|
||||||
expected := `NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
expected := `NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||||
service/baz ClusterIP <none> <none> <none> <unknown>
|
service/baz ClusterIP <none> <none> <none> <unknown>
|
||||||
|
|
||||||
NAME STATUS ROLES AGE VERSION
|
NAME STATUS ROLES AGE VERSION
|
||||||
node/foo Unknown <none> <unknown>
|
node/foo Unknown <none> <unknown>
|
||||||
`
|
`
|
||||||
@ -2590,3 +2663,11 @@ func nodeTableObjBody(codec runtime.Codec, nodes ...corev1.Node) io.ReadCloser {
|
|||||||
}
|
}
|
||||||
return cmdtesting.ObjBody(codec, table)
|
return cmdtesting.ObjBody(codec, table)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build an empty table response
|
||||||
|
func emptyTableObjBody(codec runtime.Codec) io.ReadCloser {
|
||||||
|
table := &metav1.Table{
|
||||||
|
ColumnDefinitions: podColumns,
|
||||||
|
}
|
||||||
|
return cmdtesting.ObjBody(codec, table)
|
||||||
|
}
|
||||||
|
@ -126,6 +126,30 @@ func TestData() (*corev1.PodList, *corev1.ServiceList, *corev1.ReplicationContro
|
|||||||
return pods, svc, rc
|
return pods, svc, rc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EmptyTestData returns no pod, service, or replication controller
|
||||||
|
func EmptyTestData() (*corev1.PodList, *corev1.ServiceList, *corev1.ReplicationControllerList) {
|
||||||
|
pods := &corev1.PodList{
|
||||||
|
ListMeta: metav1.ListMeta{
|
||||||
|
ResourceVersion: "15",
|
||||||
|
},
|
||||||
|
Items: []corev1.Pod{},
|
||||||
|
}
|
||||||
|
svc := &corev1.ServiceList{
|
||||||
|
ListMeta: metav1.ListMeta{
|
||||||
|
ResourceVersion: "16",
|
||||||
|
},
|
||||||
|
Items: []corev1.Service{},
|
||||||
|
}
|
||||||
|
|
||||||
|
rc := &corev1.ReplicationControllerList{
|
||||||
|
ListMeta: metav1.ListMeta{
|
||||||
|
ResourceVersion: "17",
|
||||||
|
},
|
||||||
|
Items: []corev1.ReplicationController{},
|
||||||
|
}
|
||||||
|
return pods, svc, rc
|
||||||
|
}
|
||||||
|
|
||||||
func GenResponseWithJsonEncodedBody(bodyStruct interface{}) (*http.Response, error) {
|
func GenResponseWithJsonEncodedBody(bodyStruct interface{}) (*http.Response, error) {
|
||||||
jsonBytes, err := json.Marshal(bodyStruct)
|
jsonBytes, err := json.Marshal(bodyStruct)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user