Merge pull request #60793 from charrywanganthony/inert_flag_showall

Automatic merge from submit-queue (batch tested with PRs 60793, 61181, 61267, 61252, 61334). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

--show-all is inert in v1.11

**What this PR does / why we need it**:

`--show-all` is inert in v1.11
ref: #60210

**Special notes for your reviewer**:
/assign @deads2k 

**Release note**:

```release-note
`--show-all` (which only affected pods and only for human readable/non-API printers) is inert in v1.11, and will be removed in a future release.
```
This commit is contained in:
Kubernetes Submit Queue 2018-03-21 20:23:07 -07:00 committed by GitHub
commit 114d481183
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 28 additions and 385 deletions

View File

@ -5302,8 +5302,6 @@ run_initializer_tests() {
output_message=$(kubectl get deployments web 2>&1 "${kube_flags[@]}") output_message=$(kubectl get deployments web 2>&1 "${kube_flags[@]}")
# Post-condition: I assume "web" is the deployment name # Post-condition: I assume "web" is the deployment name
kube::test::if_has_string "${output_message}" 'web' kube::test::if_has_string "${output_message}" 'web'
# Command
output_message=$(kubectl get deployments --show-all 2>&1 "${kube_flags[@]}")
# Post-condition: The text "No resources found" should be part of the output # Post-condition: The text "No resources found" should be part of the output
kube::test::if_has_string "${output_message}" 'No resources found' kube::test::if_has_string "${output_message}" 'No resources found'

View File

@ -21,7 +21,6 @@ go_test(
"pdb_test.go", "pdb_test.go",
"priorityclass_test.go", "priorityclass_test.go",
"quota_test.go", "quota_test.go",
"resource_filter_test.go",
"rolebinding_test.go", "rolebinding_test.go",
"rollback_test.go", "rollback_test.go",
"rolling_updater_test.go", "rolling_updater_test.go",
@ -52,7 +51,6 @@ go_test(
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion:go_default_library",
"//pkg/kubectl/util:go_default_library", "//pkg/kubectl/util:go_default_library",
"//pkg/printers:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/k8s.io/api/apps/v1beta1:go_default_library", "//vendor/k8s.io/api/apps/v1beta1:go_default_library",
"//vendor/k8s.io/api/apps/v1beta2:go_default_library", "//vendor/k8s.io/api/apps/v1beta2:go_default_library",
@ -112,7 +110,6 @@ go_library(
"pdb.go", "pdb.go",
"priorityclass.go", "priorityclass.go",
"quota.go", "quota.go",
"resource_filter.go",
"rolebinding.go", "rolebinding.go",
"rollback.go", "rollback.go",
"rolling_updater.go", "rolling_updater.go",

View File

@ -441,49 +441,17 @@ func Example_printPodShowTerminated() {
} }
cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr) cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr)
podList := newAllPhasePodList() podList := newAllPhasePodList()
// filter pods
filterFuncs := tf.DefaultResourceFilterFunc()
filterOpts := cmdutil.ExtractCmdPrintOptions(cmd, false)
_, filteredPodList, errs := cmdutil.FilterResourceList(podList, filterFuncs, filterOpts)
if errs != nil {
fmt.Printf("Unexpected filter error: %v\n", errs)
}
printer, err := cmdutil.PrinterForOptions(cmdutil.ExtractCmdPrintOptions(cmd, false)) printer, err := cmdutil.PrinterForOptions(cmdutil.ExtractCmdPrintOptions(cmd, false))
if err != nil { if err != nil {
fmt.Printf("Unexpected printer get error: %v\n", errs) fmt.Printf("Unexpected printer get error: %v\n", err)
} }
for _, pod := range filteredPodList { for _, pod := range []runtime.Object{podList} {
err := printer.PrintObj(pod, os.Stdout) err := printer.PrintObj(pod, os.Stdout)
if err != nil { if err != nil {
fmt.Printf("Unexpected error: %v", err) fmt.Printf("Unexpected error: %v", err)
} }
} }
// Output: // Output:
// NAME READY STATUS RESTARTS AGE
// test1 1/2 Pending 6 10y
// test2 1/2 Running 6 10y
// test3 1/2 Succeeded 6 10y
// test4 1/2 Failed 6 10y
// test5 1/2 Unknown 6 10y
}
func Example_printPodShowAll() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: nil,
}
cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr)
podList := newAllPhasePodList()
err := cmdutil.PrintObject(cmd, podList, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
// Output:
// NAME READY STATUS RESTARTS AGE // NAME READY STATUS RESTARTS AGE
// test1 1/2 Pending 6 10y // test1 1/2 Pending 6 10y
// test2 1/2 Running 6 10y // test2 1/2 Running 6 10y

View File

@ -186,15 +186,11 @@ func (o *ConvertOptions) RunConvert() error {
} }
if meta.IsListType(objects) { if meta.IsListType(objects) {
_, items, err := cmdutil.FilterResourceList(objects, nil, nil) obj, err := objectListToVersionedObject([]runtime.Object{objects}, o.specifiedOutputVersion)
if err != nil { if err != nil {
return err return err
} }
filteredObj, err := objectListToVersionedObject(items, o.specifiedOutputVersion) return o.printer.PrintObj(obj, o.out)
if err != nil {
return err
}
return o.printer.PrintObj(filteredObj, o.out)
} }
return o.printer.PrintObj(objects, o.out) return o.printer.PrintObj(objects, o.out)

View File

@ -293,14 +293,8 @@ func (options *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []str
return err return err
} }
filterOpts := cmdutil.ExtractCmdPrintOptions(cmd, options.AllNamespaces)
filterFuncs := f.DefaultResourceFilterFunc()
if r.TargetsSingleItems() {
filterFuncs = nil
}
if printer.IsGeneric() { if printer.IsGeneric() {
return options.printGeneric(printer, r, filterFuncs, filterOpts) return options.printGeneric(printer, r)
} }
allErrs := []error{} allErrs := []error{}
@ -347,7 +341,6 @@ func (options *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []str
showKind := options.ShowKind || resource.MultipleTypesRequested(args) || cmdutil.MustPrintWithKinds(objs, infos, sorter) showKind := options.ShowKind || resource.MultipleTypesRequested(args) || cmdutil.MustPrintWithKinds(objs, infos, sorter)
filteredResourceCount := 0
noHeaders := cmdutil.GetFlagBool(cmd, "no-headers") noHeaders := cmdutil.GetFlagBool(cmd, "no-headers")
for ix := range objs { for ix := range objs {
var mapping *meta.RESTMapping var mapping *meta.RESTMapping
@ -409,18 +402,6 @@ func (options *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []str
typedObj := info.AsInternal() typedObj := info.AsInternal()
// filter objects if filter has been defined for current object
if isFiltered, err := filterFuncs.Filter(typedObj, filterOpts); isFiltered {
if err == nil {
filteredResourceCount++
continue
}
if !errs.Has(err.Error()) {
errs.Insert(err.Error())
allErrs = append(allErrs, err)
}
}
if resourcePrinter, found := printer.(*printers.HumanReadablePrinter); found { if resourcePrinter, found := printer.(*printers.HumanReadablePrinter); found {
resourceName := resourcePrinter.GetResourceKind() resourceName := resourcePrinter.GetResourceKind()
if mapping != nil { if mapping != nil {
@ -475,7 +456,9 @@ func (options *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []str
nonEmptyObjCount++ nonEmptyObjCount++
} }
cmdutil.PrintFilterCount(options.ErrOut, nonEmptyObjCount, filteredResourceCount, len(allErrs), filterOpts, options.IgnoreNotFound) if nonEmptyObjCount == 0 && !options.IgnoreNotFound {
fmt.Fprintln(options.ErrOut, "No resources found.")
}
return utilerrors.NewAggregate(allErrs) return utilerrors.NewAggregate(allErrs)
} }
@ -544,12 +527,6 @@ func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []s
} }
} }
filterOpts := cmdutil.ExtractCmdPrintOptions(cmd, options.AllNamespaces)
filterFuncs := f.DefaultResourceFilterFunc()
if r.TargetsSingleItems() {
filterFuncs = nil
}
info := infos[0] info := infos[0]
mapping := info.ResourceMapping() mapping := info.ResourceMapping()
printOpts := cmdutil.ExtractCmdPrintOptions(cmd, options.AllNamespaces) printOpts := cmdutil.ExtractCmdPrintOptions(cmd, options.AllNamespaces)
@ -588,18 +565,11 @@ func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []s
objsToPrint = append(objsToPrint, obj) objsToPrint = append(objsToPrint, obj)
} }
for _, objToPrint := range objsToPrint { for _, objToPrint := range objsToPrint {
if isFiltered, err := filterFuncs.Filter(objToPrint, filterOpts); !isFiltered { // printing always takes the internal version, but the watch event uses externals
if err != nil { // TODO fix printing to use server-side or be version agnostic
glog.V(2).Infof("Unable to filter resource: %v", err) internalGV := mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
continue if err := printer.PrintObj(attemptToConvertToInternal(objToPrint, mapping, internalGV), writer); err != nil {
} return fmt.Errorf("unable to output the provided object: %v", err)
// printing always takes the internal version, but the watch event uses externals
// TODO fix printing to use server-side or be version agnostic
internalGV := mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
if err := printer.PrintObj(attemptToConvertToInternal(objToPrint, mapping, internalGV), writer); err != nil {
return fmt.Errorf("unable to output the provided object: %v", err)
}
} }
} }
writer.Flush() writer.Flush()
@ -621,18 +591,11 @@ func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []s
return false, nil return false, nil
} }
if isFiltered, err := filterFuncs.Filter(e.Object, filterOpts); !isFiltered { // printing always takes the internal version, but the watch event uses externals
if err != nil { // TODO fix printing to use server-side or be version agnostic
glog.V(2).Infof("Unable to filter resource: %v", err) internalGV := mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
return false, nil if err := printer.PrintObj(attemptToConvertToInternal(e.Object, mapping, internalGV), options.Out); err != nil {
} return false, err
// printing always takes the internal version, but the watch event uses externals
// TODO fix printing to use server-side or be version agnostic
internalGV := mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
if err := printer.PrintObj(attemptToConvertToInternal(e.Object, mapping, internalGV), options.Out); err != nil {
return false, err
}
} }
return false, nil return false, nil
}) })
@ -670,7 +633,7 @@ func (options *GetOptions) decodeIntoTable(encoder runtime.Encoder, obj runtime.
return table, nil return table, nil
} }
func (options *GetOptions) printGeneric(printer printers.ResourcePrinter, r *resource.Result, filterFuncs kubectl.Filters, filterOpts *printers.PrintOptions) error { func (options *GetOptions) printGeneric(printer printers.ResourcePrinter, r *resource.Result) error {
// we flattened the data from the builder, so we have individual items, but now we'd like to either: // 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 // 1. if there is more than one item, combine them all into a single list
// 2. if there is a single item and that item is a list, leave it as its specific list // 2. if there is a single item and that item is a list, leave it as its specific list
@ -723,12 +686,12 @@ func (options *GetOptions) printGeneric(printer printers.ResourcePrinter, r *res
isList := meta.IsListType(obj) isList := meta.IsListType(obj)
if isList { if isList {
_, items, err := cmdutil.FilterResourceList(obj, filterFuncs, filterOpts) items, err := meta.ExtractList(obj)
if err != nil { if err != nil {
return err return err
} }
// take the filtered items and create a new list for display // take the items and create a new list for display
list := &unstructured.UnstructuredList{ list := &unstructured.UnstructuredList{
Object: map[string]interface{}{ Object: map[string]interface{}{
"kind": "List", "kind": "List",
@ -752,12 +715,8 @@ func (options *GetOptions) printGeneric(printer printers.ResourcePrinter, r *res
return utilerrors.Reduce(utilerrors.Flatten(utilerrors.NewAggregate(errs))) return utilerrors.Reduce(utilerrors.Flatten(utilerrors.NewAggregate(errs)))
} }
if isFiltered, err := filterFuncs.Filter(obj, filterOpts); !isFiltered { if printErr := printer.PrintObj(obj, options.Out); printErr != nil {
if err != nil { errs = append(errs, printErr)
glog.V(2).Infof("Unable to filter resource: %v", err)
} else if err := printer.PrintObj(obj, options.Out); err != nil {
errs = append(errs, err)
}
} }
return utilerrors.Reduce(utilerrors.Flatten(utilerrors.NewAggregate(errs))) return utilerrors.Reduce(utilerrors.Flatten(utilerrors.NewAggregate(errs)))

View File

@ -19,7 +19,6 @@ package resource
import ( import (
"bytes" "bytes"
encjson "encoding/json" encjson "encoding/json"
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
@ -351,77 +350,6 @@ foo 0/0 0 <unknown>
} }
} }
func TestGetObjectsFiltered(t *testing.T) {
initTestErrorHandler(t)
pods, _, _ := testData()
pods.Items[0].Status.Phase = api.PodFailed
first := &pods.Items[0]
testCases := []struct {
args []string
resp runtime.Object
flags map[string]string
expect string
}{
{args: []string{"pods", "foo"}, resp: first, flags: map[string]string{"show-all": "true"},
expect: "NAME READY STATUS RESTARTS AGE\nfoo 0/0 Failed 0 <unknown>\n"},
{args: []string{"pods", "foo"}, flags: map[string]string{"show-all": "false"}, resp: first,
expect: "NAME READY STATUS RESTARTS AGE\nfoo 0/0 Failed 0 <unknown>\n"},
{args: []string{"pods"}, flags: map[string]string{"show-all": "true"}, resp: pods,
expect: "NAME READY STATUS RESTARTS AGE\nfoo 0/0 Failed 0 <unknown>\nbar 0/0 0 <unknown>\n"},
{args: []string{"pods/foo"}, resp: first, flags: map[string]string{"show-all": "false"},
expect: "NAME READY STATUS RESTARTS AGE\nfoo 0/0 Failed 0 <unknown>\n"},
{args: []string{"pods"}, flags: map[string]string{"show-all": "false", "output": "name"}, resp: pods,
expect: "pod/foo\npod/bar\n"},
{args: []string{}, flags: map[string]string{"show-all": "false", "filename": "../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}, resp: pods,
expect: "NAME READY STATUS RESTARTS AGE\nfoo 0/0 Failed 0 <unknown>\nbar 0/0 0 <unknown>\n"},
{args: []string{"pods"}, resp: pods, flags: map[string]string{"show-all": "false"},
expect: "NAME READY STATUS RESTARTS AGE\nbar 0/0 0 <unknown>\n"},
{args: []string{"pods"}, flags: map[string]string{"show-all": "true", "output": "name"}, resp: pods,
expect: "pod/foo\npod/bar\n"},
{args: []string{"pods"}, flags: map[string]string{"show-all": "false"}, resp: pods,
expect: "NAME READY STATUS RESTARTS AGE\nbar 0/0 0 <unknown>\n"},
}
for i, test := range testCases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
tf.UnstructuredClient = &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: unstructuredSerializer,
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, test.resp)},
}
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdGet(tf, buf, errBuf)
cmd.SetOutput(buf)
for k, v := range test.flags {
cmd.Flags().Lookup(k).Value.Set(v)
}
cmd.Run(cmd, test.args)
if e, a := test.expect, buf.String(); e != a {
t.Errorf("expected %q, got %q", e, a)
}
})
}
}
func TestGetObjectIgnoreNotFound(t *testing.T) { func TestGetObjectIgnoreNotFound(t *testing.T) {
initTestErrorHandler(t) initTestErrorHandler(t)

View File

@ -127,9 +127,6 @@ type ClientAccessFactory interface {
// BindExternalFlags adds any flags defined by external projects (not part of pflags) // BindExternalFlags adds any flags defined by external projects (not part of pflags)
BindExternalFlags(flags *pflag.FlagSet) BindExternalFlags(flags *pflag.FlagSet)
// DefaultResourceFilterFunc returns a collection of FilterFuncs suitable for filtering specific resource types.
DefaultResourceFilterFunc() kubectl.Filters
// SuggestedPodTemplateResources returns a list of resource types that declare a pod template // SuggestedPodTemplateResources returns a list of resource types that declare a pod template
SuggestedPodTemplateResources() []schema.GroupResource SuggestedPodTemplateResources() []schema.GroupResource

View File

@ -403,10 +403,6 @@ func (f *ring0Factory) BindExternalFlags(flags *pflag.FlagSet) {
flags.AddGoFlagSet(flag.CommandLine) flags.AddGoFlagSet(flag.CommandLine)
} }
func (f *ring0Factory) DefaultResourceFilterFunc() kubectl.Filters {
return kubectl.NewResourceFilter()
}
func (f *ring0Factory) SuggestedPodTemplateResources() []schema.GroupResource { func (f *ring0Factory) SuggestedPodTemplateResources() []schema.GroupResource {
return []schema.GroupResource{ return []schema.GroupResource{
{Resource: "replicationcontroller"}, {Resource: "replicationcontroller"},

View File

@ -43,10 +43,8 @@ import (
"k8s.io/apimachinery/pkg/util/strategicpatch" "k8s.io/apimachinery/pkg/util/strategicpatch"
"k8s.io/apimachinery/pkg/util/yaml" "k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/printers"
utilexec "k8s.io/utils/exec" utilexec "k8s.io/utils/exec"
) )
@ -689,56 +687,6 @@ func MustPrintWithKinds(objs []runtime.Object, infos []*resource.Info, sorter *k
return false return false
} }
// FilterResourceList receives a list of runtime objects.
// If any objects are filtered, that number is returned along with a modified list.
func FilterResourceList(obj runtime.Object, filterFuncs kubectl.Filters, filterOpts *printers.PrintOptions) (int, []runtime.Object, error) {
items, err := meta.ExtractList(obj)
if err != nil {
return 0, []runtime.Object{obj}, utilerrors.NewAggregate([]error{err})
}
if errs := runtime.DecodeList(items, legacyscheme.Codecs.UniversalDecoder(), unstructured.UnstructuredJSONScheme); len(errs) > 0 {
return 0, []runtime.Object{obj}, utilerrors.NewAggregate(errs)
}
filterCount := 0
list := make([]runtime.Object, 0, len(items))
for _, obj := range items {
if isFiltered, err := filterFuncs.Filter(obj, filterOpts); !isFiltered {
if err != nil {
glog.V(2).Infof("Unable to filter resource: %v", err)
continue
}
list = append(list, obj)
} else if isFiltered {
filterCount++
}
}
return filterCount, list, nil
}
// PrintFilterCount displays informational messages based on the number of resources found, hidden, or
// config flags shown.
func PrintFilterCount(out io.Writer, found, hidden, errors int, options *printers.PrintOptions, ignoreNotFound bool) {
switch {
case errors > 0 || ignoreNotFound:
// print nothing
case found <= hidden:
if found == 0 {
fmt.Fprintln(out, "No resources found.")
} else {
fmt.Fprintln(out, "No resources found, use --show-all to see completed objects.")
}
case hidden > 0 && !options.ShowAll && !options.NoHeaders:
if glog.V(2) {
if hidden > 1 {
fmt.Fprintf(out, "info: %d objects not shown, use --show-all to see completed objects.\n", hidden)
} else {
fmt.Fprintf(out, "info: 1 object not shown, use --show-all to see completed objects.\n")
}
}
}
}
// IsSiblingCommandExists receives a pointer to a cobra command and a target string. // IsSiblingCommandExists receives a pointer to a cobra command and a target string.
// Returns true if the target string is found in the list of sibling commands. // Returns true if the target string is found in the list of sibling commands.
func IsSiblingCommandExists(cmd *cobra.Command, targetCmdName string) bool { func IsSiblingCommandExists(cmd *cobra.Command, targetCmdName string) bool {

View File

@ -1,65 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kubectl
import (
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/printers"
)
// FilterFunc is a function that knows how to filter a specific resource kind.
// It receives a generic runtime.Object which must be type-checked by the function.
// Returns a boolean value true if a resource is filtered, or false otherwise.
type FilterFunc func(runtime.Object, printers.PrintOptions) bool
// Filters is a collection of filter funcs
type Filters []FilterFunc
func NewResourceFilter() Filters {
return []FilterFunc{
filterPods,
}
}
// filterPods returns true if a pod should be skipped.
// If show-all is true, the pod will be never be skipped (return false);
// otherwise, skip terminated pod.
func filterPods(obj runtime.Object, options printers.PrintOptions) bool {
if options.ShowAll {
return false
}
switch p := obj.(type) {
case *v1.Pod:
return p.Status.Phase == v1.PodSucceeded || p.Status.Phase == v1.PodFailed
case *api.Pod:
return p.Status.Phase == api.PodSucceeded || p.Status.Phase == api.PodFailed
}
return false
}
// Filter loops through a collection of FilterFuncs until it finds one that can filter the given resource
func (f Filters) Filter(obj runtime.Object, opts *printers.PrintOptions) (bool, error) {
for _, filter := range f {
if ok := filter(obj, *opts); ok {
return true, nil
}
}
return false, nil
}

View File

@ -1,76 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kubectl
import (
"testing"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/printers"
)
func TestResourceFilter(t *testing.T) {
tests := []struct {
name string
hide bool
object runtime.Object
}{
{"v1.Pod pending", false, &v1.Pod{Status: v1.PodStatus{Phase: v1.PodPending}}},
{"v1.Pod running", false, &v1.Pod{Status: v1.PodStatus{Phase: v1.PodRunning}}},
{"v1.Pod succeeded", true, &v1.Pod{Status: v1.PodStatus{Phase: v1.PodSucceeded}}},
{"v1.Pod failed", true, &v1.Pod{Status: v1.PodStatus{Phase: v1.PodFailed}}},
{"v1.Pod evicted", true, &v1.Pod{Status: v1.PodStatus{Phase: v1.PodFailed, Reason: "Evicted"}}},
{"v1.Pod unknown", false, &v1.Pod{Status: v1.PodStatus{Phase: v1.PodUnknown}}},
{"api.Pod pending", false, &api.Pod{Status: api.PodStatus{Phase: api.PodPending}}},
{"api.Pod running", false, &api.Pod{Status: api.PodStatus{Phase: api.PodRunning}}},
{"api.Pod succeeded", true, &api.Pod{Status: api.PodStatus{Phase: api.PodSucceeded}}},
{"api.Pod failed", true, &api.Pod{Status: api.PodStatus{Phase: api.PodFailed}}},
{"api.Pod evicted", true, &api.Pod{Status: api.PodStatus{Phase: api.PodFailed, Reason: "Evicted"}}},
{"api.Pod unknown", false, &api.Pod{Status: api.PodStatus{Phase: api.PodUnknown}}},
}
filters := NewResourceFilter()
options := &printers.PrintOptions{
ShowAll: false,
}
for _, test := range tests {
got, err := filters.Filter(test.object, options)
if err != nil {
t.Errorf("%v: unexpected error: %v", test.name, err)
continue
}
if want := test.hide; got != want {
t.Errorf("%v: got %v, want %v", test.name, got, want)
}
}
options.ShowAll = true
for _, test := range tests {
got, err := filters.Filter(test.object, options)
if err != nil {
t.Errorf("%v: unexpected error: %v", test.name, err)
continue
}
if want := false; got != want {
t.Errorf("%v (ShowAll): got %v, want %v", test.name, got, want)
}
}
}

View File

@ -375,9 +375,6 @@ func PrintTable(table *metav1beta1.Table, output io.Writer, options PrintOptions
fmt.Fprintln(output) fmt.Fprintln(output)
} }
for _, row := range table.Rows { for _, row := range table.Rows {
if !options.ShowAll && hasCondition(row.Conditions, metav1beta1.RowCompleted) {
continue
}
first := true first := true
for i, cell := range row.Cells { for i, cell := range row.Cells {
column := table.ColumnDefinitions[i] column := table.ColumnDefinitions[i]

View File

@ -1542,7 +1542,7 @@ func TestPrintPodTable(t *testing.T) {
expect: "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\tLABELS\ntest1\t1/2\tRunning\t6\t<unknown>\ta=1,b=2\n", expect: "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\tLABELS\ntest1\t1/2\tRunning\t6\t<unknown>\ta=1,b=2\n",
}, },
{ {
obj: &api.PodList{Items: []api.Pod{*runningPod, *failedPod}}, opts: printers.PrintOptions{ShowAll: true, ColumnLabels: []string{"a"}}, obj: &api.PodList{Items: []api.Pod{*runningPod, *failedPod}}, opts: printers.PrintOptions{ColumnLabels: []string{"a"}},
expect: "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\tA\ntest1\t1/2\tRunning\t6\t<unknown>\t1\ntest2\t1/2\tFailed\t6\t<unknown>\t\n", expect: "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\tA\ntest1\t1/2\tRunning\t6\t<unknown>\t1\ntest2\t1/2\tFailed\t6\t<unknown>\t\n",
}, },
{ {
@ -1551,11 +1551,11 @@ func TestPrintPodTable(t *testing.T) {
}, },
{ {
obj: failedPod, opts: printers.PrintOptions{}, obj: failedPod, opts: printers.PrintOptions{},
expect: "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\n", expect: "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\ntest2\t1/2\tFailed\t6\t<unknown>\n",
ignoreLegacy: true, // filtering is not done by the printer in the legacy path ignoreLegacy: true, // filtering is not done by the printer in the legacy path
}, },
{ {
obj: failedPod, opts: printers.PrintOptions{ShowAll: true}, obj: failedPod, opts: printers.PrintOptions{},
expect: "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\ntest2\t1/2\tFailed\t6\t<unknown>\n", expect: "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\ntest2\t1/2\tFailed\t6\t<unknown>\n",
}, },
} }
@ -1671,7 +1671,7 @@ func TestPrintPod(t *testing.T) {
} }
for i, test := range tests { for i, test := range tests {
rows, err := printPod(&test.pod, printers.PrintOptions{ShowAll: true}) rows, err := printPod(&test.pod, printers.PrintOptions{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -1781,7 +1781,7 @@ func TestPrintPodList(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
rows, err := printPodList(&test.pods, printers.PrintOptions{ShowAll: true}) rows, err := printPodList(&test.pods, printers.PrintOptions{})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)