cleanup printers some more

This commit is contained in:
David Eads 2018-02-19 15:16:45 -05:00
parent 064338951f
commit dd6405681f
32 changed files with 169 additions and 150 deletions

View File

@ -266,9 +266,8 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro
}
}
mapper := r.Mapper().RESTMapper
if len(o.outputFormat) > 0 {
return f.PrintObject(cmd, o.local, mapper, outputObj, o.out)
return f.PrintObject(cmd, outputObj, o.out)
}
f.PrintSuccess(false, o.out, info.Mapping.Resource, info.Name, o.dryrun, "annotated")
return nil

View File

@ -156,7 +156,7 @@ func RunAutoscale(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s
object = hpa.Object
}
if cmdutil.GetDryRunFlag(cmd) {
return f.PrintObject(cmd, false, mapper, object, out)
return f.PrintObject(cmd, object, out)
}
if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), hpa, f.JSONEncoder()); err != nil {
@ -170,7 +170,7 @@ func RunAutoscale(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s
count++
if len(cmdutil.GetFlagString(cmd, "output")) > 0 {
return f.PrintObject(cmd, false, mapper, object, out)
return f.PrintObject(cmd, object, out)
}
f.PrintSuccess(false, out, info.Mapping.Resource, info.Name, cmdutil.GetDryRunFlag(cmd), "autoscaled")

View File

@ -237,8 +237,7 @@ func Example_printReplicationControllerWithNamespace() {
ReadyReplicas: 1,
},
}
mapper, _ := f.Object()
err := f.PrintObject(cmd, false, mapper, ctrl, os.Stdout)
err := f.PrintObject(cmd, ctrl, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
@ -291,8 +290,7 @@ func Example_printMultiContainersReplicationControllerWithWide() {
Replicas: 1,
},
}
mapper, _ := f.Object()
err := f.PrintObject(cmd, false, mapper, ctrl, os.Stdout)
err := f.PrintObject(cmd, ctrl, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
@ -344,8 +342,7 @@ func Example_printReplicationController() {
Replicas: 1,
},
}
mapper, _ := f.Object()
err := f.PrintObject(cmd, false, mapper, ctrl, os.Stdout)
err := f.PrintObject(cmd, ctrl, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
@ -386,8 +383,7 @@ func Example_printPodWithWideFormat() {
PodIP: "10.1.1.3",
},
}
mapper, _ := f.Object()
err := f.PrintObject(cmd, false, mapper, pod, os.Stdout)
err := f.PrintObject(cmd, pod, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
@ -431,8 +427,7 @@ func Example_printPodWithShowLabels() {
},
},
}
mapper, _ := f.Object()
err := f.PrintObject(cmd, false, mapper, pod, os.Stdout)
err := f.PrintObject(cmd, pod, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
@ -554,8 +549,7 @@ func Example_printPodHideTerminated() {
fmt.Printf("Unexpected filter error: %v\n", errs)
}
for _, pod := range filteredPodList {
mapper, _ := f.Object()
err := f.PrintObject(cmd, false, mapper, pod, os.Stdout)
err := f.PrintObject(cmd, pod, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
@ -581,8 +575,7 @@ func Example_printPodShowAll() {
}
cmd := NewCmdRun(f, os.Stdin, os.Stdout, os.Stderr)
podList := newAllPhasePodList()
mapper, _ := f.Object()
err := f.PrintObject(cmd, false, mapper, podList, os.Stdout)
err := f.PrintObject(cmd, podList, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
@ -657,8 +650,7 @@ func Example_printServiceWithNamespacesAndLabels() {
}
ld := strings.NewLineDelimiter(os.Stdout, "|")
defer ld.Flush()
mapper, _ := f.Object()
err := f.PrintObject(cmd, false, mapper, svc, ld)
err := f.PrintObject(cmd, svc, ld)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}

View File

@ -82,7 +82,6 @@ func NewCmdConfigView(f cmdutil.Factory, out, errOut io.Writer, ConfigAccess cli
printOpts := cmdutil.ExtractCmdPrintOptions(cmd, false)
printer, err := f.PrinterForOptions(printOpts)
cmdutil.CheckErr(err)
printer = printers.NewVersionedPrinter(printer, latest.Scheme, latest.ExternalVersion)
cmdutil.CheckErr(options.Run(out, printer))
},
@ -120,7 +119,12 @@ func (o ViewOptions) Run(out io.Writer, printer printers.ResourcePrinter) error
clientcmdapi.ShortenConfig(config)
}
err = printer.PrintObj(config, out)
convertedObj, err := latest.Scheme.ConvertToVersion(config, latest.ExternalVersion)
if err != nil {
return err
}
err = printer.PrintObj(convertedObj, out)
if err != nil {
return err
}

View File

@ -360,5 +360,5 @@ func RunCreateSubcommand(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, o
return nil
}
return f.PrintObject(cmd, false, mapper, obj, out)
return f.PrintObject(cmd, obj, out)
}

View File

@ -206,7 +206,7 @@ func (c *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
}
c.PrintObject = func(obj runtime.Object) error {
return f.PrintObject(cmd, false, c.Mapper, obj, c.Out)
return f.PrintObject(cmd, obj, c.Out)
}
clientset, err := f.KubernetesClientSet()

View File

@ -255,7 +255,7 @@ func RunExpose(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
info.Refresh(object, true)
if cmdutil.GetDryRunFlag(cmd) {
if len(cmdutil.GetFlagString(cmd, "output")) > 0 {
return f.PrintObject(cmd, false, mapper, object, out)
return f.PrintObject(cmd, object, out)
}
f.PrintSuccess(false, out, info.Mapping.Resource, info.Name, true, "exposed")
return nil
@ -271,7 +271,7 @@ func RunExpose(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
}
if len(cmdutil.GetFlagString(cmd, "output")) > 0 {
return f.PrintObject(cmd, false, mapper, object, out)
return f.PrintObject(cmd, object, out)
}
f.PrintSuccess(false, out, info.Mapping.Resource, info.Name, false, "exposed")

View File

@ -288,7 +288,7 @@ func (o *LabelOptions) RunLabel(f cmdutil.Factory, cmd *cobra.Command) error {
}
if len(o.outputFormat) > 0 {
return f.PrintObject(cmd, o.local, r.Mapper().RESTMapper, outputObj, o.out)
return f.PrintObject(cmd, outputObj, o.out)
}
f.PrintSuccess(false, o.out, info.Mapping.Resource, info.Name, o.dryrun, dataChangeMsg)
return nil

View File

@ -22,6 +22,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",

View File

@ -32,6 +32,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/watch"
@ -340,7 +341,7 @@ func (options *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []str
updatePrintOptionsForOpenAPI(f, mapping, printOpts)
}
printer, err = f.PrinterForMapping(printOpts, mapping)
printer, err = f.PrinterForMapping(printOpts)
if err != nil {
if !errs.Has(err.Error()) {
errs.Insert(err.Error())
@ -493,7 +494,7 @@ func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []s
info := infos[0]
mapping := info.ResourceMapping()
printOpts := cmdutil.ExtractCmdPrintOptions(cmd, options.AllNamespaces)
printer, err := f.PrinterForMapping(printOpts, mapping)
printer, err := f.PrinterForMapping(printOpts)
if err != nil {
return err
}
@ -531,7 +532,13 @@ func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []s
if isFiltered, err := filterFuncs.Filter(objToPrint, filterOpts); !isFiltered {
if err != nil {
glog.V(2).Infof("Unable to filter resource: %v", err)
} else if err := printer.PrintObj(objToPrint, writer); err != nil {
continue
}
// 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)
}
}
@ -558,7 +565,13 @@ func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []s
if isFiltered, err := filterFuncs.Filter(e.Object, filterOpts); !isFiltered {
if err != nil {
glog.V(2).Infof("Unable to filter resource: %v", err)
} else if err := printer.PrintObj(e.Object, options.Out); err != nil {
return false, nil
}
// 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
}
}
@ -569,6 +582,16 @@ func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []s
return nil
}
// attemptToConvertToInternal tries to convert to an internal type, but returns the original if it can't
func attemptToConvertToInternal(obj runtime.Object, converter runtime.ObjectConvertor, targetVersion schema.GroupVersion) runtime.Object {
internalObject, err := converter.ConvertToVersion(obj, targetVersion)
if err != nil {
glog.V(1).Infof("Unable to convert %T to %v: err", obj, targetVersion, err)
return obj
}
return internalObject
}
func (options *GetOptions) printGeneric(printer printers.ResourcePrinter, r *resource.Result, filterFuncs kubectl.Filters, filterOpts *printers.PrintOptions) error {
// 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

View File

@ -191,8 +191,6 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args
var keepOldName bool
var replicasDefaulted bool
mapper, _ := f.Object()
if len(filename) != 0 {
schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"))
if err != nil {
@ -322,10 +320,10 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args
oldRcData.WriteString(oldRc.Name)
newRcData.WriteString(newRc.Name)
} else {
if err := f.PrintObject(cmd, false, mapper, oldRc, oldRcData); err != nil {
if err := f.PrintObject(cmd, oldRc, oldRcData); err != nil {
return err
}
if err := f.PrintObject(cmd, false, mapper, newRc, newRcData); err != nil {
if err := f.PrintObject(cmd, newRc, newRcData); err != nil {
return err
}
}
@ -370,7 +368,7 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args
return err
}
if outputFormat != "" {
return f.PrintObject(cmd, false, mapper, newRc, out)
return f.PrintObject(cmd, newRc, out)
}
f.PrintSuccess(false, out, "replicationcontrollers", oldName, dryrun, message)
return nil

View File

@ -407,7 +407,7 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
if runObject != nil {
outputFormat := cmdutil.GetFlagString(cmd, "output")
if outputFormat != "" || cmdutil.GetDryRunFlag(cmd) {
return f.PrintObject(cmd, false, runObject.Mapper, runObject.Object, cmdOut)
return f.PrintObject(cmd, runObject.Object, cmdOut)
}
f.PrintSuccess(false, cmdOut, runObject.Mapping.Resource, args[0], cmdutil.GetDryRunFlag(cmd), "created")
}
@ -557,7 +557,7 @@ func generateService(f cmdutil.Factory, cmd *cobra.Command, args []string, servi
}
if cmdutil.GetFlagString(cmd, "output") != "" || cmdutil.GetDryRunFlag(cmd) {
err := f.PrintObject(cmd, false, runObject.Mapper, runObject.Object, out)
err := f.PrintObject(cmd, runObject.Object, out)
if err != nil {
return nil, err
}

View File

@ -59,6 +59,7 @@ go_test(
embed = [":go_default_library"],
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/set",
deps = [
"//pkg/api/legacyscheme:go_default_library",
"//pkg/api/testapi:go_default_library",
"//pkg/apis/rbac:go_default_library",
"//pkg/kubectl/categories:go_default_library",

View File

@ -26,7 +26,6 @@ import (
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
@ -116,7 +115,6 @@ type EnvOptions struct {
From string
Prefix string
Mapper meta.RESTMapper
Builder *resource.Builder
Infos []*resource.Info
Encoder runtime.Encoder
@ -124,7 +122,7 @@ type EnvOptions struct {
Cmd *cobra.Command
UpdatePodSpecForObject func(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error)
PrintObject func(cmd *cobra.Command, isLocal bool, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error
PrintObject func(cmd *cobra.Command, obj runtime.Object, out io.Writer) error
}
// NewCmdEnv implements the OpenShift cli env command
@ -189,7 +187,6 @@ func (o *EnvOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
return cmdutil.UsageErrorf(cmd, "one or more resources must be specified as <resource> <name> or <resource>/<name>")
}
o.Mapper, _ = f.Object()
o.UpdatePodSpecForObject = f.UpdatePodSpecForObject
o.Encoder = f.JSONEncoder()
o.ContainerSelector = cmdutil.GetFlagString(cmd, "containers")
@ -417,7 +414,7 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error {
}
if o.PrintObject != nil && (o.Local || o.DryRun) {
if err := o.PrintObject(o.Cmd, o.Local, o.Mapper, patch.Info.AsVersioned(), o.Out); err != nil {
if err := o.PrintObject(o.Cmd, patch.Info.AsVersioned(), o.Out); err != nil {
return err
}
continue
@ -437,7 +434,7 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error {
}
if len(o.Output) > 0 {
if err := o.PrintObject(o.Cmd, o.Local, o.Mapper, info.AsVersioned(), o.Out); err != nil {
if err := o.PrintObject(o.Cmd, info.AsVersioned(), o.Out); err != nil {
return err
}
continue

View File

@ -38,6 +38,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/kubectl/categories"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
@ -435,7 +436,7 @@ func TestSetEnvRemote(t *testing.T) {
testapi.Default = testapi.Groups[input.testAPIGroup]
f, tf, _, ns := cmdtesting.NewAPIFactory()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
tf.Printer = printers.NewVersionedPrinter(&printers.YAMLPrinter{}, testapi.Default.Converter(), *testapi.Default.GroupVersion())
tf.Printer = printers.NewVersionedPrinter(&printers.YAMLPrinter{}, legacyscheme.Scheme, legacyscheme.Scheme, scheme.Versions...)
tf.Namespace = "test"
tf.CategoryExpander = categories.LegacyCategoryExpander
tf.Client = &fake.RESTClient{

View File

@ -22,7 +22,6 @@ import (
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
@ -37,7 +36,6 @@ import (
type ImageOptions struct {
resource.FilenameOptions
Mapper meta.RESTMapper
Infos []*resource.Info
Encoder runtime.Encoder
Decoder runtime.Decoder
@ -55,7 +53,7 @@ type ImageOptions struct {
ResolveImage func(in string) (string, error)
PrintSuccess func(shortOutput bool, out io.Writer, resource, name string, dryRun bool, operation string)
PrintObject func(cmd *cobra.Command, isLocal bool, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error
PrintObject func(cmd *cobra.Command, obj runtime.Object, out io.Writer) error
UpdatePodSpecForObject func(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error)
Resources []string
ContainerImages map[string]string
@ -117,7 +115,6 @@ func NewCmdImage(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
}
func (o *ImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.Mapper, _ = f.Object()
o.PrintSuccess = f.PrintSuccess
o.UpdatePodSpecForObject = f.UpdatePodSpecForObject
o.Encoder = f.JSONEncoder()
@ -249,7 +246,7 @@ func (o *ImageOptions) Run() error {
}
if o.PrintObject != nil && (o.Local || o.DryRun) {
if err := o.PrintObject(o.Cmd, o.Local, o.Mapper, patch.Info.AsVersioned(), o.Out); err != nil {
if err := o.PrintObject(o.Cmd, patch.Info.AsVersioned(), o.Out); err != nil {
return err
}
continue
@ -275,7 +272,7 @@ func (o *ImageOptions) Run() error {
info.Refresh(obj, true)
if len(o.Output) > 0 {
if err := o.PrintObject(o.Cmd, o.Local, o.Mapper, info.AsVersioned(), o.Out); err != nil {
if err := o.PrintObject(o.Cmd, info.AsVersioned(), o.Out); err != nil {
return err
}
continue

View File

@ -37,6 +37,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/kubectl/categories"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
@ -502,7 +503,7 @@ func TestSetImageRemote(t *testing.T) {
testapi.Default = testapi.Groups[input.testAPIGroup]
f, tf, _, ns := cmdtesting.NewAPIFactory()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
tf.Printer = printers.NewVersionedPrinter(&printers.YAMLPrinter{}, testapi.Default.Converter(), *testapi.Default.GroupVersion())
tf.Printer = printers.NewVersionedPrinter(&printers.YAMLPrinter{}, legacyscheme.Scheme, legacyscheme.Scheme, scheme.Versions...)
tf.Namespace = "test"
tf.CategoryExpander = categories.LegacyCategoryExpander
tf.Client = &fake.RESTClient{

View File

@ -23,7 +23,6 @@ import (
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
@ -62,7 +61,6 @@ var (
type ResourcesOptions struct {
resource.FilenameOptions
Mapper meta.RESTMapper
Infos []*resource.Info
Encoder runtime.Encoder
Out io.Writer
@ -81,7 +79,7 @@ type ResourcesOptions struct {
ResourceRequirements v1.ResourceRequirements
PrintSuccess func(shortOutput bool, out io.Writer, resource, name string, dryRun bool, operation string)
PrintObject func(cmd *cobra.Command, isLocal bool, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error
PrintObject func(cmd *cobra.Command, obj runtime.Object, out io.Writer) error
UpdatePodSpecForObject func(obj runtime.Object, fn func(*v1.PodSpec) error) (bool, error)
Resources []string
}
@ -128,7 +126,6 @@ func NewCmdResources(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.
}
func (o *ResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.Mapper, _ = f.Object()
o.PrintSuccess = f.PrintSuccess
o.UpdatePodSpecForObject = f.UpdatePodSpecForObject
o.Encoder = f.JSONEncoder()
@ -241,7 +238,7 @@ func (o *ResourcesOptions) Run() error {
}
if o.Local || cmdutil.GetDryRunFlag(o.Cmd) {
if err := o.PrintObject(o.Cmd, o.Local, o.Mapper, patch.Info.AsVersioned(), o.Out); err != nil {
if err := o.PrintObject(o.Cmd, patch.Info.AsVersioned(), o.Out); err != nil {
return err
}
continue
@ -266,7 +263,7 @@ func (o *ResourcesOptions) Run() error {
shortOutput := o.Output == "name"
if len(o.Output) > 0 && !shortOutput {
if err := o.PrintObject(o.Cmd, o.Local, o.Mapper, info.AsVersioned(), o.Out); err != nil {
if err := o.PrintObject(o.Cmd, info.AsVersioned(), o.Out); err != nil {
return err
}
continue

View File

@ -152,7 +152,7 @@ func (o *SelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [
}
o.PrintObject = func(obj runtime.Object) error {
return f.PrintObject(cmd, o.local, mapper, obj, o.out)
return f.PrintObject(cmd, obj, o.out)
}
o.ClientForMapping = func(mapping *meta.RESTMapping) (resource.RESTClient, error) {
return f.ClientForMapping(mapping)

View File

@ -24,7 +24,6 @@ import (
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
@ -56,7 +55,6 @@ var (
// serviceAccountConfig encapsulates the data required to perform the operation.
type serviceAccountConfig struct {
fileNameOptions resource.FilenameOptions
mapper meta.RESTMapper
encoder runtime.Encoder
out io.Writer
err io.Writer
@ -68,7 +66,7 @@ type serviceAccountConfig struct {
output string
changeCause string
local bool
PrintObject func(cmd *cobra.Command, isLocal bool, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error
PrintObject func(cmd *cobra.Command, obj runtime.Object, out io.Writer) error
updatePodSpecForObject func(runtime.Object, func(*v1.PodSpec) error) (bool, error)
printSuccess func(shortOutput bool, out io.Writer, resource, name string, dryRun bool, operation string)
infos []*resource.Info
@ -108,7 +106,6 @@ func NewCmdServiceAccount(f cmdutil.Factory, out, err io.Writer) *cobra.Command
// Complete configures serviceAccountConfig from command line args.
func (saConfig *serviceAccountConfig) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
saConfig.mapper, _ = f.Object()
saConfig.encoder = f.JSONEncoder()
saConfig.shortOutput = cmdutil.GetFlagString(cmd, "output") == "name"
saConfig.record = cmdutil.GetRecordFlag(cmd)
@ -168,7 +165,7 @@ func (saConfig *serviceAccountConfig) Run() error {
continue
}
if saConfig.local || saConfig.dryRun {
if err := saConfig.PrintObject(saConfig.cmd, saConfig.local, saConfig.mapper, patch.Info.AsVersioned(), saConfig.out); err != nil {
if err := saConfig.PrintObject(saConfig.cmd, patch.Info.AsVersioned(), saConfig.out); err != nil {
return err
}
continue
@ -187,7 +184,7 @@ func (saConfig *serviceAccountConfig) Run() error {
}
}
if len(saConfig.output) > 0 {
if err := saConfig.PrintObject(saConfig.cmd, saConfig.local, saConfig.mapper, info.AsVersioned(), saConfig.out); err != nil {
if err := saConfig.PrintObject(saConfig.cmd, info.AsVersioned(), saConfig.out); err != nil {
return err
}
continue

View File

@ -37,6 +37,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/kubectl/categories"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
@ -83,7 +84,7 @@ func TestSetServiceAccountLocal(t *testing.T) {
cmd.Flags().Set("output", "yaml")
cmd.Flags().Set("local", "true")
testapi.Default = testapi.Groups[input.apiGroup]
tf.Printer = printers.NewVersionedPrinter(&printers.YAMLPrinter{}, testapi.Default.Converter(), *testapi.Default.GroupVersion())
tf.Printer = printers.NewVersionedPrinter(&printers.YAMLPrinter{}, legacyscheme.Scheme, legacyscheme.Scheme, scheme.Versions...)
saConfig := serviceAccountConfig{fileNameOptions: resource.FilenameOptions{
Filenames: []string{input.yaml}},
out: out,
@ -317,7 +318,7 @@ func TestSetServiceAccountRemote(t *testing.T) {
testapi.Default = testapi.Groups[input.testAPIGroup]
f, tf, _, ns := cmdtesting.NewAPIFactory()
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
tf.Printer = printers.NewVersionedPrinter(&printers.YAMLPrinter{}, testapi.Default.Converter(), *testapi.Default.GroupVersion())
tf.Printer = printers.NewVersionedPrinter(&printers.YAMLPrinter{}, legacyscheme.Scheme, legacyscheme.Scheme, scheme.Versions...)
tf.Namespace = "test"
tf.CategoryExpander = categories.LegacyCategoryExpander
tf.Client = &fake.RESTClient{

View File

@ -23,7 +23,6 @@ import (
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
@ -57,8 +56,6 @@ type updateSubjects func(existings []rbac.Subject, targets []rbac.Subject) (bool
type SubjectOptions struct {
resource.FilenameOptions
Mapper meta.RESTMapper
Typer runtime.ObjectTyper
Infos []*resource.Info
Encoder runtime.Encoder
Out io.Writer
@ -74,7 +71,7 @@ type SubjectOptions struct {
Groups []string
ServiceAccounts []string
PrintObject func(mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error
PrintObject func(obj runtime.Object, out io.Writer) error
}
func NewCmdSubject(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
@ -111,12 +108,11 @@ func NewCmdSubject(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Co
}
func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.Mapper, o.Typer = f.Object()
o.Encoder = f.JSONEncoder()
o.Output = cmdutil.GetFlagString(cmd, "output")
o.DryRun = cmdutil.GetDryRunFlag(cmd)
o.PrintObject = func(mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error {
return f.PrintObject(cmd, o.Local, mapper, obj, out)
o.PrintObject = func(obj runtime.Object, out io.Writer) error {
return f.PrintObject(cmd, obj, out)
}
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
@ -242,7 +238,7 @@ func (o *SubjectOptions) Run(f cmdutil.Factory, fn updateSubjects) error {
}
if o.Local || o.DryRun {
if err := o.PrintObject(o.Mapper, info.Object, o.Out); err != nil {
if err := o.PrintObject(info.Object, o.Out); err != nil {
return err
}
continue
@ -257,7 +253,7 @@ func (o *SubjectOptions) Run(f cmdutil.Factory, fn updateSubjects) error {
shortOutput := o.Output == "name"
if len(o.Output) > 0 && !shortOutput {
return o.PrintObject(o.Mapper, info.AsVersioned(), o.Out)
return o.PrintObject(info.AsVersioned(), o.Out)
}
f.PrintSuccess(shortOutput, o.Out, info.Mapping.Resource, info.Name, false, "subjects updated")
}

View File

@ -28,7 +28,7 @@ import (
)
func TestValidate(t *testing.T) {
f, tf, _, _ := cmdtesting.NewAPIFactory()
_, tf, _, _ := cmdtesting.NewAPIFactory()
tf.Namespace = "test"
tests := map[string]struct {
@ -107,7 +107,6 @@ func TestValidate(t *testing.T) {
}
for name, test := range tests {
test.options.Mapper, _ = f.Object()
err := test.options.Validate()
if test.expectErr && err != nil {
continue

View File

@ -274,10 +274,9 @@ func (o TaintOptions) RunTaint() error {
return err
}
mapper, _ := o.f.Object()
outputFormat := cmdutil.GetFlagString(o.cmd, "output")
if outputFormat != "" {
return o.f.PrintObject(o.cmd, false, mapper, outputObj, o.out)
return o.f.PrintObject(o.cmd, outputObj, o.out)
}
o.f.PrintSuccess(false, o.out, info.Mapping.Resource, info.Name, false, operation)

View File

@ -368,7 +368,7 @@ func (f *FakeFactory) PrintResourceInfoForCommand(cmd *cobra.Command, info *reso
return err
}
if !printer.IsGeneric() {
printer, err = f.PrinterForMapping(&printers.PrintOptions{}, nil)
printer, err = f.PrinterForMapping(&printers.PrintOptions{})
if err != nil {
return err
}
@ -514,11 +514,11 @@ func (f *FakeFactory) BindFlags(flags *pflag.FlagSet) {
func (f *FakeFactory) BindExternalFlags(flags *pflag.FlagSet) {
}
func (f *FakeFactory) PrintObject(cmd *cobra.Command, isLocal bool, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error {
func (f *FakeFactory) PrintObject(cmd *cobra.Command, obj runtime.Object, out io.Writer) error {
return nil
}
func (f *FakeFactory) PrinterForMapping(printOpts *printers.PrintOptions, mapping *meta.RESTMapping) (printers.ResourcePrinter, error) {
func (f *FakeFactory) PrinterForMapping(printOpts *printers.PrintOptions) (printers.ResourcePrinter, error) {
return f.tf.Printer, f.tf.Err
}
@ -763,7 +763,7 @@ func (f *fakeAPIFactory) PrintResourceInfoForCommand(cmd *cobra.Command, info *r
return err
}
if !printer.IsGeneric() {
printer, err = f.PrinterForMapping(&printers.PrintOptions{}, nil)
printer, err = f.PrinterForMapping(&printers.PrintOptions{})
if err != nil {
return err
}
@ -848,25 +848,15 @@ func (f *fakeAPIFactory) Generators(cmdName string) map[string]kubectl.Generator
return cmdutil.DefaultGenerators(cmdName)
}
func (f *fakeAPIFactory) PrintObject(cmd *cobra.Command, isLocal bool, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error {
gvks, _, err := legacyscheme.Scheme.ObjectKinds(obj)
if err != nil {
return err
}
mapping, err := mapper.RESTMapping(gvks[0].GroupKind())
if err != nil {
return err
}
printer, err := f.PrinterForMapping(&printers.PrintOptions{}, mapping)
func (f *fakeAPIFactory) PrintObject(cmd *cobra.Command, obj runtime.Object, out io.Writer) error {
printer, err := f.PrinterForMapping(&printers.PrintOptions{})
if err != nil {
return err
}
return printer.PrintObj(obj, out)
}
func (f *fakeAPIFactory) PrinterForMapping(outputOpts *printers.PrintOptions, mapping *meta.RESTMapping) (printers.ResourcePrinter, error) {
func (f *fakeAPIFactory) PrinterForMapping(outputOpts *printers.PrintOptions) (printers.ResourcePrinter, error) {
return f.tf.Printer, f.tf.Err
}

View File

@ -239,9 +239,9 @@ type BuilderFactory interface {
// Requires that printer flags have been added to cmd (see AddPrinterFlags).
// Returns a printer, true if the printer is generic (is not internal), or
// an error if a printer could not be found.
PrinterForMapping(options *printers.PrintOptions, mapping *meta.RESTMapping) (printers.ResourcePrinter, error)
PrinterForMapping(options *printers.PrintOptions) (printers.ResourcePrinter, error)
// PrintObject prints an api object given command line flags to modify the output format
PrintObject(cmd *cobra.Command, isLocal bool, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error
PrintObject(cmd *cobra.Command, obj runtime.Object, out io.Writer) error
// PrintResourceInfoForCommand receives a *cobra.Command and a *resource.Info and
// attempts to print an info object based on the specified output format. If the
// object passed is non-generic, it attempts to print the object using a HumanReadablePrinter.

View File

@ -25,11 +25,12 @@ import (
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/kubectl/plugins"
"k8s.io/kubernetes/pkg/kubectl/resource"
kubectlscheme "k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/printers"
)
@ -48,34 +49,17 @@ func NewBuilderFactory(clientAccessFactory ClientAccessFactory, objectMappingFac
}
func (f *ring2Factory) PrinterForOptions(options *printers.PrintOptions) (printers.ResourcePrinter, error) {
_, 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}
encoder := f.clientAccessFactory.JSONEncoder()
return printerForOptions(typer, encoder, decoders, options)
return printerForOptions(options)
}
func (f *ring2Factory) PrinterForMapping(options *printers.PrintOptions, mapping *meta.RESTMapping) (printers.ResourcePrinter, error) {
func (f *ring2Factory) PrinterForMapping(options *printers.PrintOptions) (printers.ResourcePrinter, error) {
printer, err := f.PrinterForOptions(options)
if err != nil {
return nil, err
}
// Make sure we output versioned data for generic printers
if printer.IsGeneric() {
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())
}
// wrap the printer in a versioning printer that understands when to convert and when not to convert
printer = printers.NewVersionedPrinter(printer, legacyscheme.Scheme, legacyscheme.Scheme, kubectlscheme.Versions...)
return printer, nil
}
@ -101,26 +85,8 @@ func (f *ring2Factory) PrintSuccess(shortOutput bool, out io.Writer, resource, n
}
}
func (f *ring2Factory) PrintObject(cmd *cobra.Command, isLocal bool, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error {
// try to get a typed object
_, typer := f.objectMappingFactory.Object()
gvks, _, err := typer.ObjectKinds(obj)
if err != nil {
return err
}
// Prefer the existing external version if specified
var preferredVersion []string
if gvks[0].Version != "" && gvks[0].Version != runtime.APIVersionInternal {
preferredVersion = []string{gvks[0].Version}
}
mapping, err := mapper.RESTMapping(gvks[0].GroupKind(), preferredVersion...)
if err != nil {
return err
}
printer, err := f.PrinterForMapping(ExtractCmdPrintOptions(cmd, false), mapping)
func (f *ring2Factory) PrintObject(cmd *cobra.Command, obj runtime.Object, out io.Writer) error {
printer, err := f.PrinterForMapping(ExtractCmdPrintOptions(cmd, false))
if err != nil {
return err
}
@ -134,7 +100,7 @@ func (f *ring2Factory) PrintResourceInfoForCommand(cmd *cobra.Command, info *res
return err
}
if !printer.IsGeneric() {
printer, err = f.PrinterForMapping(printOpts, nil)
printer, err = f.PrinterForMapping(printOpts)
if err != nil {
return err
}

View File

@ -23,10 +23,12 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
kubectlscheme "k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/printers"
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
// AddPrinterFlags adds printing related flags to a command (e.g. output format, no headers, template path)
@ -83,8 +85,12 @@ func ValidateOutputArgs(cmd *cobra.Command) error {
// printerForOptions returns the printer for the outputOptions (if given) or
// returns the default printer for the command. Requires that printer flags have
// been added to cmd (see AddPrinterFlags).
func printerForOptions(typer runtime.ObjectTyper, encoder runtime.Encoder, decoders []runtime.Decoder, options *printers.PrintOptions) (printers.ResourcePrinter, error) {
printer, err := printers.GetStandardPrinter(typer, encoder, decoders, *options)
func printerForOptions(options *printers.PrintOptions) (printers.ResourcePrinter, error) {
// TODO: used by the custom column implementation and the name implementation, break this dependency
decoders := []runtime.Decoder{kubectlscheme.Codecs.UniversalDecoder(), unstructured.UnstructuredJSONScheme}
encoder := kubectlscheme.Codecs.LegacyCodec(kubectlscheme.Registry.EnabledVersions()...)
printer, err := printers.GetStandardPrinter(kubectlscheme.Scheme, encoder, decoders, *options)
if err != nil {
return nil, err
}

View File

@ -60,6 +60,7 @@ func init() {
scheme.AddToScheme(Scheme)
// Register external types for Registry
Versions = append(Versions, corev1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: corev1.GroupName,
@ -90,6 +91,7 @@ func init() {
panic(err)
}
Versions = append(Versions, admissionv1alpha1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: admissionv1alpha1.GroupName,
@ -103,6 +105,7 @@ func init() {
panic(err)
}
Versions = append(Versions, admissionregistrationv1alpha1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: admissionregistrationv1alpha1.GroupName,
@ -116,6 +119,7 @@ func init() {
panic(err)
}
Versions = append(Versions, appsv1.SchemeGroupVersion, appsv1beta2.SchemeGroupVersion, appsv1beta1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: appsv1.GroupName,
@ -130,6 +134,7 @@ func init() {
panic(err)
}
Versions = append(Versions, authenticationv1.SchemeGroupVersion, authenticationv1beta1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: authenticationv1beta1.GroupName,
@ -144,6 +149,7 @@ func init() {
panic(err)
}
Versions = append(Versions, authorizationv1.SchemeGroupVersion, authorizationv1beta1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: authorizationv1.GroupName,
@ -158,6 +164,7 @@ func init() {
panic(err)
}
Versions = append(Versions, autoscalingv1.SchemeGroupVersion, autoscalingv2beta1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: autoscalingv1.GroupName,
@ -171,6 +178,7 @@ func init() {
panic(err)
}
Versions = append(Versions, batchv1.SchemeGroupVersion, batchv1beta1.SchemeGroupVersion, batchv2alpha1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: batchv1.GroupName,
@ -185,6 +193,7 @@ func init() {
panic(err)
}
Versions = append(Versions, certificatesv1beta1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: certificatesv1beta1.GroupName,
@ -198,6 +207,7 @@ func init() {
panic(err)
}
Versions = append(Versions, extensionsv1beta1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: extensionsv1beta1.GroupName,
@ -211,6 +221,7 @@ func init() {
panic(err)
}
Versions = append(Versions, imagepolicyv1alpha1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: imagepolicyv1alpha1.GroupName,
@ -224,6 +235,7 @@ func init() {
panic(err)
}
Versions = append(Versions, networkingv1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: networkingv1.GroupName,
@ -236,6 +248,7 @@ func init() {
panic(err)
}
Versions = append(Versions, policyv1beta1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: policyv1beta1.GroupName,
@ -248,6 +261,7 @@ func init() {
panic(err)
}
Versions = append(Versions, rbacv1.SchemeGroupVersion, rbacv1beta1.SchemeGroupVersion, rbacv1alpha1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: rbacv1.GroupName,
@ -263,6 +277,7 @@ func init() {
panic(err)
}
Versions = append(Versions, schedulingv1alpha1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: schedulingv1alpha1.GroupName,
@ -276,6 +291,7 @@ func init() {
panic(err)
}
Versions = append(Versions, settingsv1alpha1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: settingsv1alpha1.GroupName,
@ -288,6 +304,7 @@ func init() {
panic(err)
}
Versions = append(Versions, storagev1.SchemeGroupVersion, storagev1beta1.SchemeGroupVersion)
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: storagev1.GroupName,

View File

@ -22,6 +22,7 @@ import (
"k8s.io/apimachinery/pkg/apimachinery/announced"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
)
@ -41,3 +42,8 @@ var Codecs = serializer.NewCodecFactory(Scheme)
// ParameterCodec handles versioning of objects that are converted to query parameters.
var ParameterCodec = runtime.NewParameterCodec(Scheme)
// Versions is a list of group versions in order of preferred serialization. This used to be discovered dynamically,
// from the server for use in the client, but that gives conflicting lists of non-existent versions. This only needs to
// live until we stop attempting to perform any conversion client-side and is only valid for items existent in our scheme.
var Versions = []schema.GroupVersion{}

View File

@ -91,6 +91,7 @@ func TestVersionedPrinter(t *testing.T) {
return nil
}),
legacyscheme.Scheme,
legacyscheme.Scheme,
legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
)
if err := p.PrintObj(original, nil); err != nil {
@ -288,7 +289,7 @@ func TestPrinter(t *testing.T) {
t.Errorf("in %s, unexpected error: %#v", test.Name, err)
}
if printer.IsGeneric() && len(test.OutputVersions) > 0 {
printer = printers.NewVersionedPrinter(printer, legacyscheme.Scheme, test.OutputVersions...)
printer = printers.NewVersionedPrinter(printer, legacyscheme.Scheme, legacyscheme.Scheme, test.OutputVersions...)
}
if err := printer.PrintObj(test.Input, buf); err != nil {
t.Errorf("in %s, unexpected error: %#v", test.Name, err)
@ -622,7 +623,7 @@ func TestTemplateStrings(t *testing.T) {
t.Fatalf("tmpl fail: %v", err)
}
printer := printers.NewVersionedPrinter(p, legacyscheme.Scheme, legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion)
printer := printers.NewVersionedPrinter(p, legacyscheme.Scheme, legacyscheme.Scheme, legacyscheme.Registry.GroupOrDie(api.GroupName).GroupVersion)
for name, item := range table {
buffer := &bytes.Buffer{}
@ -655,19 +656,19 @@ func TestPrinters(t *testing.T) {
if err != nil {
t.Fatal(err)
}
templatePrinter = printers.NewVersionedPrinter(templatePrinter, legacyscheme.Scheme, v1.SchemeGroupVersion)
templatePrinter = printers.NewVersionedPrinter(templatePrinter, legacyscheme.Scheme, legacyscheme.Scheme, v1.SchemeGroupVersion)
templatePrinter2, err = printers.NewTemplatePrinter([]byte("{{len .items}}"))
if err != nil {
t.Fatal(err)
}
templatePrinter2 = printers.NewVersionedPrinter(templatePrinter2, legacyscheme.Scheme, v1.SchemeGroupVersion)
templatePrinter2 = printers.NewVersionedPrinter(templatePrinter2, legacyscheme.Scheme, legacyscheme.Scheme, v1.SchemeGroupVersion)
jsonpathPrinter, err = printers.NewJSONPathPrinter("{.metadata.name}")
if err != nil {
t.Fatal(err)
}
jsonpathPrinter = printers.NewVersionedPrinter(jsonpathPrinter, legacyscheme.Scheme, v1.SchemeGroupVersion)
jsonpathPrinter = printers.NewVersionedPrinter(jsonpathPrinter, legacyscheme.Scheme, legacyscheme.Scheme, v1.SchemeGroupVersion)
allPrinters := map[string]printers.ResourcePrinter{
"humanReadable": printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{

View File

@ -20,6 +20,7 @@ import (
"fmt"
"io"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
@ -29,14 +30,16 @@ import (
type VersionedPrinter struct {
printer ResourcePrinter
converter runtime.ObjectConvertor
typer runtime.ObjectTyper
versions []schema.GroupVersion
}
// NewVersionedPrinter wraps a printer to convert objects to a known API version prior to printing.
func NewVersionedPrinter(printer ResourcePrinter, converter runtime.ObjectConvertor, versions ...schema.GroupVersion) ResourcePrinter {
func NewVersionedPrinter(printer ResourcePrinter, converter runtime.ObjectConvertor, typer runtime.ObjectTyper, versions ...schema.GroupVersion) ResourcePrinter {
return &VersionedPrinter{
printer: printer,
converter: converter,
typer: typer,
versions: versions,
}
}
@ -47,6 +50,33 @@ func (p *VersionedPrinter) AfterPrint(w io.Writer, res string) error {
// PrintObj implements ResourcePrinter
func (p *VersionedPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
gvks, _, err := p.typer.ObjectKinds(obj)
if err != nil {
return err
}
needsConversion := false
for _, gvk := range gvks {
if len(gvk.Version) == 0 || gvk.Version == runtime.APIVersionInternal {
needsConversion = true
}
}
// if we're unstructured, no conversion necessary
if _, ok := obj.(*unstructured.Unstructured); ok {
return p.printer.PrintObj(obj, w)
}
// if we aren't a generic printer, we don't convert. This means the printer must be aware of what it is getting.
// The default printers fall into this category.
// TODO eventually, all printers must be generic
if !p.IsGeneric() {
return p.printer.PrintObj(obj, w)
}
// if we're already external, no conversion necessary
if !needsConversion {
return p.printer.PrintObj(obj, w)
}
if len(p.versions) == 0 {
return fmt.Errorf("no version specified, object cannot be converted")
}