command Factory should provide Printers

The factory knows all possible types, and should abstract the process of
creating all printers. A future refactor can further reduce the
dependencies between printer code and internal types.
This commit is contained in:
Clayton Coleman 2017-02-19 17:39:43 -05:00
parent 90fdd067e9
commit 19ae89dcd8
No known key found for this signature in database
GPG Key ID: 3D16906B4F1C5CB3
7 changed files with 114 additions and 75 deletions

View File

@ -41,6 +41,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/printers"
) )
type InternalType struct { type InternalType struct {
@ -214,13 +215,15 @@ type TestFactory struct {
Typer runtime.ObjectTyper Typer runtime.ObjectTyper
Client kubectl.RESTClient Client kubectl.RESTClient
UnstructuredClient kubectl.RESTClient UnstructuredClient kubectl.RESTClient
Describer kubectl.Describer Describer printers.Describer
Printer kubectl.ResourcePrinter Printer printers.ResourcePrinter
CommandPrinter printers.ResourcePrinter
Validator validation.Schema Validator validation.Schema
Namespace string Namespace string
ClientConfig *restclient.Config ClientConfig *restclient.Config
Err error Err error
Command string Command string
GenericPrinter bool
ClientForMappingFunc func(mapping *meta.RESTMapping) (resource.RESTClient, error) ClientForMappingFunc func(mapping *meta.RESTMapping) (resource.RESTClient, error)
UnstructuredClientForMappingFunc func(mapping *meta.RESTMapping) (resource.RESTClient, error) UnstructuredClientForMappingFunc func(mapping *meta.RESTMapping) (resource.RESTClient, error)
@ -331,11 +334,15 @@ func (f *FakeFactory) UnstructuredClientForMapping(mapping *meta.RESTMapping) (r
return f.tf.UnstructuredClient, f.tf.Err return f.tf.UnstructuredClient, f.tf.Err
} }
func (f *FakeFactory) Describer(*meta.RESTMapping) (kubectl.Describer, error) { func (f *FakeFactory) Describer(*meta.RESTMapping) (printers.Describer, error) {
return f.tf.Describer, f.tf.Err return f.tf.Describer, f.tf.Err
} }
func (f *FakeFactory) Printer(mapping *meta.RESTMapping, options kubectl.PrintOptions) (kubectl.ResourcePrinter, error) { func (f *FakeFactory) PrinterForCommand(cmd *cobra.Command) (printers.ResourcePrinter, bool, error) {
return f.tf.CommandPrinter, f.tf.GenericPrinter, f.tf.Err
}
func (f *FakeFactory) Printer(mapping *meta.RESTMapping, options printers.PrintOptions) (printers.ResourcePrinter, error) {
return f.tf.Printer, f.tf.Err return f.tf.Printer, f.tf.Err
} }
@ -451,7 +458,7 @@ func (f *FakeFactory) PrintObject(cmd *cobra.Command, mapper meta.RESTMapper, ob
return nil return nil
} }
func (f *FakeFactory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMapping, withNamespace bool) (kubectl.ResourcePrinter, error) { func (f *FakeFactory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMapping, withNamespace bool) (printers.ResourcePrinter, error) {
return f.tf.Printer, f.tf.Err return f.tf.Printer, f.tf.Err
} }
@ -587,11 +594,15 @@ func (f *fakeAPIFactory) UnstructuredClientForMapping(m *meta.RESTMapping) (reso
return f.tf.UnstructuredClient, f.tf.Err return f.tf.UnstructuredClient, f.tf.Err
} }
func (f *fakeAPIFactory) Describer(*meta.RESTMapping) (kubectl.Describer, error) { func (f *fakeAPIFactory) PrinterForCommand(cmd *cobra.Command) (printers.ResourcePrinter, bool, error) {
return f.tf.CommandPrinter, f.tf.GenericPrinter, f.tf.Err
}
func (f *fakeAPIFactory) Describer(*meta.RESTMapping) (printers.Describer, error) {
return f.tf.Describer, f.tf.Err return f.tf.Describer, f.tf.Err
} }
func (f *fakeAPIFactory) Printer(mapping *meta.RESTMapping, options kubectl.PrintOptions) (kubectl.ResourcePrinter, error) { func (f *fakeAPIFactory) Printer(mapping *meta.RESTMapping, options printers.PrintOptions) (printers.ResourcePrinter, error) {
return f.tf.Printer, f.tf.Err return f.tf.Printer, f.tf.Err
} }
@ -664,7 +675,7 @@ func (f *fakeAPIFactory) PrintObject(cmd *cobra.Command, mapper meta.RESTMapper,
return printer.PrintObj(obj, out) return printer.PrintObj(obj, out)
} }
func (f *fakeAPIFactory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMapping, withNamespace bool) (kubectl.ResourcePrinter, error) { func (f *fakeAPIFactory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMapping, withNamespace bool) (printers.ResourcePrinter, error) {
return f.tf.Printer, f.tf.Err return f.tf.Printer, f.tf.Err
} }

View File

@ -51,6 +51,7 @@ import (
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
"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"
) )
const ( const (
@ -136,7 +137,8 @@ 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)
DefaultResourceFilterOptions(cmd *cobra.Command, withNamespace bool) *kubectl.PrintOptions // TODO: Break the dependency on cmd here.
DefaultResourceFilterOptions(cmd *cobra.Command, withNamespace bool) *printers.PrintOptions
// DefaultResourceFilterFunc returns a collection of FilterFuncs suitable for filtering specific resource types. // DefaultResourceFilterFunc returns a collection of FilterFuncs suitable for filtering specific resource types.
DefaultResourceFilterFunc() kubectl.Filters DefaultResourceFilterFunc() kubectl.Filters
@ -144,7 +146,7 @@ type ClientAccessFactory interface {
SuggestedPodTemplateResources() []schema.GroupResource SuggestedPodTemplateResources() []schema.GroupResource
// Returns a Printer for formatting objects of the given type or an error. // Returns a Printer for formatting objects of the given type or an error.
Printer(mapping *meta.RESTMapping, options kubectl.PrintOptions) (kubectl.ResourcePrinter, error) Printer(mapping *meta.RESTMapping, options printers.PrintOptions) (printers.ResourcePrinter, error)
// Pauser marks the object in the info as paused. Currently supported only for Deployments. // Pauser marks the object in the info as paused. Currently supported only for Deployments.
// Returns the patched object in bytes and any error that occured during the encoding or // Returns the patched object in bytes and any error that occured during the encoding or
// in case the object is already paused. // in case the object is already paused.
@ -193,7 +195,7 @@ type ObjectMappingFactory interface {
// Returns a RESTClient for working with Unstructured objects. // Returns a RESTClient for working with Unstructured objects.
UnstructuredClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error) UnstructuredClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error)
// Returns a Describer for displaying the specified RESTMapping type or an error. // Returns a Describer for displaying the specified RESTMapping type or an error.
Describer(mapping *meta.RESTMapping) (kubectl.Describer, error) Describer(mapping *meta.RESTMapping) (printers.Describer, error)
// LogsForObject returns a request for the logs associated with the provided object // LogsForObject returns a request for the logs associated with the provided object
LogsForObject(object, options runtime.Object) (*restclient.Request, error) LogsForObject(object, options runtime.Object) (*restclient.Request, error)
@ -211,10 +213,6 @@ type ObjectMappingFactory interface {
// AttachablePodForObject returns the pod to which to attach given an object. // AttachablePodForObject returns the pod to which to attach given an object.
AttachablePodForObject(object runtime.Object) (*api.Pod, error) AttachablePodForObject(object runtime.Object) (*api.Pod, error)
// PrinterForMapping returns a printer suitable for displaying the provided resource type.
// Requires that printer flags have been added to cmd (see AddPrinterFlags).
PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMapping, withNamespace bool) (kubectl.ResourcePrinter, error)
// Returns a schema that can validate objects stored on disk. // Returns a schema that can validate objects stored on disk.
Validator(validate bool, cacheDir string) (validation.Schema, error) Validator(validate bool, cacheDir string) (validation.Schema, error)
// SwaggerSchema returns the schema declaration for the provided group version kind. // SwaggerSchema returns the schema declaration for the provided group version kind.
@ -224,6 +222,14 @@ type ObjectMappingFactory interface {
// BuilderFactory holds the second level of factory methods. These functions depend upon ObjectMappingFactory and ClientAccessFactory methods. // BuilderFactory holds the second level of factory methods. These functions depend upon ObjectMappingFactory and ClientAccessFactory methods.
// Generally they depend upon client mapper functions // Generally they depend upon client mapper functions
type BuilderFactory interface { type BuilderFactory interface {
// PrinterForCommand returns the default printer for the command. It requires that certain options
// are declared on the command (see AddPrinterFlags). Returns a printer, true if the printer is
// generic (is not internal), or an error if a printer could not be found.
// TODO: Break the dependency on cmd here.
PrinterForCommand(cmd *cobra.Command) (printers.ResourcePrinter, bool, error)
// PrinterForMapping returns a printer suitable for displaying the provided resource type.
// Requires that printer flags have been added to cmd (see AddPrinterFlags).
PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMapping, withNamespace bool) (printers.ResourcePrinter, error)
// PrintObject prints an api object given command line flags to modify the output format // PrintObject prints an api object given command line flags to modify the output format
PrintObject(cmd *cobra.Command, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error PrintObject(cmd *cobra.Command, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error
// One stop shopping for a Builder // One stop shopping for a Builder

View File

@ -19,13 +19,16 @@ limitations under the License.
package util package util
import ( import (
"fmt"
"io" "io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/printers"
) )
type ring2Factory struct { type ring2Factory struct {
@ -42,6 +45,54 @@ func NewBuilderFactory(clientAccessFactory ClientAccessFactory, objectMappingFac
return f return f
} }
func (f *ring2Factory) PrinterForCommand(cmd *cobra.Command) (printers.ResourcePrinter, bool, error) {
mapper, typer := f.objectMappingFactory.Object()
// TODO: used by the custom column implementation and the name implementation, break this dependency
decoders := []runtime.Decoder{f.clientAccessFactory.Decoder(true), unstructured.UnstructuredJSONScheme}
return PrinterForCommand(cmd, mapper, typer, decoders)
}
func (f *ring2Factory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMapping, withNamespace bool) (printers.ResourcePrinter, error) {
printer, generic, err := f.PrinterForCommand(cmd)
if err != nil {
return nil, err
}
// Make sure we output versioned data for generic printers
if generic {
if mapping == nil {
return nil, fmt.Errorf("no serialization format found")
}
version := mapping.GroupVersionKind.GroupVersion()
if version.Empty() {
return nil, fmt.Errorf("no serialization format found")
}
printer = printers.NewVersionedPrinter(printer, mapping.ObjectConvertor, version, mapping.GroupVersionKind.GroupVersion())
} else {
// Some callers do not have "label-columns" so we can't use the GetFlagStringSlice() helper
columnLabel, err := cmd.Flags().GetStringSlice("label-columns")
if err != nil {
columnLabel = []string{}
}
printer, err = f.clientAccessFactory.Printer(mapping, printers.PrintOptions{
NoHeaders: GetFlagBool(cmd, "no-headers"),
WithNamespace: withNamespace,
Wide: GetWideFlag(cmd),
ShowAll: GetFlagBool(cmd, "show-all"),
ShowLabels: GetFlagBool(cmd, "show-labels"),
AbsoluteTimestamps: isWatch(cmd),
ColumnLabels: columnLabel,
})
if err != nil {
return nil, err
}
printer = maybeWrapSortingPrinter(cmd, printer)
}
return printer, nil
}
func (f *ring2Factory) PrintObject(cmd *cobra.Command, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error { func (f *ring2Factory) PrintObject(cmd *cobra.Command, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error {
// try to get a typed object // try to get a typed object
_, typer := f.objectMappingFactory.Object() _, typer := f.objectMappingFactory.Object()
@ -66,7 +117,7 @@ func (f *ring2Factory) PrintObject(cmd *cobra.Command, mapper meta.RESTMapper, o
return err return err
} }
printer, err := f.objectMappingFactory.PrinterForMapping(cmd, mapping, false) printer, err := f.PrinterForMapping(cmd, mapping, false)
if err != nil { if err != nil {
return err return err
} }

View File

@ -49,6 +49,8 @@ import (
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"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"
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
) )
type ring0Factory struct { type ring0Factory struct {
@ -360,12 +362,12 @@ func (f *ring0Factory) BindExternalFlags(flags *pflag.FlagSet) {
flags.AddGoFlagSet(flag.CommandLine) flags.AddGoFlagSet(flag.CommandLine)
} }
func (f *ring0Factory) DefaultResourceFilterOptions(cmd *cobra.Command, withNamespace bool) *kubectl.PrintOptions { func (f *ring0Factory) DefaultResourceFilterOptions(cmd *cobra.Command, withNamespace bool) *printers.PrintOptions {
columnLabel, err := cmd.Flags().GetStringSlice("label-columns") columnLabel, err := cmd.Flags().GetStringSlice("label-columns")
if err != nil { if err != nil {
columnLabel = []string{} columnLabel = []string{}
} }
opts := &kubectl.PrintOptions{ opts := &printers.PrintOptions{
NoHeaders: GetFlagBool(cmd, "no-headers"), NoHeaders: GetFlagBool(cmd, "no-headers"),
WithNamespace: withNamespace, WithNamespace: withNamespace,
Wide: GetWideFlag(cmd), Wide: GetWideFlag(cmd),
@ -392,8 +394,10 @@ func (f *ring0Factory) SuggestedPodTemplateResources() []schema.GroupResource {
} }
} }
func (f *ring0Factory) Printer(mapping *meta.RESTMapping, options kubectl.PrintOptions) (kubectl.ResourcePrinter, error) { func (f *ring0Factory) Printer(mapping *meta.RESTMapping, options printers.PrintOptions) (printers.ResourcePrinter, error) {
return kubectl.NewHumanReadablePrinter(options), nil p := printers.NewHumanReadablePrinter(options)
printersinternal.AddHandlers(p)
return p, nil
} }
func (f *ring0Factory) Pauser(info *resource.Info) ([]byte, error) { func (f *ring0Factory) Pauser(info *resource.Info) ([]byte, error) {

View File

@ -27,7 +27,6 @@ import (
"time" "time"
"github.com/emicklei/go-restful/swagger" "github.com/emicklei/go-restful/swagger"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -48,6 +47,8 @@ import (
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
"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"
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
) )
type ring1Factory struct { type ring1Factory struct {
@ -58,10 +59,12 @@ func NewObjectMappingFactory(clientAccessFactory ClientAccessFactory) ObjectMapp
f := &ring1Factory{ f := &ring1Factory{
clientAccessFactory: clientAccessFactory, clientAccessFactory: clientAccessFactory,
} }
return f return f
} }
// TODO: This method should return an error now that it can fail. Alternatively, it needs to
// return lazy implementations of mapper and typer that don't hit the wire until they are
// invoked.
func (f *ring1Factory) Object() (meta.RESTMapper, runtime.ObjectTyper) { func (f *ring1Factory) Object() (meta.RESTMapper, runtime.ObjectTyper) {
mapper := api.Registry.RESTMapper() mapper := api.Registry.RESTMapper()
discoveryClient, err := f.clientAccessFactory.DiscoveryClient() discoveryClient, err := f.clientAccessFactory.DiscoveryClient()
@ -143,7 +146,7 @@ func (f *ring1Factory) UnstructuredClientForMapping(mapping *meta.RESTMapping) (
return restclient.RESTClientFor(cfg) return restclient.RESTClientFor(cfg)
} }
func (f *ring1Factory) Describer(mapping *meta.RESTMapping) (kubectl.Describer, error) { func (f *ring1Factory) Describer(mapping *meta.RESTMapping) (printers.Describer, error) {
mappingVersion := mapping.GroupVersionKind.GroupVersion() mappingVersion := mapping.GroupVersionKind.GroupVersion()
if mapping.GroupVersionKind.Group == federation.GroupName { if mapping.GroupVersionKind.Group == federation.GroupName {
fedClientSet, err := f.clientAccessFactory.FederationClientSetForVersion(&mappingVersion) fedClientSet, err := f.clientAccessFactory.FederationClientSetForVersion(&mappingVersion)
@ -151,7 +154,7 @@ func (f *ring1Factory) Describer(mapping *meta.RESTMapping) (kubectl.Describer,
return nil, err return nil, err
} }
if mapping.GroupVersionKind.Kind == "Cluster" { if mapping.GroupVersionKind.Kind == "Cluster" {
return &kubectl.ClusterDescriber{Interface: fedClientSet}, nil return &printersinternal.ClusterDescriber{Interface: fedClientSet}, nil
} }
} }
@ -166,7 +169,7 @@ func (f *ring1Factory) Describer(mapping *meta.RESTMapping) (kubectl.Describer,
} }
// try to get a describer // try to get a describer
if describer, ok := kubectl.DescriberFor(mapping.GroupVersionKind.GroupKind(), clientset); ok { if describer, ok := printersinternal.DescriberFor(mapping.GroupVersionKind.GroupKind(), clientset); ok {
return describer, nil return describer, nil
} }
// if this is a kind we don't have a describer for yet, go generic if possible // if this is a kind we don't have a describer for yet, go generic if possible
@ -178,7 +181,7 @@ func (f *ring1Factory) Describer(mapping *meta.RESTMapping) (kubectl.Describer,
} }
// helper function to make a generic describer, or return an error // helper function to make a generic describer, or return an error
func genericDescriber(clientAccessFactory ClientAccessFactory, mapping *meta.RESTMapping) (kubectl.Describer, error) { func genericDescriber(clientAccessFactory ClientAccessFactory, mapping *meta.RESTMapping) (printers.Describer, error) {
clientConfig, err := clientAccessFactory.ClientConfig() clientConfig, err := clientAccessFactory.ClientConfig()
if err != nil { if err != nil {
return nil, err return nil, err
@ -202,7 +205,7 @@ func genericDescriber(clientAccessFactory ClientAccessFactory, mapping *meta.RES
} }
eventsClient := clientSet.Core() eventsClient := clientSet.Core()
return kubectl.GenericDescriberFor(mapping, dynamicClient, eventsClient), nil return printersinternal.GenericDescriberFor(mapping, dynamicClient, eventsClient), nil
} }
func (f *ring1Factory) LogsForObject(object, options runtime.Object) (*restclient.Request, error) { func (f *ring1Factory) LogsForObject(object, options runtime.Object) (*restclient.Request, error) {
@ -361,48 +364,6 @@ func (f *ring1Factory) AttachablePodForObject(object runtime.Object) (*api.Pod,
return pod, err return pod, err
} }
func (f *ring1Factory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMapping, withNamespace bool) (kubectl.ResourcePrinter, error) {
printer, generic, err := PrinterForCommand(cmd)
if err != nil {
return nil, err
}
// Make sure we output versioned data for generic printers
if generic {
if mapping == nil {
return nil, fmt.Errorf("no serialization format found")
}
version := mapping.GroupVersionKind.GroupVersion()
if version.Empty() {
return nil, fmt.Errorf("no serialization format found")
}
printer = kubectl.NewVersionedPrinter(printer, mapping.ObjectConvertor, version, mapping.GroupVersionKind.GroupVersion())
} else {
// Some callers do not have "label-columns" so we can't use the GetFlagStringSlice() helper
columnLabel, err := cmd.Flags().GetStringSlice("label-columns")
if err != nil {
columnLabel = []string{}
}
printer, err = f.clientAccessFactory.Printer(mapping, kubectl.PrintOptions{
NoHeaders: GetFlagBool(cmd, "no-headers"),
WithNamespace: withNamespace,
Wide: GetWideFlag(cmd),
ShowAll: GetFlagBool(cmd, "show-all"),
ShowLabels: GetFlagBool(cmd, "show-labels"),
AbsoluteTimestamps: isWatch(cmd),
ColumnLabels: columnLabel,
})
if err != nil {
return nil, err
}
printer = maybeWrapSortingPrinter(cmd, printer)
}
return printer, nil
}
func (f *ring1Factory) Validator(validate bool, cacheDir string) (validation.Schema, error) { func (f *ring1Factory) Validator(validate bool, cacheDir string) (validation.Schema, error) {
if validate { if validate {
discovery, err := f.clientAccessFactory.DiscoveryClient() discovery, err := f.clientAccessFactory.DiscoveryClient()

View File

@ -47,6 +47,7 @@ import (
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions"
"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/kubernetes/pkg/util/exec" utilexec "k8s.io/kubernetes/pkg/util/exec"
) )
@ -672,7 +673,7 @@ func MustPrintWithKinds(objs []runtime.Object, infos []*resource.Info, sorter *k
// FilterResourceList receives a list of runtime objects. // FilterResourceList receives a list of runtime objects.
// If any objects are filtered, that number is returned along with a modified list. // If any objects are filtered, that number is returned along with a modified list.
func FilterResourceList(obj runtime.Object, filterFuncs kubectl.Filters, filterOpts *kubectl.PrintOptions) (int, []runtime.Object, error) { func FilterResourceList(obj runtime.Object, filterFuncs kubectl.Filters, filterOpts *printers.PrintOptions) (int, []runtime.Object, error) {
items, err := meta.ExtractList(obj) items, err := meta.ExtractList(obj)
if err != nil { if err != nil {
return 0, []runtime.Object{obj}, utilerrors.NewAggregate([]error{err}) return 0, []runtime.Object{obj}, utilerrors.NewAggregate([]error{err})
@ -697,7 +698,7 @@ func FilterResourceList(obj runtime.Object, filterFuncs kubectl.Filters, filterO
return filterCount, list, nil return filterCount, list, nil
} }
func PrintFilterCount(hiddenObjNum int, resource string, options *kubectl.PrintOptions) { func PrintFilterCount(hiddenObjNum int, resource string, options *printers.PrintOptions) {
if !options.NoHeaders && !options.ShowAll && hiddenObjNum > 0 { if !options.NoHeaders && !options.ShowAll && hiddenObjNum > 0 {
glog.V(2).Infof(" info: %d completed object(s) was(were) not shown in %s list. Pass --show-all to see all objects.\n\n", hiddenObjNum, resource) glog.V(2).Infof(" info: %d completed object(s) was(were) not shown in %s list. Pass --show-all to see all objects.\n\n", hiddenObjNum, resource)
} }

View File

@ -22,8 +22,10 @@ import (
"strings" "strings"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"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"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -105,7 +107,7 @@ func ValidateOutputArgs(cmd *cobra.Command) error {
// PrinterForCommand returns the default printer for this command. // PrinterForCommand returns the default printer for this command.
// Requires that printer flags have been added to cmd (see AddPrinterFlags). // Requires that printer flags have been added to cmd (see AddPrinterFlags).
func PrinterForCommand(cmd *cobra.Command) (kubectl.ResourcePrinter, bool, error) { func PrinterForCommand(cmd *cobra.Command, mapper meta.RESTMapper, typer runtime.ObjectTyper, decoders []runtime.Decoder) (printers.ResourcePrinter, bool, error) {
outputFormat := GetFlagString(cmd, "output") outputFormat := GetFlagString(cmd, "output")
// templates are logically optional for specifying a format. // templates are logically optional for specifying a format.
@ -131,7 +133,10 @@ func PrinterForCommand(cmd *cobra.Command) (kubectl.ResourcePrinter, bool, error
if cmd.Flags().Lookup("allow-missing-template-keys") != nil { if cmd.Flags().Lookup("allow-missing-template-keys") != nil {
allowMissingTemplateKeys = GetFlagBool(cmd, "allow-missing-template-keys") allowMissingTemplateKeys = GetFlagBool(cmd, "allow-missing-template-keys")
} }
printer, generic, err := kubectl.GetPrinter(outputFormat, templateFile, GetFlagBool(cmd, "no-headers"), allowMissingTemplateKeys) printer, generic, err := printers.GetStandardPrinter(
outputFormat, templateFile, GetFlagBool(cmd, "no-headers"), allowMissingTemplateKeys,
mapper, typer, decoders,
)
if err != nil { if err != nil {
return nil, generic, err return nil, generic, err
} }
@ -144,7 +149,7 @@ func PrinterForCommand(cmd *cobra.Command) (kubectl.ResourcePrinter, bool, error
// object passed is non-generic, it attempts to print the object using a HumanReadablePrinter. // object passed is non-generic, it attempts to print the object using a HumanReadablePrinter.
// Requires that printer flags have been added to cmd (see AddPrinterFlags). // Requires that printer flags have been added to cmd (see AddPrinterFlags).
func PrintResourceInfoForCommand(cmd *cobra.Command, info *resource.Info, f Factory, out io.Writer) error { func PrintResourceInfoForCommand(cmd *cobra.Command, info *resource.Info, f Factory, out io.Writer) error {
printer, generic, err := PrinterForCommand(cmd) printer, generic, err := f.PrinterForCommand(cmd)
if err != nil { if err != nil {
return err return err
} }
@ -157,7 +162,7 @@ func PrintResourceInfoForCommand(cmd *cobra.Command, info *resource.Info, f Fact
return printer.PrintObj(info.Object, out) return printer.PrintObj(info.Object, out)
} }
func maybeWrapSortingPrinter(cmd *cobra.Command, printer kubectl.ResourcePrinter) kubectl.ResourcePrinter { func maybeWrapSortingPrinter(cmd *cobra.Command, printer printers.ResourcePrinter) printers.ResourcePrinter {
sorting, err := cmd.Flags().GetString("sort-by") sorting, err := cmd.Flags().GetString("sort-by")
if err != nil { if err != nil {
// error can happen on missing flag or bad flag type. In either case, this command didn't intent to sort // error can happen on missing flag or bad flag type. In either case, this command didn't intent to sort